Merge pull request #768 from chflo/OPM_157_RFT_write
OPM 157 write RFT data
This commit is contained in:
commit
7a5f188dd3
@ -41,6 +41,7 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
opm/core/grid/cpgpreprocess/uniquepoints.c
|
||||
opm/core/io/eclipse/EclipseGridInspector.cpp
|
||||
opm/core/io/eclipse/EclipseWriter.cpp
|
||||
opm/core/io/eclipse/EclipseWriteRFTHandler.cpp
|
||||
opm/core/io/eclipse/writeECLData.cpp
|
||||
opm/core/io/OutputWriter.cpp
|
||||
opm/core/io/vag/vag.cpp
|
||||
@ -157,6 +158,7 @@ list (APPEND MAIN_SOURCE_FILES
|
||||
list (APPEND TEST_SOURCE_FILES
|
||||
tests/test_writenumwells.cpp
|
||||
tests/test_EclipseWriter.cpp
|
||||
tests/test_EclipseWriteRFTHandler.cpp
|
||||
tests/test_compressedpropertyaccess.cpp
|
||||
tests/test_spline.cpp
|
||||
tests/test_propertysystem.cpp
|
||||
@ -289,6 +291,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/core/io/eclipse/EclipseGridInspector.hpp
|
||||
opm/core/io/eclipse/EclipseUnits.hpp
|
||||
opm/core/io/eclipse/EclipseWriter.hpp
|
||||
opm/core/io/eclipse/EclipseWriteRFTHandler.hpp
|
||||
opm/core/io/eclipse/writeECLData.hpp
|
||||
opm/core/io/OutputWriter.hpp
|
||||
opm/core/io/vag/vag.hpp
|
||||
|
143
opm/core/io/eclipse/EclipseWriteRFTHandler.cpp
Normal file
143
opm/core/io/eclipse/EclipseWriteRFTHandler.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright 2015 Statoil ASA.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <opm/core/io/eclipse/EclipseWriteRFTHandler.hpp>
|
||||
#include <opm/core/simulator/SimulatorState.hpp>
|
||||
#include <opm/core/simulator/BlackoilState.hpp>
|
||||
#include <opm/core/simulator/SimulatorTimer.hpp>
|
||||
#include <opm/core/props/BlackoilPhases.hpp>
|
||||
#include <opm/core/utility/Units.hpp>
|
||||
#include <opm/core/utility/miscUtilities.hpp>
|
||||
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellSet.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
|
||||
|
||||
#include <ert/ecl/ecl_rft_node.h>
|
||||
#include <ert/ecl/ecl_rft_file.h>
|
||||
|
||||
|
||||
|
||||
namespace Opm {
|
||||
namespace EclipseWriterDetails {
|
||||
|
||||
EclipseWriteRFTHandler::EclipseWriteRFTHandler(const int * compressedToCartesianCellIdx, size_t numCells, size_t cartesianSize) {
|
||||
initGlobalToActiveIndex(compressedToCartesianCellIdx, numCells, cartesianSize);
|
||||
}
|
||||
|
||||
void EclipseWriteRFTHandler::writeTimeStep(const std::string& filename,
|
||||
const ert_ecl_unit_enum ecl_unit,
|
||||
const SimulatorTimerInterface& simulatorTimer,
|
||||
std::vector<WellConstPtr>& wells,
|
||||
EclipseGridConstPtr eclipseGrid,
|
||||
std::vector<double>& pressure,
|
||||
std::vector<double>& swat,
|
||||
std::vector<double>& sgas) {
|
||||
|
||||
|
||||
|
||||
std::vector<ecl_rft_node_type *> rft_nodes;
|
||||
for (std::vector<WellConstPtr>::const_iterator ci = wells.begin(); ci != wells.end(); ++ci) {
|
||||
WellConstPtr well = *ci;
|
||||
if ((well->getRFTActive(simulatorTimer.currentStepNum())) || (well->getPLTActive(simulatorTimer.currentStepNum()))) {
|
||||
ecl_rft_node_type * ecl_node = createEclRFTNode(well,
|
||||
simulatorTimer,
|
||||
eclipseGrid,
|
||||
pressure,
|
||||
swat,
|
||||
sgas);
|
||||
|
||||
if (well->getPLTActive(simulatorTimer.currentStepNum())) {
|
||||
std::cerr << "PLT not supported, writing RFT data" << std::endl;
|
||||
}
|
||||
|
||||
rft_nodes.push_back(ecl_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (rft_nodes.size() > 0) {
|
||||
ecl_rft_file_update(filename.c_str(), rft_nodes.data(), rft_nodes.size(), ecl_unit);
|
||||
}
|
||||
|
||||
//Cleanup: The ecl_rft_file_update method takes care of freeing the ecl_rft_nodes that it receives.
|
||||
// Each ecl_rft_node is again responsible for freeing it's cells.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ecl_rft_node_type * EclipseWriteRFTHandler::createEclRFTNode(WellConstPtr well,
|
||||
const SimulatorTimerInterface& simulatorTimer,
|
||||
EclipseGridConstPtr eclipseGrid,
|
||||
const std::vector<double>& pressure,
|
||||
const std::vector<double>& swat,
|
||||
const std::vector<double>& sgas) {
|
||||
|
||||
|
||||
const std::string& well_name = well->name();
|
||||
size_t timestep = (size_t)simulatorTimer.currentStepNum();
|
||||
time_t recording_date = simulatorTimer.currentPosixTime();
|
||||
double days = Opm::unit::convert::to(simulatorTimer.simulationTimeElapsed(), Opm::unit::day);
|
||||
|
||||
std::string type = "RFT";
|
||||
ecl_rft_node_type * ecl_rft_node = ecl_rft_node_alloc_new(well_name.c_str(), type.c_str(), recording_date, days);
|
||||
|
||||
CompletionSetConstPtr completionsSet = well->getCompletions(timestep);
|
||||
for (int index = 0; index < completionsSet->size(); ++index) {
|
||||
CompletionConstPtr completion = completionsSet->get(index);
|
||||
size_t i = (size_t)completion->getI();
|
||||
size_t j = (size_t)completion->getJ();
|
||||
size_t k = (size_t)completion->getK();
|
||||
|
||||
size_t global_index = eclipseGrid->getGlobalIndex(i,j,k);
|
||||
int active_index = globalToActiveIndex_[global_index];
|
||||
|
||||
if (active_index > -1) {
|
||||
double depth = eclipseGrid->getCellDepth(i,j,k);
|
||||
double completion_pressure = pressure.size() > 0 ? pressure[active_index] : 0.0;
|
||||
double saturation_water = swat.size() > 0 ? swat[active_index] : 0.0;
|
||||
double saturation_gas = sgas.size() > 0 ? sgas[active_index] : 0.0;
|
||||
|
||||
ecl_rft_cell_type * ecl_rft_cell = ecl_rft_cell_alloc_RFT( i ,j, k , depth, completion_pressure, saturation_water, saturation_gas);
|
||||
ecl_rft_node_append_cell( ecl_rft_node , ecl_rft_cell);
|
||||
}
|
||||
}
|
||||
|
||||
return ecl_rft_node;
|
||||
}
|
||||
|
||||
|
||||
void EclipseWriteRFTHandler::initGlobalToActiveIndex(const int * compressedToCartesianCellIdx, size_t numCells, size_t cartesianSize) {
|
||||
globalToActiveIndex_.resize(cartesianSize, -1);
|
||||
for (int active_index = 0; active_index < numCells; ++active_index) {
|
||||
//If compressedToCartesianCellIdx is NULL, assume no compressed to cartesian mapping, set global equal to active index
|
||||
int global_index = (NULL != compressedToCartesianCellIdx) ? compressedToCartesianCellIdx[active_index] : active_index;
|
||||
globalToActiveIndex_[global_index] = active_index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}//namespace EclipseWriterDetails
|
||||
}//namespace Opm
|
76
opm/core/io/eclipse/EclipseWriteRFTHandler.hpp
Normal file
76
opm/core/io/eclipse/EclipseWriteRFTHandler.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2015 Statoil ASA.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPM_ECLIPSE_WRITE_RFT_HANDLER_HPP
|
||||
#define OPM_ECLIPSE_WRITE_RFT_HANDLER_HPP
|
||||
|
||||
#include <opm/core/simulator/SimulatorTimer.hpp>
|
||||
#include <opm/core/simulator/BlackoilState.hpp>
|
||||
#include <opm/core/simulator/SimulatorState.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
|
||||
#include <ert/ecl/ecl_rft_node.h>
|
||||
#include <ert/ecl/ecl_util.h>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
namespace EclipseWriterDetails {
|
||||
|
||||
|
||||
class EclipseWriteRFTHandler {
|
||||
|
||||
public:
|
||||
EclipseWriteRFTHandler(const int * compressedToCartesianCellIdx, size_t numCells, size_t cartesianSize);
|
||||
|
||||
|
||||
void writeTimeStep(const std::string& filename,
|
||||
const ert_ecl_unit_enum ecl_unit,
|
||||
const SimulatorTimerInterface& simulatorTimer,
|
||||
std::vector<WellConstPtr>& wells,
|
||||
EclipseGridConstPtr eclipseGrid,
|
||||
std::vector<double>& pressure,
|
||||
std::vector<double>& swat,
|
||||
std::vector<double>& sgas);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
ecl_rft_node_type * createEclRFTNode(WellConstPtr well,
|
||||
const SimulatorTimerInterface& simulatorTimer,
|
||||
EclipseGridConstPtr eclipseGrid,
|
||||
const std::vector<double>& pressure,
|
||||
const std::vector<double>& swat,
|
||||
const std::vector<double>& sgas);
|
||||
|
||||
void initGlobalToActiveIndex(const int * compressedToCartesianCellIdx, size_t numCells, size_t cartesianSize);
|
||||
|
||||
std::vector<int> globalToActiveIndex_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}//namespace EclipseWriterDetails
|
||||
}//namespace Opm
|
||||
|
||||
|
||||
#endif //OPM_ECLIPSE_WRITE_RFT_HANDLER_HPP
|
@ -29,6 +29,7 @@
|
||||
#include <opm/core/simulator/SimulatorState.hpp>
|
||||
#include <opm/core/simulator/SimulatorTimerInterface.hpp>
|
||||
#include <opm/core/simulator/WellState.hpp>
|
||||
#include <opm/core/io/eclipse/EclipseWriteRFTHandler.hpp>
|
||||
#include <opm/core/utility/ErrorMacros.hpp>
|
||||
#include <opm/core/utility/parameters/Parameter.hpp>
|
||||
#include <opm/core/utility/parameters/ParameterGroup.hpp>
|
||||
@ -997,6 +998,31 @@ int EclipseWriter::eclipseWellStatusMask(WellCommon::StatusEnum wellStatus)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert opm-core UnitType to eclipse format: ert_ecl_unit_enum
|
||||
*/
|
||||
ert_ecl_unit_enum EclipseWriter::convertUnitTypeErtEclUnitEnum(UnitSystem::UnitType unit)
|
||||
{
|
||||
ert_ecl_unit_enum ecl_type;
|
||||
switch (unit) {
|
||||
case(UnitSystem::UNIT_TYPE_METRIC):
|
||||
ecl_type = ERT_ECL_METRIC_UNITS;
|
||||
break;
|
||||
case(UnitSystem::UNIT_TYPE_FIELD) :
|
||||
ecl_type = ERT_ECL_FIELD_UNITS;
|
||||
break;
|
||||
case(UnitSystem::UNIT_TYPE_LAB):
|
||||
ecl_type = ERT_ECL_LAB_UNITS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return ecl_type;
|
||||
}
|
||||
|
||||
|
||||
void EclipseWriter::writeInit(const SimulatorTimerInterface &timer)
|
||||
{
|
||||
// if we don't want to write anything, this method becomes a
|
||||
@ -1115,29 +1141,67 @@ void EclipseWriter::writeTimeStep(const SimulatorTimerInterface& timer,
|
||||
// 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> tmp = reservoirState.pressure();
|
||||
EclipseWriterDetails::convertFromSiTo(tmp, deckToSiPressure_);
|
||||
EclipseWriterDetails::restrictAndReorderToActiveCells(tmp, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
|
||||
std::vector<double> pressure = reservoirState.pressure();
|
||||
EclipseWriterDetails::convertFromSiTo(pressure, deckToSiPressure_);
|
||||
EclipseWriterDetails::restrictAndReorderToActiveCells(pressure, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
|
||||
|
||||
sol.add(EclipseWriterDetails::Keyword<float>("PRESSURE", tmp));
|
||||
sol.add(EclipseWriterDetails::Keyword<float>("PRESSURE", pressure));
|
||||
|
||||
for (int phase = 0; phase != BlackoilPhases::MaxNumPhases; ++phase) {
|
||||
// Eclipse never writes the oil saturation, so all post-processors
|
||||
// must calculate this from the other saturations anyway
|
||||
if (phase == BlackoilPhases::PhaseIndex::Liquid) {
|
||||
continue;
|
||||
}
|
||||
if (phaseUsage_.phase_used[phase]) {
|
||||
tmp = reservoirState.saturation();
|
||||
EclipseWriterDetails::extractFromStripedData(tmp,
|
||||
/*offset=*/phaseUsage_.phase_pos[phase],
|
||||
/*stride=*/phaseUsage_.num_phases);
|
||||
EclipseWriterDetails::restrictAndReorderToActiveCells(tmp, gridToEclipseIdx_.size(), gridToEclipseIdx_.data());
|
||||
sol.add(EclipseWriterDetails::Keyword<float>(EclipseWriterDetails::saturationKeywordNames[phase], tmp));
|
||||
}
|
||||
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
|
||||
std::shared_ptr<EclipseWriterDetails::EclipseWriteRFTHandler> eclipseWriteRFTHandler = std::make_shared<EclipseWriterDetails::EclipseWriteRFTHandler>(
|
||||
compressedToCartesianCellIdx_,
|
||||
numCells_,
|
||||
eclipseState_->getEclipseGrid()->getCartesianSize());
|
||||
|
||||
|
||||
char * rft_filename = ecl_util_alloc_filename(outputDir_.c_str(),
|
||||
baseName_.c_str(),
|
||||
ECL_RFT_FILE,
|
||||
false,
|
||||
0);
|
||||
|
||||
std::shared_ptr<const UnitSystem> unitsystem = eclipseState_->getDeckUnitSystem();
|
||||
ert_ecl_unit_enum ecl_unit = convertUnitTypeErtEclUnitEnum(unitsystem->getType());
|
||||
|
||||
std::vector<WellConstPtr> wells = eclipseState_->getSchedule()->getWells(timer.currentStepNum());
|
||||
|
||||
|
||||
eclipseWriteRFTHandler->writeTimeStep(rft_filename,
|
||||
ecl_unit,
|
||||
timer,
|
||||
wells,
|
||||
eclipseState_->getEclipseGrid(),
|
||||
pressure,
|
||||
saturation_water,
|
||||
saturation_gas);
|
||||
|
||||
|
||||
|
||||
/* Summary variables (well reporting) */
|
||||
// TODO: instead of writing the header (smspec) every time, it should
|
||||
// only be written when there is a change in the well configuration
|
||||
|
@ -103,6 +103,7 @@ public:
|
||||
|
||||
static int eclipseWellTypeMask(WellType wellType, WellInjector::TypeEnum injectorType);
|
||||
static int eclipseWellStatusMask(WellCommon::StatusEnum wellStatus);
|
||||
static ert_ecl_unit_enum convertUnitTypeErtEclUnitEnum(UnitSystem::UnitType unit);
|
||||
|
||||
private:
|
||||
Opm::EclipseStateConstPtr eclipseState_;
|
||||
|
233
tests/test_EclipseWriteRFTHandler.cpp
Executable file
233
tests/test_EclipseWriteRFTHandler.cpp
Executable file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
Copyright 2015 Statoil ASA.
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_DYNAMIC_BOOST_TEST
|
||||
#define BOOST_TEST_DYN_LINK
|
||||
#endif
|
||||
|
||||
#define BOOST_TEST_MODULE EclipseRFTWriter
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <opm/core/io/eclipse/EclipseWriteRFTHandler.hpp>
|
||||
#include <opm/core/io/eclipse/EclipseWriter.hpp>
|
||||
#include <opm/core/grid/GridManager.hpp>
|
||||
#include <opm/core/grid/GridHelpers.hpp>
|
||||
#include <opm/core/simulator/BlackoilState.hpp>
|
||||
#include <opm/core/simulator/WellState.hpp>
|
||||
#include <opm/core/simulator/SimulatorTimer.hpp>
|
||||
#include <opm/core/props/phaseUsageFromDeck.hpp>
|
||||
#include <opm/core/utility/parameters/ParameterGroup.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
|
||||
#include <ert/ecl/ecl_rft_file.h>
|
||||
#include <ert/util/test_work_area.h>
|
||||
#include <ert/util/util.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
void verifyRFTFile(const std::string& rft_filename) {
|
||||
|
||||
ecl_rft_file_type * new_rft_file = ecl_rft_file_alloc(rft_filename.c_str());
|
||||
std::shared_ptr<ecl_rft_file_type> rft_file;
|
||||
rft_file.reset(new_rft_file, ecl_rft_file_free);
|
||||
|
||||
//Get RFT node for well/time OP_1/10 OKT 2008
|
||||
time_t recording_time = util_make_datetime(0, 0, 0, 10, 10, 2008);
|
||||
ecl_rft_node_type * ecl_rft_node = ecl_rft_file_get_well_time_rft(rft_file.get() , "OP_1" , recording_time);
|
||||
BOOST_CHECK(ecl_rft_node_is_RFT(ecl_rft_node));
|
||||
|
||||
//Verify RFT data for completions (ijk) 9 9 1, 9 9 2 and 9 9 3 for OP_1
|
||||
const ecl_rft_cell_type * ecl_rft_cell1 = ecl_rft_node_lookup_ijk(ecl_rft_node, 8, 8, 0);
|
||||
const ecl_rft_cell_type * ecl_rft_cell2 = ecl_rft_node_lookup_ijk(ecl_rft_node, 8, 8, 1);
|
||||
const ecl_rft_cell_type * ecl_rft_cell3 = ecl_rft_node_lookup_ijk(ecl_rft_node, 8, 8, 2);
|
||||
|
||||
BOOST_CHECK_CLOSE(ecl_rft_cell_get_pressure(ecl_rft_cell1), 210088*0.00001, 0.00001);
|
||||
BOOST_CHECK_CLOSE(ecl_rft_cell_get_pressure(ecl_rft_cell2), 210188*0.00001, 0.00001);
|
||||
BOOST_CHECK_CLOSE(ecl_rft_cell_get_pressure(ecl_rft_cell3), 210288*0.00001, 0.00001);
|
||||
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_sgas(ecl_rft_cell1), 0.0);
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_sgas(ecl_rft_cell2), 0.0);
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_sgas(ecl_rft_cell3), 0.0);
|
||||
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_swat(ecl_rft_cell1), 0.0);
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_swat(ecl_rft_cell2), 0.0);
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_swat(ecl_rft_cell3), 0.0);
|
||||
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_soil(ecl_rft_cell1), 1.0);
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_soil(ecl_rft_cell2), 1.0);
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_soil(ecl_rft_cell3), 1.0);
|
||||
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_depth(ecl_rft_cell1), (0.250 + (0.250/2)));
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_depth(ecl_rft_cell2), (2*0.250 + (0.250/2)));
|
||||
BOOST_CHECK_EQUAL(ecl_rft_cell_get_depth(ecl_rft_cell3), (3*0.250 + (0.250/2)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Opm::DeckConstPtr createDeck(const std::string& input_str) {
|
||||
Opm::ParserPtr parser = std::make_shared<Opm::Parser>();
|
||||
Opm::DeckConstPtr deck = parser->parseString(input_str);
|
||||
return deck;
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Opm::WellState> createWellState(std::shared_ptr<Opm::BlackoilState> blackoilState)
|
||||
{
|
||||
std::shared_ptr<Opm::WellState> wellState = std::make_shared<Opm::WellState>();
|
||||
wellState->init(0, *blackoilState);
|
||||
return wellState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<Opm::BlackoilState> createBlackoilState(int timeStepIdx, std::shared_ptr<Opm::GridManager> ourFineGridManagerPtr)
|
||||
{
|
||||
const UnstructuredGrid &ourFinerUnstructuredGrid = *ourFineGridManagerPtr->c_grid();
|
||||
|
||||
std::shared_ptr<Opm::BlackoilState> blackoilState = std::make_shared<Opm::BlackoilState>();
|
||||
blackoilState->init(ourFinerUnstructuredGrid, 3);
|
||||
|
||||
size_t numCells = ourFinerUnstructuredGrid.number_of_cells;
|
||||
|
||||
auto &pressure = blackoilState->pressure();
|
||||
for (size_t cellIdx = 0; cellIdx < numCells; ++cellIdx) {
|
||||
pressure[cellIdx] = timeStepIdx*1e5 + 1e4 + cellIdx;
|
||||
}
|
||||
return blackoilState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<Opm::EclipseWriter> createEclipseWriter(std::shared_ptr<const Opm::Deck> deck,
|
||||
std::shared_ptr<Opm::EclipseState> eclipseState,
|
||||
std::shared_ptr<Opm::GridManager> ourFineGridManagerPtr,
|
||||
const int * compressedToCartesianCellIdx)
|
||||
{
|
||||
Opm::parameter::ParameterGroup params;
|
||||
params.insertParameter("deck_filename", "testcase.data");
|
||||
|
||||
Opm::PhaseUsage phaseUsage = Opm::phaseUsageFromDeck(deck);
|
||||
|
||||
const UnstructuredGrid &ourFinerUnstructuredGrid = *ourFineGridManagerPtr->c_grid();
|
||||
|
||||
std::shared_ptr<Opm::EclipseWriter> eclipseWriter = std::make_shared<Opm::EclipseWriter>(params,
|
||||
eclipseState,
|
||||
phaseUsage,
|
||||
ourFinerUnstructuredGrid.number_of_cells,
|
||||
compressedToCartesianCellIdx);
|
||||
|
||||
return eclipseWriter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_EclipseWriterRFTHandler)
|
||||
{
|
||||
const std::string& deckString =
|
||||
"RUNSPEC\n"
|
||||
"OIL\n"
|
||||
"GAS\n"
|
||||
"WATER\n"
|
||||
"DIMENS\n"
|
||||
" 10 10 10 /\n"
|
||||
"GRID\n"
|
||||
"DXV\n"
|
||||
"10*0.25 /\n"
|
||||
"DYV\n"
|
||||
"10*0.25 /\n"
|
||||
"DZV\n"
|
||||
"10*0.25 /\n"
|
||||
"TOPS\n"
|
||||
"100*0.25 /\n"
|
||||
"\n"
|
||||
"START -- 0 \n"
|
||||
"1 NOV 1979 / \n"
|
||||
"SCHEDULE\n"
|
||||
"DATES -- 1\n"
|
||||
" 1 DES 1979/ \n"
|
||||
"/\n"
|
||||
"WELSPECS\n"
|
||||
" 'OP_1' 'OP' 9 9 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
||||
" 'OP_2' 'OP' 4 4 1* 'OIL' 1* 1* 1* 1* 1* 1* 1* / \n"
|
||||
"/\n"
|
||||
"COMPDAT\n"
|
||||
" 'OP_1' 9 9 1 1 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_1' 9 9 2 2 'OPEN' 1* 46.825 0.311 4332.346 1* 1* 'X' 22.123 / \n"
|
||||
" 'OP_1' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
" 'OP_2' 4 4 4 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
|
||||
"/\n"
|
||||
"DATES -- 2\n"
|
||||
" 10 OKT 2008 / \n"
|
||||
"/\n"
|
||||
"WRFT \n"
|
||||
"/ \n"
|
||||
"WELOPEN\n"
|
||||
" 'OP_1' OPEN / \n"
|
||||
" 'OP_2' OPEN / \n"
|
||||
"/\n"
|
||||
"DATES -- 3\n"
|
||||
" 10 NOV 2008 / \n"
|
||||
"/\n";
|
||||
|
||||
|
||||
|
||||
test_work_area_type * new_ptr = test_work_area_alloc("test_EclipseWriterRFTHandler");
|
||||
std::shared_ptr<test_work_area_type> test_area;
|
||||
test_area.reset(new_ptr, test_work_area_free);
|
||||
|
||||
std::shared_ptr<const Opm::Deck> deck = createDeck(deckString);
|
||||
std::shared_ptr<Opm::EclipseState> eclipseState = std::make_shared<Opm::EclipseState>(deck);
|
||||
|
||||
std::shared_ptr<Opm::SimulatorTimer> simulatorTimer = std::make_shared<Opm::SimulatorTimer>();
|
||||
simulatorTimer->init(eclipseState->getSchedule()->getTimeMap());
|
||||
|
||||
std::shared_ptr<Opm::GridManager> ourFineGridManagerPtr = std::make_shared<Opm::GridManager>(eclipseState->getEclipseGrid());
|
||||
const UnstructuredGrid &ourFinerUnstructuredGrid = *ourFineGridManagerPtr->c_grid();
|
||||
const int* compressedToCartesianCellIdx = Opm::UgGridHelpers::globalCell(ourFinerUnstructuredGrid);
|
||||
|
||||
std::shared_ptr<Opm::EclipseWriter> eclipseWriter = createEclipseWriter(deck,
|
||||
eclipseState,
|
||||
ourFineGridManagerPtr,
|
||||
compressedToCartesianCellIdx);
|
||||
eclipseWriter->writeInit(*simulatorTimer);
|
||||
|
||||
|
||||
for (; simulatorTimer->currentStepNum() < simulatorTimer->numSteps(); ++ (*simulatorTimer)) {
|
||||
std::shared_ptr<Opm::BlackoilState> blackoilState2 = createBlackoilState(simulatorTimer->currentStepNum(),ourFineGridManagerPtr);
|
||||
std::shared_ptr<Opm::WellState> wellState = createWellState(blackoilState2);
|
||||
eclipseWriter->writeTimeStep(*simulatorTimer, *blackoilState2, *wellState);
|
||||
}
|
||||
|
||||
std::string cwd(test_work_area_get_cwd(test_area.get()));
|
||||
std::string rft_filename = cwd + "/TESTCASE.RFT";
|
||||
verifyRFTFile(rft_filename);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user