26 #include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
27 #include <opm/core/utility/initHydroCarbonState.hpp>
28 #include <opm/core/well_controls.h>
29 #include <opm/core/wells/DynamicListEconLimited.hpp>
30 #include <opm/autodiff/BlackoilModel.hpp>
35 template <
class Implementation>
40 const RockCompressibility* rock_comp_props,
42 const double* gravity,
43 const bool has_disgas,
44 const bool has_vapoil,
45 std::shared_ptr<EclipseState> eclipse_state,
46 OutputWriter& output_writer,
47 const std::vector<double>& threshold_pressures_by_face,
48 const std::unordered_set<std::string>& defunct_well_names)
54 rock_comp_props_(rock_comp_props),
58 has_disgas_(has_disgas),
59 has_vapoil_(has_vapoil),
60 terminal_output_(param.getDefault(
"output_terminal", true)),
61 eclipse_state_(eclipse_state),
62 output_writer_(output_writer),
63 rateConverter_(props_.phaseUsage(), std::vector<int>(AutoDiffGrid::numCells(grid_), 0)),
64 threshold_pressures_by_face_(threshold_pressures_by_face),
65 is_parallel_run_( false ),
66 defunct_well_names_(defunct_well_names)
69 const int num_cells = AutoDiffGrid::numCells(grid);
70 allcells_.resize(num_cells);
71 for (
int cell = 0; cell < num_cells; ++cell) {
72 allcells_[cell] = cell;
77 const ParallelISTLInformation& info =
80 terminal_output_ = terminal_output_ && ( info.communicator().rank() == 0 );
81 is_parallel_run_ = ( info.communicator().size() > 1 );
86 template <
class Implementation>
88 ReservoirState& state)
90 WellState prev_well_state;
93 if (output_writer_.isRestart()) {
95 output_writer_.initFromRestartFile(props_.phaseUsage(), grid_, state, prev_well_state, extra);
96 initHydroCarbonState(state, props_.phaseUsage(), Opm::UgGridHelpers::numCells(grid_), has_disgas_, has_vapoil_);
97 initHysteresisParams(state);
101 Opm::time::StopWatch solver_timer;
102 Opm::time::StopWatch step_timer;
103 Opm::time::StopWatch total_timer;
105 std::string tstep_filename = output_writer_.outputDirectory() +
"/step_timing.txt";
106 std::ofstream tstep_os;
108 if ( output_writer_.output() ) {
109 if ( output_writer_.isIORank() )
110 tstep_os.open(tstep_filename.c_str());
113 const auto& schedule = eclipse_state_->getSchedule();
116 const auto& events = schedule.getEvents();
117 std::unique_ptr< AdaptiveTimeStepping > adaptiveTimeStepping;
118 if( param_.getDefault(
"timestep.adaptive",
true ) )
121 if (param_.getDefault(
"use_TUNING",
false)) {
126 if (output_writer_.isRestart()) {
127 if (extra.suggested_step > 0.0) {
128 adaptiveTimeStepping->setSuggestedNextStep(extra.suggested_step);
133 std::string restorefilename = param_.getDefault(
"restorefile", std::string(
"") );
134 if( ! restorefilename.empty() )
137 const int desiredRestoreStep = param_.getDefault(
"restorestep",
int(-1) );
139 output_writer_.restore( timer,
143 desiredRestoreStep );
146 DynamicListEconLimited dynamic_list_econ_limited;
147 SimulatorReport report;
148 SimulatorReport stepReport;
150 bool ooip_computed =
false;
151 std::vector<int> fipnum_global = eclipse_state_->get3DProperties().getIntGridProperty(
"FIPNUM").getData();
153 std::vector<int> fipnum(AutoDiffGrid::numCells(grid_));
154 if (fipnum_global.empty()) {
155 std::fill(fipnum.begin(), fipnum.end(), 0);
157 for (
size_t c = 0; c < fipnum.size(); ++c) {
158 fipnum[c] = fipnum_global[AutoDiffGrid::globalCell(grid_)[c]];
161 std::vector<std::vector<double> > OOIP;
163 while (!timer.
done()) {
166 if ( terminal_output_ )
168 std::ostringstream ss;
170 OpmLog::note(ss.str());
174 WellsManager wells_manager(*eclipse_state_,
176 Opm::UgGridHelpers::numCells(grid_),
177 Opm::UgGridHelpers::globalCell(grid_),
178 Opm::UgGridHelpers::cartDims(grid_),
179 Opm::UgGridHelpers::dimensions(grid_),
180 Opm::UgGridHelpers::cell2Faces(grid_),
181 Opm::UgGridHelpers::beginFaceCentroids(grid_),
182 dynamic_list_econ_limited,
184 defunct_well_names_);
185 const Wells* wells = wells_manager.c_wells();
186 WellState well_state;
187 well_state.init(wells, state, prev_well_state, props_.phaseUsage());
190 asImpl().handleAdditionalWellInflow(timer, wells_manager, well_state, wells);
194 Dune::Timer perfTimer;
199 output_writer_.writeTimeStepWithoutCellProperties( timer, state, well_state, {}, {} );
201 report.output_write_time += perfTimer.stop();
205 props_.updateSatOilMax(state.saturation());
206 props_.updateSatHyst(state.saturation(), allcells_);
209 asImpl().computeRESV(timer.
currentStepNum(), wells, state, well_state);
212 solver_timer.start();
214 const WellModel well_model(wells, &(wells_manager.wellCollection()));
216 std::unique_ptr<Solver> solver = asImpl().createSolver(well_model);
219 if (!ooip_computed) {
220 OOIP = solver->computeFluidInPlace(state, fipnum);
221 FIPUnitConvert(eclipse_state_->getUnits(), OOIP);
222 ooip_computed =
true;
225 if( terminal_output_ )
227 std::ostringstream step_msg;
228 boost::posix_time::time_facet* facet =
new boost::posix_time::time_facet(
"%d-%b-%Y");
229 step_msg.imbue(std::locale(std::locale::classic(), facet));
230 step_msg <<
"\nTime step " << std::setw(4) <<timer.
currentStepNum()
232 <<
"/" << (
double)unit::convert::to(timer.
totalTime(), unit::day)
234 OpmLog::info(step_msg.str());
242 if( adaptiveTimeStepping ) {
243 bool event = events.hasEvent(ScheduleEvents::NEW_WELL, timer.
currentStepNum()) ||
244 events.hasEvent(ScheduleEvents::PRODUCTION_UPDATE, timer.
currentStepNum()) ||
245 events.hasEvent(ScheduleEvents::INJECTION_UPDATE, timer.
currentStepNum()) ||
246 events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE, timer.
currentStepNum());
247 report += adaptiveTimeStepping->step( timer, *solver, state, well_state, event, output_writer_,
248 output_writer_.requireFIPNUM() ? &fipnum : nullptr );
252 stepReport = solver->step(timer, state, well_state);
253 report += stepReport;
255 if( terminal_output_ )
257 std::ostringstream iter_msg;
258 iter_msg <<
"Stepsize " << (double)unit::convert::to(timer.
currentStepLength(), unit::day);
259 if (solver->wellIterations() != 0) {
260 iter_msg <<
" days well iterations = " << solver->wellIterations() <<
", ";
262 iter_msg <<
"non-linear iterations = " << solver->nonlinearIterations()
263 <<
", total linear iterations = " << solver->linearIterations()
265 OpmLog::info(iter_msg.str());
272 if (nextTimeStepIdx < timer.
numSteps()
273 && events.hasEvent(ScheduleEvents::GEO_MODIFIER, nextTimeStepIdx)) {
278 const auto& miniDeck = schedule.getModifierDeck(nextTimeStepIdx);
279 eclipse_state_->applyModifierDeck(miniDeck);
280 geo_.update(grid_, props_, *eclipse_state_, gravity_);
287 report.solver_time += solver_timer.secsSinceStart();
290 std::vector<std::vector<double> > COIP;
291 COIP = solver->computeFluidInPlace(state, fipnum);
292 std::vector<double> OOIP_totals = FIPTotals(OOIP, state);
293 std::vector<double> COIP_totals = FIPTotals(COIP, state);
296 FIPUnitConvert(eclipse_state_->getUnits(), COIP);
297 FIPUnitConvert(eclipse_state_->getUnits(), OOIP_totals);
298 FIPUnitConvert(eclipse_state_->getUnits(), COIP_totals);
300 if ( terminal_output_ )
302 outputFluidInPlace(OOIP_totals, COIP_totals,eclipse_state_->getUnits(), 0);
303 for (
size_t reg = 0; reg < OOIP.size(); ++reg) {
304 outputFluidInPlace(OOIP[reg], COIP[reg], eclipse_state_->getUnits(), reg+1);
308 if ( terminal_output_ )
311 msg =
"Fully implicit solver took: " + std::to_string(stepReport.solver_time) +
" seconds. Total solver time taken: " + std::to_string(report.solver_time) +
" seconds.";
315 if ( tstep_os.is_open() ) {
316 stepReport.reportParam(tstep_os);
323 Dune::Timer perfTimer;
325 const auto& physicalModel = solver->model();
326 output_writer_.writeTimeStep( timer, state, well_state, physicalModel );
327 report.output_write_time += perfTimer.stop();
329 prev_well_state = well_state;
331 asImpl().updateListEconLimited(solver, eclipse_state_->getSchedule(), timer.
currentStepNum(), wells,
332 well_state, dynamic_list_econ_limited);
337 report.total_time = total_timer.secsSinceStart();
338 report.converged =
true;
342 namespace SimFIBODetails {
343 typedef std::unordered_map<std::string, const Well* > WellMap;
346 mapWells(
const std::vector< const Well* >& wells)
350 for (std::vector< const Well* >::const_iterator
351 w = wells.begin(), e = wells.end();
354 wmap.insert(std::make_pair((*w)->name(), *w));
361 resv_control(
const WellControls* ctrl)
363 int i, n = well_controls_get_num(ctrl);
366 for (i = 0; (! match) && (i < n); ++i) {
367 match = well_controls_iget_type(ctrl, i) == RESERVOIR_RATE;
370 if (! match) { i = 0; }
376 is_resv(
const Wells& wells,
379 return (0 <= resv_control(wells.ctrls[w]));
383 is_resv(
const WellMap& wmap,
384 const std::string& name,
385 const std::size_t step)
389 WellMap::const_iterator i = wmap.find(name);
391 if (i != wmap.end()) {
392 const Well* wp = i->second;
394 match = (wp->isProducer(step) &&
395 wp->getProductionProperties(step)
396 .hasProductionControl(WellProducer::RESV))
397 || (wp->isInjector(step) &&
398 wp->getInjectionProperties(step)
399 .hasInjectionControl(WellInjector::RESV));
405 inline std::vector<int>
406 resvWells(
const Wells* wells,
407 const std::size_t step,
410 std::vector<int> resv_wells;
413 for (
int w = 0, nw = wells->number_of_wells; w < nw; ++w) {
414 if (is_resv(*wells, w) ||
415 ((wells->name[w] != 0) &&
416 is_resv(wmap, wells->name[w], step)))
418 resv_wells.push_back(w);
427 historyRates(
const PhaseUsage& pu,
428 const WellProductionProperties& p,
429 std::vector<double>& rates)
431 assert (! p.predictionMode);
432 assert (rates.size() ==
433 std::vector<double>::size_type(pu.num_phases));
435 if (pu.phase_used[ BlackoilPhases::Aqua ]) {
436 const std::vector<double>::size_type
437 i = pu.phase_pos[ BlackoilPhases::Aqua ];
439 rates[i] = p.WaterRate;
442 if (pu.phase_used[ BlackoilPhases::Liquid ]) {
443 const std::vector<double>::size_type
444 i = pu.phase_pos[ BlackoilPhases::Liquid ];
446 rates[i] = p.OilRate;
449 if (pu.phase_used[ BlackoilPhases::Vapour ]) {
450 const std::vector<double>::size_type
451 i = pu.phase_pos[ BlackoilPhases::Vapour ];
453 rates[i] = p.GasRate;
458 template <
class Implementation>
459 void SimulatorBase<Implementation>::handleAdditionalWellInflow(SimulatorTimer& ,
465 template <
class Implementation>
466 auto SimulatorBase<Implementation>::createSolver(
const WellModel& well_model)
467 -> std::unique_ptr<Solver>
469 auto model = std::unique_ptr<Model>(
new Model(model_param_,
481 if (!threshold_pressures_by_face_.empty()) {
482 model->setThresholdPressures(threshold_pressures_by_face_);
485 return std::unique_ptr<Solver>(
new Solver(solver_param_, std::move(model)));
489 template <
class Implementation>
490 void SimulatorBase<Implementation>::computeRESV(
const std::size_t step,
492 const BlackoilState& x,
495 typedef SimFIBODetails::WellMap WellMap;
497 const auto w_ecl = eclipse_state_->getSchedule().getWells(step);
498 const WellMap& wmap = SimFIBODetails::mapWells(w_ecl);
500 const std::vector<int>& resv_wells = SimFIBODetails::resvWells(wells, step, wmap);
502 const std::size_t number_resv_wells = resv_wells.size();
503 std::size_t global_number_resv_wells = number_resv_wells;
505 if ( solver_.parallelInformation().type() ==
typeid(ParallelISTLInformation) )
508 boost::any_cast<
const ParallelISTLInformation&>(solver_.parallelInformation());
509 global_number_resv_wells = info.communicator().sum(global_number_resv_wells);
510 if ( global_number_resv_wells )
516 rateConverter_.defineState(x, boost::any_cast<const ParallelISTLInformation&>(solver_.parallelInformation()));
522 if ( global_number_resv_wells )
524 rateConverter_.defineState(x);
528 if (! resv_wells.empty()) {
529 const PhaseUsage& pu = props_.phaseUsage();
530 const std::vector<double>::size_type np = props_.numPhases();
532 std::vector<double> distr (np);
533 std::vector<double> hrates(np);
534 std::vector<double> prates(np);
536 for (std::vector<int>::const_iterator
537 rp = resv_wells.begin(), e = resv_wells.end();
540 WellControls* ctrl = wells->ctrls[*rp];
541 const bool is_producer = wells->type[*rp] == PRODUCER;
545 const int rctrl = SimFIBODetails::resv_control(ctrl);
548 const std::vector<double>::size_type off = (*rp) * np;
553 std::transform(xw.wellRates().begin() + (off + 0*np),
554 xw.wellRates().begin() + (off + 1*np),
555 prates.begin(), std::negate<double>());
557 std::copy(xw.wellRates().begin() + (off + 0*np),
558 xw.wellRates().begin() + (off + 1*np),
562 const int fipreg = 0;
563 const int well_cell_top = wells->well_cells[wells->well_connpos[*rp]];
564 const int pvtreg = props_.cellPvtRegionIndex()[well_cell_top];
565 rateConverter_.calcCoeff(fipreg, pvtreg, distr);
567 well_controls_iset_distr(ctrl, rctrl, & distr[0]);
573 if (is_producer && wells->name[*rp] != 0) {
574 WellMap::const_iterator i = wmap.find(wells->name[*rp]);
576 if (i != wmap.end()) {
577 const auto* wp = i->second;
579 const WellProductionProperties& p =
580 wp->getProductionProperties(step);
582 if (! p.predictionMode) {
584 SimFIBODetails::historyRates(pu, p, hrates);
586 const int fipreg = 0;
587 const int well_cell_top = wells->well_cells[wells->well_connpos[*rp]];
588 const int pvtreg = props_.cellPvtRegionIndex()[well_cell_top];
589 rateConverter_.calcCoeff(fipreg, pvtreg, distr);
595 const double target =
596 - std::inner_product(distr.begin(), distr.end(),
597 hrates.begin(), 0.0);
599 well_controls_clear(ctrl);
600 well_controls_assert_number_of_phases(ctrl,
int(np));
602 static const double invalid_alq = -std::numeric_limits<double>::max();
603 static const int invalid_vfp = -std::numeric_limits<int>::max();
606 well_controls_add_new(RESERVOIR_RATE, target,
607 invalid_alq, invalid_vfp,
612 double bhp_limit = (p.BHPLimit > 0) ? p.BHPLimit : unit::convert::from(1.0, unit::atm);
614 well_controls_add_new(BHP, bhp_limit,
615 invalid_alq, invalid_vfp,
618 if (ok_resv != 0 && ok_bhp != 0) {
619 xw.currentControls()[*rp] = 0;
620 well_controls_set_current(ctrl, 0);
630 for (
int w = 0, nw = wells->number_of_wells; w < nw; ++w) {
631 WellControls* ctrl = wells->ctrls[w];
632 const bool is_producer = wells->type[w] == PRODUCER;
633 if (!is_producer && wells->name[w] != 0) {
634 WellMap::const_iterator i = wmap.find(wells->name[w]);
635 if (i != wmap.end()) {
636 const auto* wp = i->second;
637 const WellInjectionProperties& injector = wp->getInjectionProperties(step);
638 if (!injector.predictionMode) {
640 static const double invalid_alq = -std::numeric_limits<double>::max();
641 static const int invalid_vfp = -std::numeric_limits<int>::max();
644 double bhp_limit = (injector.BHPLimit > 0) ? injector.BHPLimit : std::numeric_limits<double>::max();
646 well_controls_add_new(BHP, bhp_limit,
647 invalid_alq, invalid_vfp,
650 OPM_THROW(std::runtime_error,
"Failed to add well control.");
659 template <
class Implementation>
661 SimulatorBase<Implementation>::FIPUnitConvert(
const UnitSystem& units,
662 std::vector<std::vector<double> >& fip)
664 for (
size_t i = 0; i < fip.size(); ++i) {
665 FIPUnitConvert(units, fip[i]);
669 template <
class Implementation>
671 SimulatorBase<Implementation>::FIPUnitConvert(
const UnitSystem& units, std::vector<double>& fip)
673 if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) {
674 fip[0] = unit::convert::to(fip[0], unit::stb);
675 fip[1] = unit::convert::to(fip[1], unit::stb);
676 fip[2] = unit::convert::to(fip[2], 1000*unit::cubic(unit::feet));
677 fip[3] = unit::convert::to(fip[3], 1000*unit::cubic(unit::feet));
678 fip[4] = unit::convert::to(fip[4], unit::stb);
679 fip[5] = unit::convert::to(fip[5], unit::stb);
680 fip[6] = unit::convert::to(fip[6], unit::psia);
682 else if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_METRIC) {
683 fip[6] = unit::convert::to(fip[6], unit::barsa);
686 OPM_THROW(std::runtime_error,
"Unsupported unit type for fluid in place output.");
691 template <
class Implementation>
693 SimulatorBase<Implementation>::FIPTotals(
const std::vector<std::vector<double> >& fip,
const ReservoirState& state)
695 std::vector<double> totals(7, 0.0);
696 for (
int i = 0; i < 5; ++i) {
697 for (
size_t reg = 0; reg < fip.size(); ++reg) {
698 totals[i] += fip[reg][i];
701 const int nc = Opm::AutoDiffGrid::numCells(grid_);
702 const int np = state.numPhases();
703 const PhaseUsage& pu = props_.phaseUsage();
704 const DataBlock s = Eigen::Map<const DataBlock>(& state.saturation()[0], nc, np);
705 std::vector<double> so(nc);
706 std::vector<double> sg(nc);
707 std::vector<double> hydrocarbon(nc);
709 const int oilpos = pu.phase_used[BlackoilPhases::Liquid] ? pu.phase_pos[BlackoilPhases::Liquid] : 0;
710 const int gaspos = pu.phase_used[BlackoilPhases::Vapour] ? pu.phase_pos[BlackoilPhases::Vapour] : 0;
711 const auto& soCol = s.col(oilpos);
712 const auto& sgCol = s.col(gaspos);
713 for (
unsigned c = 0; c < so.size(); ++ c) {
715 if (pu.phase_used[BlackoilPhases::Liquid]) {
719 if (pu.phase_used[BlackoilPhases::Vapour]) {
724 hydrocarbon[c] = mySo + mySg;
726 const std::vector<double> p = state.pressure();
727 if ( ! is_parallel_run_ )
731 for (
unsigned i = 0; i < p.size(); ++i) {
732 tmp += p[i] * geo_.poreVolume()[i] * hydrocarbon[i];
733 tmp2 += geo_.poreVolume()[i] * hydrocarbon[i];
735 totals[5] = geo_.poreVolume().sum();
736 totals[6] = tmp/tmp2;
742 boost::any_cast<
const ParallelISTLInformation&>(solver_.parallelInformation());
743 auto operators = std::make_tuple(Opm::Reduction::makeGlobalSumFunctor<double>(),
744 Opm::Reduction::makeGlobalSumFunctor<double>(),
745 Opm::Reduction::makeGlobalSumFunctor<double>());
746 std::vector<double> pav_nom(p.size());
747 std::vector<double> pav_denom(pav_nom.size());
748 for (
unsigned i = 0; i < p.size(); ++i) {
749 pav_nom[i] = p[i] * geo_.poreVolume()[i] * hydrocarbon[i];
750 pav_denom[i] = geo_.poreVolume()[i] * hydrocarbon[i];
754 auto inputs = std::make_tuple(std::cref(geo_.poreVolume()),
755 std::cref(pav_nom), std::cref(pav_denom));
756 std::tuple<double, double, double> results(0.0, 0.0, 0.0);
758 pinfo.computeReduction(inputs, operators, results);
760 totals[5] = get<0>(results);
761 totals[6] = get<1>(results)/get<2>(results);
765 OPM_THROW(std::logic_error,
"HAVE_MPI should be defined if we are running in parallel");
774 template <
class Implementation>
776 SimulatorBase<Implementation>::outputFluidInPlace(
const std::vector<double>& oip,
const std::vector<double>& cip,
const UnitSystem& units,
const int reg)
778 std::ostringstream ss;
780 ss <<
" ===================================================\n"
781 <<
" : Field Totals :\n";
783 ss <<
" ===================================================\n"
784 <<
" : FIPNUM report region "
785 << std::setw(2) << reg <<
" :\n";
787 if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_METRIC) {
788 ss <<
" : PAV =" << std::setw(14) << cip[6] <<
" BARSA :\n"
789 << std::fixed << std::setprecision(0)
790 <<
" : PORV =" << std::setw(14) << cip[5] <<
" RM3 :\n";
792 ss <<
" : Pressure is weighted by hydrocarbon pore volume :\n"
793 <<
" : Porv volumes are taken at reference conditions :\n";
795 ss <<
" :--------------- Oil SM3 ---------------:-- Wat SM3 --:--------------- Gas SM3 ---------------:\n";
797 if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) {
798 ss <<
" : PAV =" << std::setw(14) << cip[6] <<
" PSIA :\n"
799 << std::fixed << std::setprecision(0)
800 <<
" : PORV =" << std::setw(14) << cip[5] <<
" RB :\n";
802 ss <<
" : Pressure is weighted by hydrocarbon pore voulme :\n"
803 <<
" : Pore volumes are taken at reference conditions :\n";
805 ss <<
" :--------------- Oil STB ---------------:-- Wat STB --:--------------- Gas MSCF ---------------:\n";
807 ss <<
" : Liquid Vapour Total : Total : Free Dissolved Total :" <<
"\n"
808 <<
":------------------------:------------------------------------------:----------------:------------------------------------------:" <<
"\n"
809 <<
":Currently in place :" << std::setw(14) << cip[1] << std::setw(14) << cip[4] << std::setw(14) << (cip[1]+cip[4]) <<
":"
810 << std::setw(13) << cip[0] <<
" :" << std::setw(14) << (cip[2]) << std::setw(14) << cip[3] << std::setw(14) << (cip[2] + cip[3]) <<
":\n"
811 <<
":------------------------:------------------------------------------:----------------:------------------------------------------:\n"
812 <<
":Originally in place :" << std::setw(14) << oip[1] << std::setw(14) << oip[4] << std::setw(14) << (oip[1]+oip[4]) <<
":"
813 << std::setw(13) << oip[0] <<
" :" << std::setw(14) << oip[2] << std::setw(14) << oip[3] << std::setw(14) << (oip[2] + oip[3]) <<
":\n"
814 <<
":========================:==========================================:================:==========================================:\n";
815 OpmLog::note(ss.str());
819 template <
class Implementation>
821 SimulatorBase<Implementation>::
822 updateListEconLimited(
const std::unique_ptr<Solver>& solver,
823 const Schedule& schedule,
824 const int current_step,
826 const WellState& well_state,
827 DynamicListEconLimited& list_econ_limited)
const
830 solver->model().wellModel().updateListEconLimited(schedule, current_step, wells,
831 well_state, list_econ_limited);
834 template <
class Implementation>
836 SimulatorBase<Implementation>::
837 initHysteresisParams(ReservoirState& state)
839 typedef std::vector<double> VectorType;
841 const VectorType& somax = state.getCellData(
"SOMAX" );
843 VectorType& pcSwMdc_ow = state.getCellData(
"PCSWMDC_OW" );
844 VectorType& krnSwMdc_ow = state.getCellData(
"KRNSWMDC_OW" );
846 VectorType& pcSwMdc_go = state.getCellData(
"PCSWMDC_GO" );
847 VectorType& krnSwMdc_go = state.getCellData(
"KRNSWMDC_GO" );
849 props_.setSatOilMax(somax);
850 props_.setOilWaterHystParams(pcSwMdc_ow, krnSwMdc_ow, allcells_);
851 props_.setGasOilHystParams(pcSwMdc_go, krnSwMdc_go, allcells_);
int currentStepNum() const
Current step number.
Definition: SimulatorTimer.cpp:77
virtual const boost::any & parallelInformation() const =0
Get the information about the parallelization of the grid.
double totalTime() const
Total time.
Definition: SimulatorTimer.cpp:121
bool done() const
Return true if op++() has been called numSteps() times.
Definition: SimulatorTimer.cpp:155
Definition: AdaptiveTimeStepping.hpp:38
double simulationTimeElapsed() const
Time elapsed since the start of the simulation until the beginning of the current time step [s]...
Definition: SimulatorTimer.cpp:104
SimulatorBase(const ParameterGroup ¶m, const Grid &grid, DerivedGeology &geo, BlackoilPropsAdFromDeck &props, const RockCompressibility *rock_comp_props, NewtonIterationBlackoilInterface &linsolver, const double *gravity, const bool disgas, const bool vapoil, std::shared_ptr< EclipseState > eclipse_state, OutputWriter &output_writer, const std::vector< double > &threshold_pressures_by_face, const std::unordered_set< std::string > &defunct_well_names)
Initialise from parameters and objects to observe.
Definition: SimulatorBase_impl.hpp:36
double currentStepLength() const
Current step length.
Definition: SimulatorTimer.cpp:91
int numSteps() const
Total number of steps.
Definition: SimulatorTimer.cpp:71
boost::posix_time::ptime currentDateTime() const
Return current date.
Definition: SimulatorTimer.cpp:115
bool initialStep() const
Whether the current step is the first step.
Definition: SimulatorTimer.cpp:65
void report(std::ostream &os) const
Print a report with current and total time etc.
Definition: SimulatorTimer.cpp:136
Class containing static geological properties that are derived from grid and petrophysical properties...
Definition: GeoProps.hpp:59
SimulatorReport run(SimulatorTimer &timer, ReservoirState &state)
Run the simulation.
Definition: SimulatorBase_impl.hpp:87
Interface class for (linear) solvers for the fully implicit black-oil system.
Definition: NewtonIterationBlackoilInterface.hpp:31
This class implements the AD-adapted fluid interface for three-phase black-oil.
Definition: BlackoilPropsAdFromDeck.hpp:61
Definition: SimulatorTimer.hpp:34