From 6eeecbb02b80d19b3ebf81199f07f05acd661627 Mon Sep 17 00:00:00 2001 From: Robert K Date: Thu, 8 Jan 2015 12:42:05 +0100 Subject: [PATCH] - adjust OutputWriter to SimulatorTimerInterface - remove WriterTimer from EclipseWriter and use SimulatorTimerInterface - adjust to the above in AdaptiveTimeStepping. --- opm/core/io/OutputWriter.cpp | 15 +-- opm/core/io/OutputWriter.hpp | 24 +--- opm/core/io/eclipse/EclipseWriter.cpp | 107 ++++-------------- opm/core/io/eclipse/EclipseWriter.hpp | 28 +---- opm/core/simulator/AdaptiveSimulatorTimer.hpp | 1 - opm/core/simulator/AdaptiveTimeStepping.hpp | 37 +++--- .../simulator/AdaptiveTimeStepping_impl.hpp | 58 +++++----- 7 files changed, 85 insertions(+), 185 deletions(-) diff --git a/opm/core/io/OutputWriter.cpp b/opm/core/io/OutputWriter.cpp index 4c7e25ca..1431ad46 100644 --- a/opm/core/io/OutputWriter.cpp +++ b/opm/core/io/OutputWriter.cpp @@ -26,26 +26,17 @@ struct MultiWriter : public OutputWriter { MultiWriter (ptr_t writers) : writers_ (std::move (writers)) { } /// Forward the call to all writers - virtual void writeInit(const SimulatorTimer &timer) { + virtual void writeInit(const SimulatorTimerInterface &timer) { for (it_t it = writers_->begin (); it != writers_->end (); ++it) { (*it)->writeInit (timer); } } - virtual void writeTimeStep(const SimulatorTimer& timer, - const SimulatorState& reservoirState, - const WellState& wellState) { - for (it_t it = writers_->begin (); it != writers_->end(); ++it) { - (*it)->writeTimeStep (timer, reservoirState, wellState); - } - } - - virtual void writeTimeStep(const SimulatorTimer& timer, - const AdaptiveSimulatorTimer& substepTimer, + virtual void writeTimeStep(const SimulatorTimerInterface& timer, const SimulatorState& reservoirState, const WellState& wellState) { for (it_t it = writers_->begin (); it != writers_->end(); ++it) { - (*it)->writeTimeStep (timer, substepTimer, reservoirState, wellState); + (*it)->writeTimeStep (timer, reservoirState, wellState); } } diff --git a/opm/core/io/OutputWriter.hpp b/opm/core/io/OutputWriter.hpp index c4d71c79..27f4dd3b 100644 --- a/opm/core/io/OutputWriter.hpp +++ b/opm/core/io/OutputWriter.hpp @@ -21,6 +21,7 @@ #define OPM_OUTPUT_WRITER_HPP #include // unique_ptr, shared_ptr +#include struct UnstructuredGrid; @@ -30,8 +31,6 @@ namespace Opm { class EclipseState; namespace parameter { class ParameterGroup; } class SimulatorState; -class SimulatorTimer; -class AdaptiveSimulatorTimer; class WellState; struct PhaseUsage; @@ -74,7 +73,7 @@ public: * This routine should be called before the first timestep (i.e. when * timer.currentStepNum () == 0) */ - virtual void writeInit(const SimulatorTimer &timer) = 0; + virtual void writeInit(const SimulatorTimerInterface &timer) = 0; /*! * \brief Write a blackoil reservoir state to disk for later inspection with @@ -87,24 +86,7 @@ public: * This routine should be called after the timestep has been advanced, * i.e. timer.currentStepNum () > 0. */ - virtual void writeTimeStep(const SimulatorTimer& timer, - const SimulatorState& reservoirState, - const WellState& wellState) = 0; - - /*! - * \brief Write a blackoil reservoir state to disk for later inspection with - * visualization tools like ResInsight - * - * \param[in] timer The timer providing time, time step, etc. information - * \param[in] subStepTimer The timer providing sub step time information - * \param[in] reservoirState The thermodynamic state of the reservoir - * \param[in] wellState The production/injection data for all wells - * - * This routine should be called after the timestep has been advanced, - * i.e. timer.currentStepNum () > 0. - */ - virtual void writeTimeStep(const SimulatorTimer& timer, - const AdaptiveSimulatorTimer& subStepTimer, + virtual void writeTimeStep(const SimulatorTimerInterface& timer, const SimulatorState& reservoirState, const WellState& wellState) = 0; diff --git a/opm/core/io/eclipse/EclipseWriter.cpp b/opm/core/io/eclipse/EclipseWriter.cpp index 1e9d56a4..8af5080d 100644 --- a/opm/core/io/eclipse/EclipseWriter.cpp +++ b/opm/core/io/eclipse/EclipseWriter.cpp @@ -27,8 +27,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -126,40 +125,6 @@ int ertPhaseMask(const PhaseUsage uses) } -// wrapper class to make EclipseWriter work with either the SimulatorTimer or a -// combination of SimulatorTimer and AdaptiveSimulatorTimer. -struct WriterTimer -{ - const double time_; - const double stepLength_; - const time_t posixTime_; - const int deckReportStep_; - - // copy values from SimulatorTimer - WriterTimer( const SimulatorTimer& timer ) - : time_( timer.simulationTimeElapsed() ), - stepLength_( timer.stepLengthTaken() ), - posixTime_( timer.currentPosixTime() ), - deckReportStep_( timer.currentStepNum() ) - {} - - // copy values from SimulatorTimer and add values from - // AdaptiveSimulatorTimer, except the deck's reportStep - WriterTimer( const SimulatorTimer& timer, const AdaptiveSimulatorTimer& subStepTimer ) - : time_( subStepTimer.simulationTimeElapsed() ), - stepLength_( subStepTimer.currentStepLength() ), - posixTime_( timer.currentPosixTime() + time_t(time_ - timer.simulationTimeElapsed()) ), - deckReportStep_( timer.currentStepNum() ) - {} - - int deckReportStep () const { return deckReportStep_; } - double simulationTimeElapsed() const { return time_; } - /// time elapsed since the start of the POSIX epoch (Jan 1st, 1970) [s]. - time_t currentPosixTime() const { return posixTime_; } - double stepLengthTaken () const { return stepLength_; } -}; - - /** * Eclipse "keyword" (i.e. named data) for a vector. */ @@ -405,7 +370,7 @@ public: ecl_rst_file_close(restartFileHandle_); } - void writeHeader(const WriterTimer& timer, + void writeHeader(const SimulatorTimerInterface& timer, int reportStepIdx, ecl_rsthead_type * rsthead_data) { @@ -460,7 +425,7 @@ class Summary : private boost::noncopyable public: Summary(const std::string& outputDir, const std::string& baseName, - const WriterTimer& timer, + const SimulatorTimerInterface& timer, int nx, int ny, int nz) @@ -497,7 +462,7 @@ public: void addAllWells(Opm::EclipseStateConstPtr eclipseState, const PhaseUsage& uses); void writeTimeStep(int reportStepIdx, - const WriterTimer& timer, + const SimulatorTimerInterface& timer, const WellState& wellState); ecl_sum_type *ertHandle() const @@ -515,7 +480,7 @@ class SummaryTimeStep : private boost::noncopyable public: SummaryTimeStep(Summary& summaryHandle, int reportStepIdx, - const WriterTimer &timer) + const SimulatorTimerInterface &timer) { ertHandle_ = ecl_sum_add_tstep(summaryHandle.ertHandle(), reportStepIdx, @@ -570,7 +535,7 @@ public: void writeHeader(int numCells, const int* compressedToCartesianCellIdx, - const WriterTimer& timer, + const SimulatorTimerInterface& timer, Opm::EclipseStateConstPtr eclipseState, const PhaseUsage uses) { @@ -655,7 +620,7 @@ public: /// Retrieve the value which the monitor is supposed to write to the summary file /// according to the state of the well. virtual double retrieveValue(const int reportStepIdx, - const WriterTimer& timer, + const SimulatorTimerInterface& timer, const WellState& wellState, const std::map& nameToIdxMap) = 0; @@ -787,7 +752,7 @@ public: { } virtual double retrieveValue(const int reportStepIdx, - const WriterTimer& timer, + const SimulatorTimerInterface& timer, const WellState& wellState, const std::map& wellNameToIdxMap) { @@ -798,7 +763,7 @@ public: return 0.0; } - if (well_->getStatus(timer.deckReportStep()) == WellCommon::SHUT) { + if (well_->getStatus(timer.reportStepNum()) == WellCommon::SHUT) { // well is shut in the current time step return 0.0; } @@ -833,7 +798,7 @@ public: { } virtual double retrieveValue(const int reportStepIdx, - const WriterTimer& timer, + const SimulatorTimerInterface& timer, const WellState& wellState, const std::map& wellNameToIdxMap) { @@ -843,7 +808,7 @@ public: return 0.0; } - if (well_->getStatus(timer.deckReportStep()) == WellCommon::SHUT) { + if (well_->getStatus(timer.reportStepNum()) == WellCommon::SHUT) { // well is shut in the current time step return 0.0; } @@ -892,7 +857,7 @@ public: { } virtual double retrieveValue(const int reportStepIdx, - const WriterTimer& timer, + const SimulatorTimerInterface& timer, const WellState& wellState, const std::map& wellNameToIdxMap) { @@ -902,7 +867,7 @@ public: // well not active in current time step return 0.0; } - if (well_->getStatus(timer.deckReportStep()) == WellCommon::SHUT) { + if (well_->getStatus(timer.reportStepNum()) == WellCommon::SHUT) { // well is shut in the current time step return 0.0; } @@ -914,16 +879,16 @@ public: // no inline implementation of this since it depends on the // WellReport type being completed first void Summary::writeTimeStep(int reportStepIdx, - const WriterTimer& timer, + const SimulatorTimerInterface& timer, const WellState& wellState) { // create a name -> well index map const Opm::ScheduleConstPtr schedule = eclipseState_->getSchedule(); - const auto& timeStepWells = schedule->getWells(timer.deckReportStep()); + const auto& timeStepWells = schedule->getWells(timer.reportStepNum()); std::map wellNameToIdxMap; int openWellIdx = 0; for (size_t tsWellIdx = 0; tsWellIdx < timeStepWells.size(); ++tsWellIdx) { - if (timeStepWells[tsWellIdx]->getStatus(timer.deckReportStep()) != WellCommon::SHUT ) { + if (timeStepWells[tsWellIdx]->getStatus(timer.reportStepNum()) != WellCommon::SHUT ) { wellNameToIdxMap[timeStepWells[tsWellIdx]->name()] = openWellIdx; openWellIdx++; } @@ -1050,13 +1015,7 @@ int EclipseWriter::eclipseWellStatusMask(WellCommon::StatusEnum wellStatus) } -void EclipseWriter::writeInit(const SimulatorTimer &timer) -{ - EclipseWriterDetails::WriterTimer writerTimer( timer ); - writeInit( writerTimer ); -} - -void EclipseWriter::writeInit(const EclipseWriterDetails::WriterTimer &timer) +void EclipseWriter::writeInit(const SimulatorTimerInterface &timer) { // if we don't want to write anything, this method becomes a // no-op... @@ -1101,26 +1060,8 @@ void EclipseWriter::writeInit(const EclipseWriterDetails::WriterTimer &timer) summary_->addAllWells(eclipseState_, phaseUsage_); } - -void EclipseWriter::writeTimeStep(const SimulatorTimer& timer, - const SimulatorState& reservoirState, - const WellState& wellState) -{ - EclipseWriterDetails::WriterTimer writerTimer ( timer ); - writeTimeStep( writerTimer, reservoirState, wellState ); -} - -void EclipseWriter::writeTimeStep(const SimulatorTimer& timer, - const AdaptiveSimulatorTimer& subStepTimer, - const SimulatorState& reservoirState, - const WellState& wellState) -{ - EclipseWriterDetails::WriterTimer writerTimer ( timer, subStepTimer ); - writeTimeStep( writerTimer, reservoirState, wellState ); -} - // implementation of the writeTimeStep method -void EclipseWriter::writeTimeStep(const EclipseWriterDetails::WriterTimer& timer, +void EclipseWriter::writeTimeStep(const SimulatorTimerInterface& timer, const SimulatorState& reservoirState, const WellState& wellState) { @@ -1136,7 +1077,7 @@ void EclipseWriter::writeTimeStep(const EclipseWriterDetails::WriterTimer& timer } - std::vector wells_ptr = eclipseState_->getSchedule()->getWells(timer.deckReportStep()); + std::vector wells_ptr = eclipseState_->getSchedule()->getWells(timer.reportStepNum()); std::vector iwell_data; std::vector zwell_data; std::vector icon_data; @@ -1147,7 +1088,7 @@ void EclipseWriter::writeTimeStep(const EclipseWriterDetails::WriterTimer& timer rsthead_data.nx = cartesianSize_[0]; rsthead_data.ny = cartesianSize_[1]; rsthead_data.nz = cartesianSize_[2]; - rsthead_data.nwells = eclipseState_->getSchedule()->numWells(timer.deckReportStep()); + rsthead_data.nwells = eclipseState_->getSchedule()->numWells(timer.reportStepNum()); rsthead_data.niwelz = 0; rsthead_data.nzwelz = 0; rsthead_data.niconz = 0; @@ -1159,10 +1100,10 @@ void EclipseWriter::writeTimeStep(const EclipseWriterDetails::WriterTimer& timer for (std::vector::const_iterator c_iter = wells_ptr.begin(); c_iter != wells_ptr.end(); ++c_iter) { WellConstPtr well_ptr = *c_iter; - rsthead_data.ncwmax = eclipseState_->getSchedule()->getMaxNumCompletionsForWells(timer.deckReportStep()); - restartHandle.addRestartFileIwelData(iwell_data, timer.deckReportStep(), well_ptr); - restartHandle.addRestartFileZwelData(zwell_data, timer.deckReportStep(), well_ptr); - restartHandle.addRestartFileIconData(icon_data, timer.deckReportStep(), rsthead_data.ncwmax, well_ptr); + rsthead_data.ncwmax = eclipseState_->getSchedule()->getMaxNumCompletionsForWells(timer.reportStepNum()); + restartHandle.addRestartFileIwelData(iwell_data, timer.reportStepNum(), well_ptr); + restartHandle.addRestartFileZwelData(zwell_data, timer.reportStepNum(), well_ptr); + restartHandle.addRestartFileIconData(icon_data, timer.reportStepNum(), rsthead_data.ncwmax, well_ptr); rsthead_data.niwelz = EclipseWriterDetails::Restart::NIWELZ; rsthead_data.nzwelz = EclipseWriterDetails::Restart::NZWELZ; diff --git a/opm/core/io/eclipse/EclipseWriter.hpp b/opm/core/io/eclipse/EclipseWriter.hpp index c9cdc3b0..533781ec 100644 --- a/opm/core/io/eclipse/EclipseWriter.hpp +++ b/opm/core/io/eclipse/EclipseWriter.hpp @@ -25,6 +25,7 @@ #include #include #include // WellType +#include #include @@ -44,8 +45,6 @@ struct WriterTimer; } class SimulatorState; -class SimulatorTimer; -class AdaptiveSimulatorTimer; class WellState; namespace parameter { class ParameterGroup; } @@ -81,7 +80,7 @@ public: /** * Write the static eclipse data (grid, PVT curves, etc) to disk. */ - virtual void writeInit(const SimulatorTimer &timer); + virtual void writeInit(const SimulatorTimerInterface &timer); /*! * \brief Write a reservoir state and summary information to disk. @@ -98,32 +97,11 @@ public: * \param[in] reservoirState The thermodynamic state of the reservoir * \param[in] wellState The production/injection data for all wells */ - virtual void writeTimeStep(const SimulatorTimer& timer, + virtual void writeTimeStep(const SimulatorTimerInterface& timer, const SimulatorState& reservoirState, const WellState& wellState); - /*! - * \brief Write a reservoir state and summary information to disk. - * - * - * The reservoir state can be inspected with visualization tools like - * ResInsight. - * - * The summary information can then be visualized using tools from - * ERT or ECLIPSE. Note that calling this method is only - * meaningful after the first time step has been completed. - * - * \param[in] timer The timer providing time step and time information - * \param[in] subStepTimer The timer providing sub step information - * \param[in] reservoirState The thermodynamic state of the reservoir - * \param[in] wellState The production/injection data for all wells - */ - virtual void writeTimeStep(const SimulatorTimer& timer, - const AdaptiveSimulatorTimer& subStepTimer, - const SimulatorState& reservoirState, - const WellState& wellState); - static int eclipseWellTypeMask(WellType wellType, WellInjector::TypeEnum injectorType); static int eclipseWellStatusMask(WellCommon::StatusEnum wellStatus); diff --git a/opm/core/simulator/AdaptiveSimulatorTimer.hpp b/opm/core/simulator/AdaptiveSimulatorTimer.hpp index 9958f4c9..d82dda41 100644 --- a/opm/core/simulator/AdaptiveSimulatorTimer.hpp +++ b/opm/core/simulator/AdaptiveSimulatorTimer.hpp @@ -16,7 +16,6 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ - #ifndef OPM_ADAPTIVESIMULATORTIMER_HEADER_INCLUDED #define OPM_ADAPTIVESIMULATORTIMER_HEADER_INCLUDED diff --git a/opm/core/simulator/AdaptiveTimeStepping.hpp b/opm/core/simulator/AdaptiveTimeStepping.hpp index 0b1af84b..fe5f860a 100644 --- a/opm/core/simulator/AdaptiveTimeStepping.hpp +++ b/opm/core/simulator/AdaptiveTimeStepping.hpp @@ -1,3 +1,21 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #ifndef OPM_SUBSTEPPING_HEADER_INCLUDED #define OPM_SUBSTEPPING_HEADER_INCLUDED @@ -21,19 +39,6 @@ namespace Opm { //! \brief contructor taking parameter object AdaptiveTimeStepping( const parameter::ParameterGroup& param ); - /** \brief step method that acts like the solver::step method - in a sub cycle of time steps - - \param solver solver object that must implement a method step( dt, state, well_state ) - \param state current state of the solution variables - \param well_state additional well state object - \param time current simulation time - \param timestep current time step length that is to be sub cycled - */ - template - void step( Solver& solver, State& state, WellState& well_state, - const double time, const double timestep ); - /** \brief step method that acts like the solver::step method in a sub cycle of time steps @@ -62,9 +67,9 @@ namespace Opm { protected: template - void stepImpl( Solver& solver, State& state, WellState& well_state, - const double time, const double timestep, - const SimulatorTimer* timer, OutputWriter* outputWriter); + void stepImpl( const SimulatorTimer& timer, + Solver& solver, State& state, WellState& well_state, + OutputWriter* outputWriter); typedef std::unique_ptr< TimeStepControlInterface > TimeStepControlType; diff --git a/opm/core/simulator/AdaptiveTimeStepping_impl.hpp b/opm/core/simulator/AdaptiveTimeStepping_impl.hpp index 4ec083df..ace9eafa 100644 --- a/opm/core/simulator/AdaptiveTimeStepping_impl.hpp +++ b/opm/core/simulator/AdaptiveTimeStepping_impl.hpp @@ -1,3 +1,21 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OPM is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with OPM. If not, see . +*/ #ifndef OPM_ADAPTIVETIMESTEPPING_IMPL_HEADER_INCLUDED #define OPM_ADAPTIVETIMESTEPPING_IMPL_HEADER_INCLUDED @@ -48,10 +66,7 @@ namespace Opm { void AdaptiveTimeStepping:: step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state ) { - const double time = simulatorTimer.simulationTimeElapsed(); - const double timestep = simulatorTimer.currentStepLength(); - - step( solver, state, well_state, time, timestep ); + stepImpl( simulatorTimer, solver, state, well_state ); } template @@ -59,37 +74,25 @@ namespace Opm { step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state, OutputWriter& outputWriter ) { - const double time = simulatorTimer.simulationTimeElapsed(); - const double timestep = simulatorTimer.currentStepLength(); - - stepImpl( solver, state, well_state, time, timestep, &simulatorTimer, &outputWriter ); - } - - // implementation of the step method - template - void AdaptiveTimeStepping:: - step( Solver& solver, State& state, WellState& well_state, - const double time, const double timestep ) - { - stepImpl( solver, state, well_state, time, timestep, - (SimulatorTimer *) 0, (OutputWriter *) 0 ); + stepImpl( simulatorTimer, solver, state, well_state, &outputWriter ); } // implementation of the step method template void AdaptiveTimeStepping:: - stepImpl( Solver& solver, State& state, WState& well_state, - const double time, const double timestep, - const SimulatorTimer* simulatorTimer, + stepImpl( const SimulatorTimer& simulatorTimer, + Solver& solver, State& state, WState& well_state, OutputWriter* outputWriter ) { + const double timestep = simulatorTimer.currentStepLength(); + // init last time step as a fraction of the given time step if( last_timestep_ < 0 ) { - last_timestep_ = initial_fraction_ * timestep ; + last_timestep_ = initial_fraction_ * timestep; } // create adaptive step timer with previously used sub step size - AdaptiveSimulatorTimer substepTimer( time, time+timestep, last_timestep_ ); + AdaptiveSimulatorTimer substepTimer( simulatorTimer, last_timestep_ ); // copy states in case solver has to be restarted (to be revised) State last_state( state ); @@ -145,8 +148,10 @@ namespace Opm { if( timestep_verbose_ ) { - std::cout << "Substep[ " << substepTimer.currentStepNum() << " ] " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl; - std::cout << "Suggested time step size = " << unit::convert::to(dtEstimate, unit::day) << " (days)" << std::endl; + std::cout << std::endl + <<"Substep( " << substepTimer.currentStepNum() + << " ): Current time (days) " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl + << " Current stepsize est (days) " << unit::convert::to(dtEstimate, unit::day) << std::endl; } // set new time step length @@ -158,8 +163,7 @@ namespace Opm { // write data if outputWriter was provided if( outputWriter ) { - assert( simulatorTimer ); - outputWriter->writeTimeStep( *simulatorTimer, substepTimer, state, well_state ); + outputWriter->writeTimeStep( substepTimer, state, well_state ); } } else // in case of no convergence (linearIterations < 0)