From a3efb49de2a99abf60bff729e2b25b6209613dba Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 7 Nov 2012 13:31:46 +0100 Subject: [PATCH 1/2] Added comments + make sure to only export active cells in writeEclData --- opm/core/utility/writeECLData.cpp | 46 +++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/opm/core/utility/writeECLData.cpp b/opm/core/utility/writeECLData.cpp index 6baadb2a..9ea8c507 100644 --- a/opm/core/utility/writeECLData.cpp +++ b/opm/core/utility/writeECLData.cpp @@ -45,23 +45,44 @@ namespace Opm const std::vector * data , int offset , int stride ) { - const int ecl_data_size = grid.cartdims[0]*grid.cartdims[1]*grid.cartdims[2]; - if (ecl_data_size < int(data->size()) / stride) { - THROW("Logical cartesian size claimed to be " << ecl_data_size << ", while active data size is " << data->size() - << "\n --- check if the grid is really a corner-point grid or other logical cartesian grid."); - } - ecl_kw_type * ecl_kw = ecl_kw_alloc( kw_name.c_str() , ecl_data_size , ECL_FLOAT_TYPE ); - if (grid.global_cell == NULL) { + + if (grid.number_of_cells != data->size() / stride) + THROW("Internal mismatch grid.number_of_cells: " << grid.number_of_cells << " data size: " << data->size() / stride); + { + ecl_kw_type * ecl_kw = ecl_kw_alloc( kw_name.c_str() , grid.number_of_cells , ECL_FLOAT_TYPE ); for (int i=0; i < grid.number_of_cells; i++) ecl_kw_iset_float( ecl_kw , i , (*data)[i*stride + offset]); - } else { - for (int i=0; i < grid.number_of_cells; i++) - ecl_kw_iset_float( ecl_kw , grid.global_cell[i] , (*data)[i*stride + offset]); + return ecl_kw; } - return ecl_kw; } + /* + This function will write the data solution data in the DataMap + @data as an ECLIPSE restart file, in addition to the solution + fields the ECLIPSE restart file will have a minimum (hopefully + sufficient) amount of header information. + + The ECLIPSE restart files come in two varietes; unified restart + files which have all the report steps lumped together in one large + chunk and non-unified restart files which are one file for each + report step. In addition the files can be either formatted + (i.e. ASCII) or unformatted (i.e. binary). + + The writeECLData() function has two hardcoded settings: + 'file_type' and 'fmt_file' which regulate which type of files the + should be created. The extension of the files follow a convention: + + Unified, formatted : .FUNRST + Unified, unformatted : .UNRST + Multiple, formatted : .Fnnnn + Multiple, unformatted : .Xnnnn + + For the multiple files the 'nnnn' part is the report number, + formatted with '%04d' format specifier. The writeECLData() + function will use the ecl_util_alloc_filename() function to create + an ECLIPSE filename according to this conventions. + */ void writeECLData(const UnstructuredGrid& grid, const DataMap& data, @@ -69,9 +90,10 @@ namespace Opm const std::string& output_dir, const std::string& base_name) { - int step = simtimer.currentStepNum(); ecl_file_enum file_type = ECL_UNIFIED_RESTART_FILE; bool fmt_file = true; + + int step = simtimer.currentStepNum(); char * filename = ecl_util_alloc_filename(output_dir.c_str() , base_name.c_str() , file_type , fmt_file , step ); int phases = ECL_OIL_PHASE + ECL_WATER_PHASE; double days = Opm::unit::convert::to(simtimer.currentTime(), Opm::unit::day); From 43adfaeda59fd77c96825cc1dcb08fbe9323250b Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 7 Nov 2012 14:53:26 +0100 Subject: [PATCH 2/2] Added start_date_ property to the SimulatorTimer class --- opm/core/eclipse/EclipseGridParser.cpp | 10 +++- opm/core/eclipse/EclipseGridParser.hpp | 4 +- opm/core/simulator/SimulatorTimer.cpp | 62 ++++++++++++++---------- opm/core/simulator/SimulatorTimer.hpp | 67 ++++++++++++++------------ opm/core/utility/writeECLData.cpp | 13 ++++- 5 files changed, 94 insertions(+), 62 deletions(-) diff --git a/opm/core/eclipse/EclipseGridParser.cpp b/opm/core/eclipse/EclipseGridParser.cpp index 5af1e2ec..eda601df 100644 --- a/opm/core/eclipse/EclipseGridParser.cpp +++ b/opm/core/eclipse/EclipseGridParser.cpp @@ -395,9 +395,9 @@ void EclipseGridParser::readImpl(istream& is) // This will only ever happen in the first epoch, // upon first encountering a timestepping keyword. if (hasField("START")) { - start_date_ = getSTART().date; + start_date_ = getSTART().date; } else { - start_date_ = boost::gregorian::date(1983, 1, 1); + start_date_ = boost::gregorian::date( 1983 , 1 , 1 ); } } if (current_reading_mode_ == Regular) { @@ -658,6 +658,12 @@ void EclipseGridParser::setCurrentEpoch(int epoch) current_epoch_ = epoch; } +//----------------------------------------------------------------- +boost::gregorian::date EclipseGridParser::getStartDate() const +//--------------------------------------------------------------------------- +{ + return start_date_; +} //--------------------------------------------------------------------------- const std::vector& EclipseGridParser::getIntegerValue(const std::string& keyword) const diff --git a/opm/core/eclipse/EclipseGridParser.hpp b/opm/core/eclipse/EclipseGridParser.hpp index 0d72abaf..b5001a31 100644 --- a/opm/core/eclipse/EclipseGridParser.hpp +++ b/opm/core/eclipse/EclipseGridParser.hpp @@ -95,7 +95,6 @@ namespace Opm /// converted to SI units. explicit EclipseGridParser(const std::string& filename, bool convert_to_SI = true); - static FieldType classifyKeyword(const std::string& keyword); static bool readKeyword(std::istream& is, std::string& keyword); @@ -128,6 +127,9 @@ namespace Opm /// After reading, current epoch always starts at 0. void setCurrentEpoch(int epoch); + /// Returns the start_date_ + boost::gregorian::date getStartDate() const; + /// Returns a reference to a vector containing the values /// corresponding to the given integer keyword. const std::vector& getIntegerValue(const std::string& keyword) const; diff --git a/opm/core/simulator/SimulatorTimer.cpp b/opm/core/simulator/SimulatorTimer.cpp index db4b5aac..337723db 100644 --- a/opm/core/simulator/SimulatorTimer.cpp +++ b/opm/core/simulator/SimulatorTimer.cpp @@ -29,8 +29,9 @@ namespace Opm /// Default constructor. SimulatorTimer::SimulatorTimer() - : current_step_(0), - current_time_(0.0) + : current_step_(0), + current_time_(0.0), + start_date_(2012,1,1) // A really arbitrary default starting value?! { } @@ -39,31 +40,32 @@ namespace Opm /// stepsize_days (default 1) void SimulatorTimer::init(const parameter::ParameterGroup& param) { - const int num_psteps = param.getDefault("num_psteps", 1); - const double stepsize_days = param.getDefault("stepsize_days", 1.0); - const double stepsize = Opm::unit::convert::from(stepsize_days, Opm::unit::day); - timesteps_.clear(); - timesteps_.resize(num_psteps, stepsize); - total_time_ = num_psteps*stepsize; + const int num_psteps = param.getDefault("num_psteps", 1); + const double stepsize_days = param.getDefault("stepsize_days", 1.0); + const double stepsize = Opm::unit::convert::from(stepsize_days, Opm::unit::day); + timesteps_.clear(); + timesteps_.resize(num_psteps, stepsize); + total_time_ = num_psteps*stepsize; } /// Initialize from TSTEP field. void SimulatorTimer::init(const EclipseGridParser& deck) { - timesteps_ = deck.getTSTEP().tstep_; - total_time_ = std::accumulate(timesteps_.begin(), timesteps_.end(), 0.0); + timesteps_ = deck.getTSTEP().tstep_; + total_time_ = std::accumulate(timesteps_.begin(), timesteps_.end(), 0.0); + start_date_ = deck.getStartDate(); } /// Total number of steps. int SimulatorTimer::numSteps() const { - return timesteps_.size(); + return timesteps_.size(); } /// Current step number. int SimulatorTimer::currentStepNum() const { - return current_step_; + return current_step_; } /// Set current step number. @@ -82,20 +84,28 @@ namespace Opm /// Current step length. double SimulatorTimer::currentStepLength() const { - ASSERT(!done()); - return timesteps_[current_step_]; + ASSERT(!done()); + return timesteps_[current_step_]; } /// Current time. double SimulatorTimer::currentTime() const { - return current_time_; + return current_time_; } + + boost::posix_time::ptime SimulatorTimer::currentDateTime() const + { + return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); + } + + + /// Total time. double SimulatorTimer::totalTime() const { - return total_time_; + return total_time_; } /// Set total time. @@ -104,32 +114,32 @@ namespace Opm /// access to later timesteps. void SimulatorTimer::setTotalTime(double time) { - total_time_ = time; + total_time_ = time; } /// Print a report with current and total time etc. void SimulatorTimer::report(std::ostream& os) const { os << "\n\n--------------- Simulation step number " << currentStepNum() << " ---------------" - << "\n Current time (days) " << Opm::unit::convert::to(currentTime(), Opm::unit::day) - << "\n Current stepsize (days) " << Opm::unit::convert::to(currentStepLength(), Opm::unit::day) - << "\n Total time (days) " << Opm::unit::convert::to(totalTime(), Opm::unit::day) - << "\n" << std::endl; + << "\n Current time (days) " << Opm::unit::convert::to(currentTime(), Opm::unit::day) + << "\n Current stepsize (days) " << Opm::unit::convert::to(currentStepLength(), Opm::unit::day) + << "\n Total time (days) " << Opm::unit::convert::to(totalTime(), Opm::unit::day) + << "\n" << std::endl; } /// Next step. SimulatorTimer& SimulatorTimer::operator++() { - ASSERT(!done()); - current_time_ += timesteps_[current_step_]; - ++current_step_; - return *this; + ASSERT(!done()); + current_time_ += timesteps_[current_step_]; + ++current_step_; + return *this; } /// Return true if op++() has been called numSteps() times. bool SimulatorTimer::done() const { - return int(timesteps_.size()) == current_step_; + return int(timesteps_.size()) == current_step_; } diff --git a/opm/core/simulator/SimulatorTimer.hpp b/opm/core/simulator/SimulatorTimer.hpp index d9a35a16..832cdef9 100644 --- a/opm/core/simulator/SimulatorTimer.hpp +++ b/opm/core/simulator/SimulatorTimer.hpp @@ -22,6 +22,8 @@ #include #include +#include +#include namespace Opm { @@ -33,57 +35,60 @@ namespace Opm class SimulatorTimer { public: - /// Default constructor. - SimulatorTimer(); + /// Default constructor. + SimulatorTimer(); - /// Initialize from parameters. Accepts the following: - /// num_psteps (default 1) - /// stepsize_days (default 1) - void init(const parameter::ParameterGroup& param); + /// Initialize from parameters. Accepts the following: + /// num_psteps (default 1) + /// stepsize_days (default 1) + void init(const parameter::ParameterGroup& param); - /// Initialize from TSTEP field. - void init(const EclipseGridParser& deck); + /// Initialize from TSTEP field. + void init(const EclipseGridParser& deck); - /// Total number of steps. - int numSteps() const; + /// Total number of steps. + int numSteps() const; - /// Current step number. - int currentStepNum() const; + /// Current step number. + int currentStepNum() const; /// Set current step number. void setCurrentStepNum(int step); - /// Current step length. - /// Note: if done(), it is an error to call currentStepLength(). - double currentStepLength() const; + /// Current step length. + /// Note: if done(), it is an error to call currentStepLength(). + double currentStepLength() const; - /// Current time. - double currentTime() const; + /// Current time. + double currentTime() const; - /// Total time. - double totalTime() const; + boost::posix_time::ptime currentDateTime() const; + + /// Total time. + double totalTime() const; /// Set total time. /// This is primarily intended for multi-epoch schedules, /// where a timer for a given epoch does not have /// access to later timesteps. - void setTotalTime(double time); + void setTotalTime(double time); - /// Print a report with current and total time etc. - /// Note: if done(), it is an error to call report(). - void report(std::ostream& os) const; + /// Print a report with current and total time etc. + /// Note: if done(), it is an error to call report(). + void report(std::ostream& os) const; - /// Next step. - SimulatorTimer& operator++(); + /// Next step. + SimulatorTimer& operator++(); - /// Return true if op++() has been called numSteps() times. - bool done() const; + /// Return true if op++() has been called numSteps() times. + bool done() const; private: - std::vector timesteps_; - int current_step_; - double current_time_; - double total_time_; + std::vector timesteps_; + int current_step_; + double current_time_; + double total_time_; + boost::gregorian::date start_date_; }; diff --git a/opm/core/utility/writeECLData.cpp b/opm/core/utility/writeECLData.cpp index 9ea8c507..6dc94af8 100644 --- a/opm/core/utility/writeECLData.cpp +++ b/opm/core/utility/writeECLData.cpp @@ -90,9 +90,9 @@ namespace Opm const std::string& output_dir, const std::string& base_name) { - ecl_file_enum file_type = ECL_UNIFIED_RESTART_FILE; + ecl_file_enum file_type = ECL_UNIFIED_RESTART_FILE; // Alternatively ECL_RESTART_FILE for multiple restart files. bool fmt_file = true; - + int step = simtimer.currentStepNum(); char * filename = ecl_util_alloc_filename(output_dir.c_str() , base_name.c_str() , file_type , fmt_file , step ); int phases = ECL_OIL_PHASE + ECL_WATER_PHASE; @@ -104,6 +104,15 @@ namespace Opm int nactive = grid.number_of_cells; ecl_rst_file_type * rst_file; + { + using namespace boost::posix_time; + ptime t1 = simtimer.currentDateTime(); + ptime t0( boost::gregorian::date(1970 , 1 ,1) ); + time_duration::sec_type seconds = (t1 - t0).total_seconds(); + + date = time_t( seconds ); + } + if (step > 0 && file_type == ECL_UNIFIED_RESTART_FILE) rst_file = ecl_rst_file_open_append( filename ); else