restore the hydrostatic equilibration test from opm-core

This involved quite a bit of kicking and screaming. The result
certainly is not pretty, but it works.
This commit is contained in:
Andreas Lauser 2018-01-02 14:28:52 +01:00
parent c2e9a7a518
commit adb2783a0c
11 changed files with 482 additions and 736 deletions

View File

@ -1,174 +0,0 @@
/*
Copyright 2014 SINTEF ICT, Applied Mathematics.
Copyright 2017 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/>.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H
#include <opm/core/grid.h>
#include <opm/core/grid/GridManager.hpp>
#include <opm/common/ErrorMacros.hpp>
#include <opm/core/simulator/initStateEquil.hpp>
#include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <opm/core/props/BlackoilPhases.hpp>
#include <opm/core/props/phaseUsageFromDeck.hpp>
#include <opm/core/simulator/BlackoilState.hpp>
#include <opm/core/utility/compressedToCartesian.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/material/fluidmatrixinteractions/EclMaterialLawManager.hpp>
#include <boost/filesystem.hpp>
#include <fstream>
namespace
{
void warnIfUnusedParams(const Opm::ParameterGroup& param)
{
if (param.anyUnused()) {
std::cout << "-------------------- Unused parameters: --------------------\n";
param.displayUsage();
std::cout << "----------------------------------------------------------------" << std::endl;
}
}
void outputData(const std::string& output_dir,
const std::string& name,
const std::vector<double>& data)
{
std::ostringstream fname;
fname << output_dir << "/" << name;
boost::filesystem::path fpath = fname.str();
try {
create_directories(fpath);
}
catch (...) {
OPM_THROW(std::runtime_error, "Creating directories failed: " << fpath);
}
fname << "/" << "initial.txt";
std::ofstream file(fname.str().c_str());
if (!file) {
OPM_THROW(std::runtime_error, "Failed to open " << fname.str());
}
std::copy(data.begin(), data.end(), std::ostream_iterator<double>(file, "\n"));
}
/// Convert saturations from a vector of individual phase saturation vectors
/// to an interleaved format where all values for a given cell come before all
/// values for the next cell, all in a single vector.
template <class FluidSystem>
void convertSats(std::vector<double>& sat_interleaved, const std::vector< std::vector<double> >& sat, const Opm::PhaseUsage& pu)
{
assert(sat.size() == 3);
const auto nc = sat[0].size();
const auto np = sat_interleaved.size() / nc;
for (size_t c = 0; c < nc; ++c) {
if ( FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
const int opos = pu.phase_pos[Opm::BlackoilPhases::Liquid];
const std::vector<double>& sat_p = sat[ FluidSystem::oilPhaseIdx];
sat_interleaved[np*c + opos] = sat_p[c];
}
if ( FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
const int wpos = pu.phase_pos[Opm::BlackoilPhases::Aqua];
const std::vector<double>& sat_p = sat[ FluidSystem::waterPhaseIdx];
sat_interleaved[np*c + wpos] = sat_p[c];
}
if ( FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
const int gpos = pu.phase_pos[Opm::BlackoilPhases::Vapour];
const std::vector<double>& sat_p = sat[ FluidSystem::gasPhaseIdx];
sat_interleaved[np*c + gpos] = sat_p[c];
}
}
}
} // anon namespace
// ----------------- Main program -----------------
int
main(int argc, char** argv)
try
{
using namespace Opm;
// Setup.
ParameterGroup param(argc, argv);
std::cout << "--------------- Reading parameters ---------------" << std::endl;
const std::string deck_filename = param.get<std::string>("deck_filename");
Opm::ParseContext parseContext;
Opm::Parser parser;
const Opm::Deck& deck = parser.parseFile(deck_filename , parseContext);
const Opm::EclipseState eclipseState(deck, parseContext);
const double grav = param.getDefault("gravity", unit::gravity);
GridManager gm(eclipseState.getInputGrid());
const UnstructuredGrid& grid = *gm.c_grid();
warnIfUnusedParams(param);
// Create material law manager.
std::vector<int> compressedToCartesianIdx
= Opm::compressedToCartesian(grid.number_of_cells, grid.global_cell);
typedef FluidSystems::BlackOil<double> FluidSystem;
// Forward declaring the MaterialLawManager template.
typedef Opm::ThreePhaseMaterialTraits<double,
/*wettingPhaseIdx=*/FluidSystem::waterPhaseIdx,
/*nonWettingPhaseIdx=*/FluidSystem::oilPhaseIdx,
/*gasPhaseIdx=*/FluidSystem::gasPhaseIdx> MaterialTraits;
typedef Opm::EclMaterialLawManager<MaterialTraits> MaterialLawManager;
MaterialLawManager materialLawManager = MaterialLawManager();
materialLawManager.initFromDeck(deck, eclipseState, compressedToCartesianIdx);
// Initialisation.
//initBlackoilSurfvolUsingRSorRV(UgGridHelpers::numCells(grid), props, state);
BlackoilState state( UgGridHelpers::numCells(grid) , UgGridHelpers::numFaces(grid), 3);
FluidSystem::initFromDeck(deck, eclipseState);
PhaseUsage pu = phaseUsageFromDeck(deck);
typedef EQUIL::DeckDependent::InitialStateComputer<FluidSystem> ISC;
ISC isc(materialLawManager, eclipseState, grid, grav);
const bool oil = FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx);
const int oilpos = FluidSystem::oilPhaseIdx;
const int waterpos = FluidSystem::waterPhaseIdx;
const int ref_phase = oil ? oilpos : waterpos;
state.pressure() = isc.press()[ref_phase];
convertSats<FluidSystem>(state.saturation(), isc.saturation(), pu);
state.gasoilratio() = isc.rs();
state.rv() = isc.rv();
// Output.
const std::string output_dir = param.getDefault<std::string>("output_dir", "output");
outputData(output_dir, "pressure", state.pressure());
outputData(output_dir, "saturation", state.saturation());
outputData(output_dir, "rs", state.gasoilratio());
outputData(output_dir, "rv", state.rv());
}
catch (const std::exception& e) {
std::cerr << "Program threw an exception: " << e.what() << "\n";
throw;
}

115
tests/data/equil_base.DATA Normal file
View File

@ -0,0 +1,115 @@
RUNSPEC
WATER
GAS
OIL
METRIC
DIMENS
10 1 10 /
GRID
DX
100*1 /
DY
100*1 /
DZ
100*1 /
TOPS
10*0. /
PORO
100*0.3 /
PERMX
100*500 /
PROPS
PVTW
4017.55 1.038 3.22E-6 0.318 0.0 /
ROCK
14.7 3E-6 /
SWOF
0.12 0 1 0
0.18 4.64876033057851E-008 1 0
0.24 0.000000186 0.997 0
0.3 4.18388429752066E-007 0.98 0
0.36 7.43801652892562E-007 0.7 0
0.42 1.16219008264463E-006 0.35 0
0.48 1.67355371900826E-006 0.2 0
0.54 2.27789256198347E-006 0.09 0
0.6 2.97520661157025E-006 0.021 0
0.66 3.7654958677686E-006 0.01 0
0.72 4.64876033057851E-006 0.001 0
0.78 0.000005625 0.0001 0
0.84 6.69421487603306E-006 0 0
0.91 8.05914256198347E-006 0 0
1 0.00001 0 0 /
SGOF
0 0 1 0
0.001 0 1 0
0.02 0 0.997 0
0.05 0.005 0.980 0
0.12 0.025 0.700 0
0.2 0.075 0.350 0
0.25 0.125 0.200 0
0.3 0.190 0.090 0
0.4 0.410 0.021 0
0.45 0.60 0.010 0
0.5 0.72 0.001 0
0.6 0.87 0.0001 0
0.7 0.94 0.000 0
0.85 0.98 0.000 0
0.88 0.984 0.000 0 /
DENSITY
53.66 64.49 0.0533 /
PVDG
14.700 166.666 0.008000
264.70 12.0930 0.009600
514.70 6.27400 0.011200
1014.7 3.19700 0.014000
2014.7 1.61400 0.018900
2514.7 1.29400 0.020800
3014.7 1.08000 0.022800
4014.7 0.81100 0.026800
5014.7 0.64900 0.030900
9014.7 0.38600 0.047000 /
PVTO
0.0010 14.7 1.0620 1.0400 /
0.0905 264.7 1.1500 0.9750 /
0.1800 514.7 1.2070 0.9100 /
0.3710 1014.7 1.2950 0.8300 /
0.6360 2014.7 1.4350 0.6950 /
0.7750 2514.7 1.5000 0.6410 /
0.9300 3014.7 1.5650 0.5940 /
1.2700 4014.7 1.6950 0.5100
9014.7 1.5790 0.7400 /
1.6180 5014.7 1.8270 0.4490
9014.7 1.7370 0.6310 /
/
SOLUTION
SWAT
100*0.0 /
SGAS
100*0.0 /
PRESSURE
100*300.0 /
SUMMARY
SCHEDULE

View File

@ -11,7 +11,7 @@ OIL
GAS
DIMENS
40 40 40 /
1 1 20 /
TABDIMS
1 1 40 20 1 20 /
@ -27,16 +27,22 @@ GRID
-- specify a fake one...
DXV
40*1 /
1*1 /
DYV
40*1 /
1*1 /
DZV
40*1 /
20*5 /
DEPTHZ
1681*123.456 /
4*0.0 /
PORO
20*0.3 /
PERMX
20*500 /
-------------------------------------
PROPS

View File

@ -7,36 +7,43 @@
RUNSPEC
WATER
OIL
GAS
OIL
METRIC
DIMENS
3 3 3 /
1 1 10 /
TABDIMS
1 1 40 20 1 20 /
EQLDIMS
-- NTEQUL
1 /
-------------------------------------
GRID
-- Opm::EclipseState assumes that _some_ grid gets defined, so let's
-- specify a fake one...
DXV
1 2 3 /
1*1 /
DYV
4 5 6 /
1*1 /
DZV
7 8 9 /
10*1 /
DEPTHZ
16*123.456 /
TOPS
1*0.0 /
PORO
10*0.3 /
PERMX
10*500 /
-------------------------------------
PROPS

File diff suppressed because it is too large Load Diff

View File

@ -1,155 +0,0 @@
/*
Copyright 2014 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
/* --- Boost.Test boilerplate --- */
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE // Suppress own messages when throw()ing
#define BOOST_TEST_MODULE RegionMapping
#include <opm/common/utility/platform_dependent/disable_warnings.h>
#include <boost/test/unit_test.hpp>
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
/* --- our own headers --- */
#include <opm/core/utility/RegionMapping.hpp>
#include <algorithm>
#include <map>
BOOST_AUTO_TEST_SUITE ()
BOOST_AUTO_TEST_CASE (Forward)
{
std::vector<int> regions = { 2, 5, 2, 4, 2, 7, 6, 3, 6 };
Opm::RegionMapping<> rm(regions);
for (decltype(regions.size()) i = 0, n = regions.size(); i < n; ++i) {
BOOST_CHECK_EQUAL(rm.region(i), regions[i]);
}
}
BOOST_AUTO_TEST_CASE (ActiveRegions)
{
// 0 1 2 3 4 5 6 7 8
std::vector<int> regions = { 2, 5, 2, 4, 2, 7, 6, 3, 6 };
Opm::RegionMapping<> rm(regions);
std::vector<int> region_ids = { 2, 3, 4, 5, 6, 7 };
auto active = [&region_ids](const int reg)
{
auto b = region_ids.begin();
auto e = region_ids.end();
return std::find(b, e, reg) != e;
};
BOOST_CHECK_EQUAL(rm.activeRegions().size(), region_ids.size());
for (const auto& reg : rm.activeRegions()) {
BOOST_CHECK(active(reg));
}
}
BOOST_AUTO_TEST_CASE (Consecutive)
{
using RegionCells = std::map<int, std::vector<int>>;
// 0 1 2 3 4 5 6 7 8
std::vector<int> regions = { 2, 5, 2, 4, 2, 7, 6, 3, 6 };
Opm::RegionMapping<> rm(regions);
std::vector<int> region_ids = { 2, 3, 4, 5, 6, 7 };
RegionCells region_cells;
{
using VT = RegionCells::value_type;
region_cells.insert(VT(2, { 0, 2, 4 }));
region_cells.insert(VT(3, { 7 }));
region_cells.insert(VT(4, { 3 }));
region_cells.insert(VT(5, { 1 }));
region_cells.insert(VT(6, { 6, 8 }));
region_cells.insert(VT(7, { 5 }));
}
for (const auto& reg : region_ids) {
const auto& cells = rm.cells(reg);
const auto& expect = region_cells[reg];
BOOST_CHECK_EQUAL_COLLECTIONS(cells .begin(), cells .end(),
expect.begin(), expect.end());
}
// Verify that there are no cells in unused regions 0 and 1.
for (const auto& r : { 0, 1 }) {
BOOST_CHECK(rm.cells(r).empty());
}
}
BOOST_AUTO_TEST_CASE (NonConsecutive)
{
using RegionCells = std::map<int, std::vector<int>>;
// 0 1 2 3 4 5 6 7 8
std::vector<int> regions = { 2, 4, 2, 4, 2, 7, 6, 3, 6 };
Opm::RegionMapping<> rm(regions);
std::vector<int> region_ids = { 2, 3, 4, 6, 7 };
RegionCells region_cells;
{
using VT = RegionCells::value_type;
region_cells.insert(VT(2, { 0, 2, 4 }));
region_cells.insert(VT(3, { 7 }));
region_cells.insert(VT(4, { 1, 3 }));
region_cells.insert(VT(6, { 6, 8 }));
region_cells.insert(VT(7, { 5 }));
}
for (const auto& reg : region_ids) {
const auto& cells = rm.cells(reg);
const auto& expect = region_cells[reg];
BOOST_CHECK_EQUAL_COLLECTIONS(cells .begin(), cells .end(),
expect.begin(), expect.end());
}
// Verify that there are no cells in unused regions 0, 1, and 5.
for (const auto& r : { 0, 1, 5 }) {
BOOST_CHECK(rm.cells(r).empty());
}
}
BOOST_AUTO_TEST_SUITE_END()