int main(int argc, char** argv) { try { // define the problem dimensions const int dim=2; // create a grid object typedef double NumberType; typedef Dune::SGrid<dim,dim> GridType; Dune::FieldVector<GridType::ctype,dim> L(0); Dune::FieldVector<GridType::ctype,dim> R(300); Dune::FieldVector<int,dim> N(2); GridType grid(N,L,R); typedef GridType::LevelGridView GridView; GridView gridView(grid.levelView(0)); //Uniform mat; Dune::Uniform mat; Dune::HomogeneousSoil<GridType, NumberType> soil; // Dune::HeterogeneousSoil<GridType, NumberType> soil(grid, "permeab.dat", true); // printvector(std::cout, *(soil.permeability), "permeability", "row", 200, 1); // soil.permeability.vtkout("permeability", grid); Dune::TwoPhaseRelations<GridType, NumberType> materialLaw(soil, mat, mat); typedef Dune::VariableClass<GridView, NumberType> VC; double initsat = 0.8; // VC variables(gridView,initsat); //for fe discretisation -> pressure on the nodes! VC variables(gridView, dim, initsat); Dune::UniformProblem<GridView, NumberType, VC> problem(variables, mat, mat, soil, materialLaw, R); Dune::Timer timer; timer.reset(); // Dune::LeafFEPressure2P<GridView, NumberType, VC> diffusion(gridView, problem); Dune::FVWettingPhaseVelocity2P<GridView, NumberType, VC> diffusion(gridView, problem, "pw","Sw"); // Dune::MimeticPressure2P<GridView, NumberType, VC> diffusion(gridView, problem); diffusion.pressure(); std::cout << "pressure calculation took " << timer.elapsed() << " seconds" << std::endl; printvector(std::cout, variables.pressure(), "pressure", "row", 200, 1, 3); variables.vtkout("fv", 0); diffusion.calculateVelocity(); printvector(std::cout, variables.velocity(), "velocity", "row", 4, 1, 3); return 0; } catch (Dune::Exception &e) { std::cerr << "Dune reported error: " << e << std::endl; } catch (...) { std::cerr << "Unknown exception thrown!" << std::endl; } }
// ----------------- Main program ----------------- int main(int argc, char** argv) { Dune::Timer externalSetupTimer; externalSetupTimer.start(); detail::handleVersionCmdLine(argc, argv); // MPI setup. #if HAVE_DUNE_FEM Dune::Fem::MPIManager::initialize(argc, argv); int mpiRank = Dune::Fem::MPIManager::rank(); #else // the design of the plain dune MPIHelper class is quite flawed: there is no way to // get the instance without having the argc and argv parameters available and it is // not possible to determine the MPI rank and size without an instance. (IOW: the // rank() and size() methods are supposed to be static.) const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv); int mpiRank = mpiHelper.rank(); #endif // we always want to use the default locale, and thus spare us the trouble // with incorrect locale settings. Opm::resetLocale(); // this is a work-around for a catch 22: we do not know what code path to use without // parsing the deck, but we don't know the deck without having access to the // parameters and this requires to know the type tag to be used. To solve this, we // use a type tag just for parsing the parameters before we instantiate the actual // simulator object. (Which parses the parameters again, but since this is done in an // identical manner it does not matter.) typedef TTAG(FlowEarlyBird) PreTypeTag; typedef GET_PROP_TYPE(PreTypeTag, Problem) PreProblem; PreProblem::setBriefDescription("Flow, an advanced reservoir simulator for ECL-decks provided by the Open Porous Media project."); int status = Opm::FlowMainEbos<PreTypeTag>::setupParameters_(argc, argv); if (status != 0) // if setupParameters_ returns a value smaller than 0, there was no error, but // the program should abort. This is the case e.g. for the --help and the // --print-properties parameters. return (status >= 0)?status:0; bool outputCout = false; if (mpiRank == 0) outputCout = EWOMS_GET_PARAM(PreTypeTag, bool, EnableTerminalOutput); std::string deckFilename = EWOMS_GET_PARAM(PreTypeTag, std::string, EclDeckFileName); typedef typename GET_PROP_TYPE(PreTypeTag, Vanguard) PreVanguard; try { deckFilename = PreVanguard::canonicalDeckPath(deckFilename).string(); } catch (const std::exception& e) { if ( mpiRank == 0 ) std::cerr << "Exception received: " << e.what() << ". Try '--help' for a usage description.\n"; #if HAVE_MPI MPI_Finalize(); #endif return 1; } if (outputCout) { Opm::FlowMainEbos<PreTypeTag>::printBanner(); } // Create Deck and EclipseState. try { if (outputCout) { std::cout << "Reading deck file '" << deckFilename << "'\n"; std::cout.flush(); } std::shared_ptr<Opm::Deck> deck; std::shared_ptr<Opm::EclipseState> eclipseState; std::shared_ptr<Opm::Schedule> schedule; std::shared_ptr<Opm::SummaryConfig> summaryConfig; { Opm::Parser parser; Opm::ParseContext parseContext; Opm::ErrorGuard errorGuard; if (EWOMS_GET_PARAM(PreTypeTag, bool, EclStrictParsing)) parseContext.update( Opm::InputError::DELAYED_EXIT1); else { parseContext.update(Opm::ParseContext::PARSE_RANDOM_SLASH, Opm::InputError::IGNORE); parseContext.update(Opm::ParseContext::PARSE_MISSING_DIMS_KEYWORD, Opm::InputError::WARN); parseContext.update(Opm::ParseContext::SUMMARY_UNKNOWN_WELL, Opm::InputError::WARN); parseContext.update(Opm::ParseContext::SUMMARY_UNKNOWN_GROUP, Opm::InputError::WARN); } deck.reset( new Opm::Deck( parser.parseFile(deckFilename , parseContext, errorGuard))); Opm::MissingFeatures::checkKeywords(*deck, parseContext, errorGuard); if ( outputCout ) Opm::checkDeck(*deck, parser, parseContext, errorGuard); eclipseState.reset( new Opm::EclipseState(*deck, parseContext, errorGuard )); schedule.reset(new Opm::Schedule(*deck, *eclipseState, parseContext, errorGuard)); summaryConfig.reset( new Opm::SummaryConfig(*deck, *schedule, eclipseState->getTableManager(), parseContext, errorGuard)); if (errorGuard) { errorGuard.dump(); errorGuard.clear(); throw std::runtime_error("Unrecoverable errors were encountered while loading input."); } } const auto& phases = Opm::Runspec(*deck).phases(); // run the actual simulator // // TODO: make sure that no illegal combinations like thermal and twophase are // requested. // Twophase cases if( phases.size() == 2 ) { // oil-gas if (phases.active( Opm::Phase::GAS )) { Opm::flowEbosGasOilSetDeck(externalSetupTimer.elapsed(), *deck, *eclipseState, *schedule, *summaryConfig); return Opm::flowEbosGasOilMain(argc, argv); } // oil-water else if ( phases.active( Opm::Phase::WATER ) ) { Opm::flowEbosOilWaterSetDeck(externalSetupTimer.elapsed(), *deck, *eclipseState, *schedule, *summaryConfig); return Opm::flowEbosOilWaterMain(argc, argv); } else { if (outputCout) std::cerr << "No suitable configuration found, valid are Twophase (oilwater and oilgas), polymer, solvent, or blackoil" << std::endl; return EXIT_FAILURE; } } // Polymer case else if ( phases.active( Opm::Phase::POLYMER ) ) { if ( !phases.active( Opm::Phase::WATER) ) { if (outputCout) std::cerr << "No valid configuration is found for polymer simulation, valid options include " << "oilwater + polymer and blackoil + polymer" << std::endl; return EXIT_FAILURE; } // Need to track the polymer molecular weight // for the injectivity study if ( phases.active( Opm::Phase::POLYMW ) ) { // only oil water two phase for now assert( phases.size() == 4); return Opm::flowEbosOilWaterPolymerInjectivityMain(argc, argv); } if ( phases.size() == 3 ) { // oil water polymer case Opm::flowEbosOilWaterPolymerSetDeck(externalSetupTimer.elapsed(), *deck, *eclipseState, *schedule, *summaryConfig); return Opm::flowEbosOilWaterPolymerMain(argc, argv); } else { Opm::flowEbosPolymerSetDeck(externalSetupTimer.elapsed(), *deck, *eclipseState, *schedule, *summaryConfig); return Opm::flowEbosPolymerMain(argc, argv); } } // Solvent case else if ( phases.active( Opm::Phase::SOLVENT ) ) { Opm::flowEbosSolventSetDeck(externalSetupTimer.elapsed(), *deck, *eclipseState, *schedule, *summaryConfig); return Opm::flowEbosSolventMain(argc, argv); } // Energy case else if (eclipseState->getSimulationConfig().isThermal()) { Opm::flowEbosEnergySetDeck(externalSetupTimer.elapsed(), *deck, *eclipseState, *schedule, *summaryConfig); return Opm::flowEbosEnergyMain(argc, argv); } // Blackoil case else if( phases.size() == 3 ) { Opm::flowEbosBlackoilSetDeck(externalSetupTimer.elapsed(), *deck, *eclipseState, *schedule, *summaryConfig); return Opm::flowEbosBlackoilMain(argc, argv); } else { if (outputCout) std::cerr << "No suitable configuration found, valid are Twophase, polymer, solvent, energy, or blackoil" << std::endl; return EXIT_FAILURE; } }