00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef OPM_SIMULATORFULLYIMPLICITBLACKOILSOLVENT_IMPL_HEADER_INCLUDED
00021 #define OPM_SIMULATORFULLYIMPLICITBLACKOILSOLVENT_IMPL_HEADER_INCLUDED
00022
00023 namespace Opm
00024 {
00025 template <class GridT>
00026 SimulatorFullyImplicitBlackoilSolvent<GridT>::
00027 SimulatorFullyImplicitBlackoilSolvent(const ParameterGroup& param,
00028 const GridT& grid,
00029 DerivedGeology& geo,
00030 BlackoilPropsAdFromDeck& props,
00031 const SolventPropsAdFromDeck& solvent_props,
00032 const RockCompressibility* rock_comp_props,
00033 NewtonIterationBlackoilInterface& linsolver,
00034 const double* gravity,
00035 const bool has_disgas,
00036 const bool has_vapoil,
00037 std::shared_ptr<EclipseState> eclipse_state,
00038 BlackoilOutputWriter& output_writer,
00039 std::shared_ptr< Deck > deck,
00040 const std::vector<double>& threshold_pressures_by_face,
00041 const bool has_solvent)
00042 : BaseType(param,
00043 grid,
00044 geo,
00045 props,
00046 rock_comp_props,
00047 linsolver,
00048 gravity,
00049 has_disgas,
00050 has_vapoil,
00051 eclipse_state,
00052 output_writer,
00053 threshold_pressures_by_face,
00054
00055 std::unordered_set<std::string>())
00056 , has_solvent_(has_solvent)
00057 , deck_(deck)
00058 , solvent_props_(solvent_props)
00059 , is_miscible_(false)
00060 {
00061 if(deck->hasKeyword("MISCIBLE")) {
00062 is_miscible_ = true;
00063 }
00064 }
00065
00066 template <class GridT>
00067 auto SimulatorFullyImplicitBlackoilSolvent<GridT>::
00068 createSolver(const WellModel& well_model)
00069 -> std::unique_ptr<Solver>
00070 {
00071 typedef typename Traits::Model Model;
00072
00073
00074 auto model = std::unique_ptr<Model>(new Model(BaseType::model_param_,
00075 BaseType::grid_,
00076 BaseType::props_,
00077 BaseType::geo_,
00078 BaseType::rock_comp_props_,
00079 solvent_props_,
00080 well_model,
00081 BaseType::solver_,
00082 BaseType::eclipse_state_,
00083 BaseType::has_disgas_,
00084 BaseType::has_vapoil_,
00085 BaseType::terminal_output_,
00086 has_solvent_,
00087 is_miscible_));
00088
00089 if (!BaseType::threshold_pressures_by_face_.empty()) {
00090 model->setThresholdPressures(BaseType::threshold_pressures_by_face_);
00091 }
00092
00093 return std::unique_ptr<Solver>(new Solver(BaseType::solver_param_, std::move(model)));
00094 }
00095
00096 template <class GridT>
00097 void SimulatorFullyImplicitBlackoilSolvent<GridT>::
00098 handleAdditionalWellInflow(SimulatorTimer& timer,
00099 WellsManager& ,
00100 typename BaseType::WellState& well_state,
00101 const Wells* wells)
00102 {
00103
00104 const int nw = wells->number_of_wells;
00105 std::vector<double> perfcells_fraction(wells->well_connpos[nw], 0.0);
00106
00107 size_t currentStep = timer.currentStepNum();
00108 const auto& schedule = BaseType::eclipse_state_->getSchedule();
00109
00110 for (const auto& well_solvent : schedule.getWells( currentStep )) {
00111 if (well_solvent->getStatus( currentStep ) == WellCommon::SHUT) {
00112 continue;
00113 }
00114
00115 WellInjectionProperties injection = well_solvent->getInjectionProperties(currentStep);
00116 if (injection.injectorType == WellInjector::GAS) {
00117
00118 double solventFraction = well_solvent->getSolventFraction(currentStep);
00119
00120
00121 int wix = 0;
00122 for (; wix < nw; ++wix) {
00123 if (well_solvent->name() == wells->name[wix]) {
00124 break;
00125 }
00126 }
00127 if (wix == wells->number_of_wells) {
00128 OPM_THROW(std::runtime_error, "Could not find a match for well "
00129 << well_solvent->name()
00130 << " from WSOLVENT.");
00131 }
00132 for (int j = wells->well_connpos[wix]; j < wells->well_connpos[wix+1]; ++j) {
00133 perfcells_fraction[j] = solventFraction;
00134 }
00135 }
00136 }
00137 well_state.solventFraction() = perfcells_fraction;
00138 }
00139
00140 }
00141
00142 #endif // OPM_SIMULATORFULLYIMPLICITBLACKOILSOLVENT_IMPL_HEADER_INCLUDED