905 lines
46 KiB
C++
905 lines
46 KiB
C++
/*
|
|
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/>.
|
|
*/
|
|
|
|
|
|
#include <boost/algorithm/string/join.hpp>
|
|
|
|
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
|
#include <opm/parser/eclipse/Deck/Section.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Grid/BoxManager.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
|
|
#include <opm/parser/eclipse/Units/Dimension.hpp>
|
|
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
|
|
|
namespace Opm {
|
|
|
|
namespace GridPropertyPostProcessor {
|
|
|
|
void distTopLayer( std::vector<double>& values,
|
|
const TableManager* /* tableManager */,
|
|
const EclipseGrid* eclipseGrid,
|
|
GridProperties<int>* /* intGridProperties */,
|
|
GridProperties<double>* /* doubleGridProperties */)
|
|
{
|
|
size_t layerSize = eclipseGrid->getNX() * eclipseGrid->getNY();
|
|
size_t gridSize = eclipseGrid->getCartesianSize();
|
|
|
|
for( size_t globalIndex = layerSize; globalIndex < gridSize; globalIndex++ ) {
|
|
if( std::isnan( values[ globalIndex ] ) )
|
|
values[globalIndex] = values[globalIndex - layerSize];
|
|
}
|
|
}
|
|
|
|
/// initPORV uses doubleGridProperties: PORV, PORO, NTG, MULTPV
|
|
void initPORV( std::vector<double>& values,
|
|
const TableManager* /* tableManager */,
|
|
const EclipseGrid* eclipseGrid,
|
|
GridProperties<int>* /* intGridProperties */,
|
|
GridProperties<double>* doubleGridProperties)
|
|
{
|
|
/*
|
|
Observe that this apply method does not alter the values input
|
|
vector, instead it fetches the PORV property one more time, and
|
|
then manipulates that.
|
|
*/
|
|
|
|
const auto& porv = doubleGridProperties->getOrCreateProperty("PORV");
|
|
|
|
if (porv.containsNaN()) {
|
|
const auto& poro = doubleGridProperties->getOrCreateProperty("PORO");
|
|
|
|
const auto& ntg = doubleGridProperties->getOrCreateProperty("NTG");
|
|
if (poro.containsNaN())
|
|
throw std::logic_error("Do not have information for the PORV keyword - some defaulted values in PORO");
|
|
else {
|
|
const auto& poroData = poro.getData();
|
|
for (size_t globalIndex = 0; globalIndex < porv.getCartesianSize(); globalIndex++) {
|
|
if (std::isnan(values[globalIndex])) {
|
|
double cell_poro = poroData[globalIndex];
|
|
double cell_ntg = ntg.iget(globalIndex);
|
|
double cell_volume = eclipseGrid->getCellVolume(globalIndex);
|
|
values[globalIndex] = cell_poro * cell_volume * cell_ntg;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (doubleGridProperties->hasKeyword("MULTPV")) {
|
|
const auto& multpvData = doubleGridProperties->getKeyword("MULTPV").getData();
|
|
for (size_t globalIndex = 0; globalIndex < porv.getCartesianSize(); globalIndex++) {
|
|
values[globalIndex] *= multpvData[globalIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
static std::vector< GridProperties< int >::SupportedKeywordInfo >
|
|
makeSupportedIntKeywords() {
|
|
return {GridProperties< int >::SupportedKeywordInfo( "SATNUM" , 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "IMBNUM" , 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "PVTNUM" , 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "EQLNUM" , 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "ENDNUM" , 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "FLUXNUM", 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "MULTNUM", 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "FIPNUM" , 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "MISCNUM", 1, "1" ),
|
|
GridProperties< int >::SupportedKeywordInfo( "OPERNUM", 1, "1" ),
|
|
};
|
|
}
|
|
|
|
static std::vector< GridProperties< double >::SupportedKeywordInfo >
|
|
makeSupportedDoubleKeywords(const TableManager* tableManager,
|
|
const EclipseGrid* eclipseGrid,
|
|
GridProperties<int>* intGridProperties)
|
|
{
|
|
GridPropertyInitFunction< double > SGLLookup ( &SGLEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > ISGLLookup ( &ISGLEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > SWLLookup ( &SWLEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > ISWLLookup ( &ISWLEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > SGULookup ( &SGUEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > ISGULookup ( &ISGUEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > SWULookup ( &SWUEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > ISWULookup ( &ISWUEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > SGCRLookup ( &SGCREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > ISGCRLookup ( &ISGCREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > SOWCRLookup ( &SOWCREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > ISOWCRLookup ( &ISOWCREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > SOGCRLookup ( &SOGCREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > ISOGCRLookup ( &ISOGCREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > SWCRLookup ( &SWCREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > ISWCRLookup ( &ISWCREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
|
|
GridPropertyInitFunction< double > PCWLookup ( &PCWEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IPCWLookup ( &IPCWEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > PCGLookup ( &PCGEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IPCGLookup ( &IPCGEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > KRWLookup ( &KRWEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IKRWLookup ( &IKRWEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > KRWRLookup ( &KRWREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IKRWRLookup ( &IKRWREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > KROLookup ( &KROEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IKROLookup ( &IKROEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > KRORWLookup ( &KRORWEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IKRORWLookup ( &IKRORWEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > KRORGLookup ( &KRORGEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IKRORGLookup ( &IKRORGEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > KRGLookup ( &KRGEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IKRGLookup ( &IKRGEndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > KRGRLookup ( &KRGREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
GridPropertyInitFunction< double > IKRGRLookup ( &IKRGREndpoint, tableManager, eclipseGrid, intGridProperties, nullptr);
|
|
|
|
GridPropertyInitFunction< double > tempLookup ( &temperature_lookup,
|
|
tableManager, eclipseGrid, intGridProperties, nullptr );
|
|
|
|
GridPropertyPostFunction< double > distributeTopLayer( &GridPropertyPostProcessor::distTopLayer,
|
|
tableManager, eclipseGrid, intGridProperties, nullptr );
|
|
|
|
std::vector< GridProperties< double >::SupportedKeywordInfo > supportedDoubleKeywords;
|
|
|
|
// keywords to specify the scaled connate gas saturations.
|
|
for( const auto& kw : { "SGL", "SGLX", "SGLX-", "SGLY", "SGLY-", "SGLZ", "SGLZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, SGLLookup, "1" );
|
|
for( const auto& kw : { "ISGL", "ISGLX", "ISGLX-", "ISGLY", "ISGLY-", "ISGLZ", "ISGLZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, ISGLLookup, "1" );
|
|
|
|
// keywords to specify the connate water saturation.
|
|
for( const auto& kw : { "SWL", "SWLX", "SWLX-", "SWLY", "SWLY-", "SWLZ", "SWLZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, SWLLookup, "1" );
|
|
for( const auto& kw : { "ISWL", "ISWLX", "ISWLX-", "ISWLY", "ISWLY-", "ISWLZ", "ISWLZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, ISWLLookup, "1" );
|
|
|
|
// keywords to specify the maximum gas saturation.
|
|
for( const auto& kw : { "SGU", "SGUX", "SGUX-", "SGUY", "SGUY-", "SGUZ", "SGUZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, SGULookup, "1" );
|
|
for( const auto& kw : { "ISGU", "ISGUX", "ISGUX-", "ISGUY", "ISGUY-", "ISGUZ", "ISGUZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, ISGULookup, "1" );
|
|
|
|
// keywords to specify the maximum water saturation.
|
|
for( const auto& kw : { "SWU", "SWUX", "SWUX-", "SWUY", "SWUY-", "SWUZ", "SWUZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, SWULookup, "1" );
|
|
for( const auto& kw : { "ISWU", "ISWUX", "ISWUX-", "ISWUY", "ISWUY-", "ISWUZ", "ISWUZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, ISWULookup, "1" );
|
|
|
|
// keywords to specify the scaled critical gas saturation.
|
|
for( const auto& kw : { "SGCR", "SGCRX", "SGCRX-", "SGCRY", "SGCRY-", "SGCRZ", "SGCRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, SGCRLookup, "1" );
|
|
for( const auto& kw : { "ISGCR", "ISGCRX", "ISGCRX-", "ISGCRY", "ISGCRY-", "ISGCRZ", "ISGCRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, ISGCRLookup, "1" );
|
|
|
|
// keywords to specify the scaled critical oil-in-water saturation.
|
|
for( const auto& kw : { "SOWCR", "SOWCRX", "SOWCRX-", "SOWCRY", "SOWCRY-", "SOWCRZ", "SOWCRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, SOWCRLookup, "1" );
|
|
for( const auto& kw : { "ISOWCR", "ISOWCRX", "ISOWCRX-", "ISOWCRY", "ISOWCRY-", "ISOWCRZ", "ISOWCRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, ISOWCRLookup, "1" );
|
|
|
|
// keywords to specify the scaled critical oil-in-gas saturation.
|
|
for( const auto& kw : { "SOGCR", "SOGCRX", "SOGCRX-", "SOGCRY", "SOGCRY-", "SOGCRZ", "SOGCRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, SOGCRLookup, "1" );
|
|
for( const auto& kw : { "ISOGCR", "ISOGCRX", "ISOGCRX-", "ISOGCRY", "ISOGCRY-", "ISOGCRZ", "ISOGCRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, ISOGCRLookup, "1" );
|
|
|
|
// keywords to specify the scaled critical water saturation.
|
|
for( const auto& kw : { "SWCR", "SWCRX", "SWCRX-", "SWCRY", "SWCRY-", "SWCRZ", "SWCRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, SWCRLookup, "1" );
|
|
for( const auto& kw : { "ISWCR", "ISWCRX", "ISWCRX-", "ISWCRY", "ISWCRY-", "ISWCRZ", "ISWCRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, ISWCRLookup, "1" );
|
|
|
|
// keywords to specify the scaled oil-water capillary pressure
|
|
for( const auto& kw : { "PCW", "PCWX", "PCWX-", "PCWY", "PCWY-", "PCWZ", "PCWZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, PCWLookup, "1" );
|
|
for( const auto& kw : { "IPCW", "IPCWX", "IPCWX-", "IPCWY", "IPCWY-", "IPCWZ", "IPCWZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IPCWLookup, "1" );
|
|
|
|
// keywords to specify the scaled gas-oil capillary pressure
|
|
for( const auto& kw : { "PCG", "PCGX", "PCGX-", "PCGY", "PCGY-", "PCGZ", "PCGZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, PCGLookup, "1" );
|
|
for( const auto& kw : { "IPCG", "IPCGX", "IPCGX-", "IPCGY", "IPCGY-", "IPCGZ", "IPCGZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IPCGLookup, "1" );
|
|
|
|
// keywords to specify the scaled water relative permeability
|
|
for( const auto& kw : { "KRW", "KRWX", "KRWX-", "KRWY", "KRWY-", "KRWZ", "KRWZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, KRWLookup, "1" );
|
|
for( const auto& kw : { "IKRW", "IKRWX", "IKRWX-", "IKRWY", "IKRWY-", "IKRWZ", "IKRWZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IKRWLookup, "1" );
|
|
|
|
// keywords to specify the scaled water relative permeability at the critical
|
|
// saturation
|
|
for( const auto& kw : { "KRWR" , "KRWRX" , "KRWRX-" , "KRWRY" , "KRWRY-" , "KRWRZ" , "KRWRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, KRWRLookup, "1" );
|
|
for( const auto& kw : { "IKRWR" , "IKRWRX" , "IKRWRX-" , "IKRWRY" , "IKRWRY-" , "IKRWRZ" , "IKRWRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IKRWRLookup, "1" );
|
|
|
|
// keywords to specify the scaled oil relative permeability
|
|
for( const auto& kw : { "KRO", "KROX", "KROX-", "KROY", "KROY-", "KROZ", "KROZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, KROLookup, "1" );
|
|
for( const auto& kw : { "IKRO", "IKROX", "IKROX-", "IKROY", "IKROY-", "IKROZ", "IKROZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IKROLookup, "1" );
|
|
|
|
// keywords to specify the scaled water relative permeability at the critical
|
|
// water saturation
|
|
for( const auto& kw : { "KRORW", "KRORWX", "KRORWX-", "KRORWY", "KRORWY-", "KRORWZ", "KRORWZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, KRORWLookup, "1" );
|
|
for( const auto& kw : { "IKRORW", "IKRORWX", "IKRORWX-", "IKRORWY", "IKRORWY-", "IKRORWZ", "IKRORWZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IKRORWLookup, "1" );
|
|
|
|
// keywords to specify the scaled water relative permeability at the critical
|
|
// water saturation
|
|
for( const auto& kw : { "KRORG", "KRORGX", "KRORGX-", "KRORGY", "KRORGY-", "KRORGZ", "KRORGZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, KRORGLookup, "1" );
|
|
for( const auto& kw : { "IKRORG", "IKRORGX", "IKRORGX-", "IKRORGY", "IKRORGY-", "IKRORGZ", "IKRORGZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IKRORGLookup, "1" );
|
|
|
|
// keywords to specify the scaled gas relative permeability
|
|
for( const auto& kw : { "KRG", "KRGX", "KRGX-", "KRGY", "KRGY-", "KRGZ", "KRGZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, KRGLookup, "1" );
|
|
for( const auto& kw : { "IKRG", "IKRGX", "IKRGX-", "IKRGY", "IKRGY-", "IKRGZ", "IKRGZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IKRGLookup, "1" );
|
|
|
|
// keywords to specify the scaled gas relative permeability
|
|
for( const auto& kw : { "KRGR", "KRGRX", "KRGRX-", "KRGRY", "KRGRY-", "KRGRZ", "KRGRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, KRGRLookup, "1" );
|
|
for( const auto& kw : { "IKRGR", "IKRGRX", "IKRGRX-", "IKRGRY", "IKRGRY-", "IKRGRZ", "IKRGRZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, IKRGRLookup, "1" );
|
|
|
|
|
|
|
|
// cell temperature (E300 only, but makes a lot of sense for E100, too)
|
|
supportedDoubleKeywords.emplace_back( "TEMPI", tempLookup, "Temperature" );
|
|
|
|
const double nan = std::numeric_limits<double>::quiet_NaN();
|
|
// porosity
|
|
supportedDoubleKeywords.emplace_back( "PORO", nan, distributeTopLayer, "1" );
|
|
|
|
// pore volume multipliers
|
|
supportedDoubleKeywords.emplace_back( "MULTPV", 1.0, "1" );
|
|
|
|
// the permeability keywords
|
|
for( const auto& kw : { "PERMX", "PERMY", "PERMZ" } )
|
|
supportedDoubleKeywords.emplace_back( kw, nan, distributeTopLayer, "Permeability" );
|
|
|
|
/* E300 only */
|
|
for( const auto& kw : { "PERMXY", "PERMYZ", "PERMZX" } )
|
|
supportedDoubleKeywords.emplace_back( kw, nan, distributeTopLayer, "Permeability" );
|
|
|
|
/* the transmissibility keywords for neighboring connections. note that
|
|
* these keywords don't seem to require a post-processor
|
|
*/
|
|
for( const auto& kw : { "TRANX", "TRANY", "TRANZ" } )
|
|
supportedDoubleKeywords.emplace_back( kw, nan, "Transmissibility" );
|
|
|
|
/* gross-to-net thickness (acts as a multiplier for PORO and the
|
|
* permeabilities in the X-Y plane as well as for the well rates.)
|
|
*/
|
|
supportedDoubleKeywords.emplace_back( "NTG", 1.0, "1" );
|
|
|
|
// transmissibility multipliers
|
|
for( const auto& kw : { "MULTX", "MULTY", "MULTZ", "MULTX-", "MULTY-", "MULTZ-" } )
|
|
supportedDoubleKeywords.emplace_back( kw, 1.0, "1" );
|
|
|
|
// initialisation
|
|
supportedDoubleKeywords.emplace_back( "SWATINIT", 0.0, "1");
|
|
supportedDoubleKeywords.emplace_back( "THCONR", 0.0, "1");
|
|
|
|
return supportedDoubleKeywords;
|
|
}
|
|
|
|
Eclipse3DProperties::Eclipse3DProperties( const Deck& deck,
|
|
const TableManager& tableManager,
|
|
const EclipseGrid& eclipseGrid)
|
|
:
|
|
|
|
m_defaultRegion("FLUXNUM"),
|
|
m_deckUnitSystem(deck.getActiveUnitSystem()),
|
|
// Note that the variants of grid keywords for radial grids are not
|
|
// supported. (and hopefully never will be)
|
|
// register the grid properties
|
|
m_intGridProperties(eclipseGrid, makeSupportedIntKeywords()),
|
|
m_doubleGridProperties(eclipseGrid,
|
|
makeSupportedDoubleKeywords(&tableManager, &eclipseGrid, &m_intGridProperties))
|
|
{
|
|
/*
|
|
* The EQUALREG, MULTREG, COPYREG, ... keywords are used to manipulate
|
|
* vectors based on region values; for instance the statement
|
|
*
|
|
* EQUALREG
|
|
* PORO 0.25 3 / -- Region array not specified
|
|
* PERMX 100 3 F /
|
|
* /
|
|
*
|
|
* will set the PORO field to 0.25 for all cells in region 3 and the PERMX
|
|
* value to 100 mD for the same cells. The fourth optional argument to the
|
|
* EQUALREG keyword is used to indicate which REGION array should be used
|
|
* for the selection.
|
|
*
|
|
* If the REGION array is not indicated (as in the PORO case) above, the
|
|
* default region to use in the xxxREG keywords depends on the GRIDOPTS
|
|
* keyword:
|
|
*
|
|
* 1. If GRIDOPTS is present, and the NRMULT item is greater than zero,
|
|
* the xxxREG keywords will default to use the MULTNUM region.
|
|
*
|
|
* 2. If the GRIDOPTS keyword is not present - or the NRMULT item equals
|
|
* zero, the xxxREG keywords will default to use the FLUXNUM keyword.
|
|
*
|
|
* This quite weird behaviour comes from reading the GRIDOPTS and MULTNUM
|
|
* documentation, and practical experience with ECLIPSE
|
|
* simulations. Ufortunately the documentation of the xxxREG keywords does
|
|
* not confirm this.
|
|
*/
|
|
if (deck.hasKeyword( "GRIDOPTS" )) {
|
|
const auto& gridOpts = deck.getKeyword( "GRIDOPTS" );
|
|
const auto& record = gridOpts.getRecord( 0 );
|
|
const auto& nrmult_item = record.getItem( "NRMULT" );
|
|
|
|
if (nrmult_item.get<int>( 0 ) > 0)
|
|
m_defaultRegion = "MULTNUM"; // GRIDOPTS and positive NRMULT
|
|
}
|
|
|
|
|
|
GridPropertyPostFunction< double > initPORV(&GridPropertyPostProcessor::initPORV,
|
|
&tableManager,
|
|
&eclipseGrid,
|
|
&m_intGridProperties,
|
|
&m_doubleGridProperties);
|
|
// pore volume
|
|
m_doubleGridProperties.postAddKeyword( "PORV",
|
|
std::numeric_limits<double>::quiet_NaN(),
|
|
initPORV,
|
|
"Volume" );
|
|
|
|
// actually create the grid property objects. we need to first process
|
|
// all integer grid properties before the double ones as these may be
|
|
// needed in order to initialize the double properties
|
|
processGridProperties(deck, eclipseGrid, /*enabledTypes=*/IntProperties);
|
|
processGridProperties(deck, eclipseGrid, /*enabledTypes=*/DoubleProperties);
|
|
|
|
}
|
|
|
|
bool Eclipse3DProperties::supportsGridProperty(const std::string& keyword,
|
|
int enabledTypes) const
|
|
{
|
|
bool result = false;
|
|
if (enabledTypes & IntProperties)
|
|
result = result ||
|
|
m_intGridProperties.supportsKeyword( keyword );
|
|
|
|
if (enabledTypes & DoubleProperties)
|
|
result = result ||
|
|
m_doubleGridProperties.supportsKeyword( keyword );
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
bool Eclipse3DProperties::hasDeckIntGridProperty(const std::string& keyword) const {
|
|
if (!m_intGridProperties.supportsKeyword( keyword ))
|
|
throw std::logic_error("Integer grid property " + keyword + " is unsupported!");
|
|
|
|
return m_intGridProperties.hasKeyword( keyword );
|
|
}
|
|
|
|
bool Eclipse3DProperties::hasDeckDoubleGridProperty(const std::string& keyword) const {
|
|
if (!m_doubleGridProperties.supportsKeyword( keyword ))
|
|
throw std::logic_error("Double grid property " + keyword + " is unsupported!");
|
|
|
|
return m_doubleGridProperties.hasKeyword( keyword );
|
|
}
|
|
|
|
/*
|
|
1. The public methods getIntGridProperty & getDoubleGridProperty will
|
|
invoke and run the property post processor (if any is registered); the
|
|
post processor will only run one time.
|
|
|
|
It is important that post processor is not run prematurely, internal
|
|
functions in EclipseState should therefore ask for properties by
|
|
invoking the getKeyword() method of the m_intGridProperties /
|
|
m_doubleGridProperties() directly and not through these methods.
|
|
|
|
2. Observe that this will autocreate a property if it has not been
|
|
explicitly added.
|
|
*/
|
|
const GridProperty<int>& Eclipse3DProperties::getIntGridProperty( const std::string& keyword ) const {
|
|
return m_intGridProperties.getKeyword( keyword );
|
|
}
|
|
|
|
/// gets property from doubleGridProperty --- and calls the runPostProcessor
|
|
const GridProperty<double>& Eclipse3DProperties::getDoubleGridProperty( const std::string& keyword ) const {
|
|
auto& gridProperty = const_cast< Eclipse3DProperties* >( this )->m_doubleGridProperties.getKeyword( keyword );
|
|
gridProperty.runPostProcessor();
|
|
return gridProperty;
|
|
}
|
|
|
|
std::string Eclipse3DProperties::getDefaultRegionKeyword() const {
|
|
return m_defaultRegion;
|
|
}
|
|
|
|
const GridProperty<int>& Eclipse3DProperties::getRegion( const DeckItem& regionItem ) const {
|
|
if (regionItem.defaultApplied(0))
|
|
return m_intGridProperties.getKeyword( m_defaultRegion );
|
|
else {
|
|
const std::string regionArray = MULTREGT::RegionNameFromDeckValue( regionItem.get< std::string >(0) );
|
|
return m_intGridProperties.getInitializedKeyword( regionArray );
|
|
}
|
|
}
|
|
|
|
/// Due to the post processor which might be applied to the GridProperty
|
|
/// objects it is essential that this method use the m_intGridProperties /
|
|
/// m_doubleGridProperties fields directly and *NOT* use the public methods
|
|
/// getIntGridProperty / getDoubleGridProperty.
|
|
void Eclipse3DProperties::loadGridPropertyFromDeckKeyword(const Box& inputBox,
|
|
const DeckKeyword& deckKeyword,
|
|
int enabledTypes)
|
|
{
|
|
const std::string& keyword = deckKeyword.name();
|
|
if (m_intGridProperties.supportsKeyword( keyword )) {
|
|
if (enabledTypes & IntProperties) {
|
|
auto& gridProperty = m_intGridProperties.getOrCreateProperty( keyword );
|
|
gridProperty.loadFromDeckKeyword( inputBox, deckKeyword );
|
|
}
|
|
} else if (m_doubleGridProperties.supportsKeyword( keyword )) {
|
|
if (enabledTypes & DoubleProperties) {
|
|
auto& gridProperty = m_doubleGridProperties.getOrCreateProperty( keyword );
|
|
gridProperty.loadFromDeckKeyword( inputBox, deckKeyword );
|
|
}
|
|
} else {
|
|
throw std::logic_error( "Tried to load unsupported grid property from keyword: " + deckKeyword.name() );
|
|
}
|
|
}
|
|
|
|
static bool isInt(double value) {
|
|
return fabs( nearbyint( value ) - value ) < 1e-6;
|
|
}
|
|
|
|
void Eclipse3DProperties::processGridProperties( const Deck& deck,
|
|
const EclipseGrid& eclipseGrid,
|
|
int enabledTypes) {
|
|
|
|
if (Section::hasGRID(deck)) {
|
|
scanSection(GRIDSection(deck), eclipseGrid, enabledTypes);
|
|
}
|
|
|
|
if (Section::hasEDIT(deck)) {
|
|
scanSection(EDITSection(deck), eclipseGrid, enabledTypes);
|
|
}
|
|
|
|
if (Section::hasPROPS(deck)) {
|
|
scanSection(PROPSSection(deck), eclipseGrid, enabledTypes);
|
|
}
|
|
|
|
if (Section::hasREGIONS(deck)) {
|
|
scanSection(REGIONSSection(deck), eclipseGrid, enabledTypes);
|
|
}
|
|
|
|
if (Section::hasSOLUTION(deck)) {
|
|
scanSection(SOLUTIONSection(deck), eclipseGrid, enabledTypes);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// private method
|
|
double Eclipse3DProperties::getSIScaling(const std::string &dimensionString) const
|
|
{
|
|
return m_deckUnitSystem.getDimension(dimensionString)->getSIScaling();
|
|
}
|
|
|
|
void Eclipse3DProperties::scanSection(const Section& section,
|
|
const EclipseGrid& eclipseGrid,
|
|
int enabledTypes) {
|
|
BoxManager boxManager(eclipseGrid.getNX(),
|
|
eclipseGrid.getNY(),
|
|
eclipseGrid.getNZ());
|
|
|
|
for( const auto& deckKeyword : section ) {
|
|
|
|
if (supportsGridProperty(deckKeyword.name(), enabledTypes) )
|
|
loadGridPropertyFromDeckKeyword( *boxManager.getActiveBox(),
|
|
deckKeyword,
|
|
enabledTypes);
|
|
else {
|
|
if (deckKeyword.name() == "ADD")
|
|
handleADDKeyword(deckKeyword, boxManager, enabledTypes);
|
|
|
|
if (deckKeyword.name() == "BOX")
|
|
handleBOXKeyword(deckKeyword, boxManager);
|
|
|
|
if (deckKeyword.name() == "COPY")
|
|
handleCOPYKeyword(deckKeyword, boxManager, enabledTypes);
|
|
|
|
if (deckKeyword.name() == "EQUALS")
|
|
handleEQUALSKeyword(deckKeyword, boxManager, enabledTypes);
|
|
|
|
if (deckKeyword.name() == "MULTIPLY")
|
|
handleMULTIPLYKeyword(deckKeyword, boxManager, enabledTypes);
|
|
|
|
if (deckKeyword.name() == "ENDBOX")
|
|
handleENDBOXKeyword(boxManager);
|
|
|
|
if (deckKeyword.name() == "EQUALREG")
|
|
handleEQUALREGKeyword(deckKeyword, enabledTypes);
|
|
|
|
if (deckKeyword.name() == "ADDREG")
|
|
handleADDREGKeyword(deckKeyword, enabledTypes);
|
|
|
|
if (deckKeyword.name() == "MULTIREG")
|
|
handleMULTIREGKeyword(deckKeyword, enabledTypes);
|
|
|
|
if (deckKeyword.name() == "COPYREG")
|
|
handleCOPYREGKeyword(deckKeyword, enabledTypes);
|
|
|
|
boxManager.endKeyword();
|
|
}
|
|
}
|
|
boxManager.endSection();
|
|
}
|
|
|
|
|
|
void Eclipse3DProperties::handleBOXKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager) {
|
|
const auto& record = deckKeyword.getRecord(0);
|
|
int I1 = record.getItem("I1").get< int >(0) - 1;
|
|
int I2 = record.getItem("I2").get< int >(0) - 1;
|
|
int J1 = record.getItem("J1").get< int >(0) - 1;
|
|
int J2 = record.getItem("J2").get< int >(0) - 1;
|
|
int K1 = record.getItem("K1").get< int >(0) - 1;
|
|
int K2 = record.getItem("K2").get< int >(0) - 1;
|
|
|
|
boxManager.setInputBox( I1 , I2 , J1 , J2 , K1 , K2 );
|
|
}
|
|
|
|
|
|
void Eclipse3DProperties::handleENDBOXKeyword(BoxManager& boxManager) {
|
|
boxManager.endInputBox();
|
|
}
|
|
|
|
|
|
void Eclipse3DProperties::handleEQUALREGKeyword( const DeckKeyword& deckKeyword,
|
|
int enabledTypes)
|
|
{
|
|
for( const auto& record : deckKeyword ) {
|
|
const std::string& targetArray = record.getItem("ARRAY").get< std::string >(0);
|
|
|
|
if (!supportsGridProperty( targetArray , IntProperties + DoubleProperties))
|
|
throw std::invalid_argument("Fatal error processing EQUALREG keyword - invalid/undefined keyword: " + targetArray);
|
|
|
|
double doubleValue = record.getItem("VALUE").template get<double>(0);
|
|
int regionValue = record.getItem("REGION_NUMBER").template get<int>(0);
|
|
auto& regionProperty = getRegion( record.getItem("REGION_NAME") );
|
|
std::vector<bool> mask;
|
|
|
|
regionProperty.initMask( regionValue , mask);
|
|
|
|
if (m_intGridProperties.supportsKeyword( targetArray )) {
|
|
if (enabledTypes & IntProperties) {
|
|
if (isInt( doubleValue )) {
|
|
auto& targetProperty = m_intGridProperties.getOrCreateProperty( targetArray );
|
|
int intValue = static_cast<int>( doubleValue + 0.5 );
|
|
targetProperty.maskedSet( intValue , mask);
|
|
} else
|
|
throw std::invalid_argument("Fatal error processing EQUALREG keyword - expected integer value for: " + targetArray);
|
|
}
|
|
}
|
|
else if (m_doubleGridProperties.supportsKeyword( targetArray )) {
|
|
if (enabledTypes & DoubleProperties) {
|
|
auto& targetProperty = m_doubleGridProperties.getOrCreateProperty( targetArray );
|
|
|
|
const std::string& dimensionString = targetProperty.getDimensionString();
|
|
double SIValue = doubleValue * getSIScaling( dimensionString );
|
|
|
|
targetProperty.maskedSet( SIValue , mask);
|
|
}
|
|
}
|
|
else {
|
|
throw std::invalid_argument("Fatal error processing EQUALREG keyword - invalid/undefined keyword: " + targetArray);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Eclipse3DProperties::handleADDREGKeyword( const DeckKeyword& deckKeyword, int enabledTypes) {
|
|
for( const auto& record : deckKeyword ) {
|
|
const std::string& targetArray = record.getItem("ARRAY").get< std::string >(0);
|
|
|
|
if (!supportsGridProperty( targetArray , IntProperties + DoubleProperties))
|
|
throw std::invalid_argument("Fatal error processing ADDREG keyword - invalid/undefined keyword: " + targetArray);
|
|
|
|
if (supportsGridProperty( targetArray , enabledTypes)) {
|
|
double doubleValue = record.getItem("SHIFT").get< double >(0);
|
|
int regionValue = record.getItem("REGION_NUMBER").get< int >(0);
|
|
auto& regionProperty = getRegion( record.getItem("REGION_NAME") );
|
|
std::vector<bool> mask;
|
|
|
|
regionProperty.initMask( regionValue , mask);
|
|
|
|
if (m_intGridProperties.hasKeyword( targetArray )) {
|
|
if (enabledTypes & IntProperties) {
|
|
if (isInt( doubleValue )) {
|
|
GridProperty<int>& targetProperty = m_intGridProperties.getKeyword(targetArray);
|
|
int intValue = static_cast<int>( doubleValue + 0.5 );
|
|
targetProperty.maskedAdd( intValue , mask);
|
|
} else
|
|
throw std::invalid_argument("Fatal error processing ADDREG keyword - expected integer value for: " + targetArray);
|
|
}
|
|
}
|
|
else if (m_doubleGridProperties.hasKeyword( targetArray )) {
|
|
if (enabledTypes & DoubleProperties) {
|
|
GridProperty<double>& targetProperty = m_doubleGridProperties.getKeyword(targetArray);
|
|
|
|
const std::string& dimensionString = targetProperty.getDimensionString();
|
|
double SIValue = doubleValue * getSIScaling( dimensionString );
|
|
|
|
targetProperty.maskedAdd( SIValue , mask);
|
|
}
|
|
}
|
|
else {
|
|
throw std::invalid_argument("Fatal error processing ADDREG keyword - invalid/undefined keyword: " + targetArray);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Eclipse3DProperties::handleMULTIREGKeyword( const DeckKeyword& deckKeyword, int enabledTypes) {
|
|
for( const auto& record : deckKeyword ) {
|
|
const std::string& targetArray = record.getItem("ARRAY").get< std::string >(0);
|
|
|
|
if (!supportsGridProperty( targetArray , IntProperties + DoubleProperties))
|
|
throw std::invalid_argument("Fatal error processing MULTIREG keyword - invalid/undefined keyword: " + targetArray);
|
|
|
|
if (supportsGridProperty( targetArray , enabledTypes)) {
|
|
double doubleValue = record.getItem("FACTOR").get< double >(0);
|
|
int regionValue = record.getItem("REGION_NUMBER").get< int >(0);
|
|
auto& regionProperty = getRegion( record.getItem("REGION_NAME") );
|
|
std::vector<bool> mask;
|
|
|
|
regionProperty.initMask( regionValue , mask);
|
|
|
|
if (enabledTypes & IntProperties) {
|
|
if (isInt( doubleValue )) {
|
|
auto& targetProperty = m_intGridProperties.getOrCreateProperty( targetArray );
|
|
int intValue = static_cast<int>( doubleValue + 0.5 );
|
|
|
|
targetProperty.maskedMultiply( intValue , mask);
|
|
} else
|
|
throw std::invalid_argument(
|
|
"Fatal error processing MULTIREG keyword - expected"
|
|
" integer value for: " + targetArray);
|
|
}
|
|
if (enabledTypes & DoubleProperties) {
|
|
auto& targetProperty = m_doubleGridProperties.getOrCreateProperty(targetArray);
|
|
targetProperty.maskedMultiply( doubleValue , mask);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Eclipse3DProperties::handleCOPYREGKeyword( const DeckKeyword& deckKeyword, int enabledTypes) {
|
|
for( const auto& record : deckKeyword ) {
|
|
const std::string& srcArray = record.getItem("ARRAY").get< std::string >(0);
|
|
const std::string& targetArray = record.getItem("TARGET_ARRAY").get< std::string >(0);
|
|
|
|
if (!supportsGridProperty( targetArray , IntProperties + DoubleProperties))
|
|
throw std::invalid_argument("Fatal error processing MULTIREG keyword - invalid/undefined keyword: " + targetArray);
|
|
|
|
if (!supportsGridProperty( srcArray , IntProperties + DoubleProperties))
|
|
throw std::invalid_argument("Fatal error processing MULTIREG keyword - invalid/undefined keyword: " + srcArray);
|
|
|
|
if (supportsGridProperty( srcArray , enabledTypes))
|
|
{
|
|
int regionValue = record.getItem("REGION_NUMBER").get< int >(0);
|
|
auto& regionProperty = getRegion( record.getItem("REGION_NAME") );
|
|
std::vector<bool> mask;
|
|
|
|
regionProperty.initMask( regionValue , mask );
|
|
|
|
if (m_intGridProperties.hasKeyword( srcArray )) {
|
|
auto& srcProperty = m_intGridProperties.getInitializedKeyword( srcArray );
|
|
if (supportsGridProperty( targetArray , IntProperties)) {
|
|
GridProperty<int>& targetProperty = m_intGridProperties.getOrCreateProperty( targetArray );
|
|
targetProperty.maskedCopy( srcProperty , mask );
|
|
} else
|
|
throw std::invalid_argument("Fatal error processing COPYREG keyword.");
|
|
} else if (m_doubleGridProperties.hasKeyword( srcArray )) {
|
|
const GridProperty<double>& srcProperty = m_doubleGridProperties.getInitializedKeyword( srcArray );
|
|
if (supportsGridProperty( targetArray , DoubleProperties)) {
|
|
auto& targetProperty = m_doubleGridProperties.getOrCreateProperty( targetArray );
|
|
targetProperty.maskedCopy( srcProperty , mask );
|
|
}
|
|
}
|
|
else {
|
|
throw std::invalid_argument("Fatal error processing COPYREG keyword - invalid/undefined keyword: " + targetArray);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Eclipse3DProperties::handleMULTIPLYKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager, int enabledTypes) {
|
|
for( const auto& record : deckKeyword ) {
|
|
const std::string& field = record.getItem("field").get< std::string >(0);
|
|
double scaleFactor = record.getItem("factor").get< double >(0);
|
|
|
|
setKeywordBox(deckKeyword, record, boxManager);
|
|
|
|
if (m_intGridProperties.hasKeyword( field )) {
|
|
if (enabledTypes & IntProperties) {
|
|
int intFactor = static_cast<int>(scaleFactor);
|
|
GridProperty<int>& property = m_intGridProperties.getKeyword( field );
|
|
property.scale( intFactor , *boxManager.getActiveBox() );
|
|
}
|
|
} else if (m_doubleGridProperties.hasKeyword( field )) {
|
|
if (enabledTypes & DoubleProperties) {
|
|
GridProperty<double>& property = m_doubleGridProperties.getKeyword( field );
|
|
property.scale( scaleFactor , *boxManager.getActiveBox() );
|
|
}
|
|
} else if (!m_intGridProperties.supportsKeyword(field) &&
|
|
!m_doubleGridProperties.supportsKeyword(field))
|
|
throw std::invalid_argument("Fatal error processing MULTIPLY keyword. Tried to multiply not defined keyword " + field);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
The fine print of the manual says the ADD keyword should support
|
|
some state dependent semantics regarding endpoint scaling arrays
|
|
in the PROPS section. That is not supported.
|
|
*/
|
|
void Eclipse3DProperties::handleADDKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager, int enabledTypes) {
|
|
for( const auto& record : deckKeyword ) {
|
|
const std::string& field = record.getItem("field").get< std::string >(0);
|
|
double shiftValue = record.getItem("shift").get< double >(0);
|
|
|
|
setKeywordBox(deckKeyword, record, boxManager);
|
|
|
|
if (m_intGridProperties.hasKeyword( field )) {
|
|
if (enabledTypes & IntProperties) {
|
|
int intShift = static_cast<int>(shiftValue);
|
|
GridProperty<int>& property = m_intGridProperties.getKeyword( field );
|
|
|
|
property.add( intShift , *boxManager.getActiveBox() );
|
|
}
|
|
} else if (m_doubleGridProperties.hasKeyword( field )) {
|
|
if (enabledTypes & DoubleProperties) {
|
|
GridProperty<double>& property = m_doubleGridProperties.getKeyword( field );
|
|
|
|
double siShiftValue = shiftValue * getSIScaling(property.getDimensionString());
|
|
property.add(siShiftValue , *boxManager.getActiveBox() );
|
|
}
|
|
} else if (!m_intGridProperties.supportsKeyword(field) &&
|
|
!m_doubleGridProperties.supportsKeyword(field))
|
|
throw std::invalid_argument("Fatal error processing ADD keyword. Tried to shift not defined keyword " + field);
|
|
}
|
|
}
|
|
|
|
|
|
void Eclipse3DProperties::handleEQUALSKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager, int enabledTypes) {
|
|
for( const auto& record : deckKeyword ) {
|
|
const std::string& field = record.getItem("field").get< std::string >(0);
|
|
double value = record.getItem("value").get< double >(0);
|
|
|
|
setKeywordBox(deckKeyword, record, boxManager);
|
|
|
|
if (m_intGridProperties.supportsKeyword( field )) {
|
|
if (enabledTypes & IntProperties) {
|
|
int intValue = static_cast<int>(value);
|
|
GridProperty<int>& property = m_intGridProperties.getOrCreateProperty( field );
|
|
|
|
property.setScalar( intValue , *boxManager.getActiveBox() );
|
|
}
|
|
} else if (m_doubleGridProperties.supportsKeyword( field )) {
|
|
|
|
if (enabledTypes & DoubleProperties) {
|
|
GridProperty<double>& property = m_doubleGridProperties.getOrCreateProperty( field );
|
|
|
|
double siValue = value * getSIScaling(property.getKeywordInfo().getDimensionString());
|
|
property.setScalar( siValue , *boxManager.getActiveBox() );
|
|
}
|
|
} else
|
|
throw std::invalid_argument("Fatal error processing EQUALS keyword. Tried to set not defined keyword " + field);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Eclipse3DProperties::handleCOPYKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager, int enabledTypes) {
|
|
for( const auto& record : deckKeyword ) {
|
|
const std::string& srcField = record.getItem("src").get< std::string >(0);
|
|
const std::string& targetField = record.getItem("target").get< std::string >(0);
|
|
|
|
setKeywordBox(deckKeyword, record, boxManager);
|
|
|
|
if (m_intGridProperties.hasKeyword( srcField )) {
|
|
if (enabledTypes & IntProperties)
|
|
m_intGridProperties.copyKeyword( srcField , targetField , *boxManager.getActiveBox() );
|
|
}
|
|
else if (m_doubleGridProperties.hasKeyword( srcField )) {
|
|
if (enabledTypes & DoubleProperties)
|
|
m_doubleGridProperties.copyKeyword( srcField , targetField , *boxManager.getActiveBox() );
|
|
}
|
|
else
|
|
if (!m_intGridProperties.supportsKeyword(srcField) &&
|
|
!m_doubleGridProperties.supportsKeyword(srcField))
|
|
throw std::invalid_argument("Fatal error processing COPY keyword."
|
|
" Tried to copy from not defined keyword " + srcField);
|
|
}
|
|
}
|
|
|
|
// static member function
|
|
void Eclipse3DProperties::setKeywordBox( const DeckKeyword& deckKeyword,
|
|
const DeckRecord& deckRecord,
|
|
BoxManager& boxManager) {
|
|
const auto& I1Item = deckRecord.getItem("I1");
|
|
const auto& I2Item = deckRecord.getItem("I2");
|
|
const auto& J1Item = deckRecord.getItem("J1");
|
|
const auto& J2Item = deckRecord.getItem("J2");
|
|
const auto& K1Item = deckRecord.getItem("K1");
|
|
const auto& K2Item = deckRecord.getItem("K2");
|
|
|
|
size_t setCount = 0;
|
|
|
|
if (!I1Item.defaultApplied(0))
|
|
setCount++;
|
|
|
|
if (!I2Item.defaultApplied(0))
|
|
setCount++;
|
|
|
|
if (!J1Item.defaultApplied(0))
|
|
setCount++;
|
|
|
|
if (!J2Item.defaultApplied(0))
|
|
setCount++;
|
|
|
|
if (!K1Item.defaultApplied(0))
|
|
setCount++;
|
|
|
|
if (!K2Item.defaultApplied(0))
|
|
setCount++;
|
|
|
|
if (setCount == 6) {
|
|
boxManager.setKeywordBox( I1Item.get< int >(0) - 1,
|
|
I2Item.get< int >(0) - 1,
|
|
J1Item.get< int >(0) - 1,
|
|
J2Item.get< int >(0) - 1,
|
|
K1Item.get< int >(0) - 1,
|
|
K2Item.get< int >(0) - 1);
|
|
} else if (setCount != 0) {
|
|
std::string msg = "BOX modifiers on keywords must be either "
|
|
"specified completely or not at all. Ignoring.";
|
|
OpmLog::addMessage(Log::MessageType::Error,
|
|
Log::fileMessage(deckKeyword.getFileName(),
|
|
deckKeyword.getLineNumber(),
|
|
msg));
|
|
}
|
|
}
|
|
}
|