Compare commits
26 Commits
release/su
...
testing/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43e4f0ca87 | ||
|
|
cdf876fa15 | ||
|
|
12402916a7 | ||
|
|
0183fa884a | ||
|
|
e407e65b54 | ||
|
|
e072365234 | ||
|
|
070acf4bef | ||
|
|
451d52c18a | ||
|
|
bbb5e27e90 | ||
|
|
37ddd82545 | ||
|
|
3c90adeea9 | ||
|
|
903118736a | ||
|
|
18a22d8f68 | ||
|
|
46be17cf58 | ||
|
|
ce5c617f41 | ||
|
|
ca1833e6ed | ||
|
|
bb2e5e0370 | ||
|
|
f6cc04a4ab | ||
|
|
d6c56982cc | ||
|
|
ee6fab7395 | ||
|
|
93b8d26f86 | ||
|
|
0627a9f8ef | ||
|
|
3c88335852 | ||
|
|
4502333751 | ||
|
|
64e5d123a2 | ||
|
|
f80644b616 |
@@ -37,11 +37,13 @@ set(OPM_PROJECT_EXTRA_CODE_INTREE "#ENABLE_ECL_INPUT is needed by opm-common-pre
|
||||
if(ENABLE_ECL_OUTPUT)
|
||||
set(OPM_PROJECT_EXTRA_CODE_INSTALLED "${OPM_PROJECT_EXTRA_CODE_INSTALLED}
|
||||
set(COMPARE_SUMMARY_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/compareSummary)
|
||||
set(COMPARE_ECL_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/compareECL)")
|
||||
set(COMPARE_ECL_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/compareECL)
|
||||
set(OPM_PACK_COMMAND ${CMAKE_INSTALL_PREFIX}/bin${${name}_VER_DIR}/opmpack)")
|
||||
|
||||
set(OPM_PROJECT_EXTRA_CODE_INTREE "${OPM_PROJECT_EXTRA_CODE_INTREE}
|
||||
set(COMPARE_SUMMARY_COMMAND ${PROJECT_BINARY_DIR}/bin/compareSummary)
|
||||
set(COMPARE_ECL_COMMAND ${PROJECT_BINARY_DIR}/bin/compareECL)")
|
||||
set(COMPARE_ECL_COMMAND ${PROJECT_BINARY_DIR}/bin/compareECL)
|
||||
set(OPM_PACK_COMMAND ${PROJECT_BINARY_DIR}/bin/opmpack)")
|
||||
endif()
|
||||
|
||||
# project information is in dune.module. Read this file and set variables.
|
||||
|
||||
@@ -73,6 +73,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/IOConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/IOConfig/RestartConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Runspec.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ActionX.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Connection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellConnections.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Events.cpp
|
||||
@@ -173,6 +174,7 @@ list (APPEND TEST_SOURCE_FILES
|
||||
)
|
||||
if(ENABLE_ECL_INPUT)
|
||||
list(APPEND TEST_SOURCE_FILES
|
||||
tests/parser/ACTIONX.cpp
|
||||
tests/parser/ADDREGTests.cpp
|
||||
tests/parser/AquiferCTTests.cpp
|
||||
tests/parser/AqudimsTests.cpp
|
||||
@@ -443,6 +445,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/EclipseConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Aquancon.hpp
|
||||
opm/parser/eclipse/EclipseState/AquiferCT.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp
|
||||
|
||||
@@ -47,7 +47,7 @@ macro (opm_defaults opm)
|
||||
endif(NOT PRECOMPILE_HEADERS)
|
||||
|
||||
# Use of OpenMP is considered experimental
|
||||
set (USE_OPENMP_DEFAULT OFF)
|
||||
set (USE_OPENMP_DEFAULT ON)
|
||||
|
||||
# if we are on a system where CMake 2.6 is the default (Hi RHEL 6!),
|
||||
# the configuration files for Boost will trip up the library paths
|
||||
|
||||
@@ -228,6 +228,13 @@ macro(opm_add_test TestName)
|
||||
set(CURTEST_EXE_NAME ${TestName})
|
||||
endif()
|
||||
|
||||
# Strip test_ prefix from name
|
||||
if ("${TestName}" MATCHES "^test_([^/]*)$")
|
||||
string (REGEX REPLACE "^test_([^/]*)$" "\\1" _FANCY "${TestName}")
|
||||
else()
|
||||
set(_FANCY ${TestName})
|
||||
endif()
|
||||
|
||||
# try to auto-detect the name of the source file if SOURCES are not
|
||||
# explicitly specified.
|
||||
if (NOT CURTEST_SOURCES)
|
||||
@@ -331,7 +338,7 @@ macro(opm_add_test TestName)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_test(NAME ${TestName}
|
||||
add_test(NAME ${_FANCY}
|
||||
WORKING_DIRECTORY "${CURTEST_WORKING_DIRECTORY}"
|
||||
COMMAND ${CURTEST_COMMAND})
|
||||
|
||||
@@ -359,7 +366,7 @@ macro(opm_add_test TestName)
|
||||
# CDash dashboard. it this is removed, the test is just silently
|
||||
# ignored.
|
||||
if (NOT CURTEST_ONLY_COMPILE AND ADD_DISABLED_CTESTS)
|
||||
add_test(${TestName} skip_test_dummy)
|
||||
add_test(${_FANCY} skip_test_dummy)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -36,6 +36,7 @@ static void printHelp() {
|
||||
<< "3. Absolute tolerance\n"
|
||||
<< "4. Relative tolerance (between 0 and 1)\n\n"
|
||||
<< "In addition, the program takes these options (which must be given before the arguments):\n\n"
|
||||
<< "-a Run a full analysis of errors.\n"
|
||||
<< "-h Print help and exit.\n"
|
||||
<< "-i Execute integration test (regression test is default).\n"
|
||||
<< " The integration test compares SGAS, SWAT and PRESSURE in unified restart files, so this option can not be used in combination with -t.\n"
|
||||
@@ -114,13 +115,17 @@ int main(int argc, char** argv) {
|
||||
bool specificKeyword = false;
|
||||
bool specificFileType = false;
|
||||
bool throwOnError = true;
|
||||
bool analysis = false;
|
||||
bool volumecheck = true;
|
||||
char* keyword = nullptr;
|
||||
char* fileTypeCstr = nullptr;
|
||||
int c = 0;
|
||||
|
||||
while ((c = getopt(argc, argv, "hiIk:lnpPt:V")) != -1) {
|
||||
while ((c = getopt(argc, argv, "hiIk:alnpPt:V")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
analysis = true;
|
||||
break;
|
||||
case 'h':
|
||||
printHelp();
|
||||
return 0;
|
||||
@@ -246,6 +251,7 @@ int main(int argc, char** argv) {
|
||||
else {
|
||||
RegressionTest comparator(file_type, basename1, basename2, absTolerance, relTolerance);
|
||||
comparator.throwOnErrors(throwOnError);
|
||||
comparator.doAnalysis(analysis);
|
||||
if (printKeywords) {
|
||||
comparator.printKeywords();
|
||||
return 0;
|
||||
|
||||
@@ -37,6 +37,7 @@ void printHelp(){
|
||||
std::cout << "The program is capable of performing both a regression test and an integration test, \nhowever only one type of test at a time. ";
|
||||
std::cout << "By default the program will run a regression test."<< std::endl;
|
||||
std::cout << "\nThe program have command line options:" << std::endl;
|
||||
std::cout << "-a \tRun a full analysis of errors." << std::endl;
|
||||
std::cout << "-h \t\tPrint help message." << std::endl << std::endl;
|
||||
std::cout << "For the regression test: " << std::endl;
|
||||
std::cout << "-r \t\tChoosing regression test (this is default)."<< std::endl;
|
||||
@@ -80,6 +81,7 @@ int main (int argc, char ** argv){
|
||||
bool throwExceptionForTooGreatErrorRatio = true;
|
||||
bool isRestartFile = false;
|
||||
bool throwOnError = true;
|
||||
bool analysis = false;
|
||||
const char* keyword = nullptr;
|
||||
const char* mainVariable = nullptr;
|
||||
int c = 0;
|
||||
@@ -88,8 +90,11 @@ int main (int argc, char ** argv){
|
||||
|
||||
//------------------------------------------------
|
||||
//For setting the options selected
|
||||
while ((c = getopt(argc, argv, "dghik:Km:npP:rRs:vV:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "dghik:Km:napP:rRs:vV:")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
analysis = true;
|
||||
break;
|
||||
case 'd':
|
||||
throwExceptionForTooGreatErrorRatio = false;
|
||||
break;
|
||||
@@ -177,6 +182,7 @@ int main (int argc, char ** argv){
|
||||
if(regressionTest){
|
||||
RegressionTest compare(basename1,basename2, absoluteTolerance, relativeTolerance);
|
||||
compare.throwOnErrors(throwOnError);
|
||||
compare.doAnalysis(analysis);
|
||||
if(printKeywords){compare.setPrintKeywords(true);}
|
||||
if(isRestartFile){compare.setIsRestartFile(true);}
|
||||
if(specificKeyword){
|
||||
|
||||
@@ -16,9 +16,14 @@ then
|
||||
cp $OPM_TESTS_ROOT_PREDEFINED $WORKSPACE/deps/opm-tests -R
|
||||
fi
|
||||
else
|
||||
# Specified in trigger, download it
|
||||
source $WORKSPACE/deps/opm-common/jenkins/build-opm-module.sh
|
||||
clone_module opm-tests $OPM_TESTS_REVISION
|
||||
# We need a full repo checkout
|
||||
cp $OPM_TESTS_ROOT_PREDEFINED $WORKSPACE/deps/opm-tests -R
|
||||
pushd $WORKSPACE/deps/opm-tests
|
||||
# Then we fetch the PR branch
|
||||
git remote add PR https://github.com/OPM/opm-tests
|
||||
git fetch --depth 1 PR $OPM_TESTS_REVISION:branch_to_build
|
||||
git checkout branch_to_build
|
||||
popd
|
||||
fi
|
||||
else
|
||||
if ! test -d $WORKSPACE/deps/opm-tests
|
||||
|
||||
@@ -131,6 +131,9 @@ namespace Opm {
|
||||
|
||||
Deck( const Deck& );
|
||||
|
||||
//! \brief Deleted assignment operator.
|
||||
Deck& operator=(const Deck& rhs) = delete;
|
||||
|
||||
void addKeyword( DeckKeyword&& keyword );
|
||||
void addKeyword( const DeckKeyword& keyword );
|
||||
|
||||
@@ -141,7 +144,8 @@ namespace Opm {
|
||||
UnitSystem& getActiveUnitSystem();
|
||||
UnitSystem& getDefaultUnitSystem();
|
||||
|
||||
const std::string getDataFile() const;
|
||||
const std::string& getInputPath() const;
|
||||
const std::string& getDataFile() const;
|
||||
void setDataFile(const std::string& dataFile);
|
||||
|
||||
iterator begin();
|
||||
@@ -156,6 +160,7 @@ namespace Opm {
|
||||
UnitSystem activeUnits;
|
||||
|
||||
std::string m_dataFile;
|
||||
std::string input_path;
|
||||
};
|
||||
}
|
||||
#endif /* DECK_HPP */
|
||||
|
||||
@@ -28,7 +28,8 @@ namespace Opm {
|
||||
|
||||
class DeckOutput {
|
||||
public:
|
||||
explicit DeckOutput(std::ostream& s);
|
||||
explicit DeckOutput(std::ostream& s, int precision = 10);
|
||||
~DeckOutput();
|
||||
void stash_default( );
|
||||
|
||||
void start_record( );
|
||||
@@ -51,9 +52,11 @@ namespace Opm {
|
||||
size_t default_count;
|
||||
size_t row_count;
|
||||
bool record_on;
|
||||
int org_precision;
|
||||
|
||||
template <typename T> void write_value(const T& value);
|
||||
void write_sep( );
|
||||
void set_precision(int precision);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef OPM_INIT_CONFIG_HPP
|
||||
#define OPM_INIT_CONFIG_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/InitConfig/Equil.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
70
opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp
Normal file
70
opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
Copyright 2013 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ActionX_HPP_
|
||||
#define ActionX_HPP_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Opm {
|
||||
/*
|
||||
The ActionX class internalizes the ACTIONX keyword. This keyword represents a
|
||||
small in-deck programming language for the SCHEDULE section. In the deck the
|
||||
ACTIONX keyword comes together with a 'ENDACTIO' kewyord and then a list of
|
||||
regular keywords in the between. The principle is then that ACTIONX represents
|
||||
a condition, and when that condition is satisfied the keywords are applied. In
|
||||
the example below the ACTIONX keyword defines a condition whether well OPX has
|
||||
watercut above 0.75, when the condition is met the WELOPEN keyword is applied
|
||||
- and the well is shut.
|
||||
|
||||
ACTIONX
|
||||
'NAME' /
|
||||
WWCT OPX > 0.50 /
|
||||
/
|
||||
|
||||
WELOPEN
|
||||
'OPX' OPEN /
|
||||
/
|
||||
|
||||
ENDACTION
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class DeckKeyword;
|
||||
|
||||
class ActionX {
|
||||
public:
|
||||
ActionX(const std::string& name, size_t max_run, double max_wait);
|
||||
explicit ActionX(const DeckKeyword& kw);
|
||||
|
||||
void addKeyword(const DeckKeyword& kw);
|
||||
|
||||
const std::string& name() const;
|
||||
private:
|
||||
std::string m_name;
|
||||
size_t max_run;
|
||||
double max_wait;
|
||||
|
||||
std::vector<DeckKeyword> keywords;
|
||||
};
|
||||
|
||||
}
|
||||
#endif /* WELL_HPP_ */
|
||||
@@ -189,6 +189,15 @@ namespace Opm
|
||||
void handleVFPINJ(const DeckKeyword& vfpprodKeyword, const UnitSystem& unit_system, size_t currentStep);
|
||||
void checkUnhandledKeywords( const SCHEDULESection& ) const;
|
||||
void checkIfAllConnectionsIsShut(size_t currentStep);
|
||||
void handleKeyword(size_t& currentStep,
|
||||
const SCHEDULESection& section,
|
||||
size_t keywordIdx,
|
||||
const DeckKeyword& keyword,
|
||||
const ParseContext& parseContext,
|
||||
const EclipseGrid& grid,
|
||||
const Eclipse3DProperties& eclipseProperties,
|
||||
const UnitSystem& unit_system,
|
||||
std::vector<std::pair<const DeckKeyword*, size_t > >& rftProperties);
|
||||
|
||||
static double convertInjectionRateToSI(double rawRate, WellInjector::TypeEnum wellType, const Opm::UnitSystem &unitSystem);
|
||||
static double convertInjectionRateToSI(double rawRate, Phase wellPhase, const Opm::UnitSystem &unitSystem);
|
||||
|
||||
@@ -40,14 +40,9 @@ namespace Opm {
|
||||
bool hasKeyword(const std::string& keyword) const;
|
||||
std::shared_ptr<const ParserKeyword> getKeyword(const std::string& keyword) const;
|
||||
std::string getJsonFile(const std::string& keyword) const;
|
||||
size_t loadKeywordDirectory(const std::string& pathname);
|
||||
size_t loadKeywordDirectory(boost::filesystem::path& path);
|
||||
void loadKeyword(const std::string& filename);
|
||||
void loadKeyword(boost::filesystem::path& path);
|
||||
|
||||
static std::vector<std::string> sortSubdirectories( const std::string& directory );
|
||||
size_t loadMultipleKeywordDirectories(const std::string& directory);
|
||||
|
||||
std::map<std::string , std::shared_ptr<ParserKeyword> >::const_iterator keyword_begin( ) const;
|
||||
std::map<std::string , std::shared_ptr<ParserKeyword> >::const_iterator keyword_end( ) const;
|
||||
private:
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef ECLFILESCOMPARATOR_HPP
|
||||
#define ECLFILESCOMPARATOR_HPP
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
@@ -61,6 +62,8 @@ class ECLFilesComparator {
|
||||
ecl_grid_type* ecl_grid2 = nullptr;
|
||||
std::vector<std::string> keywords1, keywords2;
|
||||
bool throwOnError = true; //!< Throw on first error
|
||||
bool analysis = false; //!< Perform full error analysis
|
||||
std::map<std::string, std::vector<Deviation>> deviations;
|
||||
mutable size_t num_errors = 0;
|
||||
|
||||
//! \brief Checks if the keyword exists in both cases.
|
||||
@@ -99,6 +102,9 @@ class ECLFilesComparator {
|
||||
//! \brief Set whether to throw on errors or not.
|
||||
void throwOnErrors(bool dothrow) { throwOnError = dothrow; }
|
||||
|
||||
//! \brief Set whether to perform a full error analysis.
|
||||
void doAnalysis(bool analize) { analysis = analize; }
|
||||
|
||||
//! \brief Returns the number of errors encountered in the performed comparisons.
|
||||
size_t getNoErrors() const { return num_errors; }
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
@@ -48,8 +49,8 @@ typedef struct ecl_sum_struct ecl_sum_type;
|
||||
|
||||
//! \brief Struct for storing the deviation between two values.
|
||||
struct Deviation {
|
||||
double abs = 0;//!< The absolute deviation
|
||||
double rel = 0; //!< The relative deviation
|
||||
double abs = 0; //!< The absolute deviation
|
||||
double rel = 0; //!< The relative deviation
|
||||
};
|
||||
|
||||
|
||||
@@ -73,6 +74,8 @@ class SummaryComparator {
|
||||
bool printKeyword = false; //!< Boolean value for choosing whether to print the keywords or not
|
||||
bool printSpecificKeyword = false; //!< Boolean value for choosing whether to print the vectors of a keyword or not
|
||||
bool throwOnError = true; //!< Throw on first error
|
||||
bool analysis = false; //!< Perform error analysis
|
||||
std::map<std::string, std::vector<Deviation>> deviations;
|
||||
|
||||
//! \brief Calculate deviation between two data values and stores it in a Deviation struct.
|
||||
//! \param[in] refIndex Index in reference data
|
||||
@@ -175,6 +178,9 @@ class SummaryComparator {
|
||||
|
||||
//! \brief Set whether to throw on errors or not.
|
||||
void throwOnErrors(bool dothrow) { throwOnError = dothrow; }
|
||||
|
||||
//! \brief Set whether or not to perform error analysis.
|
||||
void doAnalysis(bool analyse) { analysis = analyse; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
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/>.
|
||||
*/
|
||||
|
||||
@@ -139,7 +138,8 @@ namespace Opm {
|
||||
keywordList( std::move( x ) ),
|
||||
defaultUnits( UnitSystem::newMETRIC() ),
|
||||
activeUnits( UnitSystem::newMETRIC() ),
|
||||
m_dataFile("")
|
||||
m_dataFile(""),
|
||||
input_path("")
|
||||
{
|
||||
/*
|
||||
* If multiple unit systems are requested, metric is preferred over
|
||||
@@ -169,8 +169,8 @@ namespace Opm {
|
||||
keywordList( d.keywordList ),
|
||||
defaultUnits( d.defaultUnits ),
|
||||
activeUnits( d.activeUnits ),
|
||||
m_dataFile( d.m_dataFile ) {
|
||||
|
||||
m_dataFile( d.m_dataFile ),
|
||||
input_path( d.input_path ) {
|
||||
this->reinit(this->keywordList.begin(), this->keywordList.end());
|
||||
}
|
||||
|
||||
@@ -209,12 +209,22 @@ namespace Opm {
|
||||
return this->activeUnits;
|
||||
}
|
||||
|
||||
const std::string Deck::getDataFile() const {
|
||||
const std::string& Deck::getDataFile() const {
|
||||
return m_dataFile;
|
||||
}
|
||||
|
||||
const std::string& Deck::getInputPath() const {
|
||||
return this->input_path;
|
||||
}
|
||||
|
||||
void Deck::setDataFile(const std::string& dataFile) {
|
||||
m_dataFile = dataFile;
|
||||
this->m_dataFile = dataFile;
|
||||
|
||||
auto slash_pos = dataFile.find_last_of("/\\");
|
||||
if (slash_pos == std::string::npos)
|
||||
this->input_path = "";
|
||||
else
|
||||
this->input_path = dataFile.substr(0, slash_pos);
|
||||
}
|
||||
|
||||
Deck::iterator Deck::begin() {
|
||||
@@ -237,7 +247,7 @@ namespace Opm {
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Deck& deck) {
|
||||
DeckOutput out( os );
|
||||
DeckOutput out( os, 10 );
|
||||
deck.write( out );
|
||||
return os;
|
||||
}
|
||||
|
||||
@@ -24,13 +24,25 @@
|
||||
|
||||
namespace Opm {
|
||||
|
||||
DeckOutput::DeckOutput( std::ostream& s) :
|
||||
DeckOutput::DeckOutput( std::ostream& s, int precision) :
|
||||
os( s ),
|
||||
default_count( 0 ),
|
||||
row_count( 0 ),
|
||||
record_on( false )
|
||||
record_on( false ),
|
||||
org_precision( os.precision(precision) )
|
||||
{}
|
||||
|
||||
|
||||
DeckOutput::~DeckOutput() {
|
||||
this->set_precision(this->org_precision);
|
||||
}
|
||||
|
||||
|
||||
void DeckOutput::set_precision(int precision) {
|
||||
this->os.precision(precision);
|
||||
}
|
||||
|
||||
|
||||
void DeckOutput::endl() {
|
||||
this->os << std::endl;
|
||||
}
|
||||
|
||||
@@ -56,10 +56,14 @@ namespace Opm {
|
||||
"only from RESTART files");
|
||||
}
|
||||
|
||||
const std::string& root = record.getItem( 0 ).get< std::string >( 0 );
|
||||
int step = record.getItem( 1 ).get< int >(0);
|
||||
const std::string& root = record.getItem( 0 ).get< std::string >( 0 );
|
||||
const std::string& input_path = deck.getInputPath();
|
||||
|
||||
this->setRestart( root, step );
|
||||
if (root[0] == '/' || input_path.empty())
|
||||
this->setRestart(root, step);
|
||||
else
|
||||
this->setRestart( input_path + "/" + root, step );
|
||||
}
|
||||
|
||||
void InitConfig::setRestart( const std::string& root, int step) {
|
||||
|
||||
49
src/opm/parser/eclipse/EclipseState/Schedule/ActionX.cpp
Normal file
49
src/opm/parser/eclipse/EclipseState/Schedule/ActionX.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2018 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 <opm/parser/eclipse/Deck/DeckKeyword.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
ActionX::ActionX(const std::string& name, size_t max_run, double max_wait) :
|
||||
m_name(name),
|
||||
max_run(max_run),
|
||||
max_wait(max_wait)
|
||||
{}
|
||||
|
||||
|
||||
ActionX::ActionX(const DeckKeyword& kw) {
|
||||
const auto& record = kw.getRecord(0);
|
||||
this->m_name = record.getItem("NAME").getTrimmedString(0);
|
||||
this->max_run = record.getItem("NUM").get<int>(0);
|
||||
this->max_wait = record.getItem("MAX_WAIT").getSIDouble(0);
|
||||
}
|
||||
|
||||
|
||||
void ActionX::addKeyword(const DeckKeyword& kw) {
|
||||
this->keywords.push_back(kw);
|
||||
}
|
||||
|
||||
const std::string& ActionX::name() const {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellConnections.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp>
|
||||
@@ -117,15 +118,23 @@ namespace Opm {
|
||||
return this->m_timeMap.getEndTime();
|
||||
}
|
||||
|
||||
void Schedule::iterateScheduleSection(const ParseContext& parseContext , const SCHEDULESection& section , const EclipseGrid& grid,
|
||||
const Eclipse3DProperties& eclipseProperties) {
|
||||
/*
|
||||
geoModifiers is a list of geo modifiers which can be found in the schedule
|
||||
section. This is only partly supported, support is indicated by the bool
|
||||
value. The keywords which are supported will be assembled in a per-timestep
|
||||
'minideck', whereas ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER will be
|
||||
consulted for the others.
|
||||
*/
|
||||
|
||||
void Schedule::handleKeyword(size_t& currentStep,
|
||||
const SCHEDULESection& section,
|
||||
size_t keywordIdx,
|
||||
const DeckKeyword& keyword,
|
||||
const ParseContext& parseContext,
|
||||
const EclipseGrid& grid,
|
||||
const Eclipse3DProperties& eclipseProperties,
|
||||
const UnitSystem& unit_system,
|
||||
std::vector<std::pair<const DeckKeyword*, size_t > >& rftProperties) {
|
||||
/*
|
||||
geoModifiers is a list of geo modifiers which can be found in the schedule
|
||||
section. This is only partly supported, support is indicated by the bool
|
||||
value. The keywords which are supported will be assembled in a per-timestep
|
||||
'minideck', whereas ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER will be
|
||||
consulted for the others.
|
||||
*/
|
||||
|
||||
const std::map<std::string,bool> geoModifiers = {{"MULTFLT" , true},
|
||||
{"MULTPV" , false},
|
||||
@@ -143,145 +152,169 @@ namespace Opm {
|
||||
{"MULTTHT" , false},
|
||||
{"MULTTHT-" , false}};
|
||||
|
||||
size_t currentStep = 0;
|
||||
std::vector<std::pair< const DeckKeyword* , size_t> > rftProperties;
|
||||
const auto& unit_system = section.unitSystem();
|
||||
if (keyword.name() == "DATES") {
|
||||
checkIfAllConnectionsIsShut(currentStep);
|
||||
currentStep += keyword.size();
|
||||
}
|
||||
|
||||
for (size_t keywordIdx = 0; keywordIdx < section.size(); ++keywordIdx) {
|
||||
const auto& keyword = section.getKeyword(keywordIdx);
|
||||
else if (keyword.name() == "TSTEP") {
|
||||
checkIfAllConnectionsIsShut(currentStep);
|
||||
currentStep += keyword.getRecord(0).getItem(0).size(); // This is a bit weird API.
|
||||
}
|
||||
|
||||
if (keyword.name() == "DATES") {
|
||||
checkIfAllConnectionsIsShut(currentStep);
|
||||
currentStep += keyword.size();
|
||||
}
|
||||
else if (keyword.name() == "WELSPECS")
|
||||
handleWELSPECS( section, keywordIdx, currentStep );
|
||||
|
||||
else if (keyword.name() == "TSTEP") {
|
||||
checkIfAllConnectionsIsShut(currentStep);
|
||||
currentStep += keyword.getRecord(0).getItem(0).size(); // This is a bit weird API.
|
||||
}
|
||||
else if (keyword.name() == "WHISTCTL")
|
||||
handleWHISTCTL(parseContext, keyword);
|
||||
|
||||
else if (keyword.name() == "WELSPECS")
|
||||
handleWELSPECS( section, keywordIdx, currentStep );
|
||||
else if (keyword.name() == "WCONHIST")
|
||||
handleWCONHIST(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WHISTCTL")
|
||||
handleWHISTCTL(parseContext, keyword);
|
||||
else if (keyword.name() == "WCONPROD")
|
||||
handleWCONPROD(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WCONHIST")
|
||||
handleWCONHIST(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WCONINJE")
|
||||
handleWCONINJE(section, keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WCONPROD")
|
||||
handleWCONPROD(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WPOLYMER")
|
||||
handleWPOLYMER(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WCONINJE")
|
||||
handleWCONINJE(section, keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WSOLVENT")
|
||||
handleWSOLVENT(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WPOLYMER")
|
||||
handleWPOLYMER(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WTEST")
|
||||
handleWTEST(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WSOLVENT")
|
||||
handleWSOLVENT(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WTEMP")
|
||||
handleWTEMP(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WTEST")
|
||||
handleWTEST(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WINJTEMP")
|
||||
handleWINJTEMP(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WTEMP")
|
||||
handleWTEMP(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WCONINJH")
|
||||
handleWCONINJH(section, keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WINJTEMP")
|
||||
handleWINJTEMP(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WGRUPCON")
|
||||
handleWGRUPCON(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "WCONINJH")
|
||||
handleWCONINJH(section, keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "COMPDAT")
|
||||
handleCOMPDAT(keyword, currentStep, grid, eclipseProperties, parseContext);
|
||||
|
||||
else if (keyword.name() == "WGRUPCON")
|
||||
handleWGRUPCON(keyword, currentStep);
|
||||
else if (keyword.name() == "WELSEGS")
|
||||
handleWELSEGS(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "COMPDAT")
|
||||
handleCOMPDAT(keyword, currentStep, grid, eclipseProperties, parseContext);
|
||||
else if (keyword.name() == "COMPSEGS")
|
||||
handleCOMPSEGS(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "WELSEGS")
|
||||
handleWELSEGS(keyword, currentStep);
|
||||
else if (keyword.name() == "WELOPEN")
|
||||
handleWELOPEN(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "COMPSEGS")
|
||||
handleCOMPSEGS(keyword, currentStep);
|
||||
else if (keyword.name() == "WELTARG")
|
||||
handleWELTARG(section, keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "WELOPEN")
|
||||
handleWELOPEN(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "GRUPTREE")
|
||||
handleGRUPTREE(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "WELTARG")
|
||||
handleWELTARG(section, keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "GRUPNET")
|
||||
handleGRUPNET(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "GRUPTREE")
|
||||
handleGRUPTREE(keyword, currentStep);
|
||||
else if (keyword.name() == "GCONINJE")
|
||||
handleGCONINJE(section, keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "GRUPNET")
|
||||
handleGRUPNET(keyword, currentStep);
|
||||
else if (keyword.name() == "GCONPROD")
|
||||
handleGCONPROD(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "GCONINJE")
|
||||
handleGCONINJE(section, keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "GEFAC")
|
||||
handleGEFAC(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "GCONPROD")
|
||||
handleGCONPROD(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "TUNING")
|
||||
handleTUNING(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "GEFAC")
|
||||
handleGEFAC(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WRFT")
|
||||
rftProperties.push_back( std::make_pair( &keyword , currentStep ));
|
||||
|
||||
else if (keyword.name() == "TUNING")
|
||||
handleTUNING(keyword, currentStep);
|
||||
else if (keyword.name() == "WRFTPLT")
|
||||
rftProperties.push_back( std::make_pair( &keyword , currentStep ));
|
||||
|
||||
else if (keyword.name() == "WRFT")
|
||||
rftProperties.push_back( std::make_pair( &keyword , currentStep ));
|
||||
else if (keyword.name() == "WPIMULT")
|
||||
handleWPIMULT(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "WRFTPLT")
|
||||
rftProperties.push_back( std::make_pair( &keyword , currentStep ));
|
||||
else if (keyword.name() == "COMPORD")
|
||||
handleCOMPORD(parseContext , keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "WPIMULT")
|
||||
handleWPIMULT(keyword, currentStep);
|
||||
else if (keyword.name() == "COMPLUMP")
|
||||
handleCOMPLUMP(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "COMPORD")
|
||||
handleCOMPORD(parseContext , keyword, currentStep);
|
||||
else if (keyword.name() == "DRSDT")
|
||||
handleDRSDT(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "COMPLUMP")
|
||||
handleCOMPLUMP(keyword, currentStep);
|
||||
else if (keyword.name() == "DRVDT")
|
||||
handleDRVDT(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "DRSDT")
|
||||
handleDRSDT(keyword, currentStep);
|
||||
else if (keyword.name() == "VAPPARS")
|
||||
handleVAPPARS(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "DRVDT")
|
||||
handleDRVDT(keyword, currentStep);
|
||||
else if (keyword.name() == "WECON")
|
||||
handleWECON(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "VAPPARS")
|
||||
handleVAPPARS(keyword, currentStep);
|
||||
else if (keyword.name() == "MESSAGES")
|
||||
handleMESSAGES(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "WECON")
|
||||
handleWECON(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "WEFAC")
|
||||
handleWEFAC(keyword, currentStep, parseContext);
|
||||
|
||||
else if (keyword.name() == "MESSAGES")
|
||||
handleMESSAGES(keyword, currentStep);
|
||||
else if (keyword.name() == "VFPINJ")
|
||||
handleVFPINJ(keyword, unit_system, currentStep);
|
||||
|
||||
else if (keyword.name() == "WEFAC")
|
||||
handleWEFAC(keyword, currentStep, parseContext);
|
||||
else if (keyword.name() == "VFPPROD")
|
||||
handleVFPPROD(keyword, unit_system, currentStep);
|
||||
|
||||
else if (keyword.name() == "VFPINJ")
|
||||
handleVFPINJ(keyword, unit_system, currentStep);
|
||||
|
||||
else if (keyword.name() == "VFPPROD")
|
||||
handleVFPPROD(keyword, unit_system, currentStep);
|
||||
|
||||
else if (geoModifiers.find( keyword.name() ) != geoModifiers.end()) {
|
||||
bool supported = geoModifiers.at( keyword.name() );
|
||||
if (supported) {
|
||||
this->m_modifierDeck[ currentStep ].addKeyword( keyword );
|
||||
m_events.addEvent( ScheduleEvents::GEO_MODIFIER , currentStep);
|
||||
} else {
|
||||
std::string msg = "OPM does not support grid property modifier " + keyword.name() + " in the Schedule section. Error at report: " + std::to_string( currentStep );
|
||||
parseContext.handleError( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg );
|
||||
}
|
||||
else if (geoModifiers.find( keyword.name() ) != geoModifiers.end()) {
|
||||
bool supported = geoModifiers.at( keyword.name() );
|
||||
if (supported) {
|
||||
this->m_modifierDeck[ currentStep ].addKeyword( keyword );
|
||||
m_events.addEvent( ScheduleEvents::GEO_MODIFIER , currentStep);
|
||||
} else {
|
||||
std::string msg = "OPM does not support grid property modifier " + keyword.name() + " in the Schedule section. Error at report: " + std::to_string( currentStep );
|
||||
parseContext.handleError( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg );
|
||||
}
|
||||
}
|
||||
checkIfAllConnectionsIsShut(currentStep);
|
||||
}
|
||||
|
||||
|
||||
void Schedule::iterateScheduleSection(const ParseContext& parseContext , const SCHEDULESection& section , const EclipseGrid& grid,
|
||||
const Eclipse3DProperties& eclipseProperties) {
|
||||
size_t currentStep = 0;
|
||||
const auto& unit_system = section.unitSystem();
|
||||
std::vector<std::pair< const DeckKeyword* , size_t> > rftProperties;
|
||||
size_t keywordIdx = 0;
|
||||
|
||||
while (true) {
|
||||
const auto& keyword = section.getKeyword(keywordIdx);
|
||||
if (keyword.name() == "ACTIONX") {
|
||||
ActionX action(keyword);
|
||||
while (true) {
|
||||
keywordIdx++;
|
||||
if (keywordIdx == section.size())
|
||||
throw std::invalid_argument("Invalid ACTIONX section - missing ENDACTIO");
|
||||
|
||||
const auto& action_keyword = section.getKeyword(keywordIdx);
|
||||
if (action_keyword.name() == "ENDACTIO")
|
||||
break;
|
||||
|
||||
action.addKeyword(action_keyword);
|
||||
}
|
||||
} else
|
||||
this->handleKeyword(currentStep, section, keywordIdx, keyword, parseContext, grid, eclipseProperties, unit_system, rftProperties);
|
||||
|
||||
keywordIdx++;
|
||||
if (keywordIdx == section.size())
|
||||
break;
|
||||
}
|
||||
|
||||
checkIfAllConnectionsIsShut(currentStep);
|
||||
|
||||
for (auto rftPair = rftProperties.begin(); rftPair != rftProperties.end(); ++rftPair) {
|
||||
const DeckKeyword& keyword = *rftPair->first;
|
||||
size_t timeStep = rftPair->second;
|
||||
@@ -297,6 +330,7 @@ namespace Opm {
|
||||
checkUnhandledKeywords(section);
|
||||
}
|
||||
|
||||
|
||||
void Schedule::checkUnhandledKeywords(const SCHEDULESection& /*section*/) const
|
||||
{
|
||||
}
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||
|
||||
#include <ert/ecl/ecl_grid.h>
|
||||
|
||||
|
||||
namespace Opm {
|
||||
|
||||
|
||||
@@ -67,43 +67,6 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
size_t KeywordLoader::loadKeywordDirectory(boost::filesystem::path& path) {
|
||||
size_t loadCount = 0;
|
||||
if (boost::filesystem::is_directory( path )) {
|
||||
boost::filesystem::directory_iterator end_iterator;
|
||||
|
||||
for (boost::filesystem::directory_iterator iter(path); iter != end_iterator; ++iter) {
|
||||
boost::filesystem::path iter_path = iter->path();
|
||||
|
||||
if (boost::filesystem::is_directory( iter_path )) {
|
||||
loadCount += loadKeywordDirectory( iter_path );
|
||||
} else {
|
||||
std::string internalName = iter_path.filename().string();
|
||||
if (ParserKeyword::validInternalName(internalName)) {
|
||||
if (m_verbose)
|
||||
std::cout << "Loading keyword " << internalName << " from file: " << iter_path << "....";
|
||||
loadKeyword( iter_path );
|
||||
if (m_verbose)
|
||||
std::cout << std::endl;
|
||||
loadCount += 1;
|
||||
} else {
|
||||
if (m_verbose)
|
||||
std::cout << "Ignoring file " << iter_path << " - incorrectly formatted name." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else
|
||||
throw std::invalid_argument("Input does not correspond to existing directory\n");
|
||||
|
||||
return loadCount;
|
||||
}
|
||||
|
||||
size_t KeywordLoader::loadKeywordDirectory(const std::string& directory) {
|
||||
boost::filesystem::path path( directory );
|
||||
return loadKeywordDirectory( path );
|
||||
}
|
||||
|
||||
void KeywordLoader::loadKeyword(boost::filesystem::path& path) {
|
||||
std::shared_ptr<Json::JsonObject> jsonConfig = std::make_shared<Json::JsonObject>( path );
|
||||
std::shared_ptr<ParserKeyword> parserKeyword = std::make_shared<ParserKeyword>(*jsonConfig);
|
||||
@@ -114,19 +77,10 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
size_t KeywordLoader::loadMultipleKeywordDirectories(const std::string& directory) {
|
||||
std::vector<std::string> directories = sortSubdirectories( directory );
|
||||
|
||||
size_t load_count = 0;
|
||||
for (auto iter = directories.begin(); iter != directories.end(); ++iter)
|
||||
load_count += loadKeywordDirectory(*iter);
|
||||
|
||||
return load_count;
|
||||
}
|
||||
|
||||
|
||||
void KeywordLoader::loadKeyword(const std::string& filename) {
|
||||
boost::filesystem::path path( filename );
|
||||
if (m_verbose)
|
||||
std::cout << "Loading keyword from file: " << filename << std::endl;
|
||||
return loadKeyword( path );
|
||||
}
|
||||
|
||||
@@ -144,22 +98,6 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> KeywordLoader::sortSubdirectories( const std::string& root_path) {
|
||||
boost::filesystem::path root(root_path);
|
||||
if (boost::filesystem::is_directory( root )) {
|
||||
std::vector<std::string> paths_in_root;
|
||||
boost::filesystem::directory_iterator end_iterator;
|
||||
|
||||
for (boost::filesystem::directory_iterator iter(root); iter != end_iterator; ++iter) {
|
||||
if (boost::filesystem::is_directory( iter->path() ))
|
||||
paths_in_root.push_back(iter->path().string());
|
||||
}
|
||||
|
||||
std::sort(paths_in_root.begin(), paths_in_root.end());
|
||||
return paths_in_root;
|
||||
} else
|
||||
throw std::invalid_argument("Input argument is not a directory");
|
||||
}
|
||||
|
||||
std::map<std::string , std::shared_ptr<ParserKeyword> >::const_iterator KeywordLoader::keyword_begin( ) const {
|
||||
return m_keywords.begin( );
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name" : "ACTION", "sections" : ["SCHEDULE"], "records" : [
|
||||
"name" : "ACTIONX", "sections" : ["SCHEDULE"], "records" : [
|
||||
[{"name" : "NAME", "value_type" : "STRING"},
|
||||
{"name" : "NUM" , "value_type" : "INT", "default" : 1},
|
||||
{"name" : "MAX_WAIT" , "value_type" : "DOUBLE", "default" : 0, "dimension" : "Time"}],
|
||||
|
||||
@@ -391,10 +391,14 @@ void RegressionTest::deviationsForCell(double val1, double val2, const std::stri
|
||||
}
|
||||
Deviation dev = calculateDeviations(val1, val2);
|
||||
if (dev.abs > absTolerance && dev.rel > relTolerance) {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Deviations exceed tolerances."
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << ".");
|
||||
if (analysis) {
|
||||
deviations[keyword].push_back(dev);
|
||||
} else {
|
||||
printValuesForCell(keyword, occurrence1, occurrence2, kw_size, cell, val1, val2);
|
||||
HANDLE_ERROR(std::runtime_error, "Deviations exceed tolerances."
|
||||
<< "\nThe absolute deviation is " << dev.abs << ", and the tolerance limit is " << absTolerance << "."
|
||||
<< "\nThe relative deviation is " << dev.rel << ", and the tolerance limit is " << relTolerance << ".");
|
||||
}
|
||||
}
|
||||
if (dev.abs != -1) {
|
||||
absDeviation.push_back(dev.abs);
|
||||
@@ -496,6 +500,30 @@ void RegressionTest::results() {
|
||||
}
|
||||
for (const auto& it : keywords1)
|
||||
resultsForKeyword(it);
|
||||
|
||||
if (analysis) {
|
||||
std::cout << deviations.size() << " keyword"
|
||||
<< (deviations.size() > 1 ? "s":"") << " exhibit failures" << std::endl;
|
||||
for (const auto& iter : deviations) {
|
||||
std::cout << "\t" << iter.first << std::endl;
|
||||
std::cout << "\t\tFails for " << iter.second.size() << " entries" << std::endl;
|
||||
std::cout.precision(7);
|
||||
double absErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.abs < b.abs;
|
||||
})->abs;
|
||||
double relErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.rel < b.rel;
|
||||
})->rel;
|
||||
std::cout << "\t\tLargest absolute error: "
|
||||
<< std::scientific << absErr << std::endl;
|
||||
std::cout << "\t\tLargest relative error: "
|
||||
<< std::scientific << relErr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -72,6 +72,30 @@ void RegressionTest::getRegressionTest(){
|
||||
}
|
||||
ivar++;
|
||||
}
|
||||
if (analysis) {
|
||||
std::cout << deviations.size() << " summary keyword"
|
||||
<< (deviations.size() > 1 ? "s":"") << " exhibit failures" << std::endl;
|
||||
size_t len = ecl_sum_get_data_length(ecl_sum1);
|
||||
for (const auto& iter : deviations) {
|
||||
std::cout << "\t" << iter.first << std::endl;
|
||||
std::cout << "\t\tFails for " << iter.second.size() << " / " << len << " steps." << std::endl;
|
||||
std::cout.precision(7);
|
||||
double absErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.abs < b.abs;
|
||||
})->abs;
|
||||
double relErr = std::max_element(iter.second.begin(), iter.second.end(),
|
||||
[](const Deviation& a, const Deviation& b)
|
||||
{
|
||||
return a.rel < b.rel;
|
||||
})->rel;
|
||||
std::cout << "\t\tLargest absolute error: "
|
||||
<< std::scientific << absErr << std::endl;
|
||||
std::cout << "\t\tLargest relative error: "
|
||||
<< std::scientific << relErr << std::endl;
|
||||
}
|
||||
}
|
||||
if (throwAtEnd)
|
||||
OPM_THROW(std::runtime_error, "Regression test failed.");
|
||||
else
|
||||
@@ -107,13 +131,17 @@ bool RegressionTest::checkDeviation(Deviation deviation, const char* keyword, in
|
||||
double relTol = getRelTolerance();
|
||||
|
||||
if (deviation.rel > relTol && deviation.abs > absTol){
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
std::cout << "(days, reference value) and (days, check value) = (" << (*referenceVec)[refIndex] << ", " << (*referenceDataVec)[refIndex]
|
||||
<< ") and (" << (*checkVec)[checkIndex-1] << ", " << (*checkDataVec)[checkIndex-1] << ")\n";
|
||||
// -1 in [checkIndex -1] because checkIndex is updated after leaving getDeviation function
|
||||
std::cout << "The absolute deviation is " << deviation.abs << ". The tolerance limit is " << absTol << std::endl;
|
||||
std::cout << "The relative deviation is " << deviation.rel << ". The tolerance limit is " << relTol << std::endl;
|
||||
HANDLE_ERROR(std::runtime_error, "Deviation exceed the limit.");
|
||||
if (analysis) {
|
||||
deviations[keyword].push_back(deviation);
|
||||
} else {
|
||||
std::cout << "For keyword " << keyword << std::endl;
|
||||
std::cout << "(days, reference value) and (days, check value) = (" << (*referenceVec)[refIndex] << ", " << (*referenceDataVec)[refIndex]
|
||||
<< ") and (" << (*checkVec)[checkIndex-1] << ", " << (*checkDataVec)[checkIndex-1] << ")\n";
|
||||
// -1 in [checkIndex -1] because checkIndex is updated after leaving getDeviation function
|
||||
std::cout << "The absolute deviation is " << deviation.abs << ". The tolerance limit is " << absTol << std::endl;
|
||||
std::cout << "The relative deviation is " << deviation.rel << ". The tolerance limit is " << relTol << std::endl;
|
||||
HANDLE_ERROR(std::runtime_error, "Deviation exceed the limit.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
100
tests/parser/ACTIONX.cpp
Normal file
100
tests/parser/ACTIONX.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
Copyright 2018 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 ACTIONX
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/ActionX.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Parser/Parser.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Create) {
|
||||
const auto action_kw = std::string{ R"(
|
||||
ACTIONX
|
||||
'ACTION' /
|
||||
WWCT OPX > 0.75 /
|
||||
/
|
||||
)"};
|
||||
ActionX action1("NAME", 10, 100);
|
||||
BOOST_CHECK_EQUAL(action1.name(), "NAME");
|
||||
|
||||
const auto deck = Parser{}.parseString( action_kw );
|
||||
const auto& kw = deck.getKeyword("ACTIONX");
|
||||
|
||||
ActionX action2(kw);
|
||||
BOOST_CHECK_EQUAL(action2.name(), "ACTION");
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SCAN) {
|
||||
const auto MISSING_END= std::string{ R"(
|
||||
SCHEDULE
|
||||
|
||||
ACTIONX
|
||||
'ACTION' /
|
||||
WWCT OPX > 0.75 /
|
||||
/
|
||||
)"};
|
||||
|
||||
const auto WITH_WELSPECS = std::string{ R"(
|
||||
SCHEDULE
|
||||
|
||||
WELSPECS
|
||||
'W2' 'OP' 1 1 3.33 'OIL' 7*/
|
||||
/
|
||||
|
||||
ACTIONX
|
||||
'ACTION' /
|
||||
WWCT OPX > 0.75 /
|
||||
/
|
||||
|
||||
WELSPECS
|
||||
'W1' 'OP' 1 1 3.33 'OIL' 7*/
|
||||
/
|
||||
|
||||
ENDACTIO
|
||||
)"};
|
||||
Opm::Parser parser;
|
||||
auto deck1 = parser.parseString(MISSING_END, Opm::ParseContext());
|
||||
auto deck2 = parser.parseString(WITH_WELSPECS, Opm::ParseContext());
|
||||
EclipseGrid grid1(10,10,10);
|
||||
TableManager table ( deck1 );
|
||||
Eclipse3DProperties eclipseProperties ( deck1 , table, grid1);
|
||||
|
||||
// The ACTIONX keyword has no matching 'ENDACTIO' -> exception
|
||||
BOOST_CHECK_THROW(Schedule(deck1, grid1, eclipseProperties, Phases(true,true,true), ParseContext()), std::invalid_argument);
|
||||
|
||||
Schedule sched(deck2, grid1, eclipseProperties, Phases(true,true,true), ParseContext());
|
||||
BOOST_CHECK( !sched.hasWell("W1") );
|
||||
BOOST_CHECK( sched.hasWell("W2"));
|
||||
}
|
||||
@@ -166,9 +166,15 @@ BOOST_AUTO_TEST_CASE(keywordList_getbyindex_correctkeywordreturned) {
|
||||
BOOST_AUTO_TEST_CASE(set_and_get_data_file) {
|
||||
Deck deck;
|
||||
BOOST_CHECK_EQUAL("", deck.getDataFile());
|
||||
BOOST_CHECK_EQUAL("", deck.getInputPath());
|
||||
std::string file("/path/to/file.DATA");
|
||||
deck.setDataFile( file );
|
||||
BOOST_CHECK_EQUAL(file, deck.getDataFile());
|
||||
BOOST_CHECK_EQUAL("/path/to", deck.getInputPath());
|
||||
|
||||
deck.setDataFile("FILE");
|
||||
BOOST_CHECK_EQUAL("FILE", deck.getDataFile());
|
||||
BOOST_CHECK_EQUAL("", deck.getInputPath());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DummyDefaultsString) {
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
|
||||
#define BOOST_TEST_MODULE InitConfigTests
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -30,6 +32,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
|
||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||
|
||||
#include <ert/util/test_work_area.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
@@ -84,6 +87,18 @@ const std::string& deckStr4 =
|
||||
"19 JUN 2007 / \n"
|
||||
"SCHEDULE\n";
|
||||
|
||||
const std::string& deckStr5 =
|
||||
"RUNSPEC\n"
|
||||
"DIMENS\n"
|
||||
" 10 10 10 /\n"
|
||||
"SOLUTION\n"
|
||||
"RESTART\n"
|
||||
"'/abs/path/BASE' 5 /\n"
|
||||
"GRID\n"
|
||||
"START -- 0 \n"
|
||||
"19 JUN 2007 / \n"
|
||||
"SCHEDULE\n";
|
||||
|
||||
const std::string& deckWithEquil =
|
||||
"RUNSPEC\n"
|
||||
"DIMENS\n"
|
||||
@@ -172,3 +187,51 @@ BOOST_AUTO_TEST_CASE( EquilOperations ) {
|
||||
BOOST_CHECK( !record.wetGasInitConstantRv() );
|
||||
BOOST_CHECK_EQUAL( 20, record.initializationTargetAccuracy() );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(RestartCWD) {
|
||||
test_work_area_type * work_area = test_work_area_alloc("restart_cwd");
|
||||
mkdir("simulation", 0777);
|
||||
{
|
||||
std::fstream fs;
|
||||
fs.open ("simulation/CASE.DATA", std::fstream::out);
|
||||
fs << deckStr4;
|
||||
fs.close();
|
||||
|
||||
fs.open("simulation/CASE5.DATA", std::fstream::out);
|
||||
fs << deckStr5;
|
||||
fs.close();
|
||||
|
||||
fs.open("CASE5.DATA", std::fstream::out);
|
||||
fs << deckStr5;
|
||||
fs.close();
|
||||
|
||||
fs.open("CWD_CASE.DATA", std::fstream::out);
|
||||
fs << deckStr4;
|
||||
fs.close();
|
||||
}
|
||||
Opm::Parser parser;
|
||||
{
|
||||
Opm::Deck deck = parser.parseFile("simulation/CASE.DATA", Opm::ParseContext());
|
||||
Opm::InitConfig init_config(deck);
|
||||
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "simulation/BASE");
|
||||
}
|
||||
{
|
||||
Opm::Deck deck = parser.parseFile("simulation/CASE5.DATA", Opm::ParseContext());
|
||||
Opm::InitConfig init_config(deck);
|
||||
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "/abs/path/BASE");
|
||||
}
|
||||
{
|
||||
Opm::Deck deck = parser.parseFile("CWD_CASE.DATA", Opm::ParseContext());
|
||||
Opm::InitConfig init_config(deck);
|
||||
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "BASE");
|
||||
}
|
||||
{
|
||||
Opm::Deck deck = parser.parseFile("CASE5.DATA", Opm::ParseContext());
|
||||
Opm::InitConfig init_config(deck);
|
||||
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "/abs/path/BASE");
|
||||
}
|
||||
|
||||
test_work_area_free(work_area);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -64,46 +64,3 @@ BOOST_AUTO_TEST_CASE(LoadKeyword) {
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(LoadKeywordDirectory) {
|
||||
Opm::KeywordLoader loader(false);
|
||||
BOOST_CHECK_THROW( loader.loadKeywordDirectory("does/not/exists") , std::invalid_argument );
|
||||
BOOST_CHECK_THROW( loader.loadKeywordDirectory(prefix() + "invalid.json") , std::invalid_argument);
|
||||
|
||||
BOOST_CHECK_EQUAL( 4 , loader.loadKeywordDirectory( prefix() + "loader/001_ECLIPSE100"));
|
||||
BOOST_CHECK( loader.hasKeyword("ADDREG") );
|
||||
BOOST_CHECK( loader.hasKeyword("ACTNUM") );
|
||||
BOOST_CHECK( loader.hasKeyword("BOX") );
|
||||
BOOST_CHECK( loader.hasKeyword("BLOCK_PROBE") );
|
||||
{
|
||||
auto kw = loader.getKeyword("ADDREG");
|
||||
auto record = kw->getRecord(0);
|
||||
BOOST_CHECK( !record.hasItem("REGION_NUMBER") );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DirectorySort) {
|
||||
BOOST_CHECK_THROW( Opm::KeywordLoader::sortSubdirectories( prefix() + "loader/ZCORN") , std::invalid_argument );
|
||||
std::vector<std::string> dir_list = Opm::KeywordLoader::sortSubdirectories( prefix() + "loader");
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
BOOST_CHECK_EQUAL( 2U , dir_list.size());
|
||||
BOOST_CHECK_EQUAL( fs::path( dir_list[0] ), fs::path( prefix() + "loader/001_ECLIPSE100" ) );
|
||||
BOOST_CHECK_EQUAL( fs::path( dir_list[1] ), fs::path( prefix() + "loader/002_ECLIPSE300" ) );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BigLoad) {
|
||||
Opm::KeywordLoader loader(false);
|
||||
BOOST_CHECK_THROW( loader.loadMultipleKeywordDirectories("does/not/exists") , std::invalid_argument );
|
||||
BOOST_CHECK_THROW( loader.loadMultipleKeywordDirectories(prefix() + "invalid.json") , std::invalid_argument);
|
||||
|
||||
loader.loadMultipleKeywordDirectories(prefix() + "loader");
|
||||
BOOST_CHECK( loader.hasKeyword("EQUIL"));
|
||||
{
|
||||
auto kw = loader.getKeyword("ADDREG");
|
||||
auto record = kw->getRecord(0);
|
||||
BOOST_CHECK( record.hasItem("REGION_NUMBER"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,11 +474,6 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData_double) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) {
|
||||
// This test leads to a segmentation violation on travis, disable until
|
||||
// the cause has been found and fixed.
|
||||
if (std::getenv("TRAVIS_CI"))
|
||||
return;
|
||||
|
||||
Setup setup("FIRST_SIM.DATA");
|
||||
{
|
||||
ERT::TestArea testArea("test_Restart");
|
||||
|
||||
Reference in New Issue
Block a user