// Parse the input file into the module. bool parse(Path const& in, Config const& conf) { try { // Read the input source. File src = in.c_str(); Input_buffer buf = src; // Lex the input source. Token_stream ts; Location_map locs; Lexer lex(syms, buf); if (!lex.lex(ts)) return false; // Parse the token stream. Parser parse(syms, ts, locs); if (!parse.module(&mod)) return false; return true; } // Diagnose uncaught translation errors and exit // gracefully. All other uncaught exceptions are // ICEs and we want those to fail noisily. Note // that re-throwing does not re-establish the // origin of the error for the purpose of debugging. catch (Translation_error& err) { diagnose(err); return false; } }
static cmark_node *symbol_link_match(cmark_syntax_extension *self, cmark_parser *parser, cmark_node *parent, cmark_inline_parser *inline_parser) { cmark_node *link = NULL; char *symbol_name = NULL; NamedLink *named_link = NULL; int start_offset = cmark_inline_parser_get_offset(inline_parser); ParsingContext context; context.parser = inline_parser; context.allow_dashes = 0; if (start_offset > 0) { char prev_char = cmark_inline_parser_peek_at( inline_parser, start_offset - 1); if (prev_char && prev_char != ' ' && prev_char != '\t' && prev_char != '\n') return NULL; } cmark_inline_parser_advance_offset(inline_parser); symbol_name = cmark_inline_parser_take_while(inline_parser, (CMarkInlinePredicate) is_valid_symbol_name, &context); if (!symbol_name) goto done; named_link = PRIV(self)->link_resolve_func(symbol_name); if (!named_link || !named_link->ref) { int actual_line, actual_col; translate_sourcepos(get_first_parent_block(parent), start_offset, &actual_line, &actual_col); cmark_strbuf *message = cmark_strbuf_new(0); cmark_strbuf_puts(message, "Trying to link to non-existing symbol ‘"); cmark_strbuf_puts(message, symbol_name); cmark_strbuf_puts(message, "’"); diagnose("gtk-doc-bad-link", cmark_strbuf_get(message), actual_line - 1, actual_col - 1); cmark_strbuf_free(message); link = cmark_node_new (CMARK_NODE_TEXT); cmark_node_set_literal (link, symbol_name); } else { link = cmark_node_new(CMARK_NODE_LINK); } cmark_node_set_url(link, symbol_name); done: free(symbol_name); free_named_link(named_link); return link; }
// Parse a module. // // module -> decl-seq | <empty> // // decl-seq -> decl | decl-seq // // TODO: Return an empty module. Decl* Parser::module() { Decl_seq decls; while (!ts_.eof()) { try { Decl* d = decl(); decls.push_back(d); } catch (Translation_error& err) { diagnose(err); consume_thru(term_); } } return on_module(decls); }
bool compile(Path const& in, Path const& out) { try { // Read the input source. File src = in.c_str(); Input_buffer buf = src; // Lex the input source. Token_stream ts; Location_map locs; Lexer lex(syms, buf); if (!lex.lex(ts)) return -1; // Parse the token stream. Parser parse(syms, ts, locs); Decl* m = parse.module(); if (!parse) return -1; // Perform semantic analysis. Elaborator elab(locs, syms); elab.elaborate(m); // Translate to LLVM. Generator gen; llvm::Module* mod = gen(m); std::error_code err; llvm::raw_fd_ostream ofs(out.string(), err, llvm::sys::fs::F_None); ofs << *mod; return true; } // Diagnose uncaught translation errors and exit // gracefully. All other uncaught exceptions are // ICEs and we want those to fail noisily. Note // that re-throwing does not re-establish the // origin of the error for the purpose of debugging. catch (Translation_error& err) { diagnose(err); return false; } }
// Parse a block statement. // // block-stmt -> '{' [stmt-seq] '}' // // stmt-seq -> stmt | stmt stmt-seq Stmt* Parser::block_stmt() { Stmt_seq stmts; require(lbrace_tok); while (lookahead() != rbrace_tok) { try { Stmt* s = stmt(); stmts.push_back(s); } catch (Translation_error& err) { diagnose(err); consume_thru(term_); } } // TODO: This may be a generally unrecoverable error. term_ = rbrace_tok; match(rbrace_tok); return on_block(stmts); }
/* (I need practice using input buffers, though) */ int main(int argc, char *argv[]) { /* Open file */ if((fid = fopen(argv[1], "r")) == NULL) { printf("The diagnosis program crashed \n"); return -1; } /* Allocated to the file size, an upper bound of the number of tokens */ /* Actually I'll just allocate 1000 bytes for now. It's simpler. */ // tokens = malloc(1000*sizeof(int)); int i; for(i = 0; i < 1000; i++) { fscanf(fid, "%i", &tokens[i]); } if(diagnose() == -1) printf("The diagnosis program crashed\n"); else if (errorNum == 0) printf("The diagnosis program couldn't find any errors\n"); return 0; }
void IndexerJob::execute() { if (isAborted()) return; mTimer.start(); mData.reset(new IndexData); if (mType == Dump) { assert(id() != -1); if (shared_ptr<Project> p = project()) { for (int i=0; i<mSourceInformation.builds.size(); ++i) { parse(i); if (mUnits.at(i).second) { DumpUserData u = { 0, this, !(queryFlags() & QueryMessage::NoContext) }; clang_visitChildren(clang_getTranslationUnitCursor(mUnits.at(i).second), IndexerJob::dumpVisitor, &u); } } } } else { { MutexLocker lock(&mMutex); mStarted = true; } int errorCount = 0; int unitCount = 0; const int buildCount = mSourceInformation.builds.size(); for (int i=0; i<buildCount; ++i) { if (!parse(i)) { goto end; } if (mUnits.at(i).second) ++unitCount; } mParseTime = time(0); for (int i=0; i<buildCount; ++i) { int err = 0; if (!visit(i) || !diagnose(i, &err)) goto end; errorCount += err; } { mData->message += mSourceInformation.sourceFile.toTilde(); if (buildCount > 1) mData->message += String::format<16>(" (%d builds)", buildCount); if (!unitCount) { mData->message += " error"; } else if (unitCount != buildCount) { mData->message += String::format<16>(" (%d errors, %d ok)", buildCount - unitCount, unitCount); } mData->message += String::format<16>(" in %sms. ", String::number(mTimer.elapsed()).constData()); if (unitCount) { mData->message += String::format<1024>("(%d syms, %d symNames, %d refs, %d deps, %d files)", mData->symbols.size(), mData->symbolNames.size(), mData->references.size(), mData->dependencies.size(), mVisitedFiles.size()); } else if (mData->dependencies.size()) { mData->message += String::format<16>("(%d deps)", mData->dependencies.size()); } if (mType == Dirty) mData->message += " (dirty)"; } end: shared_ptr<Project> p = project(); if (p) { shared_ptr<IndexerJob> job = static_pointer_cast<IndexerJob>(shared_from_this()); p->onJobFinished(job); } } for (int i=0; i<mUnits.size(); ++i) { if (mUnits.at(i).first) clang_disposeIndex(mUnits.at(i).first); if (mUnits.at(i).second) clang_disposeTranslationUnit(mUnits.at(i).second); } mUnits.clear(); }
int main(int argc, char **argv) { FILE *fp; int iBr = NO_WRITING; int bForce = 0; int bPrintVersion = 0; int bKeepLabel = 1; int bWritePartitionInfo = 0; int iHeads = -1; int iRet = 0; nls_init(); if(parse_switches(argc, argv, &iBr, &bForce, &bPrintVersion, &bKeepLabel, &bWritePartitionInfo, &iHeads)) { print_help(argv[0]); return 0; } if(bPrintVersion) { print_version(); if(argc < 3) return 0; } fp=fopen(argv[argc-1], (iBr || bWritePartitionInfo) ? "r+b" : "rb"); if(!fp) { printf(_("Unable to open %s, %s\n"), argv[argc-1], strerror(errno)); return 1; } if(iBr == AUTO_BR) { iBr = smart_select(fp); if(!iBr) printf(_("Unable to automaticly select boot record for %s\n"), argv[argc-1]); } if(iBr && !bForce) { if(!sanity_check(fp, argv[argc-1], iBr, 1)) { fclose(fp); return 1; } } if(bWritePartitionInfo) { if(!iBr && !bForce) { if(!sanity_check(fp, argv[argc-1], FAT32_BR, 1)) { fclose(fp); return 1; } } if(write_partition_start_sector_number(fp)) { printf(_("Start sector %ld (nr of hidden sectors) successfully written to %s\n"), partition_start_sector(fp), argv[argc-1]); if( write_partition_physical_disk_drive_id(fp) ) { printf(_("Physical disk drive id 0x80 (C:) successfully written to %s\n"), argv[argc-1]); if( write_partition_number_of_heads(fp, iHeads)) { printf(_("Number of heads (%d) successfully written to %s\n"), iHeads != -1 ? iHeads : partition_number_of_heads(fp), argv[argc-1]); } else { printf(_("Failed writing number of heads to %s\n"), argv[argc-1]); } } else { printf(_("Failed writing physical disk drive id to %s\n"), argv[argc-1]); } } else { printf(_("Failed writing start sector to %s, this is only possible to do with\n"), argv[argc-1]); printf(_("real partitions!\n")); iRet = 1; } } switch(iBr) { case NO_WRITING: { if( ! bWritePartitionInfo ) { diagnose(fp, argv[argc-1]); } break; } case MBR_WIN7FAT: { if(write_win7_fat_mbr(fp)) printf(_("Windows 7 FAT master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing Windows 7 FAT master boot record to %s\n"), argv[argc-1]); iRet = 1; } } case MBR_WIN7: { if(write_win7_mbr(fp)) printf(_("Windows 7 master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing Windows 7 master boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case MBR_VISTA: { if(write_vista_mbr(fp)) printf(_("Windows Vista master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing Windows Vista master boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case MBR_2000: { if(write_2000_mbr(fp)) printf(_("Windows 2000/XP/2003 master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing Windows 2000/XP/2003 master boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case MBR_95B: { if(write_95b_mbr(fp)) printf(_("Windows 95B/98/98SE/ME master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing Windows 95B/98/98SE/ME master boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case MBR_DOS: { if(write_dos_mbr(fp)) printf(_("DOS/Windows NT master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing DOS/Windows NT master boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case MBR_SYSLINUX: { if(write_syslinux_mbr(fp)) printf(_("Syslinux master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing syslinux master boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case MBR_GPT_SYSLINUX: { if(write_syslinux_gpt_mbr(fp)) printf(_("Syslinux GPT master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing syslinux GPT master boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case MBR_ZERO: { if(write_zero_mbr(fp)) printf(_("Empty (zeroed) master boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing empty (zeroed) master boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT12W7_BR: { if(write_fat_12_w7_br(fp, bKeepLabel)) printf(_("FAT12 Win 7 boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT12 Win 7 boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT12_BR: { if(write_fat_12_br(fp, bKeepLabel)) printf(_("FAT12 boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT12 boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT16_BR: { if(write_fat_16_br(fp, bKeepLabel)) printf(_("FAT16 boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT16 boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT16FD_BR: { if(write_fat_16_fd_br(fp, bKeepLabel)) printf(_("FAT16 FreeDOS boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT16 FreeDOS boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT32NT_BR: { if(write_fat_32_nt_br(fp, bKeepLabel)) printf(_("FAT32 NT boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT32 NT boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT32PE_BR: { if(write_fat_32_pe_br(fp, bKeepLabel)) printf(_("FAT32 PE boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT32 PE boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT32FD_BR: { if(write_fat_32_fd_br(fp, bKeepLabel)) printf(_("FAT32 FreeDOS boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT32 FreeDOS boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT32W7_BR: { if(write_fat_32_w7_br(fp, bKeepLabel)) printf(_("FAT32 Win 7 boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT32 Win 7 boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case FAT32_BR: { if(write_fat_32_br(fp, bKeepLabel)) printf(_("FAT32 DOS boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing FAT32 DOS boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; case NTFS_BR: { if(write_ntfs_br(fp)) printf(_("NTFS Windows 7 boot record successfully written to %s\n"), argv[argc-1]); else { printf(_("Failed writing NTFS Windows 7 boot record to %s\n"), argv[argc-1]); iRet = 1; } } break; default: { printf(_("Whoops, internal error, unknown boot record\n")); } break; } fclose(fp); return iRet; } /* main */
int main(int argc, char *argv[]) { int failure = 0, option_index, rc; char path[PATH_MAX]; DIR *edir, *sdir; struct dirent *sdirent, *edirent; struct dev_vpd *diagnosed = NULL; platform = get_platform(); if (platform != PLATFORM_PSERIES_LPAR) { fprintf(stderr, "%s is not supported on the %s platform\n", argv[0], __power_platform_name(platform)); return -1; } memset(&cmd_opts, 0, sizeof(cmd_opts)); for (;;) { option_index = 0; rc = getopt_long(argc, argv, "cf:hlsvV", long_options, &option_index); if (rc == -1) break; switch (rc) { case 'c': cmd_opts.cmp_prev = 1; break; case 'f': if (cmd_opts.fake_path) { fprintf(stderr, "Multiple -f options not " "supported.\n"); return -1; } cmd_opts.fake_path = optarg; break; case 'h': print_usage(argv[0]); return 0; case 'l': cmd_opts.leds = 1; break; case 's': cmd_opts.serv_event = 1; break; case 'v': cmd_opts.verbose = 1; break; case 'V': printf("%s %s\n", argv[0], VERSION); return 0; case '?': print_usage(argv[0]); return -1; default: /* Shouldn't get here. */ fprintf(stderr, "huh?\n"); print_usage(argv[0]); return -1; } } if (cmd_opts.cmp_prev && !cmd_opts.serv_event) { fprintf(stderr, "No -c option without -s\n"); return -1; } if (cmd_opts.leds && !cmd_opts.serv_event) { fprintf(stderr, "No -l option without -s\n"); return -1; } if ((cmd_opts.serv_event || cmd_opts.leds) && geteuid() != 0) { fprintf(stderr, "-s and -l options require superuser " "privileges\n"); return -1; } if (cmd_opts.fake_path) { const char *dot = strrchr(cmd_opts.fake_path, '.'); if (!dot || strcmp(dot, ".pg2") != 0) { fprintf(stderr, "Name of file with fake diagnostic " "data must end in '.pg2'.\n"); return -1; } if (optind + 1 != argc) { fprintf(stderr, "Please specify an sg device with the " "-f pathname. It need not be an " "enclosure.\n"); return -1; } failure += diagnose(argv[optind++], &diagnosed); } else if (optind < argc) { while (optind < argc) failure += diagnose(argv[optind++], &diagnosed); } else { edir = opendir(SCSI_SES_PATH); if (!edir) { fprintf(stderr, "System does not have SCSI enclosure(s).\n"); return -1; } /* loop over all enclosures */ while ((edirent = readdir(edir)) != NULL) { if (!strcmp(edirent->d_name, ".") || !strcmp(edirent->d_name, "..")) continue; snprintf(path, PATH_MAX, "%s/%s/device/scsi_generic", SCSI_SES_PATH, edirent->d_name); sdir = opendir(path); if (!sdir) continue; while ((sdirent = readdir(sdir)) != NULL) { if (!strcmp(sdirent->d_name, ".") || !strcmp(sdirent->d_name, "..")) continue; /* run diagnostics */ failure += diagnose(sdirent->d_name, &diagnosed); } closedir(sdir); } /* outer while loop */ closedir(edir); } free(cmd_opts.prev_path); free_dev_vpd(diagnosed); return failure; }
static cmark_node *fixup_nodes(cmark_syntax_extension *self, cmark_parser *parser, cmark_inline_parser *inline_parser, cmark_node *parent, int start_offset, int size) { int node_text_len; cmark_node *prev = NULL; cmark_node *tmp; int name_size = size; cmark_strbuf *name; NamedLink *named_link; for (prev = cmark_node_last_child(parent); prev; prev = cmark_node_previous(prev)) { if (cmark_node_get_type(prev) == CMARK_NODE_TEXT) { const char *text = cmark_node_get_literal(prev); node_text_len = strlen(text); size -= node_text_len; if (size <= 0) { if (size < 0) { char *split_text = my_strndup(text, size * -1); cmark_node *split = cmark_node_new(CMARK_NODE_TEXT); cmark_node_set_literal(split, split_text); free(split_text); split_text = my_strndup(text + (size * - 1), node_text_len - size); cmark_node_set_literal(prev, split_text); free(split_text); cmark_node_insert_before(prev, split); } break; } } else { return NULL; } } name = cmark_strbuf_new(name_size + 1); tmp = prev; while (tmp) { cmark_node *next = cmark_node_next(tmp); cmark_strbuf_puts(name, cmark_node_get_literal(tmp)); if (tmp != prev) cmark_node_free(tmp); tmp = next; } named_link = PRIV(self)->link_resolve_func(cmark_strbuf_get(name)); if (!named_link || !named_link->ref) { int actual_line, actual_col; translate_sourcepos(get_first_parent_block(parent), start_offset, &actual_line, &actual_col); cmark_strbuf *message = cmark_strbuf_new(0); cmark_strbuf_puts(message, "Trying to link to non-existing symbol ‘"); cmark_strbuf_puts(message, cmark_strbuf_get(name)); cmark_strbuf_puts(message, "’"); diagnose("gtk-doc-bad-link", cmark_strbuf_get(message), actual_line - 1, actual_col - 1); cmark_strbuf_free(message); cmark_node_set_literal(prev, cmark_strbuf_get(name)); cmark_strbuf_free(name); return prev; } free_named_link(named_link); cmark_node_set_type(prev, CMARK_NODE_LINK); cmark_node_set_url(prev, cmark_strbuf_get(name)); cmark_strbuf_free(name); return prev; }
bool ClangIndexer::exec(const String &data) { Deserializer deserializer(data); uint16_t protocolVersion; deserializer >> protocolVersion; if (protocolVersion != RTags::DatabaseVersion) { error("Wrong protocol %d vs %d", protocolVersion, RTags::DatabaseVersion); return false; } String serverFile; uint32_t flags; uint32_t connectTimeout; extern bool suspendOnSigSegv; Hash<uint32_t, Path> blockedFiles; deserializer >> serverFile; deserializer >> mProject; deserializer >> mSource; deserializer >> mSourceFile; deserializer >> flags; deserializer >> mVisitFileTimeout; deserializer >> mIndexerMessageTimeout; deserializer >> connectTimeout; deserializer >> suspendOnSigSegv; deserializer >> mUnsavedFiles; uint32_t dirtySize; deserializer >> dirtySize; const uint64_t parseTime = Rct::currentTimeMs(); while (dirtySize-- > 0) { Path dirty; deserializer >> dirty; if (!mUnsavedFiles.contains(dirty)) { mUnsavedFiles[dirty] = dirty.readAll(); } } deserializer >> blockedFiles; if (mSourceFile.isEmpty()) { error("No sourcefile"); return false; } if (!mSource.fileId) { error("Bad fileId"); return false; } if (mProject.isEmpty()) { error("No project"); return false; } Location::init(blockedFiles); Location::set(mSourceFile, mSource.fileId); if (!mConnection.connectUnix(serverFile, connectTimeout)) { error("Failed to connect to rdm on %s (%dms timeout)", serverFile.constData(), connectTimeout); return false; } // mLogFile = fopen(String::format("/tmp/%s", mSourceFile.fileName()).constData(), "w"); mData.reset(new IndexData(flags)); mData->parseTime = parseTime; mData->key = mSource.key(); mData->pid = getpid(); assert(mConnection.isConnected()); mData->visited[mSource.fileId] = true; parse() && visit() && diagnose(); mData->message = mSourceFile.toTilde(); if (!mClangUnit) mData->message += " error"; mData->message += String::format<16>(" in %dms. ", mTimer.elapsed()); if (mClangUnit) { const char *format = "(%d syms, %d symNames, %d deps, %d of %d files, cursors: %d of %d, %d queried) (%d/%dms)"; mData->message += String::format<128>(format, mData->symbols.size(), mData->symbolNames.size(), mData->dependencies.size(), mIndexed, mData->visited.size(), mAllowed, mAllowed + mBlocked, mFileIdsQueried, mParseDuration, mVisitDuration); } else if (mData->dependencies.size()) { mData->message += String::format<16>("(%d deps)", mData->dependencies.size()); } if (mData->flags & IndexerJob::Dirty) mData->message += " (dirty)"; const IndexerMessage msg(mProject, mData); ++mFileIdsQueried; // FILE *f = fopen("/tmp/clangindex.log", "a"); // fprintf(f, "Writing indexer message %d\n", mData->symbols.size()); // if (Path::exists(String("/tmp/") + Location::path(source.fileId).fileName())) { // error() << "Detected problem... crashing" << Location::path(source.fileId).fileName(); // Path::rm(String("/tmp/") + Location::path(source.fileId).fileName()); // sleep(1); // abort(); // } StopWatch sw; if (!mConnection.send(msg)) { error() << "Couldn't send IndexerMessage" << mSourceFile; return false; } mConnection.finished().connect(std::bind(&EventLoop::quit, EventLoop::eventLoop())); if (EventLoop::eventLoop()->exec(mIndexerMessageTimeout) == EventLoop::Timeout) { error() << "Couldn't send IndexerMessage (2)" << mSourceFile; return false; } if (getenv("RDM_DEBUG_INDEXERMESSAGE")) error() << "Send took" << sw.elapsed() << "for" << mSourceFile; // error() << "Must have gotten a finished" << mSourceFile; // fprintf(f, "Wrote indexer message %d\n", mData->symbols.size()); // fclose(f); return true; }
void AdvectionManager::advance(double dt, const TimeLevelIndex<2> &newTimeIdx, const VelocityField &velocity) { TimeLevelIndex<2> oldTimeIdx = newTimeIdx-1; TimeLevelIndex<2> halfTimeIdx = newTimeIdx-0.5; const double eps = 1.0e-80; const double R = domain->getRadius(); for (int s = 0; s < Q.size(); ++s) { ScalarField &q = *Q[s]; double dQ; int J; //#define ONLY_LAX_WENDROFF //#define ONLY_UPWIND #ifndef ONLY_UPWIND // --------------------------------------------------------------------- // Lax-Wendroff pass for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) { for (int i = 0; i < mesh->getNumGrid(0, HALF); ++i) { double f1 = dt/(R*dlon[i]); double f2 = f1/cosLatFull[j]; double u = velocity(0)(halfTimeIdx, i, j); double q1 = q(oldTimeIdx, i, j); double q2 = q(oldTimeIdx, i+1, j); FX(i, j) = 0.5*f1*(u*(q2+q1)-u*u*f2*(q2-q1)); } } FX.applyBndCond(); for (int j = 0; j < mesh->getNumGrid(1, HALF); ++j) { for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { double f1 = dt/(R*dlat[j]); double f2 = f1/cosLatHalf[j]; double v = velocity(1)(halfTimeIdx, i, j)*cosLatHalf[j]; double q1 = q(oldTimeIdx, i, j ); double q2 = q(oldTimeIdx, i, j+1); FY(i, j) = 0.5*f1*(v*(q2+q1)-v*v*f2*(q2-q1)); } } FY.applyBndCond(); #endif #if (!defined ONLY_LAX_WENDROFF && !defined ONLY_UPWIND) // --------------------------------------------------------------------- // calculate intermediate Qstar for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) { for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { double fx1 = dt/(R*dlon[i]*cosLatFull[i]); // TODO: Should we support irregular lon grids? double fx2 = dt/(R*dlon[i]*cosLatFull[i]); double fy1 = dt/(R*dlat[j-1]*cosLatHalf[j-1]); double fy2 = dt/(R*dlat[j ]*cosLatHalf[j ]); double u1 = velocity(0)(halfTimeIdx, i-1, j); double u2 = velocity(0)(halfTimeIdx, i, j); double v1 = velocity(1)(halfTimeIdx, i, j-1); double v2 = velocity(1)(halfTimeIdx, i, j ); double tmp1 = fabs(u1*fx1)*(1-fabs(u1*fx1)); double tmp2 = fabs(u2*fx2)*(1-fabs(u2*fx2)); double tmp3 = fabs(v1*fy1)*(1-fabs(v1*fy1)); double tmp4 = fabs(v2*fy2)*(1-fabs(v2*fy2)); double gamma = fmax(fmax(tmp1, tmp2), fmax(tmp3, tmp4)); B(i, j) = 2/(2-2*gamma); } } for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) { for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { Qstar(i, j) = q(oldTimeIdx, i, j)-B(i, j)/cosLatFull[j]* (FX(i, j)-FX(i-1, j)+FY(i, j)-FY(i, j-1)); } } // handle poles // south pole dQ = 0; J = 0; for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { dQ += B(i, J+1)*FY(i, J); } dQ *= 4.0/mesh->getNumGrid(0, FULL)/cosLatHalf[J]; for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { Qstar(i, J) = q(oldTimeIdx, i, J)-dQ; } // north pole dQ = 0; J = mesh->getNumGrid(1, FULL)-1; for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { dQ += B(i, J-1)*FY(i, J-1); } dQ *= 4.0/mesh->getNumGrid(0, FULL)/cosLatHalf[J-1]; for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { Qstar(i, J) = q(oldTimeIdx, i, J)+dQ; } // --------------------------------------------------------------------- // shape-preserving rule (A <= 0 is good) for (int j = 0; j < mesh->getNumGrid(1, FULL); ++j) { for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { double Qmin = 1.0e+15; double Qmax = -1.0e+15; if (j == 0) { Qmin = fmin(fmin(q(oldTimeIdx, i, j), q(oldTimeIdx, i, j+1)), Qmin); Qmax = fmax(fmax(q(oldTimeIdx, i, j), q(oldTimeIdx, i, j+1)), Qmax); } else if (j == mesh->getNumGrid(1, FULL)-1) { Qmin = fmin(fmin(q(oldTimeIdx, i, j), q(oldTimeIdx, i, j-1)), Qmin); Qmax = fmax(fmax(q(oldTimeIdx, i, j), q(oldTimeIdx, i, j-1)), Qmax); } else { Qmin = fmin(fmin(fmin(q(oldTimeIdx, i-1, j), q(oldTimeIdx, i+1, j)), fmin(q(oldTimeIdx, i, j-1), q(oldTimeIdx, i, j+1))), fmin(q(oldTimeIdx, i, j), Qmin)); Qmax = fmax(fmax(fmax(q(oldTimeIdx, i-1, j), q(oldTimeIdx, i+1, j)), fmax(q(oldTimeIdx, i, j-1), q(oldTimeIdx, i, j+1))), fmax(q(oldTimeIdx, i, j), Qmax)); } A(i, j) = (Qstar(i, j)-Qmax)*(Qstar(i, j)-Qmin); } } A.applyBndCond(); #endif #ifndef ONLY_LAX_WENDROFF // --------------------------------------------------------------------- // upwind pass for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) { for (int i = 0; i < mesh->getNumGrid(0, HALF); ++i) { #ifndef ONLY_UPWIND double tmp1 = (fabs(A(i, j))+A(i, j))/(fabs(A(i, j))+eps); double tmp2 = (fabs(A(i+1, j))+A(i+1, j))/(fabs(A(i+1, j))+eps); double tmp3 = (fabs(A(i+1, j))+A(i+1, j))*(fabs(A(i, j))+A(i, j)); double tmp4 = fabs(A(i, j))*fabs(A(i+1, j))+eps; double cxstar = 0.5*(tmp1+tmp2)-0.25*tmp3/tmp4; #else double cxstar = 1; #endif double f = dt/(R*dlon[i]); double u = velocity(0)(halfTimeIdx, i, j); double q1 = q(oldTimeIdx, i, j); double q2 = q(oldTimeIdx, i+1, j); double cx = cxstar+(1-cxstar)*fabs(u*f/cosLatFull[j]); FX(i, j) = 0.5*f*(u*(q2+q1)-fabs(cx*u)*(q2-q1)); } } FX.applyBndCond(); for (int j = 0; j < mesh->getNumGrid(1, HALF); ++j) { for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { #ifndef ONLY_UPWIND double tmp1 = (fabs(A(i, j ))+A(i, j ))/(fabs(A(i, j ))+eps); double tmp2 = (fabs(A(i, j+1))+A(i, j+1))/(fabs(A(i, j+1))+eps); double tmp3 = (fabs(A(i, j+1))+A(i, j+1))*(fabs(A(i, j))+A(i, j)); double tmp4 = fabs(A(i, j))*fabs(A(i, j+1))+eps; double cystar = 0.5*(tmp1+tmp2)-0.25*tmp3/tmp4; #else double cystar = 1; #endif double f = dt/(R*dlat[j]); double v = velocity(1)(halfTimeIdx, i, j)*cosLatHalf[j]; double q1 = q(oldTimeIdx, i, j ); double q2 = q(oldTimeIdx, i, j+1); double cy = cystar+(1-cystar)*fabs(v*f/cosLatHalf[j]); FY(i, j) = 0.5*f*(v*(q2+q1)-fabs(cy*v)*(q2-q1)); } } FY.applyBndCond(); #endif // --------------------------------------------------------------------- // calculate final Q for (int j = 1; j < mesh->getNumGrid(1, FULL)-1; ++j) { for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { q(newTimeIdx, i, j) = q(oldTimeIdx, i, j)- (FX(i, j)-FX(i-1, j)+FY(i, j)-FY(i, j-1))/cosLatFull[j]; } } // handle poles // south pole dQ = 0; J = 0; for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { dQ += FY(i, J); } dQ *= 4.0/mesh->getNumGrid(0, FULL)/cosLatHalf[J]; for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { q(newTimeIdx, i, J) = q(oldTimeIdx, i, J)-dQ; } // north pole dQ = 0; J = mesh->getNumGrid(1, FULL)-1; for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { dQ += FY(i, J-1); } dQ *= 4.0/mesh->getNumGrid(0, FULL)/cosLatHalf[J-1]; for (int i = 0; i < mesh->getNumGrid(0, FULL); ++i) { q(newTimeIdx, i, J) = q(oldTimeIdx, i, J)+dQ; } q.applyBndCond(newTimeIdx); } diagnose(newTimeIdx); }