Remove old 3D property implementation

This commit is contained in:
Joakim Hove 2020-01-19 22:39:24 +01:00
parent 1132857324
commit 691296f91a
41 changed files with 7 additions and 6116 deletions

View File

@ -54,7 +54,6 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/EclipseState/Aquifetp.cpp
src/opm/parser/eclipse/EclipseState/Aquancon.cpp
src/opm/parser/eclipse/EclipseState/checkDeck.cpp
src/opm/parser/eclipse/EclipseState/Eclipse3DProperties.cpp
src/opm/parser/eclipse/EclipseState/EclipseConfig.cpp
src/opm/parser/eclipse/EclipseState/EclipseState.cpp
src/opm/parser/eclipse/EclipseState/EndpointScaling.cpp
@ -69,8 +68,6 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/EclipseState/Grid/Fault.cpp
src/opm/parser/eclipse/EclipseState/Grid/FaultFace.cpp
src/opm/parser/eclipse/EclipseState/Grid/GridDims.cpp
src/opm/parser/eclipse/EclipseState/Grid/GridProperties.cpp
src/opm/parser/eclipse/EclipseState/Grid/GridProperty.cpp
src/opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.cpp
src/opm/parser/eclipse/EclipseState/Grid/NNC.cpp
src/opm/parser/eclipse/EclipseState/Grid/Operate.cpp
@ -193,7 +190,6 @@ if(ENABLE_ECL_INPUT)
python/cxx/deck.cpp
python/cxx/deck_keyword.cpp
python/cxx/eclipse_io.cpp
python/cxx/eclipse_3d_properties.cpp
python/cxx/field_props.cpp
python/cxx/eclipse_config.cpp
python/cxx/eclipse_grid.cpp
@ -297,7 +293,6 @@ if(ENABLE_ECL_INPUT)
tests/parser/DeckTests.cpp
tests/parser/DynamicStateTests.cpp
tests/parser/DynamicVectorTests.cpp
tests/parser/Eclipse3DPropertiesTests.cpp
tests/parser/EclipseGridTests.cpp
tests/parser/EmbeddedPython.cpp
tests/parser/EqualRegTests.cpp
@ -308,7 +303,6 @@ if(ENABLE_ECL_INPUT)
tests/parser/FoamTests.cpp
tests/parser/FunctionalTests.cpp
tests/parser/GeomodifierTests.cpp
tests/parser/GridPropertyTests.cpp
tests/parser/GroupTests.cpp
tests/parser/InitConfigTest.cpp
tests/parser/IOConfigTests.cpp
@ -321,7 +315,6 @@ if(ENABLE_ECL_INPUT)
tests/parser/ParseContext_EXIT1.cpp
tests/parser/ParseDATAWithDefault.cpp
tests/parser/PYACTION.cpp
tests/parser/PORVTests.cpp
tests/parser/RawKeywordTests.cpp
tests/parser/ResinsightTest.cpp
tests/parser/RestartConfigTests.cpp
@ -329,7 +322,6 @@ if(ENABLE_ECL_INPUT)
tests/parser/RockTableTests.cpp
tests/parser/RunspecTests.cpp
tests/parser/SaltTableTests.cpp
tests/parser/SatfuncPropertyInitializersTests.cpp
tests/parser/ScheduleTests.cpp
tests/parser/SectionTests.cpp
tests/parser/SimpleTableTests.cpp
@ -518,7 +510,6 @@ if(ENABLE_ECL_INPUT)
opm/parser/eclipse/EclipseState/Edit/EDITNNC.hpp
opm/parser/eclipse/EclipseState/Grid/GridDims.hpp
opm/parser/eclipse/EclipseState/Grid/TransMult.hpp
opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp
opm/parser/eclipse/EclipseState/Grid/PinchMode.hpp
opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp
opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp
@ -526,14 +517,12 @@ if(ENABLE_ECL_INPUT)
opm/parser/eclipse/EclipseState/Grid/Fault.hpp
opm/parser/eclipse/EclipseState/Grid/Box.hpp
opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp
opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp
opm/parser/eclipse/EclipseState/Grid/FaultFace.hpp
opm/parser/eclipse/EclipseState/Grid/NNC.hpp
opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp
opm/parser/eclipse/EclipseState/Grid/BoxManager.hpp
opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp
opm/parser/eclipse/EclipseState/Grid/MinpvMode.hpp
opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp
opm/parser/eclipse/EclipseState/EndpointScaling.hpp
opm/parser/eclipse/EclipseState/Tables/SimpleTable.hpp
opm/parser/eclipse/EclipseState/Tables/PolyInjTable.hpp

View File

@ -1,112 +0,0 @@
/*
Copyright 2016 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_PROPERTIES_HPP
#define OPM_ECLIPSE_PROPERTIES_HPP
#include <vector>
#include <string>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
namespace Opm {
class Box;
class BoxManager;
class Deck;
class DeckItem;
class DeckKeyword;
class DeckRecord;
class EclipseGrid;
class DeckSection;
class TableManager;
class UnitSystem;
/// Class representing properties on 3D grid for use in EclipseState.
class Eclipse3DProperties
{
public:
Eclipse3DProperties() = default;
Eclipse3DProperties(const Deck& deck,
const TableManager& tableManager,
const EclipseGrid& eclipseGrid);
Eclipse3DProperties( UnitSystem unit_system,
const TableManager& tableManager,
const EclipseGrid& eclipseGrid);
std::vector< int > getRegions( const std::string& keyword ) const;
std::string getDefaultRegionKeyword() const;
const GridProperty<int>& getIntGridProperty ( const std::string& keyword ) const;
const GridProperty<double>& getDoubleGridProperty ( const std::string& keyword ) const;
const GridProperties<int>& getIntProperties() const;
const GridProperties<double>& getDoubleProperties() const;
bool hasDeckIntGridProperty(const std::string& keyword) const;
bool hasDeckDoubleGridProperty(const std::string& keyword) const;
bool supportsGridProperty(const std::string& keyword) const;
private:
const GridProperty<int>& getRegion(const DeckItem& regionItem) const;
void processGridProperties(const Deck& deck,
const EclipseGrid& eclipseGrid);
void scanSection(const DeckSection& section,
const EclipseGrid& eclipseGrid,
bool edit_section);
void handleADDKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleBOXKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleCOPYKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleENDBOXKeyword( BoxManager& boxManager);
void handleEQUALSKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleMAXVALUEKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleMINVALUEKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleMULTIPLYKeyword(const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleADDREGKeyword( const DeckKeyword& deckKeyword );
void handleCOPYREGKeyword( const DeckKeyword& deckKeyword );
void handleEQUALREGKeyword(const DeckKeyword& deckKeyword );
void handleMULTIREGKeyword(const DeckKeyword& deckKeyword );
void handleOPERATEKeyword( const DeckKeyword& deckKeyword, BoxManager& boxManager);
void handleOPERATERKeyword( const DeckKeyword& deckKeyword);
void loadGridPropertyFromDeckKeyword(const Box& inputBox,
const DeckKeyword& deckKeyword,
bool edity_section);
void adjustSOGCRwithSWL();
std::string m_defaultRegion;
UnitSystem m_deckUnitSystem;
GridProperties<int> m_intGridProperties;
GridProperties<double> m_doubleGridProperties;
};
}
#endif // OPM_ECLIPSE_PROPERTIES_HPP

View File

@ -25,7 +25,6 @@
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Edit/EDITNNC.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>

View File

@ -1,208 +0,0 @@
/*
Copyright 2014 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 ECLIPSE_GRIDPROPERTIES_HPP_
#define ECLIPSE_GRIDPROPERTIES_HPP_
#include <set>
#include <string>
#include <vector>
#include <unordered_map>
#include <map>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/BoxManager.hpp>
#include <opm/parser/eclipse/Units/Dimension.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
/*
This class implements a container (std::unordered_map<std::string ,
Gridproperty<T>>) of Gridproperties. Usage is as follows:
1. Instantiate the class; passing the number of grid cells and the
supported keywords as a list of strings to the constructor.
2. Query the container with the supportsKeyword() and hasKeyword()
methods.
3. When you ask the container to get a keyword with the
getKeyword() method it will automatically create a new
GridProperty object if the container does not have this
property.
*/
namespace Opm {
class Eclipse3DProperties;
template <typename T>
class GridProperties {
public:
typedef typename GridProperty<T>::SupportedKeywordInfo SupportedKeywordInfo;
struct const_iterator;
GridProperties() = default;
GridProperties(const EclipseGrid& eclipseGrid,
const UnitSystem* deckUnitSystem,
std::vector< SupportedKeywordInfo >&& supportedKeywords);
explicit GridProperties(const EclipseGrid& eclipseGrid,
std::vector< SupportedKeywordInfo >&& supportedKeywords);
T convertInputValue( const GridProperty<T>& property , double doubleValue) const;
T convertInputValue( double doubleValue ) const;
bool supportsKeyword(const std::string& keyword) const;
bool isDefaultInitializable(const std::string& keyword) const;
/*
The difference between hasKeyword() and hasDeckKeyword( ) is
that hasDeckKeyword( ) will return false for keywords which
have only been auto created - and are not explicitly
mentioned in the deck.
*/
bool hasKeyword(const std::string& keyword) const;
bool hasDeckKeyword(const std::string& keyword) const;
size_t size() const;
void assertKeyword(const std::string& keyword) const;
/*
The getKeyword() method will auto create a keyword if
requested, the getDeckKeyword() method will onyl return a
keyword if it has been explicitly mentioned in the deck. The
getDeckKeyword( ) method will throw an exception instead of
auto creating the keyword.
*/
const GridProperty<T>& getKeyword(const std::string& keyword) const;
const GridProperty<T>& getDeckKeyword(const std::string& keyword) const;
bool addKeyword(const std::string& keywordName);
void copyKeyword(const std::string& srcField ,
const std::string& targetField ,
const Box& inputBox);
template <class Keyword>
bool hasKeyword() const {
return hasKeyword( Keyword::keywordName );
}
template <class Keyword>
const GridProperty<T>& getKeyword() const {
return getKeyword( Keyword::keywordName );
}
template <class Keyword>
const GridProperty<T>& getInitializedKeyword() const {
return getInitializedKeyword( Keyword::keywordName );
}
GridProperty<T>& getOrCreateProperty(const std::string& name);
/**
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 handleADDRecord( const DeckRecord& record, BoxManager& boxManager);
void handleMAXVALUERecord( const DeckRecord& record, BoxManager& boxManager);
void handleMINVALUERecord( const DeckRecord& record, BoxManager& boxManager);
void handleMULTIPLYRecord( const DeckRecord& record, BoxManager& boxManager);
void handleCOPYRecord( const DeckRecord& record, BoxManager& boxManager);
void handleEQUALSRecord( const DeckRecord& record, BoxManager& boxManager);
void handleOPERATERecord( const DeckRecord& record , BoxManager& boxManager);
void handleEQUALREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleADDREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleMULTIREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleCOPYREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty );
void handleOPERATERRecord( const DeckRecord& record , const GridProperty<int>& regionProperty );
/*
Iterators over initialized properties. The overloaded
operator*() opens the pair which comes natively from the
std::map iterator.
*/
const_iterator begin() const {
return const_iterator( m_properties.begin() );
}
const_iterator end() const {
return const_iterator( m_properties.end() );
}
/*
* storage MUST ensure that std::addressof(storage.at( key )) is valid.
*/
typedef typename std::map<std::string , GridProperty<T> > storage;
typedef typename storage::const_iterator storage_iterator;
struct const_iterator : public storage_iterator {
const_iterator( storage_iterator iter ) : storage_iterator( iter ) { }
const GridProperty<T>& operator*( ) {
const auto& pair = storage_iterator::operator*( );
return pair.second;
}
};
private:
/// this method exists for (friend) Eclipse3DProperties to be allowed initializing PORV and ACTNUM keyword
void postAddKeyword(const std::string& name,
const T defaultValue,
std::function< void( const std::vector<bool>& defaulted, std::vector< T >& ) > postProcessor,
const std::string& dimString,
const bool defaultInitializable );
void postAddKeyword(const std::string& name,
std::function< std::vector< T >(size_t) > initProcessor,
const std::string& dimString);
GridProperty<T>& getKeyword(const std::string& keyword);
bool addAutoGeneratedKeyword_(const std::string& keywordName) const;
void insertKeyword(const SupportedKeywordInfo& supportedKeyword) const;
bool isAutoGenerated_(const std::string& keyword) const;
friend class Eclipse3DProperties; // needed for PORV keyword entanglement
size_t nx = 0;
size_t ny = 0;
size_t nz = 0;
const UnitSystem * m_deckUnitSystem = nullptr;
mutable std::unordered_map<std::string, SupportedKeywordInfo> m_supportedKeywords;
mutable storage m_properties;
mutable std::set<std::string> m_autoGeneratedProperties;
};
}
#endif // ECLIPSE_GRIDPROPERTIES_HPP_

View File

@ -1,329 +0,0 @@
/*
Copyright 2014 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 ECLIPSE_GRIDPROPERTY_HPP_
#define ECLIPSE_GRIDPROPERTY_HPP_
#include <functional>
#include <string>
#include <utility>
#include <vector>
/*
This class implemenents a class representing properties which are
define over an ECLIPSE grid, i.e. with one value for each logical
cartesian cell in the grid.
*/
namespace Opm {
class Box;
class DeckItem;
class DeckKeyword;
class EclipseGrid;
class TableManager;
template< typename > class GridProperties;
template< typename T >
class GridPropertySupportedKeywordInfo {
public:
GridPropertySupportedKeywordInfo() = default;
using init = std::function< std::vector< T >( size_t ) >;
/**
* Property post-processor function type.
*
* Defaulted flag (one element for each Cartesian cell/data element)
* identifies whether the property value was defaulted in that cell
* (true) or assigned through a deck mechanism (false).
*/
using post = std::function<
void(const std::vector<bool>& defaulted,
std::vector< T >&)
>;
GridPropertySupportedKeywordInfo(
const std::string& name,
init initializer,
post postProcessor,
const std::string& dimString,
bool m_defaultInitializable = false );
GridPropertySupportedKeywordInfo(
const std::string& name,
init initializer,
const std::string& dimString,
bool m_defaultInitializable = false );
/* this is a convenience constructor which can be used if the default
* value for the grid property is just a constant.
*/
GridPropertySupportedKeywordInfo(
const std::string& name,
const T defaultValue,
const std::string& dimString,
bool m_defaultInitializable = false );
GridPropertySupportedKeywordInfo(
const std::string& name,
const T defaultValue,
post postProcessor,
const std::string& dimString,
bool m_defaultInitializable = false );
const std::string& getKeywordName() const;
const std::string& getDimensionString() const;
const init& initializer() const;
const post& postProcessor() const;
bool isDefaultInitializable() const;
/**
* Replace post-processor after object is created.
*
* XXX: This is essentially a hack, but it enables using
* post-processors that can't be created at construction time.
*
* One example of this use case is the post-processor for SOGCR in
* a run using Family I (SWOF/SGOF) saturation function tables.
* The SGOF table is implicitly defined in terms of the connate
* water saturation, and the critical oil-in-gas saturation
* post-processor needs to take this fact into account. That, in
* turn, means that the post-processor must have a way of
* accessing SWL data (defaulted or assigned) which means that the
* post-processor needs to be aware of the collection of grid
* properties, not just a single property in isolation.
*
* In our current system, the GridPropertySupportedKeywordInfo
* objects are constructor arguments to that collection and so
* have no way of referring to the collection itself. This method
* provides a mechanism for creating the post-processor once the
* collection is formed.
*
* \param[in] processor New post-processor function. Replaces
* existing post-processor, typically created at construction
* time.
*/
void setPostProcessor(post processor)
{
this->m_postProcessor = std::move(processor);
}
private:
std::string m_keywordName;
init m_initializer;
post m_postProcessor;
std::string m_dimensionString;
bool m_defaultInitializable;
};
template< typename T >
class GridProperty {
public:
typedef GridPropertySupportedKeywordInfo<T> SupportedKeywordInfo;
GridProperty( size_t nx, size_t ny, size_t nz, const SupportedKeywordInfo& kwInfo );
size_t getCartesianSize() const;
size_t getNX() const;
size_t getNY() const;
size_t getNZ() const;
const std::vector<bool>& wasDefaulted() const;
const std::vector< T >& getData() const;
void assignData(std::vector<T>&& data);
void assignData(const std::vector<T>& data);
bool containsNaN() const;
const std::string& getDimensionString() const;
void multiplyWith( const GridProperty<T>& );
void multiplyValueAtIndex( size_t index, T factor );
void maskedSet( T value, const std::vector< bool >& mask );
void maskedMultiply( T value, const std::vector< bool >& mask );
void maskedAdd( T value, const std::vector< bool >& mask );
void maskedCopy( const GridProperty< T >& other, const std::vector< bool >& mask );
void initMask( T value, std::vector<bool>& mask ) const;
/**
Due to the convention where it is only necessary to supply the
top layer of the petrophysical properties we can unfortunately
not enforce that the number of elements elements in the
DeckKeyword equals nx*ny*nz.
*/
void loadFromDeckKeyword( const DeckKeyword& , bool);
void loadFromDeckKeyword( const Box&, const DeckKeyword& , bool);
void copyFrom( const GridProperty< T >&, const Box& );
void scale( T scaleFactor, const Box& );
void maxvalue( T value, const Box& );
void minvalue( T value, const Box& );
void add( T shiftValue, const Box& );
void setScalar( T value, const Box& );
const std::string& getKeywordName() const;
const SupportedKeywordInfo& getKeywordInfo() const;
/**
Will check that all elements in the property are in the closed
interval [min,max].
*/
void checkLimits( T min, T max ) const;
/*
The runPostProcessor() method is public; and it is no harm in
calling it from arbitrary locations. But the intention is that
should only be called from the Eclipse3DProperties class
assembling the properties.
*/
void runPostProcessor();
/*
Will scan through the roperty and return a vector of all the
indices where the property value agrees with the input value.
*/
std::vector<size_t> indexEqual(T value) const;
/*
Will run through all the cells in the activeMap and return a
list of the elements where the property value agrees with the
input value. The values returned will be in the space
[0,nactive) - i.e. 'active' indices.
*/
std::vector<size_t> cellsEqual(T value , const std::vector<int>& activeMap) const;
/*
If active == true the method will get the activeMap from the
grid and call the cellsEqual( T , std::vector<int>&) overload,
otherwise it will return indexEqual( value );
*/
std::vector<size_t> cellsEqual(T value, const EclipseGrid& grid, bool active = true) const;
/*
Will return a std::vector<T> of the data in the active cells.
*/
std::vector<T> compressedCopy( const EclipseGrid& grid) const;
/*
The grid properties like PORO and SATNUM can be created in essentially two
ways; either they can be explicitly assigned in the deck as:
PORO
1000*0.15 /
or they can be created indirectly through various mathematical operations
like:
MULTIPLY
TRANX 0.20 /
/
The deckAssigned() property is used so that we can differentiate between
properties which have been explicitly assigned/loaded from the deck, and
those where the default construction has been invoked. This functionality
is implemented purely to support the TRAN? keywords. The transmissibility
is be default calculated by the simulator code, but the TRAN keywords can
be used in the deck to manipulate this calculation in two different ways:
1. TRAN explicitly assigned in GRID section
===========================================
...
TRANX
1000*0.026 /
COPY
'TRANX' 'TRANY' /
/
In this case the simulator should detect that the input deck has TRANX
specified and just use the input values from the deck. This is the
normal handling of keywords, and agrees with e.g. PERMX and PORO. This
also applies when the COPY keyword has been used, as in the case of
'TRANY' above.
2. TRAN modifier present in EDIT section
========================================
The scenario here is that there is no mention of TRANX in the GRID
section, however the EDIT section contains modifiers like this:
MULTIPLY
TRANX 0.25 /
I.e. we request the TRANX values to be reduced with a factor of 0.25. In
this case the simulator should still calculate transmissibility according
to it's normal algorithm, and then subsequently scale that result with a
factor of 0.25.
In this case the input layer needs to autocreate a TRANX keyword,
defaulted to 1.0 and then scale that to 0.25.
Now - the important point is that when doing transmissibility calculations
the simulator must be able to distinguish between cases 1 and 2,
specifically whether the TRANX keyword should be interpreted as absolute
values(case 1) or as a multiplier(case 2). That is the purpose of the
deckAssigned() property. Pseudo code for the transmissibility calculations
in the simulator could be:
const auto& input_tranx = properties.getKeyword("TRANX");
if (input_tranx.deckAssigned()) {
// set simulator internal transmissibilities to values from input_tranx
tranx = input_tranx;
} else {
// Calculate transmissibilities according to normal simulator algorithm
...
...
// Scale transmissibilities with scale factor from input_tranx
tranx *= input_tranx;
}
*/
bool deckAssigned() const;
private:
const DeckItem& getDeckItem( const DeckKeyword& );
void setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem);
void mulDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem);
void setElement(const typename std::vector<T>::size_type i,
const T value,
const bool defaulted = false);
size_t m_nx, m_ny, m_nz;
SupportedKeywordInfo m_kwInfo;
std::vector<T> m_data;
std::vector<bool> m_defaulted;
bool m_hasRunPostProcessor = false;
bool assigned = false;
};
// initialize the TEMPI grid property using the temperature vs depth
// table (stemming from the TEMPVD or the RTEMPVD keyword)
std::vector< double > temperature_lookup( size_t,
const TableManager*,
const EclipseGrid*,
const GridProperties<int>* );
}
#endif

View File

@ -22,183 +22,9 @@
#include <vector>
#include <string>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
namespace Opm {
class EclipseGrid;
class TableManager;
std::vector<double> SGLEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISGLEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SGUEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISGUEndpoint(size_t, const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SWLEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISWLEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SWUEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISWUEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SGCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISGCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SOWCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISOWCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SOGCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISOGCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> SWCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> ISWCREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> PCWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IPCWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> PCGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IPCGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRWREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRWREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KROEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKROEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRORWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRORWEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRORGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRORGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRGEndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> KRGREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
std::vector<double> IKRGREndpoint(size_t,
const TableManager*,
const EclipseGrid*,
GridProperties<int>*);
/************************************************************************/
namespace satfunc {
std::vector<double> SGLEndpoint(const TableManager&,

View File

@ -27,7 +27,6 @@
namespace Opm {
class EclipseGrid;
class Eclipse3DProperties;
class FieldPropsManager;
class WellConnections {
public:
@ -56,7 +55,6 @@ namespace Opm {
const double segDistStart= 0.0,
const double segDistEnd= 0.0,
const bool defaultSatTabId = true);
void loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties);
void loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const FieldPropsManager& field_properties);
using const_iterator = std::vector< Connection >::const_iterator;

View File

@ -1,46 +0,0 @@
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <pybind11/stl.h>
#include "export.hpp"
#include "converters.hpp"
namespace {
py::list getitem( const Eclipse3DProperties& p, const std::string& kw) {
const auto& ip = p.getIntProperties();
if (ip.supportsKeyword(kw) && ip.hasKeyword(kw))
return iterable_to_pylist(p.getIntGridProperty(kw).getData());
const auto& dp = p.getDoubleProperties();
if (dp.supportsKeyword(kw) && dp.hasKeyword(kw))
return iterable_to_pylist(p.getDoubleGridProperty(kw).getData());
throw py::key_error( "no such grid property " + kw );
}
bool contains( const Eclipse3DProperties& p, const std::string& kw) {
return
(p.getIntProperties().supportsKeyword(kw) &&
p.getIntProperties().hasKeyword(kw))
||
(p.getDoubleProperties().supportsKeyword(kw) &&
p.getDoubleProperties().hasKeyword(kw))
;
}
std::vector<int> regions( const Eclipse3DProperties& p, const std::string& kw) {
return p.getRegions(kw);
}
}
void python::common::export_Eclipse3DProperties(py::module& module) {
py::class_< Eclipse3DProperties >( module, "Eclipse3DProperties")
.def( "getRegions", &regions )
.def( "__contains__", &contains )
.def( "__getitem__", &getitem )
;
}

View File

@ -12,7 +12,6 @@ void python::common::export_all(py::module& module) {
export_Group(module);
export_Connection(module);
export_EclipseConfig(module);
export_Eclipse3DProperties(module);
export_FieldProperties(module);
export_EclipseState(module);
export_TableManager(module);

View File

@ -18,7 +18,6 @@ void export_UnitSystem(py::module& module);
void export_Connection(py::module& module);
void export_Deck(py::module& module);
void export_DeckKeyword(py::module& module);
void export_Eclipse3DProperties(py::module& module);
void export_FieldProperties(py::module& module);
void export_EclipseConfig(py::module& module);
void export_EclipseGrid(py::module& module);

View File

@ -40,7 +40,6 @@ ext_modules = [
'cxx/deck.cpp',
'cxx/deck_keyword.cpp',
'cxx/eclipse_io.cpp',
'cxx/eclipse_3d_properties.cpp',
'cxx/field_props.cpp',
'cxx/eclipse_config.cpp',
'cxx/eclipse_grid.cpp',

View File

@ -26,9 +26,7 @@
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/RFTConfig.hpp>

View File

@ -21,8 +21,6 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/output/eclipse/RegionCache.hpp>

View File

@ -24,8 +24,6 @@
#include <opm/common/OpmLog/Location.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/IOConfig/IOConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group.hpp>

View File

@ -33,12 +33,9 @@
#include <opm/output/eclipse/Tables.hpp>
#include <opm/output/eclipse/WriteRestartHelpers.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/EndpointScaling.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,6 @@
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
#include <opm/parser/eclipse/Deck/Deck.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>

View File

@ -1,550 +0,0 @@
/*
Copyright 2016 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 <cmath>
#include <iostream>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/Utility/String.hpp>
#include "setKeywordBox.hpp"
#include "Operate.hpp"
namespace Opm {
/*
Before lookup the keyword strings are uppercased and trailing
space is trimmed.
*/
static std::string normalize(const std::string& keyword) {
std::string kw(keyword.begin() , std::find( keyword.begin() , keyword.end() , ' '));
uppercase( kw , kw );
return kw;
}
template<typename> bool isFipxxx( const std::string& ) { return false; }
template<>
bool isFipxxx< int >(const std::string& keyword) {
// FIPxxxx can be any keyword, e.g. FIPREG or FIPXYZ that has the pattern "FIP.+"
// However, it can not be FIPOWG as that is an actual keyword.
if (keyword.size() < 4 || keyword == "FIPOWG") {
return false;
}
return keyword[0] == 'F' && keyword[1] == 'I' && keyword[2] == 'P';
}
template <>
GridProperties<double>::GridProperties(const EclipseGrid& eclipseGrid,
const UnitSystem* deckUnitSystem,
std::vector< GridProperty<double>::SupportedKeywordInfo >&& supportedKeywords) :
nx( eclipseGrid.getNX() ),
ny( eclipseGrid.getNY() ),
nz( eclipseGrid.getNZ() ),
m_deckUnitSystem( deckUnitSystem )
{
for (auto iter = supportedKeywords.begin(); iter != supportedKeywords.end(); ++iter)
m_supportedKeywords.emplace( iter->getKeywordName(), std::move( *iter ) );
}
template <>
GridProperties<int>::GridProperties(const EclipseGrid& eclipseGrid,
std::vector< GridProperty<int>::SupportedKeywordInfo >&& supportedKeywords) :
nx( eclipseGrid.getNX() ),
ny( eclipseGrid.getNY() ),
nz( eclipseGrid.getNZ() )
{
for (auto iter = supportedKeywords.begin(); iter != supportedKeywords.end(); ++iter)
m_supportedKeywords.emplace( iter->getKeywordName(), std::move( *iter ) );
}
/*
In the case of integer properties we never really do any
transformation, but we have implemented this dummy int
specializations to enable a uniform implementation.
*/
template<>
double GridProperties<double>::convertInputValue(const GridProperty<double>& property, double doubleValue) const {
const std::string& dimensionString = property.getDimensionString( );
return m_deckUnitSystem->getDimension(dimensionString).getSIScaling() * doubleValue;
}
template<>
double GridProperties<double>::convertInputValue( double doubleValue) const {
return doubleValue;
}
template<>
int GridProperties<int>::convertInputValue(double doubleValue) const {
if (std::fabs( std::nearbyint( doubleValue ) - doubleValue ) < 1e-6)
return static_cast<int>( doubleValue );
else
throw std::invalid_argument("Expected integer argument - got: " + std::to_string( doubleValue ));
}
template<>
int GridProperties<int>::convertInputValue(const GridProperty<int>& /* property */, double doubleValue) const {
return convertInputValue(doubleValue);
}
template< typename T >
bool GridProperties<T>::supportsKeyword(const std::string& keyword) const {
const std::string kw = normalize(keyword);
return m_supportedKeywords.count( kw ) > 0 || isFipxxx<T>(kw);
}
template< typename T >
bool GridProperties<T>::hasKeyword(const std::string& keyword) const {
const std::string kw = normalize( keyword );
const auto cnt = m_properties.count( kw );
const bool positive = cnt > 0;
return positive;
}
template< typename T >
bool GridProperties<T>::hasDeckKeyword(const std::string& keyword) const {
const std::string kw = normalize( keyword );
const auto cnt = m_properties.count( kw );
const bool positive = cnt > 0;
return positive && !isAutoGenerated_( kw );
}
template< typename T >
size_t GridProperties<T>::size() const {
return m_properties.size();
}
template< typename T >
void GridProperties<T>::assertKeyword(const std::string& keyword) const {
const std::string kw = normalize(keyword);
if ( !( hasKeyword( kw ) || isDefaultInitializable( kw ) || isFipxxx<T>( kw ) ) )
throw std::invalid_argument("Keyword: " + keyword +
" is not yet defined and could not be default initialized");
if (m_properties.count( kw ) == 0)
addAutoGeneratedKeyword_(kw);
GridProperty<T>& property = m_properties.at( kw );
property.runPostProcessor( );
}
template< typename T >
const GridProperty<T>& GridProperties<T>::getKeyword(const std::string& keyword) const {
assertKeyword( keyword );
return m_properties.at( keyword );
}
template< typename T >
GridProperty<T>& GridProperties<T>::getKeyword(const std::string& keyword) {
const std::string kw = normalize(keyword);
if (!hasKeyword(kw))
addAutoGeneratedKeyword_(kw);
return m_properties.at( kw );
}
template< typename T >
const GridProperty<T>& GridProperties<T>::getDeckKeyword(const std::string& keyword) const {
const std::string kw = normalize(keyword);
if (hasDeckKeyword(kw))
return m_properties.at( kw );
else {
if (supportsKeyword(kw))
throw std::invalid_argument("Keyword: " + kw + " is supported - but not initialized.");
else
throw std::invalid_argument("Keyword: " + kw + " is not supported.");
}
}
template< typename T >
void GridProperties<T>::insertKeyword(const SupportedKeywordInfo& supportedKeyword) const {
m_properties.emplace( supportedKeyword.getKeywordName(),
GridProperty<T>( this->nx, this->ny , this->nz , supportedKeyword ));
}
template< typename T >
bool GridProperties<T>::addKeyword(const std::string& keywordName) {
if (!supportsKeyword( keywordName ))
throw std::invalid_argument("The keyword: " + keywordName + " is not supported in this container");
if (hasKeyword(keywordName))
return false;
else {
const std::string kw = normalize(keywordName);
// if the property was already added auto generated, we just need to make it
// non-auto generated
if (m_autoGeneratedProperties.count(kw)) {
OpmLog::warning("The keyword "+kw+" has been used to calculate the "
"defaults of another keyword before the first time it was "
"explicitly mentioned in the deck. Maybe you need to change "
"the ordering of your keywords (move "+kw+" to the front?).");
m_autoGeneratedProperties.erase(m_autoGeneratedProperties.find(kw));
return true;
}
if (isFipxxx<T>(kw))
m_supportedKeywords.emplace(kw, SupportedKeywordInfo( kw , 1, "1" ));
insertKeyword( m_supportedKeywords.at( kw ) );
return true;
}
}
template< typename T >
void GridProperties<T>::copyKeyword(const std::string& srcField ,
const std::string& targetField ,
const Box& inputBox) {
const auto& src = this->getKeyword( srcField );
auto& target = this->getOrCreateProperty( targetField );
target.copyFrom( src , inputBox );
}
template< typename T >
GridProperty<T>& GridProperties<T>::getOrCreateProperty(const std::string& name) {
if (!hasKeyword(name))
addKeyword(name);
return getKeyword(name);
}
/**
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.
*/
template< typename T >
void GridProperties<T>::handleADDRecord( const DeckRecord& record, BoxManager& boxManager) {
const std::string& field = record.getItem("field").get< std::string >(0);
assertKeyword(field);
GridProperty<T>& property = getKeyword( field );
T shiftValue = convertInputValue( property , record.getItem("shift").get< double >(0) );
setKeywordBox(record, boxManager);
property.add( shiftValue , boxManager.getActiveBox() );
}
template< typename T >
void GridProperties<T>::handleMAXVALUERecord( const DeckRecord& record, BoxManager& boxManager) {
const std::string& field = record.getItem("field").get< std::string >(0);
if (hasKeyword( field )) {
GridProperty<T>& property = getKeyword( field );
T value = convertInputValue( property, record.getItem("value").get< double >(0) );
setKeywordBox(record, boxManager);
property.maxvalue( value , boxManager.getActiveBox() );
} else
throw std::invalid_argument("Fatal error processing MAXVALUE keyword. Tried to limit not defined keyword " + field);
}
template< typename T >
void GridProperties<T>::handleMINVALUERecord( const DeckRecord& record, BoxManager& boxManager) {
const std::string& field = record.getItem("field").get< std::string >(0);
if (hasKeyword( field )) {
GridProperty<T>& property = getKeyword( field );
T value = convertInputValue( property, record.getItem("value").get< double >(0) );
setKeywordBox(record, boxManager);
property.minvalue( value , boxManager.getActiveBox() );
} else
throw std::invalid_argument("Fatal error processing MINVALUE keyword. Tried to limit not defined keyword " + field);
}
template< typename T >
void GridProperties<T>::handleMULTIPLYRecord( const DeckRecord& record, BoxManager& boxManager) {
const std::string& field = record.getItem("field").get< std::string >(0);
assertKeyword(field);
GridProperty<T>& property = getKeyword( field );
T factor = convertInputValue( record.getItem("factor").get< double >(0) );
setKeywordBox(record, boxManager);
property.scale( factor , boxManager.getActiveBox() );
}
template< typename T >
void GridProperties<T>::handleCOPYRecord( const DeckRecord& record, BoxManager& boxManager) {
const std::string& srcField = record.getItem("src").get< std::string >(0);
const std::string& targetField = record.getItem("target").get< std::string >(0);
if (hasKeyword( srcField )) {
setKeywordBox(record, boxManager);
copyKeyword( srcField , targetField , boxManager.getActiveBox() );
} else {
if (!supportsKeyword( srcField))
throw std::invalid_argument("Fatal error processing COPY keyword."
" Tried to copy from not defined keyword " + srcField);
}
}
template< typename T >
void GridProperties<T>::handleEQUALSRecord( const DeckRecord& record, BoxManager& boxManager) {
const std::string& field = record.getItem("field").get< std::string >(0);
double value = record.getItem("value").get< double >(0);
if (supportsKeyword( field )) {
GridProperty<T>& property = getOrCreateProperty( field );
T targetValue = convertInputValue( property , value );
setKeywordBox(record, boxManager);
property.setScalar( targetValue , boxManager.getActiveBox() );
} else
throw std::invalid_argument("Fatal error processing EQUALS keyword. Tried to set not defined keyword " + field);
}
template< typename T >
void GridProperties<T>::handleEQUALREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty ) {
const std::string& targetArray = record.getItem("ARRAY").get< std::string >(0);
if (supportsKeyword( targetArray )) {
GridProperty<T>& targetProperty = getOrCreateProperty( targetArray );
double inputValue = record.getItem("VALUE").get<double>(0);
int regionValue = record.getItem("REGION_NUMBER").get<int>(0);
T targetValue = convertInputValue( targetProperty , inputValue );
std::vector<bool> mask;
regionProperty.initMask( regionValue , mask);
targetProperty.maskedSet( targetValue , mask);
} else
throw std::invalid_argument("Fatal error processing EQUALREG record - invalid/undefined keyword: " + targetArray);
}
template< typename T >
void GridProperties<T>::handleADDREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty ) {
const std::string& targetArray = record.getItem("ARRAY").get< std::string >(0);
assertKeyword(targetArray);
GridProperty<T>& targetProperty = getKeyword( targetArray );
double inputValue = record.getItem("SHIFT").get<double>(0);
int regionValue = record.getItem("REGION_NUMBER").get<int>(0);
T shiftValue = convertInputValue( targetProperty , inputValue );
std::vector<bool> mask;
regionProperty.initMask( regionValue , mask);
targetProperty.maskedAdd( shiftValue , mask);
}
template< typename T >
void GridProperties<T>::handleMULTIREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty ) {
const std::string& targetArray = record.getItem("ARRAY").get< std::string >(0);
assertKeyword( targetArray );
GridProperty<T>& targetProperty = getOrCreateProperty( targetArray );
double inputValue = record.getItem("FACTOR").get<double>(0);
int regionValue = record.getItem("REGION_NUMBER").get<int>(0);
T factor = convertInputValue( inputValue );
std::vector<bool> mask;
regionProperty.initMask( regionValue , mask);
targetProperty.maskedMultiply( factor , mask);
}
template< typename T >
void GridProperties<T>::handleCOPYREGRecord( const DeckRecord& record, const GridProperty<int>& regionProperty ) {
const std::string& srcArray = record.getItem("SRC_ARRAY").get< std::string >(0);
const std::string& targetArray = record.getItem("TARGET_ARRAY").get< std::string >(0);
if (!supportsKeyword( targetArray))
throw std::invalid_argument("Fatal error processing COPYREG record - invalid/undefined keyword: " + targetArray);
if (!hasKeyword( srcArray ))
throw std::invalid_argument("Fatal error processing COPYREG record - invalid/undefined keyword: " + srcArray);
{
int regionValue = record.getItem("REGION_NUMBER").get< int >(0);
std::vector<bool> mask;
GridProperty<T>& targetProperty = getOrCreateProperty( targetArray );
GridProperty<T>& srcProperty = getKeyword( srcArray );
regionProperty.initMask( regionValue , mask);
targetProperty.maskedCopy( srcProperty , mask );
}
}
template <typename T>
void GridProperties<T>::handleOPERATERecord( const DeckRecord& record, BoxManager& boxManager) {
const std::string& srcArray = record.getItem("ARRAY").get< std::string >(0);
const std::string& targetArray = record.getItem("TARGET_ARRAY").get< std::string >(0);
const std::string& operation = record.getItem("OPERATION").get< std::string >(0);
double alpha = record.getItem("PARAM1").get< double >(0);
double beta = record.getItem("PARAM2").get< double >(0);
if (!supportsKeyword( targetArray))
throw std::invalid_argument("Fatal error processing OPERATE record - invalid/undefined keyword: " + targetArray);
{
auto& result_prop = getKeyword(targetArray);
if (srcArray == targetArray)
result_prop.runPostProcessor();
else {
if (operation == "MULTIPLY" || operation == "POLY")
result_prop.runPostProcessor();
}
std::vector<T> targetData = result_prop.getData();
const std::vector<T>& srcData = getKeyword( srcArray ).getData();
Operate::function func = Operate::get( operation, alpha, beta );
setKeywordBox(record, boxManager);
for (auto index : boxManager.getActiveBox().getIndexList())
targetData[index] = func( targetData[index] , srcData[index]);
result_prop.assignData(targetData);
}
}
template <typename T>
void GridProperties<T>::handleOPERATERRecord( const DeckRecord& record, const GridProperty<int>& regionProperty) {
const std::string& result_array = record.getItem("RESULT_ARRAY").get< std::string >(0);
const std::string& parameter_array = record.getItem("ARRAY_PARAMETER").get< std::string >(0);
const std::string& operation = record.getItem("OPERATION").get< std::string >(0);
double alpha = record.getItem("PARAM1").get< double >(0);
double beta = record.getItem("PARAM2").get< double >(0);
int region_value = record.getItem("REGION_NUMBER").get<int>(0);
if (!supportsKeyword( result_array))
throw std::invalid_argument("Fatal error processing OPERATER record - invalid/undefined keyword: " + result_array);
{
auto& result_prop = getKeyword(result_array);
if (parameter_array == result_array)
result_prop.runPostProcessor();
else {
if (operation == "MULTIPLY" || operation == "POLY")
result_prop.runPostProcessor();
}
std::vector<T> result_data = result_prop.getData();
const std::vector<T>& parameter_data = getKeyword( parameter_array ).getData();
Operate::function func = Operate::get(operation, alpha, beta);
std::vector<bool> mask;
regionProperty.initMask(region_value, mask);
for (size_t index = 0; index < mask.size(); index++) {
if (mask[index])
result_data[index] = func(result_data[index], parameter_data[index]);
}
result_prop.assignData(result_data);
}
}
template< typename T >
void GridProperties<T>::postAddKeyword(const std::string& name,
std::function< std::vector<T>(size_t) > initProcessor,
const std::string& dimString)
{
m_supportedKeywords.emplace(name,
SupportedKeywordInfo( name,
initProcessor,
dimString,
true));
}
template< typename T >
void GridProperties<T>::postAddKeyword(const std::string& name,
const T defaultValue,
std::function< void( const std::vector<bool>& defaulted, std::vector< T >& ) > postProcessor,
const std::string& dimString,
const bool defaultInitializable )
{
m_supportedKeywords.emplace(name,
SupportedKeywordInfo( name,
defaultValue,
postProcessor,
dimString,
defaultInitializable ));
}
/*
This is const because of the auto-generation of keywords on get().
*/
template< typename T >
bool GridProperties<T>::addAutoGeneratedKeyword_(const std::string& keywordName) const {
if (!supportsKeyword( keywordName ))
throw std::invalid_argument("The keyword: " + keywordName + " is not supported in this container");
if (m_properties.count( keywordName ) > 0)
return false; // property already exists (if it is auto generated or not doesn't matter)
else {
m_autoGeneratedProperties.insert(keywordName);
if (isFipxxx<T>(keywordName))
m_supportedKeywords.emplace(keywordName, SupportedKeywordInfo( keywordName , 1, "1" ));
insertKeyword( m_supportedKeywords.at( keywordName ) );
return true;
}
}
template< typename T >
bool GridProperties<T>::isAutoGenerated_(const std::string& keyword) const {
return m_autoGeneratedProperties.count(keyword) > 0;
}
template< typename T >
bool GridProperties<T>::isDefaultInitializable(const std::string& keyword) const {
const std::string kw = normalize(keyword);
if (m_supportedKeywords.count( kw ) == 0) return false;
return m_supportedKeywords.find(kw)->second.isDefaultInitializable();
}
}
template class Opm::GridProperties< int >;
template class Opm::GridProperties< double >;

View File

@ -1,540 +0,0 @@
/*
Copyright 2014 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 <limits>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/RtempvdTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
namespace Opm {
template< typename T >
static std::function< std::vector< T >( size_t ) > constant( T val ) {
return [=]( size_t size ) { return std::vector< T >( size, val ); };
}
template< typename T >
static std::function< void( const std::vector<bool>&, std::vector< T >& ) > noop() {
return []( const std::vector<bool>&, std::vector< T >& ) { return; };
}
template< typename T >
GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo(
const std::string& name,
std::function< std::vector< T >( size_t ) > init,
std::function< void( const std::vector<bool>& defaulted, std::vector< T >& ) > post,
const std::string& dimString,
bool defaultInitializable ) :
m_keywordName( name ),
m_initializer( init ),
m_postProcessor( post ),
m_dimensionString( dimString ),
m_defaultInitializable ( defaultInitializable )
{}
template< typename T >
GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo(
const std::string& name,
std::function< std::vector< T >( size_t ) > init,
const std::string& dimString,
bool defaultInitializable ) :
m_keywordName( name ),
m_initializer( init ),
m_postProcessor( noop< T >() ),
m_dimensionString( dimString ),
m_defaultInitializable ( defaultInitializable )
{}
template< typename T >
GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo(
const std::string& name,
const T defaultValue,
const std::string& dimString,
bool defaultInitializable ) :
m_keywordName( name ),
m_initializer( constant( defaultValue ) ),
m_postProcessor( noop< T >() ),
m_dimensionString( dimString ),
m_defaultInitializable ( defaultInitializable )
{}
template< typename T >
GridPropertySupportedKeywordInfo< T >::GridPropertySupportedKeywordInfo(
const std::string& name,
const T defaultValue,
std::function< void( const std::vector<bool>&, std::vector< T >& ) > post,
const std::string& dimString,
bool defaultInitializable ) :
m_keywordName( name ),
m_initializer( constant( defaultValue ) ),
m_postProcessor( post ),
m_dimensionString( dimString ),
m_defaultInitializable ( defaultInitializable )
{}
template< typename T >
const std::string& GridPropertySupportedKeywordInfo< T >::getKeywordName() const {
return this->m_keywordName;
}
template< typename T >
const std::string& GridPropertySupportedKeywordInfo< T >::getDimensionString() const {
return this->m_dimensionString;
}
template< typename T >
const std::function< std::vector< T >( size_t ) >& GridPropertySupportedKeywordInfo< T >::initializer() const {
return this->m_initializer;
}
template< typename T >
const std::function< void( const std::vector<bool>&, std::vector< T >& ) >&
GridPropertySupportedKeywordInfo< T >::postProcessor() const
{
return this->m_postProcessor;
}
template<typename T>
bool GridPropertySupportedKeywordInfo< T >::isDefaultInitializable() const {
return m_defaultInitializable;
}
template< typename T >
GridProperty< T >::GridProperty( size_t nx, size_t ny, size_t nz, const SupportedKeywordInfo& kwInfo ) :
m_nx( nx ),
m_ny( ny ),
m_nz( nz ),
m_kwInfo( kwInfo ),
m_data( kwInfo.initializer()( nx * ny * nz ) ),
m_defaulted( nx * ny * nz, true ),
m_hasRunPostProcessor( false )
{}
template< typename T >
size_t GridProperty< T >::getCartesianSize() const {
return m_data.size();
}
template< typename T >
size_t GridProperty< T >::getNX() const {
return m_nx;
}
template< typename T >
size_t GridProperty< T >::getNY() const {
return m_ny;
}
template< typename T >
size_t GridProperty< T >::getNZ() const {
return m_nz;
}
template< typename T >
bool GridProperty<T>::deckAssigned() const {
return this->assigned;
}
template< typename T >
const std::vector< bool >& GridProperty< T >::wasDefaulted() const {
return this->m_defaulted;
}
template< typename T >
const std::vector< T >& GridProperty< T >::getData() const {
return m_data;
}
template< typename T >
void GridProperty< T >::assignData(std::vector<T>&& data) {
this->m_data = std::move(data);
}
template< typename T >
void GridProperty< T >::assignData(const std::vector<T>& data) {
this->m_data = data;
}
template< typename T >
void GridProperty< T >::multiplyWith( const GridProperty< T >& other ) {
if ((m_nx == other.m_nx) && (m_ny == other.m_ny) && (m_nz == other.m_nz)) {
for (size_t g=0; g < m_data.size(); g++)
m_data[g] *= other.m_data[g];
} else
throw std::invalid_argument("Size mismatch between properties in mulitplyWith.");
}
template< typename T >
void GridProperty< T >::multiplyValueAtIndex(size_t index, T factor) {
m_data[index] *= factor;
}
template< typename T >
void GridProperty< T >::maskedSet( T value, const std::vector< bool >& mask ) {
for (size_t g = 0; g < getCartesianSize(); g++) {
if (mask[g])
this->setElement(g, value);
}
this->assigned = true;
}
template< typename T >
void GridProperty< T >::maskedMultiply( T value, const std::vector<bool>& mask ) {
for (size_t g = 0; g < getCartesianSize(); g++) {
if (mask[g])
m_data[g] *= value;
}
}
template< typename T >
void GridProperty< T >::maskedAdd( T value, const std::vector<bool>& mask ) {
for (size_t g = 0; g < getCartesianSize(); g++) {
if (mask[g])
m_data[g] += value;
}
}
template< typename T >
void GridProperty< T >::maskedCopy( const GridProperty< T >& other, const std::vector< bool >& mask) {
for (size_t g = 0; g < getCartesianSize(); g++) {
if (mask[g])
this->setElement(g, other.m_data[g], other.m_defaulted[g]);
}
this->assigned = other.deckAssigned();
}
template< typename T >
void GridProperty< T >::initMask( T value, std::vector< bool >& mask ) const {
mask.resize(getCartesianSize());
for (size_t g = 0; g < getCartesianSize(); g++) {
if (m_data[g] == value)
mask[g] = true;
else
mask[g] = false;
}
}
template< typename T >
void GridProperty< T >::loadFromDeckKeyword( const DeckKeyword& deckKeyword, bool multiply ) {
const auto& deckItem = getDeckItem(deckKeyword);
const auto size = deckItem.data_size();
for (size_t dataPointIdx = 0; dataPointIdx < size; ++dataPointIdx) {
if (!deckItem.defaultApplied(dataPointIdx)) {
if (multiply)
mulDataPoint(dataPointIdx, dataPointIdx, deckItem);
else
setDataPoint(dataPointIdx, dataPointIdx, deckItem);
}
}
this->assigned = true;
}
template< typename T >
void GridProperty< T >::loadFromDeckKeyword( const Box& inputBox, const DeckKeyword& deckKeyword, bool multiply) {
if (inputBox.isGlobal())
loadFromDeckKeyword( deckKeyword, multiply );
else {
const auto& deckItem = getDeckItem(deckKeyword);
const std::vector<size_t>& indexList = inputBox.getIndexList();
if (indexList.size() == deckItem.data_size()) {
for (size_t sourceIdx = 0; sourceIdx < indexList.size(); sourceIdx++) {
size_t targetIdx = indexList[sourceIdx];
if (sourceIdx < deckItem.data_size()
&& !deckItem.defaultApplied(sourceIdx))
{
if (multiply)
mulDataPoint(sourceIdx, targetIdx, deckItem);
else
setDataPoint(sourceIdx, targetIdx, deckItem);
}
}
} else {
std::string boxSize = std::to_string(static_cast<long long>(indexList.size()));
std::string keywordSize = std::to_string(static_cast<long long>(deckItem.data_size()));
throw std::invalid_argument("Size mismatch: Box:" + boxSize + " DeckKeyword:" + keywordSize);
}
}
}
template< typename T >
void GridProperty< T >::copyFrom( const GridProperty< T >& src, const Box& inputBox ) {
if (inputBox.isGlobal())
for (size_t i = 0; i < src.getCartesianSize(); ++i)
this->setElement(i, src.m_data[i], src.m_defaulted[i]);
else
for (const auto& i : inputBox.getIndexList())
this->setElement(i, src.m_data[i], src.m_defaulted[i]);
this->assigned = src.deckAssigned();
}
template< typename T >
void GridProperty< T >::maxvalue( T value, const Box& inputBox ) {
if (inputBox.isGlobal())
for (size_t i = 0; i < m_data.size(); ++i)
this->setElement(i, std::min(value, this->m_data[i]));
else
for (const auto& i : inputBox.getIndexList())
this->setElement(i, std::min(value, this->m_data[i]));
}
template< typename T >
void GridProperty< T >::minvalue( T value, const Box& inputBox ) {
if (inputBox.isGlobal())
for (size_t i = 0; i < m_data.size(); ++i)
this->setElement(i, std::max(value, this->m_data[i]));
else
for (const auto& i : inputBox.getIndexList())
this->setElement(i, std::max(value, this->m_data[i]));
}
template< typename T >
void GridProperty< T >::scale( T scaleFactor, const Box& inputBox ) {
if (inputBox.isGlobal()) {
for (size_t i = 0; i < m_data.size(); ++i)
m_data[i] *= scaleFactor;
} else {
const std::vector<size_t>& indexList = inputBox.getIndexList();
for (size_t i = 0; i < indexList.size(); i++) {
size_t targetIndex = indexList[i];
m_data[targetIndex] *= scaleFactor;
}
}
}
template< typename T >
void GridProperty< T >::add( T shiftValue, const Box& inputBox ) {
if (inputBox.isGlobal()) {
for (size_t i = 0; i < m_data.size(); ++i)
m_data[i] += shiftValue;
} else {
const std::vector<size_t>& indexList = inputBox.getIndexList();
for (size_t i = 0; i < indexList.size(); i++) {
size_t targetIndex = indexList[i];
m_data[targetIndex] += shiftValue;
}
}
}
template< typename T >
void GridProperty< T >::setScalar( T value, const Box& inputBox ) {
if (inputBox.isGlobal()) {
std::fill(m_data.begin(), m_data.end(), value);
m_defaulted.assign(m_defaulted.size(), false);
} else
for (const auto& i : inputBox.getIndexList())
this->setElement(i, value);
this->assigned = true;
}
template< typename T >
const std::string& GridProperty< T >::getKeywordName() const {
return m_kwInfo.getKeywordName();
}
template< typename T >
const typename GridProperty< T >::SupportedKeywordInfo&
GridProperty< T >::getKeywordInfo() const {
return m_kwInfo;
}
template< typename T >
void GridProperty< T >::runPostProcessor() {
if( this->m_hasRunPostProcessor ) return;
this->m_hasRunPostProcessor = true;
this->m_kwInfo.postProcessor()( m_defaulted, m_data );
}
template< typename T >
void GridProperty< T >::checkLimits( T min, T max ) const {
for (size_t g=0; g < m_data.size(); g++) {
T value = m_data[g];
if ((value < min) || (value > max))
throw std::invalid_argument("Property element " + std::to_string( value) + " in " + getKeywordName() + " outside valid limits: [" + std::to_string(min) + ", " + std::to_string(max) + "]");
}
}
template< typename T >
const DeckItem& GridProperty< T >::getDeckItem( const DeckKeyword& deckKeyword ) {
if (deckKeyword.size() != 1)
throw std::invalid_argument("Grid properties can only have a single record (keyword "
+ deckKeyword.name() + ")");
if (deckKeyword.getRecord(0).size() != 1)
// this is an error of the definition of the ParserKeyword (most likely in
// the corresponding JSON file)
throw std::invalid_argument("Grid properties may only exhibit a single item (keyword "
+ deckKeyword.name() + ")");
const auto& deckItem = deckKeyword.getRecord(0).getItem(0);
if (deckItem.data_size() > m_data.size())
throw std::invalid_argument("Size mismatch when setting data for:" + getKeywordName()
+ " keyword size: " + std::to_string( deckItem.data_size() )
+ " input size: " + std::to_string( m_data.size()) );
return deckItem;
}
template<>
void GridProperty<int>::setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) {
this->setElement(targetIdx, deckItem.get< int >(sourceIdx));
}
template<>
void GridProperty<double>::setDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) {
this->setElement(targetIdx, deckItem.getSIDouble(sourceIdx));
}
template <typename T>
void GridProperty<T>::setElement(const typename std::vector<T>::size_type i, const T value, const bool defaulted) {
this->m_data[i] = value;
this->m_defaulted[i] = defaulted;
}
template<>
void GridProperty<double>::mulDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) {
this->m_data[targetIdx] *= deckItem.getSIDouble(sourceIdx);
}
template<>
void GridProperty<int>::mulDataPoint(size_t sourceIdx, size_t targetIdx, const DeckItem& deckItem) {
this->m_data[targetIdx] *= deckItem.get<int>(sourceIdx);
}
template<>
bool GridProperty<int>::containsNaN( ) const {
throw std::logic_error("Only <double> and can be meaningfully queried for nan");
}
template<>
bool GridProperty<double>::containsNaN( ) const {
bool return_value = false;
size_t size = m_data.size();
size_t index = 0;
while (true) {
if (std::isnan(m_data[index])) {
return_value = true;
break;
}
index++;
if (index == size)
break;
}
return return_value;
}
template<>
const std::string& GridProperty<int>::getDimensionString() const {
throw std::logic_error("Only <double> grid properties have dimension");
}
template<>
const std::string& GridProperty<double>::getDimensionString() const {
return m_kwInfo.getDimensionString();
}
template<typename T>
std::vector<T> GridProperty<T>::compressedCopy(const EclipseGrid& grid) const {
if (grid.allActive())
return m_data;
else {
return grid.compressedVector( m_data );
}
}
template<typename T>
std::vector<size_t> GridProperty<T>::cellsEqual(T value, const std::vector<int>& activeMap) const {
std::vector<size_t> cells;
for (size_t active_index = 0; active_index < activeMap.size(); active_index++) {
size_t global_index = activeMap[ active_index ];
if (m_data[global_index] == value)
cells.push_back( active_index );
}
return cells;
}
template<typename T>
std::vector<size_t> GridProperty<T>::indexEqual(T value) const {
std::vector<size_t> index_list;
for (size_t index = 0; index < m_data.size(); index++) {
if (m_data[index] == value)
index_list.push_back( index );
}
return index_list;
}
template<typename T>
std::vector<size_t> GridProperty<T>::cellsEqual(T value, const EclipseGrid& grid, bool active) const {
if (active)
return cellsEqual( value , grid.getActiveMap());
else
return indexEqual( value );
}
std::vector< double > temperature_lookup( size_t size,
const TableManager* tables,
const EclipseGrid* grid,
const GridProperties<int>* ig_props ) {
if (tables->hasTables("RTEMPVD")) {
const std::vector< int >& eqlNum = ig_props->getKeyword("EQLNUM").getData();
const auto& rtempvdTables = tables->getRtempvdTables();
std::vector< double > values( size, 0 );
for (size_t cellIdx = 0; cellIdx < eqlNum.size(); ++ cellIdx) {
int cellEquilRegionIdx = eqlNum[cellIdx] - 1; // EQLNUM contains fortran-style indices!
const RtempvdTable& rtempvdTable = rtempvdTables.getTable<RtempvdTable>(cellEquilRegionIdx);
double cellDepth = std::get<2>(grid->getCellCenter(cellIdx));
values[cellIdx] = rtempvdTable.evaluate("Temperature", cellDepth);
}
return values;
} else
return std::vector< double >( size, tables->rtemp( ) );
}
}
template class Opm::GridPropertySupportedKeywordInfo< int >;
template class Opm::GridPropertySupportedKeywordInfo< double >;
template class Opm::GridProperty< int >;
template class Opm::GridProperty< double >;

View File

@ -23,8 +23,8 @@
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
namespace Opm {

View File

@ -20,10 +20,8 @@
#include <stdexcept>
#include <string>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/SgfnTable.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/SgofTable.hpp>
@ -787,38 +785,6 @@ namespace Opm {
}
static std::vector< double > satnumApply( size_t size,
const std::string& columnName,
const std::vector< double >& fallbackValues,
const TableManager& tableManager,
const EclipseGrid& grid,
const GridProperties<int>* intGridProperties,
bool useOneMinusTableValue ) {
auto tabdims = tableManager.getTabdims();
const auto& satnum = intGridProperties->getKeyword("SATNUM");
const auto& endnum = intGridProperties->getKeyword("ENDNUM");
int numSatTables = tabdims.getNumSatTables();
std::vector<double> cell_depth(grid.getCartesianSize());
for (std::size_t g=0; g < grid.getCartesianSize(); g++)
cell_depth[g] = grid.getCellDepth(g);
// SATNUM = 0 *might* occur in deactivated cells
satnum.checkLimits( 0 , numSatTables );
return satnumApply(size,
columnName,
fallbackValues,
tableManager,
cell_depth,
std::addressof(grid.getACTNUM()),
satnum.getData(),
endnum.getData(),
useOneMinusTableValue);
}
static std::vector< double > imbnumApply( size_t size,
const std::string& columnName,
@ -873,378 +839,6 @@ namespace Opm {
}
static std::vector< double > imbnumApply( size_t size,
const std::string& columnName,
const std::vector< double >& fallbackValues,
const TableManager& tableManager,
const EclipseGrid& eclipseGrid,
const GridProperties<int>* intGridProperties,
bool useOneMinusTableValue ) {
auto tabdims = tableManager.getTabdims();
const auto& imbnum = intGridProperties->getKeyword("IMBNUM");
const auto& endnum = intGridProperties->getKeyword("ENDNUM");
int numSatTables = tabdims.getNumSatTables();
std::vector<double> cell_depth(eclipseGrid.getCartesianSize());
for (std::size_t g=0; g < eclipseGrid.getCartesianSize(); g++)
cell_depth[g] = eclipseGrid.getCellDepth(g);
// IMBNUM = 0 *might* occur in deactivated cells
imbnum.checkLimits( 0 , numSatTables );
return imbnumApply(size,
columnName,
fallbackValues,
tableManager,
cell_depth,
std::addressof(eclipseGrid.getACTNUM()),
imbnum.getData(),
endnum.getData(),
useOneMinusTableValue);
}
std::vector< double > SGLEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid* eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto min_gas = findMinGasSaturation( *tableManager );
return satnumApply( size, "SGCO", min_gas, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > ISGLEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid* eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto min_gas = findMinGasSaturation( *tableManager );
return imbnumApply( size, "SGCO", min_gas, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > SGUEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid* eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_gas = findMaxGasSaturation( *tableManager );
return satnumApply( size, "SGMAX", max_gas, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > ISGUEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid* eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_gas = findMaxGasSaturation( *tableManager );
return imbnumApply( size, "SGMAX", max_gas, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > SWLEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid* eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto min_water = findMinWaterSaturation( *tableManager );
return satnumApply( size, "SWCO", min_water, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > ISWLEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto min_water = findMinWaterSaturation( *tableManager );
return imbnumApply( size, "SWCO", min_water, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > SWUEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_water = findMaxWaterSaturation( *tableManager );
return satnumApply( size, "SWMAX", max_water, *tableManager, *eclipseGrid,
intGridProperties, true );
}
std::vector< double > ISWUEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_water = findMaxWaterSaturation( *tableManager );
return imbnumApply( size, "SWMAX", max_water, *tableManager, *eclipseGrid,
intGridProperties, true);
}
std::vector< double > SGCREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto crit_gas = findCriticalGas( *tableManager );
return satnumApply( size, "SGCRIT", crit_gas, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > ISGCREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto crit_gas = findCriticalGas( *tableManager );
return imbnumApply( size, "SGCRIT", crit_gas, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > SOWCREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto oil_water = findCriticalOilWater( *tableManager );
return satnumApply( size, "SOWCRIT", oil_water, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > ISOWCREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto oil_water = findCriticalOilWater( *tableManager );
return imbnumApply( size, "SOWCRIT", oil_water, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > SOGCREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto crit_oil_gas = findCriticalOilGas( *tableManager );
return satnumApply( size, "SOGCRIT", crit_oil_gas, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > ISOGCREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto crit_oil_gas = findCriticalOilGas( *tableManager );
return imbnumApply( size, "SOGCRIT", crit_oil_gas, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > SWCREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto crit_water = findCriticalWater( *tableManager );
return satnumApply( size, "SWCRIT", crit_water, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > ISWCREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto crit_water = findCriticalWater( *tableManager );
return imbnumApply( size, "SWCRIT", crit_water, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > PCWEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_pcow = findMaxPcow( *tableManager );
return satnumApply( size, "PCW", max_pcow, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IPCWEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_pcow = findMaxPcow( *tableManager );
return imbnumApply( size, "IPCW", max_pcow, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > PCGEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_pcog = findMaxPcog( *tableManager );
return satnumApply( size, "PCG", max_pcog, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IPCGEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_pcog = findMaxPcog( *tableManager );
return imbnumApply( size, "IPCG", max_pcog, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > KRWEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_krw = findMaxKrw( *tableManager );
return satnumApply( size, "KRW", max_krw, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IKRWEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krwr = findKrwr( *tableManager );
return imbnumApply( size, "IKRW", krwr, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > KRWREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krwr = findKrwr( *tableManager );
return satnumApply( size, "KRWR", krwr, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IKRWREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krwr = findKrwr( *tableManager );
return imbnumApply( size, "IKRWR", krwr, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > KROEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_kro = findMaxKro( *tableManager );
return satnumApply( size, "KRO", max_kro, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IKROEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_kro = findMaxKro( *tableManager );
return imbnumApply( size, "IKRO", max_kro, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > KRORWEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krorw = findKrorw( *tableManager );
return satnumApply( size, "KRORW", krorw, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IKRORWEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krorw = findKrorw( *tableManager );
return imbnumApply( size, "IKRORW", krorw, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > KRORGEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krorg = findKrorg( *tableManager );
return satnumApply( size, "KRORG", krorg, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IKRORGEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krorg = findKrorg( *tableManager );
return imbnumApply( size, "IKRORG", krorg, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > KRGEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_krg = findMaxKrg( *tableManager );
return satnumApply( size, "KRG", max_krg, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IKRGEndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto max_krg = findMaxKrg( *tableManager );
return imbnumApply( size, "IKRG", max_krg, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > KRGREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid * eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krgr = findKrgr( *tableManager );
return satnumApply( size, "KRGR", krgr, *tableManager, *eclipseGrid,
intGridProperties, false );
}
std::vector< double > IKRGREndpoint( size_t size,
const TableManager * tableManager,
const EclipseGrid* eclipseGrid,
GridProperties<int>* intGridProperties )
{
const auto krgr = findKrgr( *tableManager );
return imbnumApply( size, "IKRGR", krgr, *tableManager, *eclipseGrid,
intGridProperties, false );
}
namespace satfunc {

View File

@ -26,7 +26,6 @@
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultFace.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>

View File

@ -29,7 +29,6 @@
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>

View File

@ -25,7 +25,6 @@
#include <opm/parser/eclipse/Units/Units.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Connection.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
@ -223,16 +222,6 @@ inline std::array< size_t, 3> directionIndices(const Opm::Connection::Direction
this->loadCOMPDAT(record, grid, satnum_data, permx, permy, permz, ntg);
}
void WellConnections::loadCOMPDAT(const DeckRecord& record, const EclipseGrid& grid, const Eclipse3DProperties& eclipseProperties) {
const auto& permx = eclipseProperties.getDoubleGridProperty("PERMX").compressedCopy(grid);
const auto& permy = eclipseProperties.getDoubleGridProperty("PERMY").compressedCopy(grid);
const auto& permz = eclipseProperties.getDoubleGridProperty("PERMZ").compressedCopy(grid);
const auto& ntg = eclipseProperties.getDoubleGridProperty("NTG").compressedCopy(grid);
const auto& satnum_data = eclipseProperties.getIntGridProperty("SATNUM").compressedCopy(grid);
this->loadCOMPDAT(record, grid, satnum_data, std::addressof(permx), std::addressof(permy), std::addressof(permz), ntg);
}
void WellConnections::loadCOMPDAT(const DeckRecord& record,
const EclipseGrid& grid,
const std::vector<int>& satnum_data,

View File

@ -21,7 +21,6 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp>

View File

@ -21,7 +21,6 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/E.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/R.hpp>

View File

@ -33,10 +33,8 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
static Opm::Deck createDeckInvalidArray() {
@ -138,98 +136,6 @@ static Opm::Deck createDeckUnInitializedVector() {
static Opm::Deck createValidIntDeck() {
const char* deckData =
"RUNSPEC\n"
"GRIDOPTS\n"
" 'YES' 2 /\n"
"\n"
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"/\n"
"SATNUM\n"
" 25*1 \n"
"/\n"
"ADDREG\n"
" SATNUM 11 1 M / \n"
" SATNUM 20 2 / \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
static Opm::Deck createValidPERMXDeck() {
const char* deckData =
"RUNSPEC\n"
"GRIDOPTS\n"
" 'YES' 2 /\n"
"\n"
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"/\n"
"BOX\n"
" 1 2 1 5 1 1 / \n"
"PERMZ\n"
" 10*1 /\n"
"ENDBOX\n"
"BOX\n"
" 3 5 1 5 1 1 / \n"
"PERMZ\n"
" 15*2 /\n"
"ENDBOX\n"
"PERMX\n"
"25*1 /\n"
"ADDREG\n"
" PERMX 1 1 / \n"
" PERMX 3 2 / \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
BOOST_AUTO_TEST_CASE(InvalidArrayThrows) {
Opm::Deck deck = createDeckInvalidArray();
BOOST_CHECK_THROW( new Opm::EclipseState( deck) , std::invalid_argument );
@ -259,38 +165,3 @@ BOOST_AUTO_TEST_CASE(UnInitializedVectorThrows) {
BOOST_CHECK_THROW( new Opm::EclipseState( deck) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(IntSetCorrectly) {
Opm::Deck deck = createValidIntDeck();
Opm::TableManager tm(deck);
Opm::EclipseGrid eg(deck);
Opm::Eclipse3DProperties props(deck, tm, eg);
const auto& property_data = props.getIntGridProperty("SATNUM").getData();
for (size_t j = 0; j < 5; j++)
for (size_t i = 0; i < 5; i++) {
if (i < 2)
BOOST_CHECK_EQUAL( 12 , property_data[eg.getGlobalIndex(i,j,0)]);
else
BOOST_CHECK_EQUAL( 21 , property_data[eg.getGlobalIndex(i,j,0)]);
}
}
BOOST_AUTO_TEST_CASE(UnitAppliedCorrectly) {
Opm::Deck deck = createValidPERMXDeck();
Opm::TableManager tm(deck);
Opm::EclipseGrid eg(deck);
Opm::Eclipse3DProperties props(deck, tm, eg);
const auto& permx_data = props.getDoubleGridProperty("PERMX").getData();
for (size_t j=0; j< 5; j++)
for (size_t i = 0; i < 5; i++) {
if (i < 2)
BOOST_CHECK_CLOSE( 2 * Opm::Metric::Permeability , permx_data[eg.getGlobalIndex(i,j,0)], 0.0001);
else
BOOST_CHECK_CLOSE( 4 * Opm::Metric::Permeability , permx_data[eg.getGlobalIndex(i,j,0)], 0.0001);
}
}

View File

@ -37,7 +37,6 @@
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
@ -153,17 +152,13 @@ Opm::WellConnections loadCOMPDAT(const std::string& compdat_keyword) {
Opm::TableManager tables;
Opm::Parser parser;
const auto deck = parser.parseString(compdat_keyword);
Opm::Eclipse3DProperties props(deck, tables, grid );
Opm::FieldPropsManager field_props(deck, grid, Opm::TableManager());
const auto& keyword = deck.getKeyword("COMPDAT", 0);
Opm::WellConnections connections1(10,10);
Opm::WellConnections connections2(10,10);
for (const auto& rec : keyword) {
connections1.loadCOMPDAT(rec, grid, props);
connections2.loadCOMPDAT(rec, grid, field_props);
}
BOOST_CHECK_EQUAL( connections1, connections2);
return connections1;
Opm::WellConnections connections(10,10);
for (const auto& rec : keyword)
connections.loadCOMPDAT(rec, grid, field_props);
return connections;
}
BOOST_AUTO_TEST_CASE(loadCOMPDATTEST) {

View File

@ -33,10 +33,8 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
@ -141,43 +139,6 @@ static Opm::Deck createDeckUnInitialized() {
}
static Opm::Deck createValidIntDeck() {
const char *deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"/\n"
"FLUXNUM\n"
" 25*3 /\n"
"REGIONS\n"
"SATNUM\n"
" 25*10 /\n"
"COPYREG\n"
" SATNUM FLUXNUM 1 M / \n"
"/\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
BOOST_AUTO_TEST_CASE(InvalidArrayThrows1) {
@ -212,20 +173,3 @@ BOOST_AUTO_TEST_CASE(TypeMismatchThrows) {
}
BOOST_AUTO_TEST_CASE(IntSetCorrectly) {
Opm::Deck deck = createValidIntDeck();
Opm::TableManager tm(deck);
Opm::EclipseGrid eg(deck);
Opm::Eclipse3DProperties props(deck, tm, eg);
const auto& property = props.getIntGridProperty("FLUXNUM").getData();
for (size_t j = 0; j < 5; j++)
for (size_t i = 0; i < 5; i++) {
std::size_t g = eg.getGlobalIndex(i,j,0);
if (i < 2)
BOOST_CHECK_EQUAL( 10 , property[g]);
else
BOOST_CHECK_EQUAL( 3 , property[g]);
}
}

View File

@ -1,819 +0,0 @@
/*
Copyright 2016 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 <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE Eclipse3DPropertiesTests
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
static Opm::Deck createDeck() {
const char *deckData = "RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DY\n"
"1000*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"FAULTS \n"
" 'F1' 1 1 1 4 1 4 'X' / \n"
" 'F2' 5 5 1 4 1 4 'X-' / \n"
"/\n"
"MULTFLT \n"
" 'F1' 0.50 / \n"
" 'F2' 0.50 / \n"
"/\n"
"EDIT\n"
"MULTFLT /\n"
" 'F2' 0.25 / \n"
"/\n"
"OIL\n"
"\n"
"GAS\n"
"\n"
"PROPS\n"
"REGIONS\n"
"swat\n"
"1000*1 /\n"
"SATNUM\n"
"1000*2 /\n"
"ROCKNUM\n"
"200*1 200*2 200*3 400*4 /\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData);
}
static Opm::Deck createValidIntDeck() {
const char *deckData = "RUNSPEC\n"
"GRIDOPTS\n"
" 'YES' 2 /\n"
"\n"
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"/\n"
"REGIONS\n"
"SATNUM\n"
" 25*1 \n"
"/\n"
"ADDREG\n"
" satnum 11 1 M / \n"
" SATNUM 20 2 / \n"
"/\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData);
}
static Opm::Deck createValidPERMXDeck() {
const char *deckData = "RUNSPEC\n"
"GRIDOPTS\n"
" 'YES' 2 /\n"
"\n"
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"/\n"
"BOX\n"
" 1 2 1 5 1 1 / \n"
"PERMZ\n"
" 10*1 /\n"
"ENDBOX\n"
"BOX\n"
" 3 5 1 5 1 1 / \n"
"PERMZ\n"
" 15*2 /\n"
"ENDBOX\n"
"PERMX\n"
"25*1 /\n"
"ADDREG\n"
"'PermX ' 1 1 / \n"
"PErmX 3 2 / \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData);
}
static Opm::Deck createQuarterCircleDeck() {
const auto* input = R"(
RUNSPEC
TITLE
'Quarter Circle 100x21x20' /
DIMENS
100 21 20 /
METRIC
RADIAL
OIL
WATER
TABDIMS
/
START
19 JUN 2017
/
WELLDIMS
3 20 1
/
EQLDIMS
2* 100 2* /
-- =====================================================================
GRID ================================================================
INRAD
1.0D0
/
DRV
5.0D0 10.0D0 2*20.0D0 45.0D0 95*50.0D0
/
-- Quarter circle, 21 sectors of 4.285714 degrees each.
DTHETAV
21*4.285714D0
/
DZV
20*0.5D0
/
BOX
1 100 1 21 1 1
/
PERMR
2100*100.0D0
/
PERMXY
2100*100.0D0
/
PORO
2100*0.3D0
/
TOPS
2100*1000.0D0
/
-- =====================================================================
EDIT ================================================================
COPY
'PERMR' 'PERMTHT' /
'PERMR' 'PERMZ' /
/
MULTIPLY
'PERMZ' 0.1D0 /
/
)";
Opm::Parser parser;
return parser.parseString(input);
}
/// Setup fixture
struct Setup
{
Opm::Deck deck;
Opm::TableManager tablemanager;
Opm::EclipseGrid grid;
Opm::Eclipse3DProperties props;
Opm::FieldPropsManager fp;
explicit Setup(Opm::Deck&& deckArg) :
deck(std::move( deckArg ) ),
tablemanager(deck),
grid(deck),
props(deck, tablemanager, grid),
fp(deck, grid, tablemanager)
{
}
};
BOOST_AUTO_TEST_CASE(HasDeckProperty) {
Setup s(createDeck());
BOOST_CHECK(s.props.hasDeckIntGridProperty("SATNUM"));
BOOST_CHECK(s.fp.try_get<int>("SATNUM") != nullptr);
}
BOOST_AUTO_TEST_CASE(SupportsProperty) {
Setup s(createDeck());
std::vector<std::string> int_keywords = {"SATNUM", "IMBNUM", "PVTNUM", "EQLNUM", "ENDNUM", "FLUXNUM", "MULTNUM", "FIPNUM", "MISCNUM", "OPERNUM", "ROCKNUM", "LWSLTNUM"};
std::vector<std::string> double_keywords = {"TEMPI", "MULTPV", "PERMX", "PERMY", "PERMZ", "SWATINIT", "THCONR", "NTG"};
for (auto keyword : int_keywords) {
BOOST_CHECK(s.props.supportsGridProperty(keyword));
BOOST_CHECK(s.fp.supported<int>(keyword));
}
for (auto keyword : double_keywords) {
BOOST_CHECK(s.props.supportsGridProperty(keyword));
BOOST_CHECK(s.fp.supported<double>(keyword));
}
}
BOOST_AUTO_TEST_CASE(DefaultRegionFluxnum) {
Setup s(createDeck());
BOOST_CHECK_EQUAL(s.props.getDefaultRegionKeyword(), "FLUXNUM");
}
BOOST_AUTO_TEST_CASE(UnsupportedKeywordsThrows) {
Setup s(createDeck());
BOOST_CHECK_THROW(s.props.hasDeckIntGridProperty("NONO"), std::logic_error);
BOOST_CHECK_THROW(s.props.hasDeckDoubleGridProperty("NONO"), std::logic_error);
BOOST_CHECK_THROW(s.props.getIntGridProperty("NONO"), std::logic_error);
BOOST_CHECK_THROW(s.props.getDoubleGridProperty("NONO"), std::logic_error);
BOOST_CHECK_THROW(s.fp.get<double>("NONO"), std::logic_error);
BOOST_CHECK_THROW(s.fp.get<int>("NONO"), std::logic_error);
BOOST_CHECK_NO_THROW(s.props.hasDeckIntGridProperty("FluxNUM"));
BOOST_CHECK_NO_THROW(s.props.supportsGridProperty("NONO"));
}
BOOST_AUTO_TEST_CASE(IntGridProperty) {
Setup s(createDeck());
{
int cnt = 0;
for (auto x : s.props.getIntGridProperty("SATNUM").getData()) {
BOOST_CHECK_EQUAL(x, 2);
cnt++;
}
BOOST_CHECK_EQUAL(cnt, 1000);
}
{
int cnt = 0;
for (auto x : s.fp.get_global<int>("SATNUM")) {
BOOST_CHECK_EQUAL(x, 2);
cnt++;
}
BOOST_CHECK_EQUAL(cnt, 1000);
}
}
BOOST_AUTO_TEST_CASE(AddregIntSetCorrectly) {
Setup s(createValidIntDeck());
const auto& grid = s.grid;
const auto& property = s.props.getIntGridProperty("SATNUM").getData();
for (size_t j = 0; j < 5; j++)
for (size_t i = 0; i < 5; i++) {
if (i < 2)
BOOST_CHECK_EQUAL(12, property[grid.getGlobalIndex(i, j, 0)]);
else
BOOST_CHECK_EQUAL(21, property[grid.getGlobalIndex(i, j, 0)]);
}
}
BOOST_AUTO_TEST_CASE(RocknumTest) {
Setup s(createDeck());
const auto& grid = s.grid;
const auto& rocknum = s.props.getIntGridProperty("ROCKNUM").getData();
for (size_t i = 0; i < 10; i++) {
for (size_t j = 0; j < 10; j++) {
for (size_t k = 0; k < 10; k++) {
if (k < 2)
BOOST_CHECK_EQUAL(1, rocknum[grid.getGlobalIndex(i, j, k)]);
else if (k < 4)
BOOST_CHECK_EQUAL(2, rocknum[grid.getGlobalIndex(i, j, k)]);
else if (k < 6)
BOOST_CHECK_EQUAL(3, rocknum[grid.getGlobalIndex(i, j, k)]);
else
BOOST_CHECK_EQUAL(4, rocknum[grid.getGlobalIndex(i, j, k)]);
}
}
}
}
BOOST_AUTO_TEST_CASE(PermxUnitAppliedCorrectly) {
Setup s( createValidPERMXDeck() );
const auto& grid = s.grid;
const auto& permx = s.props.getDoubleGridProperty("PermX").getData();
for (size_t j = 0; j < 5; j++)
for (size_t i = 0; i < 5; i++) {
if (i < 2)
BOOST_CHECK_CLOSE(2 * Opm::Metric::Permeability, permx[grid.getGlobalIndex(i, j, 0)], 0.0001);
else
BOOST_CHECK_CLOSE(4 * Opm::Metric::Permeability, permx[grid.getGlobalIndex(i, j, 0)], 0.0001);
}
}
BOOST_AUTO_TEST_CASE(DoubleIterator) {
Setup s( createValidPERMXDeck() );
const auto& doubleProperties = s.props.getDoubleProperties();
std::vector<std::string> kw_list;
for (const auto& prop : doubleProperties )
kw_list.push_back( prop.getKeywordName() );
BOOST_CHECK_EQUAL( 2 , kw_list.size() );
BOOST_CHECK( std::find( kw_list.begin() , kw_list.end() , "PERMX") != kw_list.end());
BOOST_CHECK( std::find( kw_list.begin() , kw_list.end() , "PERMZ") != kw_list.end());
}
BOOST_AUTO_TEST_CASE(IntIterator) {
Setup s( createValidPERMXDeck() );
const auto& intProperties = s.props.getIntProperties();
std::vector<std::string> kw_list;
for (const auto& prop : intProperties )
kw_list.push_back( prop.getKeywordName() );
BOOST_CHECK_EQUAL( 1 , kw_list.size() );
BOOST_CHECK_EQUAL( kw_list[0] , "MULTNUM" );
}
BOOST_AUTO_TEST_CASE(getRegions) {
const char* input =
"START -- 0 \n"
"10 MAI 2007 / \n"
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 2 2 1 /\n"
"GRID\n"
"DX\n"
"4*0.25 /\n"
"DY\n"
"4*0.25 /\n"
"DZ\n"
"4*0.25 /\n"
"TOPS\n"
"4*0.25 /\n"
"REGIONS\n"
"OPERNUM\n"
"3 3 1 3 /\n"
"FIPPGDX\n"
"2 1 1 2 /\n"
"FIPREG\n"
"3 2 3 2 /\n"
"FIPNUM\n"
"1 1 2 3 /\n";
Setup s( Opm::Parser().parseString(input) );
std::vector< int > ref = { 1, 2, 3 };
const auto& regions = s.props.getRegions( "FIPNUM" );
BOOST_CHECK_EQUAL_COLLECTIONS( ref.begin(), ref.end(),
regions.begin(), regions.end() );
BOOST_CHECK( s.props.getRegions( "EQLNUM" ).empty() );
BOOST_CHECK( ! s.props.getRegions( "FIPPGDX" ).empty() );
const auto& fipreg = s.props.getRegions( "FIPREG" );
BOOST_CHECK_EQUAL( 2, fipreg.at(0) );
BOOST_CHECK_EQUAL( 3, fipreg.at(1) );
const auto& opernum = s.props.getRegions( "OPERNUM" );
BOOST_CHECK_EQUAL( 1, opernum.at(0) );
BOOST_CHECK_EQUAL( 3, opernum.at(1) );
}
BOOST_AUTO_TEST_CASE(RadialPermeabilityTensor) {
const Setup s(createQuarterCircleDeck());
const auto& grid = s.grid;
const auto& permr = s.props.getDoubleGridProperty("PERMR").getData();
const auto& permtht = s.props.getDoubleGridProperty("PERMTHT").getData();
const auto& permz = s.props.getDoubleGridProperty("PERMZ").getData();
const auto& poro = s.props.getDoubleGridProperty("PORO").getData();
const double check_tol = 1.0e-6;
// Top layer (explicitly assigned)
BOOST_CHECK_CLOSE(100.0*Opm::Metric::Permeability, permr[0], check_tol);
BOOST_CHECK_CLOSE(permtht[0], permr[0], check_tol);
BOOST_CHECK_CLOSE(permz[0], 0.1 * permr[0], check_tol);
BOOST_CHECK_CLOSE(0.3, poro[0], check_tol);
// Middle layer (copied ultimately form top)
std::size_t g = grid.getGlobalIndex(49,10,9);
BOOST_CHECK_CLOSE(100.0*Opm::Metric::Permeability, permr[g], check_tol);
BOOST_CHECK_CLOSE(permtht[g], permr[g], check_tol);
BOOST_CHECK_CLOSE(permz[g], 0.1 * permr[g], check_tol);
BOOST_CHECK_CLOSE(0.3, poro[g], check_tol);
{
const auto& d1 = s.deck.getKeyword("PERMR");
const auto& d2 = s.deck.getKeyword("PERMXY");
BOOST_CHECK( !d1.equal( d2 ));
BOOST_CHECK( d1.equal_data( d2 ));
}
}
BOOST_AUTO_TEST_CASE(TEMPI_TEST) {
Setup s(createDeck());
BOOST_CHECK_NO_THROW( s.props.getDoubleGridProperty("TEMPI") );
}
static Opm::Deck createMultiplyDeck() {
const auto* input = R"(
RUNSPEC
TITLE
'TITTEL'
DIMENS
100 21 20 /
METRIC
OIL
WATER
TABDIMS
/
START
19 JUN 2017
/
WELLDIMS
3 20 1
/
EQLDIMS
2* 100 2* /
GRID
DXV
5.0D0 10.0D0 2*20.0D0 45.0D0 95*50.0D0
/
DYV
21*4.285714D0
/
DZV
20*0.5D0
/
TOPS
2100*1000.0D0
/
PERMX
42000*100.0D0
/
COPY
'PERMX' 'PERMZ' /
'PERMX' 'PERMY' /
/
EDIT
MULTIPLY
'PERMZ' 0.1D0 /
'PERMX' 0.1D0 * * 1 21 * 1 / -- This is a weird way to specify the top layer!
'TRANX' 0.10 /
/
COPY
'TRANX' 'TRANY' /
/
EQUALS
'TRANZ' 0.25 /
/
)";
Opm::Parser parser;
return parser.parseString(input);
}
BOOST_AUTO_TEST_CASE(DefaultedBox) {
const Setup s(createMultiplyDeck());
const auto& grid = s.grid;
const auto& permx = s.props.getDoubleGridProperty("PERMX");
const auto& permz = s.props.getDoubleGridProperty("PERMZ");
const auto& tranx = s.props.getDoubleGridProperty("TRANX");
const auto& trany = s.props.getDoubleGridProperty("TRANY");
const auto& tranz = s.props.getDoubleGridProperty("TRANZ");
const auto& permx_data = s.props.getDoubleGridProperty("PERMX").getData();
const auto& permz_data = s.props.getDoubleGridProperty("PERMZ").getData();
std::size_t g1 = grid.getGlobalIndex(0,0,0);
std::size_t g2 = grid.getGlobalIndex(0,0,1);
BOOST_CHECK_EQUAL( permx_data[g1] , permz_data[g1]);
BOOST_CHECK_EQUAL( permx_data[g2] * 0.10 , permz_data[g2]);
BOOST_CHECK( permx.deckAssigned() );
BOOST_CHECK( permz.deckAssigned() );
BOOST_CHECK( !tranx.deckAssigned());
BOOST_CHECK( !trany.deckAssigned());
BOOST_CHECK( tranz.deckAssigned() );
}
static Opm::Deck createAddDeck() {
const auto* input = R"(
RUNSPEC
TITLE
'TITTEL'
DIMENS
100 21 20 /
METRIC
OIL
WATER
TABDIMS
/
START
19 JUN 2017
/
WELLDIMS
3 20 1
/
EQLDIMS
2* 100 2* /
GRID
DXV
5.0D0 10.0D0 2*20.0D0 45.0D0 95*50.0D0
/
DYV
21*4.285714D0
/
DZV
20*0.5D0
/
TOPS
2100*1000.0D0
/
EDIT
ADD
'TRANX' 0.10 /
/
)";
Opm::Parser parser;
return parser.parseString(input);
}
BOOST_AUTO_TEST_CASE(TRANXADD) {
Opm::Deck deck = createAddDeck();
Opm::TableManager tables(deck);
Opm::EclipseGrid grid(deck);
BOOST_CHECK_THROW(Opm::Eclipse3DProperties(deck, tables, grid), std::invalid_argument);
}
static Opm::Deck createMultiplyPorvDeck() {
const auto* input = R"(
RUNSPEC
TITLE
'TITTEL'
DIMENS
10 10 5 /
METRIC
OIL
WATER
TABDIMS
/
START
19 JUN 2017
/
EQLDIMS
2* 100 2* /
GRID
DX
500*10
/
DY
500*10
/
DZ
500*10
/
TOPS
100*1000.0D0
/
PORO
500*0.5
/
MULTIPLY
PORV 0.2 /
/
BOX
1 2 1 2 1 1 /
MULTIPLY
PORV 0.1 /
/
ENDBOX
ADD
PORV 1.0 2 2 1 1 1 1 /
/
MULTIPLY
PORV 0.2 1 1 1 1 2 2 /
/
)";
Opm::Parser parser;
return parser.parseString(input);
}
BOOST_AUTO_TEST_CASE(DefaultedBoxMultiplyPorv) {
const Setup s(createMultiplyPorvDeck());
const auto& porv = s.props.getDoubleGridProperty("PORV").getData();
const auto& grid = s.grid;
BOOST_CHECK_CLOSE( porv[grid.getGlobalIndex(9,9,4)], 100, 1e-5);
BOOST_CHECK_CLOSE( porv[grid.getGlobalIndex(0,0,1)], 20, 1e-5);
BOOST_CHECK_CLOSE( porv[grid.getGlobalIndex(0,0,0)], 10, 1e-5);
BOOST_CHECK_CLOSE( porv[grid.getGlobalIndex(1,0,0)], 11, 1e-5);
}
static Opm::Deck createMultiplyPorvFailDeck() {
const auto* input = R"(
RUNSPEC
TITLE
'TITTEL'
DIMENS
10 10 5 /
METRIC
OIL
WATER
TABDIMS
/
START
19 JUN 2017
/
EQLDIMS
2* 100 2* /
GRID
DX
500*10
/
DY
500*10
/
DZ
500*10
/
TOPS
100*1000.0D0
/
MULTIPLY
PORV 0.2 /
/
)";
Opm::Parser parser;
return parser.parseString(input);
}
BOOST_AUTO_TEST_CASE(DefaultedBoxFailMultiply) {
// PORO has not been defined
BOOST_CHECK_THROW( const Setup s(createMultiplyPorvFailDeck()), std::logic_error);
}

View File

@ -30,12 +30,9 @@ along with OPM. If not, see <http://www.gnu.org/licenses/>.
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/checkDeck.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Fault.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaultCollection.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>

View File

@ -33,10 +33,8 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
@ -113,99 +111,6 @@ static Opm::Deck createDeckUnInitialized() {
}
static Opm::Deck createValidIntDeck() {
const char* deckData =
"RUNSPEC\n"
"GRIDOPTS\n"
" 'YES' 2 /"
"\n"
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"FLUXNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"/\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"/\n"
"EQUALREG\n"
" SATNUM 11 1 M / \n"
" SATNUM 20 2 / \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
static Opm::Deck createValidPERMXDeck() {
const char* deckData =
"RUNSPEC\n"
"GRIDOPTS\n"
" 'YES' 2 /"
"\n"
"DIMENS\n"
" 5 5 1 /\n"
"GRID\n"
"DX\n"
"25*0.25 /\n"
"DY\n"
"25*0.25 /\n"
"DZ\n"
"25*0.25 /\n"
"TOPS\n"
"25*0.25 /\n"
"MULTNUM \n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"1 1 2 2 2\n"
"/\n"
"BOX\n"
" 1 2 1 5 1 1 / \n"
"PERMZ\n"
" 10*1 /\n"
"ENDBOX\n"
"BOX\n"
" 3 5 1 5 1 1 / \n"
"PERMZ\n"
" 15*2 /\n"
"ENDBOX\n"
"EQUALREG\n"
" PERMX 1 1 / \n"
" PERMX 2 2 / \n"
"/\n"
"EQUALS\n"
" PERMY 1 1 2 1 5 1 1 / \n"
" PERMY 2 3 5 1 5 1 1 / \n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
BOOST_AUTO_TEST_CASE(InvalidArrayThrows) {
@ -229,32 +134,3 @@ BOOST_AUTO_TEST_CASE(UnInitializedVectorThrows) {
BOOST_CHECK_THROW( new Opm::EclipseState( deck) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(IntSetCorrectly) {
Opm::Deck deck = createValidIntDeck();
Opm::TableManager tm(deck);
Opm::EclipseGrid eg(deck);
Opm::Eclipse3DProperties props(deck, tm, eg);
const auto& property = props.getIntGridProperty("SATNUM").getData();
for (size_t j = 0; j < 5; j++)
for (size_t i = 0; i < 5; i++) {
std::size_t g = eg.getGlobalIndex(i,j,0);
if (i < 2)
BOOST_CHECK_EQUAL(11, property[g]);
else
BOOST_CHECK_EQUAL(20, property[g]);
}
}
BOOST_AUTO_TEST_CASE(UnitAppliedCorrectly) {
Opm::Deck deck = createValidPERMXDeck();
Opm::TableManager tm(deck);
Opm::EclipseGrid eg(deck);
Opm::Eclipse3DProperties props(deck, tm, eg);
const auto& permx = props.getDoubleGridProperty("PERMX").getData();
const auto& permy = props.getDoubleGridProperty("PERMY").getData();
const auto& permz = props.getDoubleGridProperty("PERMZ").getData();
for (size_t g = 0; g < 25; g++) {
BOOST_CHECK_EQUAL(permz[g], permx[g]);
BOOST_CHECK_EQUAL(permy[g], permx[g]);
}
}

View File

@ -1,799 +0,0 @@
/*
Copyright 2014 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 <stdexcept>
#include <iostream>
#include <memory>
#define BOOST_TEST_MODULE EclipseGridTests
#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
static const Opm::DeckKeyword createSATNUMKeyword( ) {
const char* deckData =
"SATNUM \n"
" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 / \n"
"\n";
Opm::Parser parser;
Opm::Deck deck = parser.parseString(deckData);
return deck.getKeyword("SATNUM");
}
static const Opm::DeckKeyword createTABDIMSKeyword( ) {
const char* deckData =
"TABDIMS\n"
" 0 1 2 3 4 5 / \n"
"\n";
Opm::Parser parser;
Opm::Deck deck = parser.parseString(deckData);
return deck.getKeyword("TABDIMS");
}
BOOST_AUTO_TEST_CASE(Empty) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("SATNUM" , 77, "1");
Opm::GridProperty<int> gridProperty( 5 , 5 , 4 , keywordInfo);
const std::vector<int>& data = gridProperty.getData();
BOOST_CHECK_EQUAL( 100U , data.size());
BOOST_CHECK_EQUAL( 100U , gridProperty.getCartesianSize());
BOOST_CHECK_EQUAL( 5U , gridProperty.getNX());
BOOST_CHECK_EQUAL( 5U , gridProperty.getNY());
BOOST_CHECK_EQUAL( 4U , gridProperty.getNZ());
for (size_t k=0; k < 4; k++) {
for (size_t j=0; j < 5; j++) {
for (size_t i=0; i < 5; i++) {
size_t g = i + j*5 + k*25;
BOOST_CHECK_EQUAL( 77 , data[g] );
}
}
}
}
BOOST_AUTO_TEST_CASE(HasNAN) {
double nan = std::numeric_limits<double>::quiet_NaN();
typedef Opm::GridProperty<double>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("PORO" , nan , "1");
Opm::GridProperty<double> poro( 2 , 2 , 1 , keywordInfo);
BOOST_CHECK( poro.containsNaN() );
auto data = poro.getData();
data[0] = 0.15;
data[1] = 0.15;
data[2] = 0.15;
poro.assignData(data);
BOOST_CHECK( poro.containsNaN() );
data[3] = 0.15;
poro.assignData(data);
BOOST_CHECK( !poro.containsNaN() );
}
BOOST_AUTO_TEST_CASE(EmptyDefault) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("SATNUM" , 0, "1");
Opm::GridProperty<int> gridProperty( /*nx=*/10,
/*ny=*/10,
/*nz=*/1 ,
keywordInfo);
const std::vector<int>& data = gridProperty.getData();
BOOST_CHECK_EQUAL( 100U , data.size());
for (size_t i=0; i < data.size(); i++)
BOOST_CHECK_EQUAL( 0 , data[i] );
}
BOOST_AUTO_TEST_CASE(SetFromDeckKeyword_notData_Throws) {
const auto& tabdimsKw = createTABDIMSKeyword();
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("TABDIMS" , 100, "1");
Opm::GridProperty<int> gridProperty( 6 ,1,1 , keywordInfo);
BOOST_CHECK_THROW( gridProperty.loadFromDeckKeyword( tabdimsKw, false ) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(SetFromDeckKeyword_wrong_size_throws) {
const auto& satnumKw = createSATNUMKeyword();
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("SATNUM" , 66, "1");
Opm::GridProperty<int> gridProperty( 15 ,1,1, keywordInfo);
BOOST_CHECK_THROW( gridProperty.loadFromDeckKeyword( satnumKw, false ) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(SetFromDeckKeyword) {
const auto& satnumKw = createSATNUMKeyword();
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("SATNUM" , 99, "1");
Opm::GridProperty<int> gridProperty( 4 , 4 , 2 , keywordInfo);
gridProperty.loadFromDeckKeyword( satnumKw, false );
const std::vector<int>& data = gridProperty.getData();
for (size_t k=0; k < 2; k++) {
for (size_t j=0; j < 4; j++) {
for (size_t i=0; i < 4; i++) {
size_t g = i + j*4 + k*16;
BOOST_CHECK_EQUAL( g , data[g] );
}
}
}
}
BOOST_AUTO_TEST_CASE(copy) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo1("P1", 0, "1");
SupportedKeywordInfo keywordInfo2("P2", 9, "1");
Opm::GridProperty<int> prop1(4, 4, 2, keywordInfo1);
Opm::GridProperty<int> prop2(4, 4, 2, keywordInfo2);
Opm::EclipseGrid grid(4,4,2);
Opm::Box global(grid);
Opm::Box layer0(grid, 0, 3, 0, 3, 0, 0);
prop2.copyFrom(prop1, layer0);
const auto& prop2_data = prop2.getData();
for (size_t j = 0; j < 4; j++) {
for (size_t i = 0; i < 4; i++) {
std::size_t g1 = i + j*4;
std::size_t g2 = g1 + 16;
BOOST_CHECK_EQUAL(prop2_data[g1], 0);
BOOST_CHECK_EQUAL(prop2_data[g2], 9);
}
}
}
BOOST_AUTO_TEST_CASE(SCALE) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo1( "P1", 1, "1" );
SupportedKeywordInfo keywordInfo2( "P2", 9, "1" );
Opm::GridProperty<int> prop1( 4, 4, 2, keywordInfo1 );
Opm::GridProperty<int> prop2( 4, 4, 2, keywordInfo2 );
Opm::EclipseGrid grid(4,4,2);
Opm::Box global(grid);
Opm::Box layer0(grid, 0, 3, 0, 3, 0, 0);
prop2.copyFrom( prop1, layer0 );
prop2.scale( 2, global );
prop2.scale( 2, layer0 );
const auto& prop2_data = prop2.getData();
for (size_t j = 0; j < 4; j++) {
for (size_t i = 0; i < 4; i++) {
std::size_t g1 = i + j*4;
std::size_t g2 = g1 + 16;
BOOST_CHECK_EQUAL( prop2_data[g1], 4 );
BOOST_CHECK_EQUAL( prop2_data[g2], 18 );
}
}
}
BOOST_AUTO_TEST_CASE(SET) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo( "P1", 1, "1" );
Opm::GridProperty<int> prop( 4, 4, 2, keywordInfo );
Opm::EclipseGrid grid(4,4,2);
Opm::Box global(grid);
Opm::Box layer0(grid, 0, 3, 0, 3, 0, 0);
prop.setScalar( 2, global );
prop.setScalar( 4, layer0 );
const auto& prop_data = prop.getData();
for (size_t j = 0; j < 4; j++) {
for (size_t i = 0; i < 4; i++) {
std::size_t g1 = i + j*4;
std::size_t g2 = g1 + 16;
BOOST_CHECK_EQUAL( prop_data[g1], 4 );
BOOST_CHECK_EQUAL( prop_data[g2], 2 );
}
}
}
BOOST_AUTO_TEST_CASE(ADD) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo1( "P1", 1, "1", true );
SupportedKeywordInfo keywordInfo2( "P2", 9, "1", true );
Opm::GridProperty<int> prop1( 4, 4, 2, keywordInfo1 );
Opm::GridProperty<int> prop2( 4, 4, 2, keywordInfo2 );
Opm::EclipseGrid grid(4,4,2);
Opm::Box global(grid);
Opm::Box layer0(grid, 0, 3, 0, 3, 0, 0);
prop2.copyFrom( prop1, layer0 );
prop2.add( 2, global );
prop2.add( 2, layer0 );
const auto& prop2_data = prop2.getData();
for (size_t j = 0; j < 4; j++) {
for (size_t i = 0; i < 4; i++) {
std::size_t g1 = i + j*4;
std::size_t g2 = g1 + 16;
BOOST_CHECK_EQUAL( prop2_data[g1], 5 );
BOOST_CHECK_EQUAL( prop2_data[g2], 11 );
}
}
}
BOOST_AUTO_TEST_CASE(GridPropertyInitialization) {
const char* deckString =
"RUNSPEC\n"
"\n"
"OIL\n"
"GAS\n"
"WATER\n"
"TABDIMS\n"
"3 /\n"
"\n"
"METRIC\n"
"\n"
"DIMENS\n"
"3 3 3 /\n"
"\n"
"GRID\n"
"\n"
"PERMX\n"
" 27*1000 /\n"
"MAXVALUE\n"
" PERMX 100 4* 1 1/\n"
"/\n"
"MINVALUE\n"
" PERMX 10000 4* 3 3/\n"
"/\n"
"ACTNUM\n"
" 0 8*1 0 8*1 0 8*1 /\n"
"DXV\n"
"1 1 1 /\n"
"\n"
"DYV\n"
"1 1 1 /\n"
"\n"
"DZV\n"
"1 1 1 /\n"
"\n"
"TOPS\n"
"9*100 /\n"
"\n"
"PORO \n"
" 27*0.15 /\n"
"PROPS\n"
"\n"
"SWOF\n"
// table 1
// S_w k_r,w k_r,o p_c,ow
" 0.1 0 1.0 2.0\n"
" 0.15 0 0.9 1.0\n"
" 0.2 0.01 0.5 0.5\n"
" 0.93 0.91 0.0 0.0\n"
"/\n"
// table 2
// S_w k_r,w k_r,o p_c,ow
" 0.00 0 1.0 2.0\n"
" 0.05 0.01 1.0 2.0\n"
" 0.10 0.02 0.9 1.0\n"
" 0.15 0.03 0.5 0.5\n"
" 0.852 1.00 0.0 0.0\n"
"/\n"
// table 3
// S_w k_r,w k_r,o p_c,ow
" 0.00 0.00 0.9 2.0\n"
" 0.05 0.02 0.8 1.0\n"
" 0.10 0.03 0.5 0.5\n"
" 0.801 1.00 0.0 0.0\n"
"/\n"
"\n"
"SGOF\n"
// table 1
// S_g k_r,g k_r,o p_c,og
" 0.00 0.00 0.9 2.0\n"
" 0.05 0.02 0.8 1.0\n"
" 0.10 0.03 0.5 0.5\n"
" 0.80 1.00 0.0 0.0\n"
"/\n"
// table 2
// S_g k_r,g k_r,o p_c,og
" 0.05 0.00 1.0 2\n"
" 0.10 0.02 0.9 1\n"
" 0.15 0.03 0.5 0.5\n"
" 0.85 1.00 0.0 0\n"
"/\n"
// table 3
// S_g k_r,g k_r,o p_c,og
" 0.1 0 1.0 2\n"
" 0.15 0 0.9 1\n"
" 0.2 0.01 0.5 0.5\n"
" 0.9 0.91 0.0 0\n"
"/\n"
"\n"
"SWU\n"
"27* /\n"
"\n"
"ISGU\n"
"27* /\n"
"\n"
"SGCR\n"
"27* /\n"
"\n"
"ISGCR\n"
"27* /\n"
"\n"
"REGIONS\n"
"\n"
"SATNUM\n"
"9*1 9*2 9*3 /\n"
"\n"
"IMBNUM\n"
"9*3 9*2 9*1 /\n"
"\n"
"SOLUTION\n"
"\n"
"SCHEDULE\n";
Opm::Parser parser;
auto deck = parser.parseString(deckString);
Opm::TableManager tm(deck);
Opm::EclipseGrid eg(deck);
Opm::Eclipse3DProperties props(deck, tm, eg);
Opm::FieldPropsManager fp(deck, eg, tm);
// make sure that Eclipse3DProperties throws if it is bugged about an _unsupported_ keyword
BOOST_CHECK_THROW(props.hasDeckIntGridProperty("ISWU"), std::logic_error);
BOOST_CHECK_THROW(props.hasDeckDoubleGridProperty("FLUXNUM"), std::logic_error);
// The FieldPropsManager will just return false if you ask for a unsupported keyword.
BOOST_CHECK(!fp.has<int>("ISWU"));
BOOST_CHECK(!fp.has<double>("FLUXNUM"));
// make sure that Eclipse3DProperties does not throw if it is asked for a supported
// grid property that is not contained in the deck
BOOST_CHECK_NO_THROW(props.hasDeckDoubleGridProperty("ISWU"));
BOOST_CHECK_NO_THROW(props.hasDeckIntGridProperty("FLUXNUM"));
BOOST_CHECK(!fp.has<int>("FLUXNUM"));
BOOST_CHECK(!fp.has<double>("ISWU"));
BOOST_CHECK(!props.hasDeckDoubleGridProperty("ISWU"));
BOOST_CHECK(!props.hasDeckIntGridProperty("FLUXNUM"));
for (const auto& kw : {"SATNUM", "IMBNUM"}) {
BOOST_CHECK(props.hasDeckIntGridProperty(kw));
BOOST_CHECK(fp.has<int>(kw));
}
for (const auto& kw : {"SWU", "ISGU", "SGCR", "ISGCR"}) {
BOOST_CHECK(props.hasDeckDoubleGridProperty(kw));
BOOST_CHECK(fp.has<double>(kw));
}
const auto& swuPropData = props.getDoubleGridProperty("SWU").getData();
BOOST_CHECK_EQUAL(swuPropData[1 + 0 * 3*3], 0.93);
BOOST_CHECK_EQUAL(swuPropData[1 + 1 * 3*3], 0.852);
BOOST_CHECK_EQUAL(swuPropData[1 + 2 * 3*3], 0.801);
const auto& fp_swu = fp.get_global<double>("SWU");
BOOST_CHECK_EQUAL(fp_swu[1 + 0 * 3*3], 0.93);
BOOST_CHECK_EQUAL(fp_swu[1 + 1 * 3*3], 0.852);
BOOST_CHECK_EQUAL(fp_swu[1 + 2 * 3*3], 0.801);
const auto& sguPropData = props.getDoubleGridProperty("ISGU").getData();
BOOST_CHECK_EQUAL(sguPropData[1 + 0 * 3*3], 0.9);
BOOST_CHECK_EQUAL(sguPropData[1 + 1 * 3*3], 0.85);
BOOST_CHECK_EQUAL(sguPropData[1 + 2 * 3*3], 0.80);
const auto& fp_sgu = fp.get_global<double>("ISGU");
BOOST_CHECK_EQUAL(fp_sgu[1 + 0 * 3*3], 0.9);
BOOST_CHECK_EQUAL(fp_sgu[1 + 1 * 3*3], 0.85);
BOOST_CHECK_EQUAL(fp_sgu[1 + 2 * 3*3], 0.80);
const auto& fp_sogcr = fp.get_global<double>("SOGCR");
const auto& prop_sogcr = props.getDoubleGridProperty("SOGCR").getData();
for (std::size_t g=0; g < eg.getCartesianSize(); g++) {
if (eg.cellActive(g))
BOOST_CHECK_EQUAL(fp_sogcr[g], prop_sogcr[g]);
}
const auto& satnum = props.getIntGridProperty("SATNUM");
{
const auto& activeMap = eg.getActiveMap();
const auto cells1 = satnum.cellsEqual(1 , activeMap);
const auto cells2 = satnum.cellsEqual(2 , activeMap);
const auto cells3 = satnum.cellsEqual(3 , activeMap);
BOOST_CHECK_EQUAL( cells1.size() , 8 );
BOOST_CHECK_EQUAL( cells2.size() , 8 );
BOOST_CHECK_EQUAL( cells3.size() , 8 );
for (size_t i = 0; i < 8; i++) {
BOOST_CHECK_EQUAL( cells1[i] , i );
BOOST_CHECK_EQUAL( cells2[i] , i + 8);
BOOST_CHECK_EQUAL( cells3[i] , i + 16);
}
}
const auto& fp_satnum = fp.get_global<int>("SATNUM");
{
BOOST_CHECK_EQUAL(8, std::count(fp_satnum.begin(), fp_satnum.end(), 1));
BOOST_CHECK_EQUAL(8, std::count(fp_satnum.begin(), fp_satnum.end(), 2));
BOOST_CHECK_EQUAL(8, std::count(fp_satnum.begin(), fp_satnum.end(), 3));
for (size_t i = 0; i < 7; i++) {
BOOST_CHECK_EQUAL( fp_satnum[1 + i] , 1 );
BOOST_CHECK_EQUAL( fp_satnum[1 + i + 9] , 2);
BOOST_CHECK_EQUAL( fp_satnum[1 + i + 18] , 3);
}
}
{
const auto cells1 = satnum.indexEqual(1 );
const auto cells2 = satnum.indexEqual(2 );
const auto cells3 = satnum.indexEqual(3 );
BOOST_CHECK_EQUAL( cells1.size() , 9 );
BOOST_CHECK_EQUAL( cells2.size() , 9 );
BOOST_CHECK_EQUAL( cells3.size() , 9 );
for (size_t i = 0; i < 9; i++) {
BOOST_CHECK_EQUAL( cells1[i] , i );
BOOST_CHECK_EQUAL( cells2[i] , i + 9);
BOOST_CHECK_EQUAL( cells3[i] , i + 18);
}
}
{
const auto cells3_a = satnum.cellsEqual(3 , eg);
const auto cells3_g = satnum.cellsEqual(3 , eg , false);
for (size_t i = 0; i < 8; i++) {
BOOST_CHECK_EQUAL( cells3_a[i] , i + 16);
BOOST_CHECK_EQUAL( cells3_g[i] , i + 18);
}
BOOST_CHECK_EQUAL( cells3_g[8] , 26);
}
const auto compressedSatnum = satnum.compressedCopy( eg );
BOOST_CHECK_EQUAL( compressedSatnum.size() , eg.getNumActive());
for (size_t i=0; i < eg.getNumActive(); i++) {
size_t g = eg.getGlobalIndex( i );
BOOST_CHECK_EQUAL( compressedSatnum[i] , satnum.getData()[g]);
}
{
const auto& double_props = props.getDoubleProperties( );
BOOST_CHECK( !double_props.hasKeyword( "NTG" ));
double_props.assertKeyword("NTG");
BOOST_CHECK( double_props.hasKeyword( "NTG" ));
}
{
const auto& double_props = props.getDoubleProperties( );
const auto& units = deck.getActiveUnitSystem();
const auto& permx = double_props.getKeyword("PERMX").getData();
BOOST_CHECK_EQUAL(permx[0], units.to_si(Opm::UnitSystem::measure::permeability, 100));
BOOST_CHECK_EQUAL(permx[9], units.to_si(Opm::UnitSystem::measure::permeability, 1000));
BOOST_CHECK_EQUAL(permx[18], units.to_si(Opm::UnitSystem::measure::permeability, 10000));
}
}
inline void TestPostProcessorMul(std::vector< double >& values,
const Opm::TableManager*,
const Opm::EclipseGrid*,
Opm::GridProperties<int>*,
Opm::GridProperties<double>*)
{
for( size_t g = 0; g < values.size(); g++ )
values[g] *= 2.0;
}
BOOST_AUTO_TEST_CASE(multiply) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo("P" , 10 , "1");
Opm::GridProperty<int> p1( 5 , 5 , 4 , keywordInfo);
Opm::GridProperty<int> p2( 5 , 5 , 5 , keywordInfo);
Opm::GridProperty<int> p3( 5 , 5 , 4 , keywordInfo);
BOOST_CHECK_THROW( p1.multiplyWith(p2) , std::invalid_argument );
p1.multiplyWith(p3);
const auto& data = p1.getData();
for (size_t g = 0; g < p1.getCartesianSize(); g++)
BOOST_CHECK( 100 == data[g]);
}
BOOST_AUTO_TEST_CASE(mask_test) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo1("P" , 10 , "1");
SupportedKeywordInfo keywordInfo2("P" , 20 , "1");
Opm::GridProperty<int> p1( 5 , 5 , 4 , keywordInfo1);
Opm::GridProperty<int> p2( 5 , 5 , 4 , keywordInfo2);
std::vector<bool> mask;
p1.initMask(10 , mask);
p2.maskedSet( 10 , mask);
const auto& d1 = p1.getData();
const auto& d2 = p2.getData();
BOOST_CHECK(d1 == d2);
}
BOOST_AUTO_TEST_CASE(CheckLimits) {
typedef Opm::GridProperty<int>::SupportedKeywordInfo SupportedKeywordInfo;
SupportedKeywordInfo keywordInfo1("P" , 1 , "1");
Opm::GridProperty<int> p1( 5 , 5 , 4 , keywordInfo1);
p1.checkLimits(0,2);
BOOST_CHECK_THROW( p1.checkLimits(-2,0) , std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(PropertiesEmpty) {
typedef Opm::GridProperties<int>::SupportedKeywordInfo SupportedKeywordInfo;
std::vector<SupportedKeywordInfo> supportedKeywords = {
SupportedKeywordInfo("SATNUM" , 0, "1"),
SupportedKeywordInfo("FIPNUM" , 2, "1")
};
const Opm::EclipseGrid grid(10, 7, 9);
Opm::GridProperties<int> gridProperties(grid, std::move(supportedKeywords));
BOOST_CHECK( gridProperties.supportsKeyword("SATNUM") );
BOOST_CHECK( gridProperties.supportsKeyword("FIPNUM") );
BOOST_CHECK( !gridProperties.supportsKeyword("FLUXNUM") );
BOOST_CHECK( !gridProperties.hasKeyword("SATNUM"));
BOOST_CHECK( !gridProperties.hasKeyword("FLUXNUM"));
BOOST_CHECK_THROW( gridProperties.getDeckKeyword("SATNUM") , std::invalid_argument);
BOOST_CHECK_THROW( gridProperties.getDeckKeyword("NONONO") , std::invalid_argument);
}
BOOST_AUTO_TEST_CASE(addKeyword) {
typedef Opm::GridProperties<int>::SupportedKeywordInfo SupportedKeywordInfo;
std::vector<SupportedKeywordInfo> supportedKeywords = {
SupportedKeywordInfo("SATNUM" , 0, "1")
};
Opm::EclipseGrid grid(10,7,9);
Opm::GridProperties<int> gridProperties(grid, std::move( supportedKeywords ));
BOOST_CHECK_THROW( gridProperties.addKeyword("NOT-SUPPORTED"), std::invalid_argument);
BOOST_CHECK( gridProperties.addKeyword("SATNUM"));
BOOST_CHECK( !gridProperties.addKeyword("SATNUM"));
BOOST_CHECK( gridProperties.hasKeyword("SATNUM"));
}
BOOST_AUTO_TEST_CASE(hasKeyword_assertKeyword) {
typedef Opm::GridProperties<int>::SupportedKeywordInfo SupportedKeywordInfo;
std::vector<SupportedKeywordInfo> supportedKeywords = {
SupportedKeywordInfo("SATNUM" , 0, "1", true),
SupportedKeywordInfo("FIPNUM" , 0, "1", true)
};
const Opm::EclipseGrid grid(10, 7, 9);
const Opm::GridProperties<int> gridProperties( grid, std::move( supportedKeywords ) );
// calling getKeyword() should not change the semantics of hasKeyword()!
BOOST_CHECK(!gridProperties.hasKeyword("SATNUM"));
BOOST_CHECK(!gridProperties.hasKeyword("FIPNUM"));
gridProperties.assertKeyword("FIPNUM");
gridProperties.getKeyword("SATNUM");
BOOST_CHECK(gridProperties.hasKeyword("SATNUM"));
BOOST_CHECK(gridProperties.hasKeyword("FIPNUM"));
BOOST_CHECK_THROW( gridProperties.getKeyword( "NOT-SUPPORTED" ), std::invalid_argument );
}
// =====================================================================
namespace {
struct Setup
{
Setup(const ::Opm::Deck& deck)
: tabMgr{ deck }
, eGrid { deck }
, props { deck, tabMgr, eGrid }
{}
Setup(const std::string& input)
: Setup(::Opm::Parser{}.parseString(input))
{}
::Opm::TableManager tabMgr;
::Opm::EclipseGrid eGrid;
::Opm::Eclipse3DProperties props;
};
} // Anonymous
BOOST_AUTO_TEST_CASE(EndScale_Horizontal)
{
const auto input = std::string { R"(
RUNSPEC
TITLE
Defaulted SOWCR
DIMENS
5 5 1 /
OIL
WATER
METRIC
ENDSCALE
/
TABDIMS
/
GRID
DXV
5*100
/
DYV
5*100
/
DZV
10
/
TOPS
25*2000 /
PROPS
SWOF
0.0 0.0 1.0 0.0
1.0 1.0 0.0 0.0
/
SOWCR
1* 1* 1* 1* 1*
1* 0.2 0.3 0.4 1*
1* 0.3 1* 0.5 1*
1* 0.4 0.5 0.6 1*
1* 1* 1* 1* 1* /
SWL
0.1 0.1 0.1 0.1 0.1
0.1 0.2 0.3 0.4 0.1
0.1 0.3 0.1 0.5 0.1
0.1 0.4 0.5 0.6 0.1
0.1 0.1 0.1 0.1 0.1 /
BOX
1 5 2 2 1 1 /
SWU
5*0.23 /
EQUALS
SWU 0.8 2 2 3 4 1 1 / Two elements
SWU 0.7 4 4 3 3 1 1 / Single element
/
-- Adds value to a defaulted value, should still be treated as defaulted
ADD
SWU 0.05 3 3 5 5 1 1 /
/
-- Assigns new value (no longer defaulted)
MINVALUE
SWU 0.3 5 5 5 5 1 1 /
/
END)" };
const auto cse = Setup{ input };
{
BOOST_CHECK(cse.props.hasDeckDoubleGridProperty("SOWCR"));
const auto& sowcr = cse.props.getDoubleGridProperty("SOWCR");
const auto& dflt = sowcr.wasDefaulted();
const auto T = true;
const auto F = false;
const auto expect_dflt = std::vector<bool> {
T, T, T, T, T,
T, F, F, F, T,
T, F, T, F, T,
T, F, F, F, T,
T, T, T, T, T,
};
BOOST_CHECK_EQUAL_COLLECTIONS(dflt .begin(), dflt .end(),
expect_dflt.begin(), expect_dflt.end());
}
{
BOOST_CHECK(cse.props.hasDeckDoubleGridProperty("SWL"));
const auto& swl = cse.props.getDoubleGridProperty("SWL");
const auto& dflt = swl.wasDefaulted();
const auto expect_dflt =
std::vector<bool>(cse.eGrid.getNumActive(), false);
BOOST_CHECK_EQUAL_COLLECTIONS(dflt .begin(), dflt .end(),
expect_dflt.begin(), expect_dflt.end());
}
{
BOOST_CHECK(cse.props.hasDeckDoubleGridProperty("SWU"));
const auto& swu = cse.props.getDoubleGridProperty("SWU");
const auto& dflt = swu.wasDefaulted();
const auto T = true;
const auto F = false;
const auto expect_dflt = std::vector<bool> {
T, T, T, T, T,
F, F, F, F, F,
T, F, T, F, T,
T, F, T, T, T,
T, T, T, T, F,
};
BOOST_CHECK_EQUAL_COLLECTIONS(dflt .begin(), dflt .end(),
expect_dflt.begin(), expect_dflt.end());
}
}

View File

@ -33,8 +33,6 @@
#include <opm/parser/eclipse/EclipseState/Grid/MULTREGTScanner.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FaceDir.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>

View File

@ -30,10 +30,8 @@
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
static Opm::Deck createDeckInvalidArray() {
@ -229,39 +227,12 @@ BOOST_AUTO_TEST_CASE(UnInitializedVectorThrows) {
BOOST_CHECK_THROW( new Opm::EclipseState( deck) , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(IntSetCorrectly) {
Opm::Deck deck = createValidIntDeck();
Opm::TableManager tm(deck);
Opm::EclipseGrid eg(deck);
Opm::Eclipse3DProperties props(deck, tm, eg);
const auto& property_data = props.getIntGridProperty("SATNUM").getData();
for (size_t j = 0; j < 5; j++)
for (size_t i = 0; i < 5; i++) {
if (i < 2)
BOOST_CHECK_EQUAL(11, property_data[eg.getGlobalIndex(i,j,0)]);
else
BOOST_CHECK_EQUAL(40, property_data[eg.getGlobalIndex(i,j,0)]);
}
}
BOOST_AUTO_TEST_CASE(Test_OPERATER) {
Opm::Deck deck = createValidIntDeck();
Opm::TableManager tm(deck);
Opm::EclipseGrid eg(deck);
Opm::Eclipse3DProperties props(deck, tm, eg);
Opm::FieldPropsManager fp(deck, eg, tm);
const auto& porv_data = props.getDoubleGridProperty("PORV").getData();
const auto& permx_data = props.getDoubleGridProperty("PERMX").getData();
const auto& permy_data = props.getDoubleGridProperty("PERMY").getData();
BOOST_CHECK_EQUAL( porv_data[0], 0.50 );
BOOST_CHECK_EQUAL( permx_data[0] / permy_data[0], 0.50 );
BOOST_CHECK_EQUAL( permx_data[1], permy_data[1]);
const auto& porv = fp.porv(true);
const auto& permx = fp.get_global<double>("PERMX");
const auto& permy = fp.get_global<double>("PERMY");

View File

@ -1,465 +0,0 @@
/*
Copyright 2014 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 <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE PORVTESTS
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
static Opm::Deck createCARTDeck() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
static Opm::Deck createDeckWithPORO() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"PORO\n"
"100*0.10 100*0.20 100*0.30 100*0.40 100*0.50 100*0.60 100*0.70 100*0.80 100*0.90 100*1.0 /\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
static Opm::Deck createDeckWithPORVPORO() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"BOX \n"
"1 10 1 10 1 1 /\n"
"PORV\n"
"100*77 /\n"
"ENDBOX \n"
"PORO\n"
"100*0.10 100*0.20 100*0.30 100*0.40 100*0.50 100*0.60 100*0.70 100*0.80 100*0.90 100*1.0 /\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
static Opm::Deck createDeckWithMULTPV() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"BOX \n"
"1 10 1 10 1 1 /\n"
"PORV\n"
"100*77 /\n"
"ENDBOX \n"
"PORO\n"
"100*0.10 100*0.20 100*0.30 100*0.40 100*0.50 100*0.60 100*0.70 100*0.80 100*0.90 100*1.0 /\n"
"EDIT\n"
"BOX \n"
"1 5 1 5 1 1 /\n"
"MULTPV\n"
"25*10 / \n"
"ENDBOX \n"
"BOX \n"
"1 10 1 10 10 10 /\n"
"MULTPV\n"
"100*10 / \n"
"ENDBOX \n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
static Opm::Deck createDeckWithBOXPORV() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"PORV\n"
"1000*123.456 /\n"
"BOX \n"
"2 3 2 3 2 3 /\n"
"PORV\n"
"8*789.012 /\n"
"ENDBOX\n"
"MULTPV\n"
"1000*10 /\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
static Opm::Deck createDeckWithNTG() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"PORO\n"
"1000*0.20 /\n"
"BOX \n"
"1 1 1 1 1 1 /\n"
"PORV \n"
"1*10 /\n"
"ENDBOX\n"
"MULTPV\n"
"1000*10 /\n"
"NTG\n"
"1000*2 /\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
static Opm::Deck createDeckWithMULTREGP() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"PORV\n"
"1000*77 /\n"
"MULTNUM\n"
"100*1 700*2 200*3 / \n"
"FLUXNUM\n"
"200*1 700*2 100*3 / \n"
"MULTREGP\n"
"1 10.0 / \n"
"1 2.0 F/ \n"
"0 123.0 F/ \n" // ignored
"2 20.0 M / \n"
"/\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
BOOST_AUTO_TEST_CASE(PORV_cartesianDeck) {
/* Check that an exception is raised if we try to create a PORV field without PORO. */
Opm::Deck deck = createCARTDeck();
Opm::TableManager tm( deck );
Opm::EclipseGrid grid( deck );
Opm::Eclipse3DProperties props( deck, tm, grid );
const auto& poro = props.getDoubleGridProperty("PORO");
BOOST_CHECK(poro.containsNaN());
BOOST_CHECK_THROW(props.getDoubleGridProperty("PORV"), std::logic_error);
}
BOOST_AUTO_TEST_CASE(PORV_initFromPoro) {
/* Check that the PORV field is correctly calculated from PORO. */
Opm::Deck deck = createDeckWithPORO();
Opm::TableManager tm( deck );
Opm::EclipseGrid grid( deck );
Opm::Eclipse3DProperties props( deck, tm, grid );
const auto& poro = props.getDoubleGridProperty("PORO");
BOOST_CHECK( !poro.containsNaN() );
const auto& porv_data = props.getDoubleGridProperty("PORV").getData();
double cell_volume = 0.25 * 0.25 * 0.25;
BOOST_CHECK_CLOSE( cell_volume * 0.10 , porv_data[grid.getGlobalIndex(0,0,0)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.10 , porv_data[grid.getGlobalIndex(9,9,0)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.50 , porv_data[grid.getGlobalIndex(0,0,4)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.50 , porv_data[grid.getGlobalIndex(9,9,4)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 1.00 , porv_data[grid.getGlobalIndex(0,0,9)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 1.00 , porv_data[grid.getGlobalIndex(9,9,9)] , 0.001);
}
BOOST_AUTO_TEST_CASE(PORV_initFromPoroWithCellVolume) {
/* Check that explicit PORV and CellVOlume * PORO can be combined. */
Opm::Deck deck = createDeckWithPORVPORO();
Opm::TableManager tm( deck );
Opm::EclipseGrid grid( deck );
Opm::Eclipse3DProperties props( deck, tm, grid );
const auto& porv_data = props.getDoubleGridProperty("PORV").getData();
double cell_volume = 0.25 * 0.25 * 0.25;
BOOST_CHECK_CLOSE( 77.0 , porv_data[grid.getGlobalIndex(0,0,0)] , 0.001);
BOOST_CHECK_CLOSE( 77.0 , porv_data[grid.getGlobalIndex(9,9,0)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.50 , porv_data[grid.getGlobalIndex(0,0,4)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.50 , porv_data[grid.getGlobalIndex(9,9,4)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 1.00 , porv_data[grid.getGlobalIndex(0,0,9)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 1.00 , porv_data[grid.getGlobalIndex(9,9,9)] , 0.001);
}
BOOST_AUTO_TEST_CASE(PORV_multpv) {
/* Check that MULTPV is correctly accounted for. */
Opm::Deck deck = createDeckWithMULTPV();
Opm::TableManager tm( deck );
Opm::EclipseGrid grid( deck );
Opm::Eclipse3DProperties props( deck, tm, grid );
const auto& porv_data = props.getDoubleGridProperty("PORV").getData();
double cell_volume = 0.25 * 0.25 * 0.25;
BOOST_CHECK_CLOSE( 770.0 , porv_data[grid.getGlobalIndex(0,0,0)] , 0.001);
BOOST_CHECK_CLOSE( 770.0 , porv_data[grid.getGlobalIndex(4,4,0)] , 0.001);
BOOST_CHECK_CLOSE( 77.0 , porv_data[grid.getGlobalIndex(9,9,0)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.50 , porv_data[grid.getGlobalIndex(0,0,4)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.50 , porv_data[grid.getGlobalIndex(9,9,4)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.90 , porv_data[grid.getGlobalIndex(0,0,8)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 0.90 , porv_data[grid.getGlobalIndex(9,9,8)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 10.00 , porv_data[grid.getGlobalIndex(0,0,9)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * 10.00 , porv_data[grid.getGlobalIndex(9,9,9)] , 0.001);
}
BOOST_AUTO_TEST_CASE(PORV_mutipleBoxAndMultpv) {
/* Check that MULTIPLE Boxed PORV and MULTPV statements work */
Opm::Deck deck = createDeckWithBOXPORV();
Opm::TableManager tm( deck );
Opm::EclipseGrid grid( deck );
Opm::Eclipse3DProperties props( deck, tm, grid );
const auto& porv_data = props.getDoubleGridProperty("PORV").getData();
BOOST_CHECK_CLOSE( 1234.56 , porv_data[grid.getGlobalIndex(0,0,0)] , 0.001);
BOOST_CHECK_CLOSE( 1234.56 , porv_data[grid.getGlobalIndex(9,9,9)] , 0.001);
BOOST_CHECK_CLOSE( 7890.12 , porv_data[grid.getGlobalIndex(1,1,1)] , 0.001);
BOOST_CHECK_CLOSE( 7890.12 , porv_data[grid.getGlobalIndex(2,2,2)] , 0.001);
}
BOOST_AUTO_TEST_CASE(PORV_multpvAndNtg) {
/* Check that MULTIPLE Boxed PORV and MULTPV statements work and NTG */
Opm::Deck deck = createDeckWithNTG();
Opm::TableManager tm( deck );
Opm::EclipseGrid grid( deck );
Opm::Eclipse3DProperties props( deck, tm, grid );
const auto& porv_data = props.getDoubleGridProperty("PORV").getData();
double cell_volume = 0.25 * 0.25 * 0.25;
double poro = 0.20;
double multpv = 10;
double NTG = 2;
double PORV = 10;
BOOST_CHECK_CLOSE( PORV * multpv , porv_data[grid.getGlobalIndex(0,0,0)] , 0.001);
BOOST_CHECK_CLOSE( cell_volume * poro*multpv*NTG , porv_data[grid.getGlobalIndex(9,9,9)] , 0.001);
}
BOOST_AUTO_TEST_CASE(PORV_multregp) {
Opm::Deck deck = createDeckWithMULTREGP();
Opm::TableManager tm( deck );
Opm::EclipseGrid grid( deck );
Opm::Eclipse3DProperties props( deck, tm, grid );
const auto& porv = props.getDoubleGridProperty("PORV");
const auto& porvData = porv.getData();
double basePorv = 77.0;
// the cumlative effect of the base pore volume is multiplied 2 for the cells in
// region 1 of FLUXNUM and by 20 for region 2 of MULTNUM. This means that the first
// 100 cels are multiplied by 2, then follow 100 cells multiplied by 2*20, then
// 600 cells multiplied by 20 while the last 200 cells are not modified at all.
for (int i=0; i < 100; ++i)
BOOST_CHECK_CLOSE(porvData[i], basePorv*2, 1e-8);
for (int i=100; i < 200; ++i)
BOOST_CHECK_CLOSE(porvData[i], basePorv*2*20, 1e-8);
for (int i=200; i < 800; ++i)
BOOST_CHECK_CLOSE(porvData[i], basePorv*20, 1e-8);
for (int i=800; i < 1000; ++i)
BOOST_CHECK_CLOSE(porvData[i], basePorv, 1e-8);
}
static Opm::Deck createDeckNakedGRID() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"PORO\n"
"100*0.10 100*0.20 100*0.30 100*0.40 100*0.50 100*0.60 100*0.70 100*0.80 100*0.90 100*1.0 /\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
BOOST_AUTO_TEST_CASE(NAKED_GRID_THROWS) {
/* Check that MULTIPLE Boxed PORV and MULTPV statements work and NTG */
Opm::Deck deck = createDeckNakedGRID();
Opm::TableManager tm( deck );
BOOST_CHECK_THROW( Opm::EclipseGrid grid( deck ), std::invalid_argument );
}
static Opm::Deck createDeckWithPOROZero() {
const char* deckData =
"RUNSPEC\n"
"\n"
"DIMENS\n"
" 10 10 10 /\n"
"GRID\n"
"DX\n"
"1000*0.25 /\n"
"DYV\n"
"10*0.25 /\n"
"DZ\n"
"1000*0.25 /\n"
"TOPS\n"
"100*0.25 /\n"
"PORO\n"
"100*0.10 100*0.20 100*0.30 100*0.40 100*0.50 100*0.60 100*0.70 100*0.80 100*0.90 100*1.0 /\n"
"EQUALS\n"
" ACTNUM 0 1 10 1 10 2 2 /\n"
"/\n"
"EQUALS\n"
" PORO 0 1 10 1 10 3 3 /\n"
"/\n"
"EQUALS\n"
" NTG 0 1 10 1 10 4 4 /\n"
"/\n"
"EDIT\n"
"\n";
Opm::Parser parser;
return parser.parseString(deckData) ;
}
BOOST_AUTO_TEST_CASE(PORO_ZERO_ACTNUM_CORRECT) {
/* Check that MULTIPLE Boxed PORV and MULTPV statements work and NTG */
Opm::Deck deck = createDeckWithPOROZero();
Opm::EclipseState state( deck);
const auto& grid = state.getInputGrid( );
/* Top layer is active */
BOOST_CHECK( grid.cellActive( 0,0,0 ));
/* Layer k=1 is inactive due to EQUAL ACTNUM */
BOOST_CHECK( !grid.cellActive(0,0,1));
/* Layer k = 2 is inactive due t PORO = 0 */
BOOST_CHECK( !grid.cellActive(0,0,2));
/* Layer k = 3 is inactive due t NTG = 0 */
BOOST_CHECK( !grid.cellActive(0,0,2));
BOOST_CHECK_EQUAL( grid.getNumActive() , 700U );
}

View File

@ -1,152 +0,0 @@
/*
Copyright 2015 IRIS
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 <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE SatfuncPropertyInitializersTests
#include <boost/test/unit_test.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
using namespace Opm;
inline void check_property(const Eclipse3DProperties& props1,
const Eclipse3DProperties& props2,
const std::string& propertyName) {
auto data1 = props1.getDoubleGridProperty(propertyName).getData();
auto data2 = props2.getDoubleGridProperty(propertyName).getData();
BOOST_CHECK_CLOSE(data1[0], data2[0], 1e-12);
}
BOOST_AUTO_TEST_CASE(SaturationFunctionFamilyTests) {
const char * deckdefault =
"RUNSPEC\n"
"OIL\n"
"GAS\n"
"WATER\n"
"DIMENS\n"
" 1 1 1 /\n"
"TABDIMS\n"
"1 /\n"
"\n"
"GRID\n"
"DX\n"
"1*0.25 /\n"
"DYV\n"
"1*0.25 /\n"
"DZ\n"
"1*0.25 /\n"
"TOPS\n"
"1*0.25 /\n"
"PORO \n"
"1*0.10 /\n"
"PERMX \n"
"10.25 /\n";
const char *family1 =
"SWOF\n"
" .2 .0 1.0 .0\n" // So = 0.8
" .3 .0 .8 .0\n" // So = 0.7
" .5 .5 .5 .0\n" // So = 0.5
" .8 .8 .0 .0\n" // So = 0.2
" 1.0 1.0 .0 .0 /\n" // So = 0.0
"SGOF\n"
" .0 .0 1.0 .0\n" // So = 0.8
" .1 .0 .3 .0\n" // So = 0.7
" .3 1* .1 .0\n" // So = 0.5
" .5 .5 .0 .0\n" // So = 0.3
" .8 1.0 .0 .0/\n"; // So = 0.0
const char *family2 =
"SWFN\n"
" .2 .0 .0\n"
" .3 .0 .0\n"
" .5 .5 .0\n"
" .8 .8 .0\n"
" 1.0 1.0 .0 /\n"
"SGFN\n"
" .0 .0 .0\n"
" .1 .0 .0\n"
" .5 .5 .0\n"
" .7 .8 .0\n"
" .8 1.0 .0/\n"
"SOF3\n"
" .0 .0 .0\n"
" .2 .0 .0\n"
" .3 1* .0\n"
" .5 .5 .1\n"
" .7 .8 .3\n"
" .8 1.0 1.0/\n";
Parser parser;
char family1Deck[500] = " ";
strcat(family1Deck , deckdefault);
strcat(family1Deck , family1);
Deck deck1 = parser.parseString(family1Deck) ;
Opm::TableManager tm1( deck1 );
Opm::EclipseGrid grid1( deck1 );
Opm::Eclipse3DProperties prop1( deck1, tm1, grid1 );
char family2Deck[700] = " ";
strcat(family2Deck , deckdefault);
strcat(family2Deck , family2);
Deck deck2 = parser.parseString(family2Deck) ;
Opm::TableManager tm2( deck2 );
Opm::EclipseGrid grid2( deck2 );
Opm::Eclipse3DProperties prop2( deck2, tm2, grid2 );
check_property(prop1, prop2, "SWL");
check_property(prop1, prop2, "SWU");
check_property(prop1, prop2, "SWCR");
check_property(prop1, prop2, "SGL");
check_property(prop1, prop2, "SGU");
check_property(prop1, prop2, "SGCR");
check_property(prop1, prop2, "SOWCR");
check_property(prop1, prop2, "SOGCR");
check_property(prop1, prop2, "PCW");
check_property(prop1, prop2, "PCG");
check_property(prop1, prop2, "KRW");
check_property(prop1, prop2, "KRO");
check_property(prop1, prop2, "KRG");
char familyMixDeck[1000] = " ";
strcat(familyMixDeck , deckdefault);
strcat(familyMixDeck , family1);
strcat(familyMixDeck , family2);
Deck deckMix = parser.parseString(familyMixDeck) ;
Opm::TableManager tmMix( deckMix );
Opm::EclipseGrid gridMix( deckMix );
Opm::Eclipse3DProperties propMix( deckMix, tmMix, gridMix );
BOOST_CHECK_THROW(propMix.getDoubleGridProperty("SGCR") , std::invalid_argument);
}

View File

@ -28,7 +28,6 @@
#include <opm/parser/eclipse/Deck/DeckSection.hpp>
#include <opm/parser/eclipse/Parser/ParserKeywords/C.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp>

View File

@ -28,15 +28,11 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperties.hpp>
using namespace Opm;

View File

@ -28,15 +28,12 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/TransMult.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridDims.hpp>
BOOST_AUTO_TEST_CASE(Empty) {
Opm::Eclipse3DProperties props;
Opm::EclipseGrid grid(10,10,10);
Opm::FieldPropsManager fp(Opm::Deck(), grid, Opm::TableManager());
Opm::TransMult transMult(grid ,{} , fp);

View File

@ -26,11 +26,9 @@
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/EclipseState/Eclipse3DProperties.hpp>
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/GridProperty.hpp>
#include <opm/parser/eclipse/EclipseState/Grid/Box.hpp>
using namespace Opm;