28 #ifndef OPM_ECL_WRITER_HPP 29 #define OPM_ECL_WRITER_HPP 31 #include <dune/grid/common/partitionset.hh> 33 #include <opm/common/TimingMacros.hpp> 34 #include <opm/common/OpmLog/OpmLog.hpp> 35 #include <opm/input/eclipse/Schedule/RPTConfig.hpp> 37 #include <opm/input/eclipse/Units/UnitSystem.hpp> 38 #include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp> 40 #include <opm/output/eclipse/Inplace.hpp> 41 #include <opm/output/eclipse/RestartValue.hpp> 46 #include <opm/simulators/flow/CollectDataOnIORank.hpp> 47 #include <opm/simulators/flow/countGlobalCells.hpp> 50 #include <opm/simulators/timestepping/SimulatorTimer.hpp> 51 #include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp> 52 #include <opm/simulators/utils/ParallelRestart.hpp> 53 #include <opm/simulators/utils/ParallelSerialization.hpp> 55 #include <opm/simulators/flow/rescoup/ReservoirCouplingEnabled.hpp> 56 #ifdef RESERVOIR_COUPLING_ENABLED 57 #include <opm/simulators/flow/rescoup/ReservoirCouplingMaster.hpp> 60 #include <boost/date_time/posix_time/posix_time.hpp> 113 template <
class TypeTag,
class OutputModule>
115 GetPropType<TypeTag, Properties::EquilGrid>,
116 GetPropType<TypeTag, Properties::GridView>,
117 GetPropType<TypeTag, Properties::ElementMapper>,
118 GetPropType<TypeTag, Properties::Scalar>>
128 using Element =
typename GridView::template Codim<0>::Entity;
130 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
133 typedef Dune::MultipleCodimMultipleGeomTypeMapper< GridView > VertexMapper;
135 static constexpr
bool enableEnergy =
136 getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal ||
137 getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::SequentialImplicitThermal;
138 enum { enableMech = getPropValue<TypeTag, Properties::EnableMech>() };
139 static constexpr
bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
140 enum { enableGeochemistry = getPropValue<TypeTag, Properties::EnableGeochemistry>() };
144 static void registerParameters()
146 OutputModule::registerParameters();
148 Parameters::Register<Parameters::EnableAsyncEclOutput>
149 (
"Write the ECL-formated results in a non-blocking way " 150 "(i.e., using a separate thread).");
151 Parameters::Register<Parameters::EnableEsmry>
152 (
"Write ESMRY file for fast loading of summary data.");
159 :
BaseType(simulator.vanguard().schedule(),
160 simulator.vanguard().eclState(),
161 simulator.vanguard().summaryConfig(),
162 simulator.vanguard().grid(),
163 ((simulator.vanguard().grid().comm().rank() == 0)
164 ? &simulator.vanguard().equilGrid()
166 simulator.vanguard().gridView(),
167 simulator.vanguard().cartesianIndexMapper(),
168 ((simulator.vanguard().grid().comm().rank() == 0)
169 ? &simulator.vanguard().equilCartesianIndexMapper()
171 Parameters::Get<Parameters::EnableAsyncEclOutput>(),
172 Parameters::Get<Parameters::EnableEsmry>())
173 , simulator_(simulator)
176 if (this->simulator_.vanguard().grid().comm().size() > 1) {
177 auto smryCfg = (this->simulator_.vanguard().grid().comm().rank() == 0)
178 ? this->eclIO_->finalSummaryConfig()
181 eclBroadcast(this->simulator_.vanguard().grid().comm(), smryCfg);
183 this->outputModule_ = std::make_unique<OutputModule>
184 (simulator, smryCfg, this->collectOnIORank_);
189 this->outputModule_ = std::make_unique<OutputModule>
190 (simulator, this->eclIO_->finalSummaryConfig(), this->collectOnIORank_);
193 this->rank_ = this->simulator_.vanguard().grid().comm().rank();
195 this->simulator_.vanguard().eclState().computeFipRegionStatistics();
201 const EquilGrid& globalGrid()
const 203 return simulator_.vanguard().equilGrid();
212 const int reportStepNum = simulator_.episodeIndex() + 1;
232 if (reportStepNum == 0)
235 const Scalar curTime = simulator_.time() + simulator_.timeStepSize();
236 const Scalar totalCpuTime =
237 simulator_.executionTimer().realTimeElapsed() +
238 simulator_.setupTimer().realTimeElapsed() +
239 simulator_.vanguard().setupTime();
241 const auto localWellData = simulator_.problem().wellModel().wellData();
242 const auto localWBP = simulator_.problem().wellModel().wellBlockAveragePressures();
243 const auto localGroupAndNetworkData = simulator_.problem().wellModel()
244 .groupAndNetworkData(reportStepNum);
246 const auto localAquiferData = simulator_.problem().aquiferModel().aquiferData();
247 const auto localWellTestState = simulator_.problem().wellModel().wellTestState();
248 this->prepareLocalCellData(isSubStep, reportStepNum);
250 if (this->outputModule_->needInterfaceFluxes(isSubStep)) {
251 this->captureLocalFluxData();
254 if (this->collectOnIORank_.isParallel()) {
255 OPM_BEGIN_PARALLEL_TRY_CATCH()
257 std::map<std::pair<std::string,int>,
double> dummy;
258 this->collectOnIORank_.collect({},
259 outputModule_->getBlockData(),
263 localGroupAndNetworkData,
266 this->outputModule_->getInterRegFlows(),
269 this->outputModule_->getLgrBlockData());
271 if (this->collectOnIORank_.isIORank()) {
272 auto& iregFlows = this->collectOnIORank_.globalInterRegFlows();
274 if (! iregFlows.readIsConsistent()) {
275 throw std::runtime_error {
276 "Inconsistent inter-region flow " 277 "region set names in parallel" 284 OPM_END_PARALLEL_TRY_CATCH(
"Collect to I/O rank: ",
285 this->simulator_.vanguard().grid().comm());
289 std::map<std::string, double> miscSummaryData;
290 std::map<std::string, std::vector<double>> regionData;
294 OPM_TIMEBLOCK(outputFipLogAndFipresvLog);
296 inplace = outputModule_->calc_inplace(miscSummaryData, regionData, simulator_.gridView().comm());
298 if (this->collectOnIORank_.isIORank()){
304 if (totalCpuTime != 0.0) {
305 miscSummaryData[
"TCPU"] = totalCpuTime;
307 if (this->sub_step_report_.total_newton_iterations != 0) {
308 miscSummaryData[
"NEWTON"] = this->sub_step_report_.total_newton_iterations;
310 if (this->sub_step_report_.total_linear_iterations != 0) {
311 miscSummaryData[
"MLINEARS"] = this->sub_step_report_.total_linear_iterations;
313 if (this->sub_step_report_.total_newton_iterations != 0) {
314 miscSummaryData[
"NLINEARS"] =
static_cast<float>(this->sub_step_report_.total_linear_iterations) / this->sub_step_report_.total_newton_iterations;
316 if (this->sub_step_report_.min_linear_iterations != std::numeric_limits<unsigned int>::max()) {
317 miscSummaryData[
"NLINSMIN"] = this->sub_step_report_.min_linear_iterations;
319 if (this->sub_step_report_.max_linear_iterations != 0) {
320 miscSummaryData[
"NLINSMAX"] = this->sub_step_report_.max_linear_iterations;
322 if (this->simulation_report_.success.total_linear_iterations != 0) {
323 miscSummaryData[
"MSUMLINS"] = this->simulation_report_.success.total_linear_iterations;
325 if (this->simulation_report_.success.total_newton_iterations != 0) {
326 miscSummaryData[
"MSUMNEWT"] = this->simulation_report_.success.total_newton_iterations;
331 const auto rcGroupRates = this->collectReservoirCouplingGroupRates_();
334 OPM_TIMEBLOCK(evalSummary);
336 const auto& blockData = this->collectOnIORank_.isParallel()
337 ? this->collectOnIORank_.globalBlockData()
338 : this->outputModule_->getBlockData();
340 const auto& lgrBlockData = this->collectOnIORank_.isParallel()
341 ? this->collectOnIORank_.globalLgrBlockData()
342 : this->outputModule_->getLgrBlockData();
344 const auto& interRegFlows = this->collectOnIORank_.isParallel()
345 ? this->collectOnIORank_.globalInterRegFlows()
346 : this->outputModule_->getInterRegFlows();
348 this->evalSummary(reportStepNum,
352 localGroupAndNetworkData,
359 this->outputModule_->initialInplace(),
361 this->summaryState(),
363 rcGroupRates ? &(*rcGroupRates) :
nullptr);
370 const auto& gridView = simulator_.vanguard().gridView();
371 const int num_interior = detail::
372 countLocalInteriorCellsGridView(gridView);
374 this->outputModule_->
375 allocBuffers(num_interior, 0,
false,
false,
false);
378 #pragma omp parallel for 380 for (
int dofIdx = 0; dofIdx < num_interior; ++dofIdx) {
381 const auto& intQuants = *simulator_.model().cachedIntensiveQuantities(dofIdx, 0);
382 const auto totVolume = simulator_.model().dofTotalVolume(dofIdx);
384 this->outputModule_->updateFluidInPlace(dofIdx, intQuants, totVolume);
389 outputModule_->calc_initial_inplace(simulator_.gridView().comm());
392 const auto& fip = simulator_.vanguard().eclState().getEclipseConfig().fip();
393 if (fip.output(FIPConfig::OutputField::FIELD) ||
394 fip.output(FIPConfig::OutputField::RESV))
396 OPM_TIMEBLOCK(outputFipLogAndFipresvLog);
398 const auto start_time = boost::posix_time::
399 from_time_t(simulator_.vanguard().schedule().getStartTime());
401 if (this->collectOnIORank_.isIORank()) {
402 this->inplace_ = *this->outputModule_->initialInplace();
404 this->outputModule_->
405 outputFipAndResvLog(this->inplace_, 0, 0.0, start_time,
406 false, simulator_.gridView().comm());
410 outputModule_->outputFipAndResvLogToCSV(0,
false, simulator_.gridView().comm());
415 if (! this->collectOnIORank_.isIORank()) {
427 const auto firstStep = this->initialStep();
431 const auto& rpt = this->schedule_[simStep].rpt_config();
433 if (rpt.contains(
"WELSPECS") && (rpt.at(
"WELSPECS") > 0)) {
436 this->writeWellspecReport(timer);
444 if (rpt.contains(
"WELLS") && rpt.at(
"WELLS") > 0) {
445 this->writeWellflowReport(timer, simStep, rpt.at(
"WELLS"));
448 this->outputModule_->outputFipAndResvLog(this->inplace_,
453 simulator_.gridView().comm());
458 void writeOutput(data::Solution&& localCellData,
const bool isSubStep,
const bool isForcedFinalOutput)
460 OPM_TIMEBLOCK(writeOutput);
462 const int reportStepNum = simulator_.episodeIndex() + 1;
463 this->prepareLocalCellData(isSubStep, reportStepNum);
464 this->outputModule_->outputErrorLog(simulator_.gridView().comm());
467 auto localWellData = simulator_.problem().wellModel().wellData();
468 auto localGroupAndNetworkData = simulator_.problem().wellModel()
469 .groupAndNetworkData(reportStepNum);
471 auto localAquiferData = simulator_.problem().aquiferModel().aquiferData();
472 auto localWellTestState = simulator_.problem().wellModel().wellTestState();
474 const bool isFlowsn = this->outputModule_->getFlows().hasFlowsn();
475 auto flowsn = this->outputModule_->getFlows().getFlowsn();
477 const bool isFloresn = this->outputModule_->getFlows().hasFloresn();
478 auto floresn = this->outputModule_->getFlows().getFloresn();
480 if (! isSubStep || Parameters::Get<Parameters::EnableWriteAllSolutions>()) {
482 if (localCellData.empty()) {
483 this->outputModule_->assignToSolution(localCellData);
487 this->outputModule_->addRftDataToWells(localWellData,
489 simulator_.gridView().comm());
492 if (this->collectOnIORank_.isParallel() ||
493 this->collectOnIORank_.doesNeedReordering())
500 this->collectOnIORank_.collect(localCellData,
501 this->outputModule_->getBlockData(),
502 this->outputModule_->getExtraBlockData(),
505 localGroupAndNetworkData,
512 if (this->collectOnIORank_.isIORank()) {
513 this->outputModule_->assignGlobalFieldsToSolution(this->collectOnIORank_.globalCellData());
516 this->outputModule_->assignGlobalFieldsToSolution(localCellData);
519 if (this->collectOnIORank_.isIORank()) {
520 const Scalar curTime = simulator_.time() + simulator_.timeStepSize();
521 const Scalar nextStepSize = simulator_.problem().nextTimeStepSize();
522 std::optional<int> timeStepIdx;
523 if (Parameters::Get<Parameters::EnableWriteAllSolutions>()) {
524 timeStepIdx = simulator_.timeStepIndex();
526 this->doWriteOutput(reportStepNum, timeStepIdx, isSubStep,
528 std::move(localCellData),
529 std::move(localWellData),
530 std::move(localGroupAndNetworkData),
531 std::move(localAquiferData),
532 std::move(localWellTestState),
535 this->summaryState(),
536 this->simulator_.problem().thresholdPressure().getRestartVector(),
537 curTime, nextStepSize,
538 Parameters::Get<Parameters::EclOutputDoublePrecision>(),
539 isFlowsn, std::move(flowsn),
540 isFloresn, std::move(floresn));
546 const auto enablePCHysteresis = simulator_.problem().materialLawManager()->enablePCHysteresis();
547 const auto enableNonWettingHysteresis = simulator_.problem().materialLawManager()->enableNonWettingHysteresis();
548 const auto enableWettingHysteresis = simulator_.problem().materialLawManager()->enableWettingHysteresis();
549 const auto oilActive = FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx);
550 const auto gasActive = FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx);
551 const auto waterActive = FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx);
552 const auto enableSwatinit = simulator_.vanguard().eclState().fieldProps().has_double(
"SWATINIT");
554 std::vector<RestartKey> solutionKeys {
555 {
"PRESSURE", UnitSystem::measure::pressure},
556 {
"SWAT", UnitSystem::measure::identity, waterActive},
557 {
"SGAS", UnitSystem::measure::identity, gasActive},
558 {
"TEMP", UnitSystem::measure::temperature, enableEnergy},
559 {
"SSOLVENT", UnitSystem::measure::identity, enableSolvent},
561 {
"RS", UnitSystem::measure::gas_oil_ratio, FluidSystem::enableDissolvedGas()},
562 {
"RV", UnitSystem::measure::oil_gas_ratio, FluidSystem::enableVaporizedOil()},
563 {
"RVW", UnitSystem::measure::oil_gas_ratio, FluidSystem::enableVaporizedWater()},
564 {
"RSW", UnitSystem::measure::gas_oil_ratio, FluidSystem::enableDissolvedGasInWater()},
566 {
"SGMAX", UnitSystem::measure::identity, enableNonWettingHysteresis && oilActive && gasActive},
567 {
"SHMAX", UnitSystem::measure::identity, enableWettingHysteresis && oilActive && gasActive},
569 {
"SOMAX", UnitSystem::measure::identity,
570 (enableNonWettingHysteresis && oilActive && waterActive)
571 || simulator_.problem().vapparsActive(simulator_.episodeIndex())},
573 {
"SOMIN", UnitSystem::measure::identity, enablePCHysteresis && oilActive && gasActive},
574 {
"SWHY1", UnitSystem::measure::identity, enablePCHysteresis && oilActive && waterActive},
575 {
"SWMAX", UnitSystem::measure::identity, enableWettingHysteresis && oilActive && waterActive},
577 {
"PPCW", UnitSystem::measure::pressure, enableSwatinit},
581 const auto& tracers = simulator_.vanguard().eclState().tracer();
583 for (
const auto& tracer : tracers) {
584 const auto enableSolTracer =
585 ((tracer.phase == Phase::GAS) && FluidSystem::enableDissolvedGas()) ||
586 ((tracer.phase == Phase::OIL) && FluidSystem::enableVaporizedOil());
588 solutionKeys.emplace_back(tracer.fname(), UnitSystem::measure::identity,
true);
589 solutionKeys.emplace_back(tracer.sname(), UnitSystem::measure::identity, enableSolTracer);
593 const auto& inputThpres = eclState().getSimulationConfig().getThresholdPressure();
594 const std::vector<RestartKey> extraKeys {
595 {
"OPMEXTRA", UnitSystem::measure::identity,
false},
596 {
"THRESHPR", UnitSystem::measure::pressure, inputThpres.active()},
599 const auto& gridView = this->simulator_.vanguard().gridView();
600 const auto numElements = gridView.size(0);
604 this->outputModule_->allocBuffers(numElements,
610 const auto restartSolution =
611 loadParallelRestartSolution(this->eclIO_.get(),
612 solutionKeys, gridView.comm(), 0);
614 if (!restartSolution.empty()) {
615 for (
auto elemIdx = 0*numElements; elemIdx < numElements; ++elemIdx) {
616 const auto globalIdx = this->collectOnIORank_.localIdxToGlobalIdx(elemIdx);
617 this->outputModule_->setRestart(restartSolution, elemIdx, globalIdx);
620 this->simulator_.problem().readSolutionFromOutputModule(0,
true);
621 this->simulator_.problem().temperatureModel().init();
622 ElementContext elemCtx(this->simulator_);
623 for (
const auto& elem : elements(gridView, Dune::Partitions::interior)) {
624 elemCtx.updatePrimaryStencil(elem);
625 elemCtx.updatePrimaryIntensiveQuantities(0);
627 this->outputModule_->updateFluidInPlace(elemCtx);
630 this->outputModule_->calc_initial_inplace(this->simulator_.gridView().comm());
638 const auto restartStepIdx = this->simulator_.vanguard()
639 .eclState().getInitConfig().getRestartStep();
641 this->outputModule_->allocBuffers(numElements,
649 const auto restartValues =
650 loadParallelRestart(this->eclIO_.get(),
652 this->summaryState(),
653 solutionKeys, extraKeys, gridView.comm());
655 for (
auto elemIdx = 0*numElements; elemIdx < numElements; ++elemIdx) {
656 const auto globalIdx = this->collectOnIORank_.localIdxToGlobalIdx(elemIdx);
657 this->outputModule_->setRestart(restartValues.solution, elemIdx, globalIdx);
660 auto& tracer_model = simulator_.problem().tracerModel();
661 for (
int tracer_index = 0; tracer_index < tracer_model.numTracers(); ++tracer_index) {
664 const auto& free_tracer_name = tracer_model.fname(tracer_index);
665 const auto& free_tracer_solution = restartValues.solution
666 .template data<double>(free_tracer_name);
668 for (
auto elemIdx = 0*numElements; elemIdx < numElements; ++elemIdx) {
669 const auto globalIdx = this->collectOnIORank_.localIdxToGlobalIdx(elemIdx);
670 tracer_model.setFreeTracerConcentration
671 (tracer_index, elemIdx, free_tracer_solution[globalIdx]);
676 if ((tracer_model.phase(tracer_index) == Phase::GAS && FluidSystem::enableDissolvedGas()) ||
677 (tracer_model.phase(tracer_index) == Phase::OIL && FluidSystem::enableVaporizedOil()))
679 tracer_model.setEnableSolTracers(tracer_index,
true);
681 const auto& sol_tracer_name = tracer_model.sname(tracer_index);
682 const auto& sol_tracer_solution = restartValues.solution
683 .template data<double>(sol_tracer_name);
685 for (
auto elemIdx = 0*numElements; elemIdx < numElements; ++elemIdx) {
686 const auto globalIdx = this->collectOnIORank_.localIdxToGlobalIdx(elemIdx);
687 tracer_model.setSolTracerConcentration
688 (tracer_index, elemIdx, sol_tracer_solution[globalIdx]);
692 tracer_model.setEnableSolTracers(tracer_index,
false);
694 for (
auto elemIdx = 0*numElements; elemIdx < numElements; ++elemIdx) {
695 tracer_model.setSolTracerConcentration(tracer_index, elemIdx, 0.0);
700 if (inputThpres.active()) {
701 const_cast<Simulator&
>(this->simulator_)
702 .problem().thresholdPressure()
703 .setFromRestart(restartValues.getExtra(
"THRESHPR"));
706 restartTimeStepSize_ = restartValues.getExtra(
"OPMEXTRA")[0];
707 if (restartTimeStepSize_ <= 0) {
708 restartTimeStepSize_ = std::numeric_limits<double>::max();
712 this->simulator_.problem().wellModel()
713 .initFromRestartFile(restartValues);
715 if (!restartValues.aquifer.empty()) {
716 this->simulator_.problem().mutableAquiferModel()
717 .initFromRestart(restartValues.aquifer);
727 this->outputModule_->calc_initial_inplace(this->simulator_.gridView().comm());
729 if (this->collectOnIORank_.isIORank()) {
730 if (
const auto* iip = this->outputModule_->initialInplace(); iip !=
nullptr) {
731 this->inplace_ = *iip;
736 const OutputModule& outputModule()
const 737 {
return *outputModule_; }
739 OutputModule& mutableOutputModule()
const 740 {
return *outputModule_; }
742 Scalar restartTimeStepSize()
const 743 {
return restartTimeStepSize_; }
745 template <
class Serializer>
746 void serializeOp(Serializer& serializer)
748 serializer(*outputModule_);
752 static bool enableEclOutput_()
754 static bool enable = Parameters::Get<Parameters::EnableEclOutput>();
758 const EclipseState& eclState()
const 759 {
return simulator_.vanguard().eclState(); }
761 SummaryState& summaryState()
762 {
return simulator_.vanguard().summaryState(); }
764 Action::State& actionState()
765 {
return simulator_.vanguard().actionState(); }
768 {
return simulator_.vanguard().udqState(); }
770 const Schedule& schedule()
const 771 {
return simulator_.vanguard().schedule(); }
775 std::optional<data::ReservoirCouplingGroupRates> collectReservoirCouplingGroupRates_()
777 #ifdef RESERVOIR_COUPLING_ENABLED 782 using WellModelType = std::remove_cvref_t<
783 decltype(simulator_.problem().wellModel())>;
784 if constexpr (requires(WellModelType& wm) { wm.isReservoirCouplingMaster(); }) {
785 auto& wellModel = simulator_.problem().wellModel();
786 if (!wellModel.isReservoirCouplingMaster()) {
789 return wellModel.reservoirCouplingMaster()
790 .collectGroupRatesForSummary();
796 void prepareLocalCellData(
const bool isSubStep,
797 const int reportStepNum)
799 OPM_TIMEBLOCK(prepareLocalCellData);
801 if (this->outputModule_->localDataValid()) {
805 const auto& gridView = simulator_.vanguard().gridView();
806 const bool log = this->collectOnIORank_.isIORank();
808 const int num_interior = detail::
809 countLocalInteriorCellsGridView(gridView);
810 this->outputModule_->
811 allocBuffers(num_interior, reportStepNum,
812 isSubStep && !Parameters::Get<Parameters::EnableWriteAllSolutions>(),
815 ElementContext elemCtx(simulator_);
817 OPM_BEGIN_PARALLEL_TRY_CATCH();
820 OPM_TIMEBLOCK(prepareCellBasedData);
822 this->outputModule_->prepareDensityAccumulation();
823 this->outputModule_->setupExtractors(isSubStep, reportStepNum);
824 for (
const auto& elem : elements(gridView, Dune::Partitions::interior)) {
825 elemCtx.updatePrimaryStencil(elem);
826 elemCtx.updatePrimaryIntensiveQuantities(0);
828 this->outputModule_->processElement(elemCtx);
829 this->outputModule_->processElementBlockData(elemCtx);
831 this->outputModule_->clearExtractors();
833 this->outputModule_->accumulateDensityParallel();
837 OPM_TIMEBLOCK(prepareFluidInPlace);
840 #pragma omp parallel for 842 for (
int dofIdx = 0; dofIdx < num_interior; ++dofIdx) {
843 const auto& intQuants = *simulator_.model().cachedIntensiveQuantities(dofIdx, 0);
844 const auto totVolume = simulator_.model().dofTotalVolume(dofIdx);
846 this->outputModule_->updateFluidInPlace(dofIdx, intQuants, totVolume);
850 this->outputModule_->validateLocalData();
852 OPM_END_PARALLEL_TRY_CATCH(
"EclWriter::prepareLocalCellData() failed: ",
853 this->simulator_.vanguard().grid().comm());
856 void captureLocalFluxData()
858 OPM_TIMEBLOCK(captureLocalData);
860 const auto& gridView = this->simulator_.vanguard().gridView();
861 const auto timeIdx = 0u;
863 auto elemCtx = ElementContext { this->simulator_ };
865 const auto elemMapper = ElementMapper { gridView, Dune::mcmgElementLayout() };
866 const auto activeIndex = [&elemMapper](
const Element& e)
868 return elemMapper.index(e);
871 const auto cartesianIndex = [
this](
const int elemIndex)
873 return this->cartMapper_.cartesianIndex(elemIndex);
876 this->outputModule_->initializeFluxData();
878 OPM_BEGIN_PARALLEL_TRY_CATCH();
880 for (
const auto& elem : elements(gridView, Dune::Partitions::interiorBorder)) {
881 elemCtx.updateStencil(elem);
882 elemCtx.updateIntensiveQuantities(timeIdx);
883 elemCtx.updateExtensiveQuantities(timeIdx);
885 this->outputModule_->processFluxes(elemCtx, activeIndex, cartesianIndex);
888 OPM_END_PARALLEL_TRY_CATCH(
"EclWriter::captureLocalFluxData() failed: ",
889 this->simulator_.vanguard().grid().comm())
891 this->outputModule_->finalizeFluxData();
894 void writeWellspecReport(
const SimulatorTimer& timer)
const 896 const auto changedWells = this->schedule_
897 .changed_wells(timer.reportStepNum(), this->initialStep());
899 const auto changedWellLists = this->schedule_
900 .changedWellLists(timer.reportStepNum(), this->initialStep());
902 if (changedWells.empty() && !changedWellLists) {
906 this->outputModule_->outputWellspecReport(changedWells,
908 timer.reportStepNum(),
909 timer.simulationTimeElapsed(),
910 timer.currentDateTime());
913 void writeWellflowReport(
const SimulatorTimer& timer,
915 const int wellsRequest)
const 917 this->outputModule_->outputTimeStamp(
"WELLS",
918 timer.simulationTimeElapsed(),
919 timer.reportStepNum(),
920 timer.currentDateTime());
922 const auto wantConnData = wellsRequest > 1;
924 this->outputModule_->outputProdLog(simStep, wantConnData);
925 this->outputModule_->outputInjLog(simStep, wantConnData);
926 this->outputModule_->outputCumLog(simStep, wantConnData);
927 this->outputModule_->outputMSWLog(simStep);
930 int initialStep()
const 932 const auto& initConfig = this->eclState().cfg().init();
934 return initConfig.restartRequested()
935 ? initConfig.getRestartStep()
939 Simulator& simulator_;
940 std::unique_ptr<OutputModule> outputModule_;
941 Scalar restartTimeStepSize_;
948 #endif // OPM_ECL_WRITER_HPP void evalSummaryState(bool isSubStep)
collect and pass data and pass it to eclIO writer
Definition: EclWriter.hpp:209
Definition: ActionHandler.hpp:34
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...))
Definition: propertysystem.hh:233
double simulationTimeElapsed() const override
Time elapsed since the start of the simulation until the beginning of the current time step [s]...
Definition: SimulatorTimer.cpp:122
Definition: EclWriter.hpp:81
Helper class for grid instantiation of ECL file-format using problems.
virtual int reportStepNum() const
Current report step number. This might differ from currentStepNum in case of sub stepping.
Definition: SimulatorTimerInterface.hpp:109
Defines the common properties required by the porous medium multi-phase models.
void compress()
Form CSR adjacency matrix representation of input graph from connections established in previous call...
Definition: InterRegFlows.cpp:164
Definition: EclWriter.hpp:77
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Definition: blackoilnewtonmethodparams.hpp:31
Definition: EclWriter.hpp:84
Declares the properties required by the black oil model.
Definition: EclWriter.hpp:74
void writeInitialFIPReport()
Writes the initial FIP report as configured in RPTSOL.
Definition: EclWriter.hpp:368
Definition: EclGenericWriter.hpp:68
Collects necessary output values and pass it to opm-common's ECL output.
Collects necessary output values and pass it to opm-common's ECL output.
Definition: EclWriter.hpp:114
Definition: SimulatorTimer.hpp:38
virtual boost::posix_time::ptime currentDateTime() const
Return the current time as a posix time object.
Definition: SimulatorTimerInterface.cpp:28