Merge pull request #91 from joakim-hove/writeEclActive

Write ecl active
This commit is contained in:
Bård Skaflestad
2012-11-07 06:40:00 -08:00
5 changed files with 127 additions and 73 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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_;
}

View File

@@ -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_;
};

View File

@@ -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