Merge pull request #1635 from joakim-hove/internalize_tracers
Internalize tracers
This commit is contained in:
commit
03efd5e589
@ -83,6 +83,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Runspec.cpp
|
||||
src/opm/parser/eclipse/EclipseState/TracerConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionAST.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionContext.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Action/ActionResult.cpp
|
||||
@ -347,6 +348,7 @@ if(ENABLE_ECL_INPUT)
|
||||
tests/parser/TableSchemaTests.cpp
|
||||
tests/parser/ThresholdPressureTest.cpp
|
||||
tests/parser/TimeMapTest.cpp
|
||||
tests/parser/TracerTests.cpp
|
||||
tests/parser/TransMultTests.cpp
|
||||
tests/parser/TuningTests.cpp
|
||||
tests/parser/UDQTests.cpp
|
||||
@ -547,6 +549,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp
|
||||
opm/parser/eclipse/EclipseState/Grid/MinpvMode.hpp
|
||||
opm/parser/eclipse/EclipseState/EndpointScaling.hpp
|
||||
opm/parser/eclipse/EclipseState/TracerConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/DenT.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/StandardCond.hpp
|
||||
@ -620,6 +623,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Tables/ImkrvdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/Sof3Table.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/SgofTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Tables/TracerVdTable.hpp
|
||||
opm/parser/eclipse/EclipseState/EclipseState.hpp
|
||||
opm/parser/eclipse/EclipseState/EclipseConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquancon.hpp
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/AquiferConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/TracerConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Edit/EDITNNC.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
@ -113,6 +114,7 @@ namespace Opm {
|
||||
|
||||
const Runspec& runspec() const;
|
||||
const AquiferConfig& aquifer() const;
|
||||
const TracerConfig& tracer() const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
@ -130,6 +132,7 @@ namespace Opm {
|
||||
m_faults.serializeOp(serializer);
|
||||
serializer(m_title);
|
||||
aquifer_config.serializeOp(serializer);
|
||||
tracer_config.serializeOp(serializer);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -158,6 +161,7 @@ namespace Opm {
|
||||
FaultCollection m_faults;
|
||||
std::string m_title;
|
||||
AquiferConfig aquifer_config;
|
||||
TracerConfig tracer_config;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ namespace Opm {
|
||||
|
||||
void addColumns();
|
||||
void init(const DeckItem& deckItem );
|
||||
void init( const DeckItem& deckItem, double scaling_factor);
|
||||
size_t numColumns() const;
|
||||
size_t numRows() const;
|
||||
void addRow( const std::vector<double>& row);
|
||||
|
55
opm/parser/eclipse/EclipseState/Tables/TracerVdTable.hpp
Normal file
55
opm/parser/eclipse/EclipseState/Tables/TracerVdTable.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
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 2 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/>.
|
||||
|
||||
Consult the COPYING file in the top-level source directory of this
|
||||
module for the precise wording of the license and the list of
|
||||
copyright holders.
|
||||
*/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \copydoc Opm::TracerVdTable
|
||||
*/
|
||||
#ifndef TRACER_VD_TABLE_HPP
|
||||
#define TRACER_VD_TABLE_HPP
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
/*!
|
||||
* \brief A class that contains tracer concentration vs depth table
|
||||
*/
|
||||
class TracerVdTable : public SimpleTable
|
||||
{
|
||||
public:
|
||||
TracerVdTable() = default;
|
||||
explicit TracerVdTable(const Opm::DeckItem& item, double inv_volume);
|
||||
|
||||
/*!
|
||||
* \brief Return the depth column
|
||||
*/
|
||||
const Opm::TableColumn& getDepthColumn() const;
|
||||
|
||||
/*!
|
||||
* \brief Return the tracer concentration column
|
||||
*/
|
||||
const Opm::TableColumn& getTracerConcentration() const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // TRACER_VD_TABLE_HPP
|
93
opm/parser/eclipse/EclipseState/TracerConfig.hpp
Normal file
93
opm/parser/eclipse/EclipseState/TracerConfig.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Copyright (C) 2020 Equinor
|
||||
|
||||
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_TRACER_CONFIG_HPP
|
||||
#define OPM_TRACER_CONFIG_HPP
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TracerVdTable.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Deck;
|
||||
class UnitSystem;
|
||||
|
||||
class TracerConfig {
|
||||
public:
|
||||
struct TracerEntry {
|
||||
std::string name;
|
||||
Phase phase = Phase::OIL;
|
||||
std::vector<double> concentration;
|
||||
TracerVdTable tvdpf;
|
||||
|
||||
TracerEntry() = default;
|
||||
TracerEntry(const std::string& name_, Phase phase_, std::vector<double> concentration_)
|
||||
: name(name_)
|
||||
, phase(phase_)
|
||||
, concentration(std::move(concentration_))
|
||||
{}
|
||||
|
||||
TracerEntry(const std::string& name_, Phase phase_, TracerVdTable tvdpf_)
|
||||
: name(name_)
|
||||
, phase(phase_)
|
||||
, tvdpf(std::move(tvdpf_))
|
||||
{}
|
||||
|
||||
bool operator==(const TracerEntry& data) const {
|
||||
return this->name == data.name &&
|
||||
this->phase == data.phase &&
|
||||
this->concentration == data.concentration &&
|
||||
this->tvdpf == data.tvdpf;
|
||||
}
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer(name);
|
||||
serializer(phase);
|
||||
serializer(concentration);
|
||||
tvdpf.serializeOp(serializer);
|
||||
}
|
||||
};
|
||||
|
||||
TracerConfig() = default;
|
||||
TracerConfig(const UnitSystem& unit_system, const Deck& deck);
|
||||
|
||||
static TracerConfig serializeObject();
|
||||
|
||||
size_t size() const;
|
||||
|
||||
const std::vector<TracerEntry>::const_iterator begin() const;
|
||||
const std::vector<TracerEntry>::const_iterator end() const;
|
||||
|
||||
template<class Serializer>
|
||||
void serializeOp(Serializer& serializer)
|
||||
{
|
||||
serializer.vector(tracers);
|
||||
}
|
||||
|
||||
bool operator==(const TracerConfig& data) const;
|
||||
|
||||
private:
|
||||
std::vector<TracerEntry> tracers;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -65,6 +65,7 @@ namespace Opm {
|
||||
OpmLog::info("Only " + std::to_string( this->runspec().phases().size() )
|
||||
+ " fluid phases are enabled" );
|
||||
this->aquifer_config = AquiferConfig(this->m_tables, this->m_inputGrid, deck);
|
||||
this->tracer_config = TracerConfig(this->m_deckUnitSystem, deck);
|
||||
|
||||
if (deck.hasKeyword( "TITLE" )) {
|
||||
const auto& titleKeyword = deck.getKeyword( "TITLE" );
|
||||
@ -176,6 +177,10 @@ namespace Opm {
|
||||
return this->aquifer_config;
|
||||
}
|
||||
|
||||
const TracerConfig& EclipseState::tracer() const {
|
||||
return this->tracer_config;
|
||||
}
|
||||
|
||||
void EclipseState::initTransMult() {
|
||||
const auto& fp = this->field_props;
|
||||
if (fp.has_double("MULTX")) this->m_transMult.applyMULT(fp.get_global_double("MULTX") , FaceDir::XPlus);
|
||||
|
@ -107,6 +107,31 @@ namespace Opm {
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleTable::init( const DeckItem& deckItem, double scaling_factor) {
|
||||
this->addColumns();
|
||||
|
||||
if ( (deckItem.data_size() % numColumns()) != 0)
|
||||
throw std::runtime_error("Number of columns in the data file is"
|
||||
"inconsistent with the ones specified");
|
||||
|
||||
size_t rows = deckItem.data_size() / numColumns();
|
||||
for (size_t colIdx = 0; colIdx < numColumns(); ++colIdx) {
|
||||
auto& column = getColumn( colIdx );
|
||||
for (size_t rowIdx = 0; rowIdx < rows; rowIdx++) {
|
||||
size_t deckItemIdx = rowIdx*numColumns() + colIdx;
|
||||
if (deckItem.defaultApplied(deckItemIdx))
|
||||
column.addDefault( );
|
||||
else if (m_jfunc) {
|
||||
column.addValue( deckItem.getData<double>()[deckItemIdx] );
|
||||
}
|
||||
else
|
||||
column.addValue( scaling_factor * deckItem.get<double>(deckItemIdx) );
|
||||
}
|
||||
if (colIdx > 0)
|
||||
column.applyDefaults(getColumn( 0 ));
|
||||
}
|
||||
}
|
||||
|
||||
size_t SimpleTable::numColumns() const {
|
||||
return m_schema.size();
|
||||
}
|
||||
|
@ -76,6 +76,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/SwfnTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/SwofTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TableContainer.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TracerVdTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/WatvisctTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/AqutabTable.hpp>
|
||||
|
||||
@ -1265,6 +1266,20 @@ const TableColumn& OverburdTable::getOverburdenPressureColumn() const {
|
||||
return SimpleTable::getColumn(1);
|
||||
}
|
||||
|
||||
TracerVdTable::TracerVdTable(const Opm::DeckItem& item, double inv_volume) {
|
||||
m_schema.addColumn(Opm::ColumnSchema("DEPTH", Table::STRICTLY_INCREASING, Table::DEFAULT_NONE));
|
||||
m_schema.addColumn(Opm::ColumnSchema("TRACER_CONCENTRATION", Table::RANDOM, Table::DEFAULT_NONE));
|
||||
SimpleTable::init(item, inv_volume);
|
||||
}
|
||||
|
||||
const TableColumn& TracerVdTable::getDepthColumn() const {
|
||||
return SimpleTable::getColumn(0);
|
||||
}
|
||||
|
||||
const TableColumn& TracerVdTable::getTracerConcentration() const {
|
||||
return SimpleTable::getColumn(1);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
|
108
src/opm/parser/eclipse/EclipseState/TracerConfig.cpp
Normal file
108
src/opm/parser/eclipse/EclipseState/TracerConfig.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
Copyright (C) 2020 Equinor
|
||||
|
||||
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 <opm/parser/eclipse/Parser/ParserKeywords/T.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/TracerConfig.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Units/Dimension.hpp>
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Tables/TracerVdTable.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace {
|
||||
|
||||
Phase phase_from_string(const std::string& phase_string) {
|
||||
if (phase_string == "WAT")
|
||||
return Phase::WATER;
|
||||
|
||||
if (phase_string == "OIL")
|
||||
return Phase::OIL;
|
||||
|
||||
if (phase_string == "GAS")
|
||||
return Phase::GAS;
|
||||
|
||||
throw std::invalid_argument("Tracer: invalid fluid name " + phase_string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TracerConfig::TracerConfig(const UnitSystem& unit_system, const Deck& deck)
|
||||
{
|
||||
using TR = ParserKeywords::TRACER;
|
||||
if (deck.hasKeyword<TR>()) {
|
||||
const auto& keyword = deck.getKeyword<TR>();
|
||||
for (const auto& record : keyword) {
|
||||
const auto& name = record.getItem<TR::NAME>().get<std::string>(0);
|
||||
Phase phase = phase_from_string(record.getItem<TR::FLUID>().get<std::string>(0));
|
||||
double inv_volume;
|
||||
|
||||
if (phase == Phase::GAS)
|
||||
inv_volume = unit_system.getDimension(UnitSystem::measure::gas_surface_volume).getSIScaling();
|
||||
else
|
||||
inv_volume = unit_system.getDimension(UnitSystem::measure::liquid_surface_volume).getSIScaling();
|
||||
|
||||
std::string tracer_field = "TBLKF" + name;
|
||||
if (deck.hasKeyword(tracer_field)) {
|
||||
auto concentration = deck.getKeyword(tracer_field).getRecord(0).getItem(0).getData<double>();
|
||||
for (auto& c : concentration)
|
||||
c *= inv_volume;
|
||||
|
||||
this->tracers.emplace_back(name, phase, std::move(concentration)) ;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string tracer_table = "TVDPF" + name;
|
||||
if (deck.hasKeyword(tracer_table)) {
|
||||
const auto& deck_item = deck.getKeyword(tracer_table).getRecord(0).getItem(0);
|
||||
this->tracers.emplace_back(name, phase, TracerVdTable(deck_item, inv_volume));
|
||||
continue;
|
||||
}
|
||||
|
||||
throw std::runtime_error("Uninitialized tracer concentration for tracer " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TracerConfig TracerConfig::serializeObject()
|
||||
{
|
||||
TracerConfig result;
|
||||
result.tracers = {{"test", Phase::OIL, {1.0}}};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t TracerConfig::size() const {
|
||||
return this->tracers.size();
|
||||
}
|
||||
|
||||
const std::vector<TracerConfig::TracerEntry>::const_iterator TracerConfig::begin() const {
|
||||
return this->tracers.begin();
|
||||
}
|
||||
|
||||
const std::vector<TracerConfig::TracerEntry>::const_iterator TracerConfig::end() const {
|
||||
return this->tracers.end();
|
||||
}
|
||||
|
||||
bool TracerConfig::operator==(const TracerConfig& other) const {
|
||||
return this->tracers == other.tracers;
|
||||
}
|
||||
|
||||
}
|
@ -2,5 +2,5 @@
|
||||
"name" : "TBLK",
|
||||
"deck_name_regex":"TBLK(F|S).{1,3}",
|
||||
"sections" : ["SOLUTION"],
|
||||
"data" : {"value_type" : "DOUBLE", "dimension" : "1"}
|
||||
"data" : {"value_type" : "DOUBLE"}
|
||||
}
|
||||
|
90
tests/parser/TracerTests.cpp
Normal file
90
tests/parser/TracerTests.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2019 SINTEF Digital, Mathematics and Cybernetics.
|
||||
Copyright 2013 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/>.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE TracerTests
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/TracerConfig.hpp>
|
||||
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
|
||||
static Deck createDeck() {
|
||||
// Using a raw string literal with xxx as delimiter.
|
||||
const char *deckData = R"xxx(
|
||||
DIMENS
|
||||
10 10 10 /
|
||||
TABDIMS
|
||||
3 /
|
||||
GRID
|
||||
DX
|
||||
1000*0.25 /
|
||||
DY
|
||||
1000*0.25 /
|
||||
DZ
|
||||
1000*0.25 /
|
||||
TOPS
|
||||
100*0.25 /
|
||||
EQLDIMS
|
||||
3 1 1 /
|
||||
|
||||
PROPS
|
||||
|
||||
TRACERS
|
||||
-- oil water gas env
|
||||
1* 1 1 1* /
|
||||
TRACER
|
||||
SEA WAT /
|
||||
OCE GAS /
|
||||
/
|
||||
TVDPFSEA
|
||||
1000 0.0
|
||||
5000 0.0 /
|
||||
TBLKFOCE
|
||||
1.0 2.0 3.0 /
|
||||
)xxx"; // End of raw string literal with xxx as delimiter.
|
||||
Parser parser;
|
||||
return parser.parseString( deckData );
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TracerConfigTest) {
|
||||
auto deck = createDeck();
|
||||
EclipseState state(deck);
|
||||
const TracerConfig& tc = state.tracer();
|
||||
BOOST_CHECK_EQUAL(tc.size(), 2U);
|
||||
|
||||
auto it = tc.begin();
|
||||
BOOST_CHECK_EQUAL(it->name, "SEA");
|
||||
BOOST_CHECK_EQUAL(it->phase, Phase::WATER);
|
||||
BOOST_CHECK(it->concentration.empty());
|
||||
BOOST_CHECK_EQUAL(it->tvdpf.numColumns(), 2);
|
||||
|
||||
++it;
|
||||
BOOST_CHECK_EQUAL(it->name, "OCE");
|
||||
BOOST_CHECK_EQUAL(it->phase, Phase::GAS);
|
||||
BOOST_CHECK_EQUAL(it->concentration.size(), 3U);
|
||||
BOOST_CHECK_EQUAL(it->tvdpf.numColumns(), 0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user