00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef OPM_FLOWMAINSEQUENTIAL_HEADER_INCLUDED
00021 #define OPM_FLOWMAINSEQUENTIAL_HEADER_INCLUDED
00022
00023
00024
00025 #include <opm/autodiff/FlowMain.hpp>
00026
00027
00028
00029 namespace Opm
00030 {
00031
00032
00033 template <class Grid, class Simulator>
00034 class FlowMainSequential : public FlowMainBase<FlowMainSequential<Grid, Simulator>, Grid, Simulator>
00035 {
00036 protected:
00037 using Base = FlowMainBase<FlowMainSequential<Grid, Simulator>, Grid, Simulator>;
00038 using Base::eclipse_state_;
00039 using Base::param_;
00040 using Base::fis_solver_;
00041 using Base::parallel_information_;
00042 friend Base;
00043
00044
00045
00046
00047
00048 void printStartupMessage()
00049 {
00050 if (Base::output_cout_) {
00051 const std::string version = moduleVersionName();
00052 std::cout << "**********************************************************************\n";
00053 std::cout << "* *\n";
00054 std::cout << "* This is Flow-Sequential (version " << version << ")"
00055 << std::string(17 - version.size(), ' ') << "*\n";
00056 std::cout << "* *\n";
00057 std::cout << "* Flow-Sequential is a simulator for fully implicit three-phase, *\n";
00058 std::cout << "* black-oil flow, and is part of OPM. *\n";
00059 std::cout << "* For more information see http://opm-project.org *\n";
00060 std::cout << "* *\n";
00061 std::cout << "**********************************************************************\n\n";
00062
00063 }
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 void setupLinearSolver()
00077 {
00078 const std::string cprSolver = "cpr";
00079 const std::string interleavedSolver = "interleaved";
00080 const std::string directSolver = "direct";
00081 std::string flowDefaultSolver = interleavedSolver;
00082
00083 if (!param_.has("solver_approach")) {
00084 if (eclipse_state_->getSimulationConfig().useCPR()) {
00085 flowDefaultSolver = cprSolver;
00086 }
00087 }
00088
00089 const std::string solver_approach = param_.getDefault("solver_approach", flowDefaultSolver);
00090
00091 if (solver_approach == cprSolver) {
00092 OPM_THROW( std::runtime_error , "CPR solver is not ready for use with sequential simulator.");
00093 } else if (solver_approach == interleavedSolver) {
00094 if (!param_.has("require_full_sparsity_pattern")) {
00095 param_.insertParameter("require_full_sparsity_pattern", "true");
00096 }
00097 fis_solver_.reset(new NewtonIterationBlackoilInterleaved(param_, parallel_information_));
00098 } else if (solver_approach == directSolver) {
00099 fis_solver_.reset(new NewtonIterationBlackoilSimple(param_, parallel_information_));
00100 } else {
00101 OPM_THROW( std::runtime_error , "Internal error - solver approach " << solver_approach << " not recognized.");
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 void createSimulator()
00113 {
00114
00115 if (!param_.has("min_iter")) {
00116 param_.insertParameter("min_iter", "0");
00117 }
00118
00119
00120 Base::simulator_.reset(new Simulator(Base::param_,
00121 Base::grid_init_->grid(),
00122 *Base::geoprops_,
00123 *Base::fluidprops_,
00124 Base::rock_comp_->isActive() ? Base::rock_comp_.get() : nullptr,
00125 *Base::fis_solver_,
00126 Base::gravity_.data(),
00127 Base::deck_->hasKeyword("DISGAS"),
00128 Base::deck_->hasKeyword("VAPOIL"),
00129 Base::eclipse_state_,
00130 *Base::output_writer_,
00131 Base::threshold_pressures_));
00132 }
00133
00134
00135 };
00136
00137
00138 }
00139
00140
00141 #endif // OPM_FLOWMAINSEQUENTIAL_HEADER_INCLUDED