26 template <
class Gr
idT>
27 auto SimulatorFullyImplicitBlackoilMultiSegment<GridT>::
28 createSolver(
const WellModel& well_model)
29 -> std::unique_ptr<Solver>
31 typedef typename Traits::Model Model;
33 auto model = std::unique_ptr<Model>(
new Model(model_param_,
45 if (!Base::threshold_pressures_by_face_.empty()) {
46 model->setThresholdPressures(Base::threshold_pressures_by_face_);
49 return std::unique_ptr<ThisType::Solver>(
new Solver(Base::solver_param_, std::move(model)));
53 template <
class Gr
idT>
54 SimulatorReport SimulatorFullyImplicitBlackoilMultiSegment<GridT>::run(SimulatorTimer& timer,
55 ReservoirState& state)
57 WellState prev_well_state;
60 Opm::time::StopWatch solver_timer;
62 Opm::time::StopWatch step_timer;
63 Opm::time::StopWatch total_timer;
65 std::string tstep_filename = output_writer_.outputDirectory() +
"/step_timing.txt";
66 std::ofstream tstep_os(tstep_filename.c_str());
69 const auto& events = eclipse_state_->getSchedule().getEvents();
70 std::unique_ptr< AdaptiveTimeStepping > adaptiveTimeStepping;
71 if( param_.getDefault(
"timestep.adaptive",
true ) )
73 adaptiveTimeStepping.reset(
new AdaptiveTimeStepping( param_, terminal_output_ ) );
76 std::string restorefilename = param_.getDefault(
"restorefile", std::string(
"") );
77 if( ! restorefilename.empty() )
80 const int desiredRestoreStep = param_.getDefault(
"restorestep",
int(-1) );
81 output_writer_.restore( timer,
88 unsigned int totalNonlinearIterations = 0;
89 unsigned int totalLinearIterations = 0;
90 DynamicListEconLimited dynamic_list_econ_limited;
92 bool ooip_computed =
false;
93 std::vector<int> fipnum_global = eclipse_state_->get3DProperties().getIntGridProperty(
"FIPNUM").getData();
95 std::vector<int> fipnum(AutoDiffGrid::numCells(grid_));
96 if (fipnum_global.empty()) {
97 std::fill(fipnum.begin(), fipnum.end(), 0);
99 for (
size_t c = 0; c < fipnum.size(); ++c) {
100 fipnum[c] = fipnum_global[AutoDiffGrid::globalCell(grid_)[c]];
103 std::vector<std::vector<double> > OOIP;
106 while (!timer.done()) {
109 if ( terminal_output_ )
111 timer.report(std::cout);
115 WellsManager wells_manager(*eclipse_state_,
116 timer.currentStepNum(),
117 Opm::UgGridHelpers::numCells(grid_),
118 Opm::UgGridHelpers::globalCell(grid_),
119 Opm::UgGridHelpers::cartDims(grid_),
120 Opm::UgGridHelpers::dimensions(grid_),
121 Opm::UgGridHelpers::cell2Faces(grid_),
122 Opm::UgGridHelpers::beginFaceCentroids(grid_),
123 dynamic_list_econ_limited,
129 Base::defunct_well_names_);
130 const Wells* wells = wells_manager.c_wells();
131 WellState well_state;
134 const auto wells_ecl = eclipse_state_->getSchedule().getWells(timer.currentStepNum());
135 const int current_time_step = timer.currentStepNum();
137 const WellModel well_model(wells, &(wells_manager.wellCollection()), wells_ecl, current_time_step);
139 well_state.init(well_model, state, prev_well_state, wells);
142 Base::asImpl().handleAdditionalWellInflow(timer, wells_manager, well_state, wells);
145 if (timer.initialStep()) {
148 output_writer_.writeTimeStepWithoutCellProperties( timer, state, well_state, {}, {} );
152 props_.updateSatOilMax(state.saturation());
153 props_.updateSatHyst(state.saturation(), allcells_);
156 Base::asImpl().computeRESV(timer.currentStepNum(), wells, state, well_state);
159 solver_timer.start();
161 auto solver = createSolver(well_model);
164 if (!ooip_computed) {
165 OOIP = solver->computeFluidInPlace(state, fipnum);
166 Base::FIPUnitConvert(eclipse_state_->getUnits(), OOIP);
167 ooip_computed =
true;
175 if( adaptiveTimeStepping ) {
176 bool event = events.hasEvent(ScheduleEvents::NEW_WELL, timer.currentStepNum()) ||
177 events.hasEvent(ScheduleEvents::PRODUCTION_UPDATE, timer.currentStepNum()) ||
178 events.hasEvent(ScheduleEvents::INJECTION_UPDATE, timer.currentStepNum()) ||
179 events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE, timer.currentStepNum());
180 adaptiveTimeStepping->step( timer, *solver, state, well_state, event, output_writer_);
184 solver->step(timer, state, well_state);
191 totalNonlinearIterations += solver->nonlinearIterations();
192 totalLinearIterations += solver->linearIterations();
195 const double st = solver_timer.secsSinceStart();
198 std::vector<std::vector<double> > COIP;
199 COIP = solver->computeFluidInPlace(state, fipnum);
200 std::vector<double> OOIP_totals = Base::FIPTotals(OOIP, state);
201 std::vector<double> COIP_totals = Base::FIPTotals(COIP, state);
204 Base::FIPUnitConvert(eclipse_state_->getUnits(), COIP);
205 Base::FIPUnitConvert(eclipse_state_->getUnits(), OOIP_totals);
206 Base::FIPUnitConvert(eclipse_state_->getUnits(), COIP_totals);
208 if ( terminal_output_ )
210 Base::outputFluidInPlace(OOIP_totals, COIP_totals,eclipse_state_->getUnits(), 0);
211 for (
size_t reg = 0; reg < OOIP.size(); ++reg) {
212 Base::outputFluidInPlace(OOIP[reg], COIP[reg], eclipse_state_->getUnits(), reg+1);
216 if ( terminal_output_ )
218 std::cout <<
"Fully implicit solver took: " << st <<
" seconds." << std::endl;
222 if ( output_writer_.output() ) {
223 SimulatorReport step_report;
224 step_report.solver_time = st;
225 step_report.total_time = step_timer.secsSinceStart();
226 step_report.reportParam(tstep_os);
234 const auto& physicalModel = solver->model();
235 output_writer_.writeTimeStep( timer, state, well_state, physicalModel );
237 prev_well_state = well_state;
242 SimulatorReport report;
243 report.total_time = total_timer.secsSinceStart();
244 report.solver_time = stime;
245 report.total_newton_iterations = totalNonlinearIterations;
246 report.total_linear_iterations = totalLinearIterations;
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: AdditionalObjectDeleter.hpp:22