Merge pull request #812 from chflo/OPM-206

Opm 206 Use IOConfig from EclipseState to decide which Eclipse output files to write (and when)
This commit is contained in:
Joakim Hove 2015-06-15 17:30:03 +02:00
commit b29ea2ae1c
4 changed files with 130 additions and 106 deletions

View File

@ -237,12 +237,13 @@ public:
FileName(const std::string& outputDir,
const std::string& baseName,
ecl_file_enum type,
int writeStepIdx)
int writeStepIdx,
bool formatted)
{
ertHandle_ = ecl_util_alloc_filename(outputDir.c_str(),
baseName.c_str(),
type,
false, // formatted?
formatted,
writeStepIdx);
}
@ -284,19 +285,23 @@ public:
Restart(const std::string& outputDir,
const std::string& baseName,
int writeStepIdx)
int writeStepIdx,
IOConfigConstPtr ioConfig)
{
ecl_file_enum type_of_restart_file = ioConfig->getUNIFOUT() ? ECL_UNIFIED_RESTART_FILE : ECL_RESTART_FILE;
restartFileName_ = ecl_util_alloc_filename(outputDir.c_str(),
baseName.c_str(),
/*type=*/ECL_UNIFIED_RESTART_FILE,
false, // use formatted instead of binary output?
type_of_restart_file,
ioConfig->getFMTOUT(), // use formatted instead of binary output?
writeStepIdx);
if (writeStepIdx == 0) {
restartFileHandle_ = ecl_rst_file_open_write(restartFileName_);
if ((writeStepIdx > 0) && (ECL_UNIFIED_RESTART_FILE == type_of_restart_file)) {
restartFileHandle_ = ecl_rst_file_open_append(restartFileName_);
}
else {
restartFileHandle_ = ecl_rst_file_open_append(restartFileName_);
restartFileHandle_ = ecl_rst_file_open_write(restartFileName_);
}
}
@ -499,25 +504,23 @@ class Init : private boost::noncopyable
public:
Init(const std::string& outputDir,
const std::string& baseName,
int writeStepIdx)
: egridFileName_(outputDir,
int writeStepIdx,
IOConfigConstPtr ioConfig) : egridFileName_(outputDir,
baseName,
ECL_EGRID_FILE,
writeStepIdx)
writeStepIdx,
ioConfig->getFMTOUT())
{
bool formatted = ioConfig->getFMTOUT();
FileName initFileName(outputDir,
baseName,
ECL_INIT_FILE,
writeStepIdx);
bool isFormatted;
if (!ecl_util_fmt_file(initFileName.ertHandle(), &isFormatted)) {
OPM_THROW(std::runtime_error,
"Could not determine formatted/unformatted status of file:" << initFileName.ertHandle() << " non-standard name?" << std::endl);
}
writeStepIdx,
formatted);
ertHandle_ = fortio_open_writer(initFileName.ertHandle(),
isFormatted,
formatted,
ECL_ENDIAN_FLIP);
}
@ -549,12 +552,17 @@ public:
// finally, write the grid to disk
IOConfigConstPtr ioConfig = eclipseState->getIOConfigConst();
if (ioConfig->getWriteEGRIDFile()) {
if (eclipseState->getDeckUnitSystem()->getType() == UnitSystem::UNIT_TYPE_METRIC){
eclGrid->fwriteEGRID(egridFileName_.ertHandle(), true);
}else{
eclGrid->fwriteEGRID(egridFileName_.ertHandle(), false);
}
}
if (ioConfig->getWriteINITFile()) {
Keyword<float> poro_kw("PORO", dataField);
ecl_init_file_fwrite_header(ertHandle(),
eclGrid->c_ptr(),
@ -562,6 +570,7 @@ public:
ertPhaseMask(uses),
timer.currentPosixTime());
}
}
void writeKeyword(const std::string& keywordName, const std::vector<double> &data)
{
@ -577,6 +586,9 @@ private:
FileName egridFileName_;
};
/**
* Summary variable that reports a characteristics of a well.
*/
@ -1149,13 +1161,16 @@ void EclipseWriter::writeInit(const SimulatorTimerInterface &timer)
writeStepIdx_ = 0;
reportStepIdx_ = -1;
EclipseWriterDetails::Init fortio(outputDir_, baseName_, /*stepIdx=*/0);
EclipseWriterDetails::Init fortio(outputDir_, baseName_, /*stepIdx=*/0, eclipseState_->getIOConfigConst());
fortio.writeHeader(numCells_,
compressedToCartesianCellIdx_,
timer,
eclipseState_,
phaseUsage_);
IOConfigConstPtr ioConfig = eclipseState_->getIOConfigConst();
if (ioConfig->getWriteINITFile()) {
if (eclipseState_->hasDoubleGridProperty("PERMX")) {
auto data = eclipseState_->getDoubleGridProperty("PERMX")->getData();
EclipseWriterDetails::convertFromSiTo(data, Opm::prefix::milli * Opm::unit::darcy);
@ -1171,6 +1186,7 @@ void EclipseWriter::writeInit(const SimulatorTimerInterface &timer)
EclipseWriterDetails::convertFromSiTo(data, Opm::prefix::milli * Opm::unit::darcy);
fortio.writeKeyword("PERMZ", data);
}
}
/* Create summary object (could not do it at construction time,
since it requires knowledge of the start time). */
@ -1205,13 +1221,38 @@ void EclipseWriter::writeTimeStep(const SimulatorTimerInterface& timer,
return;
}
// respected the output_interval parameter
if (writeStepIdx_ % outputInterval_ != 0) {
return;
std::vector<double> pressure = reservoirState.pressure();
EclipseWriterDetails::convertFromSiTo(pressure, deckToSiPressure_);
EclipseWriterDetails::restrictAndReorderToActiveCells(pressure, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
std::vector<double> saturation_water;
std::vector<double> saturation_gas;
if (phaseUsage_.phase_used[BlackoilPhases::Aqua]) {
saturation_water = reservoirState.saturation();
EclipseWriterDetails::extractFromStripedData(saturation_water,
/*offset=*/phaseUsage_.phase_pos[BlackoilPhases::Aqua],
/*stride=*/phaseUsage_.num_phases);
EclipseWriterDetails::restrictAndReorderToActiveCells(saturation_water, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
}
// only write solution when report step number has changed
if( reportStepIdx_ != timer.reportStepNum() )
if (phaseUsage_.phase_used[BlackoilPhases::Vapour]) {
saturation_gas = reservoirState.saturation();
EclipseWriterDetails::extractFromStripedData(saturation_gas,
/*offset=*/phaseUsage_.phase_pos[BlackoilPhases::Vapour],
/*stride=*/phaseUsage_.num_phases);
EclipseWriterDetails::restrictAndReorderToActiveCells(saturation_gas, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
}
IOConfigConstPtr ioConfig = eclipseState_->getIOConfigConst();
// Write restart file
if(ioConfig->getWriteRestartFile(timer.reportStepNum()))
{
const size_t ncwmax = eclipseState_->getSchedule()->getMaxNumCompletionsForWells(timer.reportStepNum());
const size_t numWells = eclipseState_->getSchedule()->numWells(timer.reportStepNum());
@ -1221,7 +1262,8 @@ void EclipseWriter::writeTimeStep(const SimulatorTimerInterface& timer,
std::vector<int> iwell_data( numWells * Opm::EclipseWriterDetails::Restart::NIWELZ , 0 );
std::vector<int> icon_data( numWells * ncwmax * Opm::EclipseWriterDetails::Restart::NICONZ , 0 );
EclipseWriterDetails::Restart restartHandle(outputDir_, baseName_, timer.reportStepNum());
EclipseWriterDetails::Restart restartHandle(outputDir_, baseName_, timer.reportStepNum(), ioConfig);
for (size_t iwell = 0; iwell < wells_ptr.size(); ++iwell) {
WellConstPtr well = wells_ptr[iwell];
@ -1236,6 +1278,7 @@ void EclipseWriter::writeTimeStep(const SimulatorTimerInterface& timer,
zwell_data[ iwell * Opm::EclipseWriterDetails::Restart::NZWELZ ] = well->name().c_str();
}
{
ecl_rsthead_type rsthead_data = {};
rsthead_data.sim_time = timer.currentPosixTime();
@ -1261,50 +1304,28 @@ void EclipseWriter::writeTimeStep(const SimulatorTimerInterface& timer,
restartHandle.add_kw(EclipseWriterDetails::Keyword<const char *>(ZWEL_KW, zwell_data));
restartHandle.add_kw(EclipseWriterDetails::Keyword<int>(ICON_KW, icon_data));
EclipseWriterDetails::Solution sol(restartHandle);
// write out the pressure of the reference phase (whatever phase that is...). this is
// not the most performant solution thinkable, but this is also not in the most
// performance critical code path!
//
// Also, we want to use the same units as the deck for pressure output, i.e. we have
// to mutliate our nice SI pressures by the inverse of the conversion factor of deck
// to SI pressure units...
std::vector<double> pressure = reservoirState.pressure();
EclipseWriterDetails::convertFromSiTo(pressure, deckToSiPressure_);
EclipseWriterDetails::restrictAndReorderToActiveCells(pressure, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
sol.add(EclipseWriterDetails::Keyword<float>("PRESSURE", pressure));
// write the cell temperature
std::vector<double> temperature = reservoirState.temperature();
EclipseWriterDetails::convertFromSiTo(temperature, deckToSiTemperatureFactor_, deckToSiTemperatureOffset_);
EclipseWriterDetails::restrictAndReorderToActiveCells(temperature, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
sol.add(EclipseWriterDetails::Keyword<float>("TEMP", temperature));
std::vector<double> saturation_water;
std::vector<double> saturation_gas;
if (phaseUsage_.phase_used[BlackoilPhases::Aqua]) {
saturation_water = reservoirState.saturation();
EclipseWriterDetails::extractFromStripedData(saturation_water,
/*offset=*/phaseUsage_.phase_pos[BlackoilPhases::Aqua],
/*stride=*/phaseUsage_.num_phases);
EclipseWriterDetails::restrictAndReorderToActiveCells(saturation_water, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
sol.add(EclipseWriterDetails::Keyword<float>(EclipseWriterDetails::saturationKeywordNames[BlackoilPhases::PhaseIndex::Aqua], saturation_water));
}
if (phaseUsage_.phase_used[BlackoilPhases::Vapour]) {
saturation_gas = reservoirState.saturation();
EclipseWriterDetails::extractFromStripedData(saturation_gas,
/*offset=*/phaseUsage_.phase_pos[BlackoilPhases::Vapour],
/*stride=*/phaseUsage_.num_phases);
EclipseWriterDetails::restrictAndReorderToActiveCells(saturation_gas, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
sol.add(EclipseWriterDetails::Keyword<float>(EclipseWriterDetails::saturationKeywordNames[BlackoilPhases::PhaseIndex::Vapour], saturation_gas));
}
}
//Write RFT data for current timestep to RFT file
@ -1317,7 +1338,7 @@ void EclipseWriter::writeTimeStep(const SimulatorTimerInterface& timer,
char * rft_filename = ecl_util_alloc_filename(outputDir_.c_str(),
baseName_.c_str(),
ECL_RFT_FILE,
false,
ioConfig->getFMTOUT(),
0);
std::shared_ptr<const UnitSystem> unitsystem = eclipseState_->getDeckUnitSystem();
@ -1335,8 +1356,10 @@ void EclipseWriter::writeTimeStep(const SimulatorTimerInterface& timer,
saturation_water,
saturation_gas);
free( rft_filename );
} // end if( reportStepIdx_ != timer.reportStepNum() )
/* Summary variables (well reporting) */
// TODO: instead of writing the header (smspec) every time, it should
@ -1428,10 +1451,6 @@ void EclipseWriter::init(const parameter::ParameterGroup& params)
// retrieve the value of the "output" parameter
enableOutput_ = params.getDefault<bool>("output", /*defaultValue=*/true);
// retrieve the interval at which something should get written to
// disk (once every N timesteps)
outputInterval_ = params.getDefault<int>("output_interval", /*defaultValue=*/1);
// store in current directory if not explicitly set
outputDir_ = params.getDefault<std::string>("output_dir", ".");

View File

@ -115,7 +115,6 @@ private:
double deckToSiTemperatureFactor_;
double deckToSiTemperatureOffset_;
bool enableOutput_;
int outputInterval_;
int writeStepIdx_;
int reportStepIdx_;
std::string outputDir_;

View File

@ -365,6 +365,8 @@ BOOST_AUTO_TEST_CASE(EclipseWriterIntegration)
{
const char *deckString =
"RUNSPEC\n"
"INIT\n"
"UNIFOUT\n"
"OIL\n"
"GAS\n"
"WATER\n"
@ -386,6 +388,9 @@ BOOST_AUTO_TEST_CASE(EclipseWriterIntegration)
"PERMX\n"
"27*1 /\n"
"SCHEDULE\n"
"RPTRST\n"
"BASIC=1\n"
"/\n"
"TSTEP\n"
"1.0 2.0 3.0 4.0 /\n"
"WELSPECS\n"

View File

@ -162,7 +162,8 @@ Opm::EclipseWriterPtr createEclipseWriter(Opm::DeckConstPtr deck,
BOOST_AUTO_TEST_CASE(EclipseWriteRestartWellInfo)
{
std::string eclipse_data_filename = "testBlackoilState3.DATA";
std::string eclipse_restart_filename = "TESTBLACKOILSTATE3.UNRST";
std::string eclipse_restart_filename = "TESTBLACKOILSTATE3.X0004";
test_work_area_type * test_area = test_work_area_alloc("TEST_EclipseWriteNumWells");
test_work_area_copy_file(test_area, eclipse_data_filename.c_str());