Merge pull request #91 from joakim-hove/writeEclActive
Write ecl active
This commit is contained in:
@@ -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<int>& EclipseGridParser::getIntegerValue(const std::string& keyword) const
|
||||
|
||||
@@ -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<int>& getIntegerValue(const std::string& keyword) const;
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
|
||||
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<double> timesteps_;
|
||||
int current_step_;
|
||||
double current_time_;
|
||||
double total_time_;
|
||||
std::vector<double> timesteps_;
|
||||
int current_step_;
|
||||
double current_time_;
|
||||
double total_time_;
|
||||
boost::gregorian::date start_date_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -45,23 +45,44 @@ namespace Opm
|
||||
const std::vector<double> * 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;
|
||||
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;
|
||||
double days = Opm::unit::convert::to(simtimer.currentTime(), Opm::unit::day);
|
||||
@@ -82,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
|
||||
|
||||
Reference in New Issue
Block a user