From 88d1d9762dfca836c688f98f1c2e95f022e2a03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Mon, 27 Aug 2012 12:20:03 +0200 Subject: [PATCH 01/32] Addes support for initialisation of three phases using SWOF and SGOF --- opm/core/utility/initState_impl.hpp | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/opm/core/utility/initState_impl.hpp b/opm/core/utility/initState_impl.hpp index c50db8a9..f6670434 100644 --- a/opm/core/utility/initState_impl.hpp +++ b/opm/core/utility/initState_impl.hpp @@ -512,11 +512,12 @@ namespace Opm State& state) { const int num_phases = props.numPhases(); - if (num_phases != 2) { - THROW("initStateFromDeck(): currently handling only two-phase scenarios."); - } + state.init(grid, num_phases); if (deck.hasField("EQUIL")) { + if (num_phases != 2) { + THROW("initStateFromDeck(): currently handling only two-phase scenarios."); + } // Set saturations depending on oil-water contact. const EQUIL& equil= deck.getEQUIL(); if (equil.equil.size() != 1) { @@ -535,11 +536,22 @@ namespace Opm const std::vector& sw_deck = deck.getFloatingPointValue("SWAT"); const std::vector& p_deck = deck.getFloatingPointValue("PRESSURE"); const int num_cells = grid.number_of_cells; - for (int c = 0; c < num_cells; ++c) { - int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c]; - s[2*c] = sw_deck[c_deck]; - s[2*c + 1] = 1.0 - s[2*c]; - p[c] = p_deck[c_deck]; + if(num_phases == 2){ + for (int c = 0; c < num_cells; ++c) { + int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c]; + s[2*c] = sw_deck[c_deck]; + s[2*c + 1] = 1.0 - s[2*c]; + p[c] = p_deck[c_deck]; + } + }else{ + const std::vector& sg_deck = deck.getFloatingPointValue("SGAS"); + for (int c = 0; c < num_cells; ++c) { + int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c]; + s[2*c] = sw_deck[c_deck]; + s[2*c + 1] = 1.0 - (sw_deck[c_deck] + sg_deck[c_deck]); + s[2*c + 2] = sg_deck[c_deck]; + p[c] = p_deck[c_deck]; + } } } else { THROW("initStateFromDeck(): we must either have EQUIL, or both SWAT and PRESSURE."); From ea09af47f4b65ac1ae7afc2140d3be5f45615f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Mon, 27 Aug 2012 12:21:25 +0200 Subject: [PATCH 02/32] Added programs to test test fluids. --- tests/Makefile.am | 10 ++++- tests/pvt_test.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++ tests/relperm_test.cpp | 82 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 tests/pvt_test.cpp create mode 100644 tests/relperm_test.cpp diff --git a/tests/Makefile.am b/tests/Makefile.am index a82a1dc3..4181eaea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -21,7 +21,9 @@ test_read_vag \ test_readpolymer \ test_sf2p \ test_writeVtkData \ -unit_test +unit_test \ +pvt_test \ +relperm_test bo_resprop_test_SOURCES = bo_resprop_test.cpp @@ -54,6 +56,12 @@ test_writeVtkData_SOURCES = test_writeVtkData.cpp unit_test_SOURCES = unit_test.cpp +pvt_test_SOURCES = pvt_test.cpp +pvt_test_LDADD = $(LDADD) + +relperm_test_SOURCES = relperm_test.cpp +relperm_test_LDADD = $(LDADD) + if UMFPACK noinst_PROGRAMS += test_cfs_tpfa diff --git a/tests/pvt_test.cpp b/tests/pvt_test.cpp new file mode 100644 index 00000000..45e2775d --- /dev/null +++ b/tests/pvt_test.cpp @@ -0,0 +1,87 @@ +/* + Copyright 2012 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 . +*/ + + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + // Parameters. + Opm::parameter::ParameterGroup param(argc, argv); + + // Parser. + std::string ecl_file = param.get("deck_filename"); + std::string input_file = param.get("input_filename"); + std::string matrix_output = param.get("matrix_outout"); + std::string rs_output = param.get("rs_output"); + std::string b_output = param.get("b_output"); + Opm::EclipseGridParser deck(ecl_file); + UnstructuredGrid grid; + grid.number_of_cells = 1; + grid.global_cell = NULL; + Opm::BlackoilPropertiesFromDeck props(deck, grid); + Opm::BlackoilPvtProperties pvt; + pvt.init(deck); + + + const int n = 1; + std::fstream inos(input_file.c_str()); + int np=props.numPhases(); + while(inos.good()){ + double p[n]; + double z[np*n]; + int cells[n] = { 0 }; + inos >> p[0]; + for(int i=0; i < np; ++i){ + inos >> z[i]; + } + double A[np*np*n]; + props.matrix(n, p, z, cells, A, 0); + std::fstream aos(matrix_output.c_str()); + std::copy(A, A + np*np, std::ostream_iterator(aos, " ")); + std::cout << std::endl; + double b[np]; + double dbdp[np]; + pvt.dBdp(n, p, z, b, dbdp); + std::fstream bos(b_output.c_str()); + std::copy(b, b + np, std::ostream_iterator(bos, " ")); + std::copy(b, dbdp + np, std::ostream_iterator(bos, " ")); + std::cout << std::endl; + double rs[np]; + double drs[np]; + //pvt.R(n, p, z, rs); + pvt.dRdp(n, p, z, rs,drs); + std::fstream rsos(rs_output.c_str()); + std::copy(b, rs + np, std::ostream_iterator(rsos, " ")); + std::copy(b, drs + np, std::ostream_iterator(rsos, " ")); + std::cout << std::endl; + } +} diff --git a/tests/relperm_test.cpp b/tests/relperm_test.cpp new file mode 100644 index 00000000..64897289 --- /dev/null +++ b/tests/relperm_test.cpp @@ -0,0 +1,82 @@ +/* + Copyright 2012 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 . +*/ + + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv) +{ + // Parameters. + Opm::parameter::ParameterGroup param(argc, argv); + + // Parser. + std::string ecl_file = param.get("deck_filename"); + std::string input_file = param.get("input_filename"); + std::string relperm_output = param.get("relperm_output"); + //std::string relperm_output = param.get("relperm_outout"); + Opm::EclipseGridParser deck(ecl_file); + UnstructuredGrid grid; + grid.number_of_cells = 1; + grid.global_cell = NULL; + Opm::BlackoilPropertiesFromDeck props(deck, grid); + + std::fstream inos(input_file.c_str());//, std::fstream::in); + if(!inos.good()){ + std::cout << "Could not open :" << input_file << std::endl; + exit(3); + } + std::fstream kros(relperm_output.c_str(), std::fstream::out | std::fstream::trunc); + if(!kros.good()){ + std::cout << "Could not open :" << input_file << std::endl; + exit(3); + } + int np=props.numPhases(); + while((inos.good()) && (!inos.eof())){ + double s[np]; + for(int i=0; i < np; ++i){ + inos >> s[i]; + } + if(inos.good()){ + double kr[np]; + double dkr[np*np]; + int cell[1]; + cell[0]=1; + props.relperm(1,s, cell, kr, dkr); + std::copy(s, s + np, std::ostream_iterator(kros, " ")); + kros << " "; + std::copy(kr, kr + np, std::ostream_iterator(kros, " ")); + kros << " "; + std::copy(dkr, dkr + np*np, std::ostream_iterator(kros, " ")); + kros << "\n"; + } + } +} From a6dcc52cba4a8cf08b91e899195377de3a496ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Mon, 27 Aug 2012 12:22:32 +0200 Subject: [PATCH 03/32] Started work on supporting 3 phases for wellreport. --- opm/core/utility/miscUtilities.cpp | 45 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/opm/core/utility/miscUtilities.cpp b/opm/core/utility/miscUtilities.cpp index 16c59b17..cc7ff127 100644 --- a/opm/core/utility/miscUtilities.cpp +++ b/opm/core/utility/miscUtilities.cpp @@ -574,9 +574,10 @@ namespace Opm { int nw = well_bhp.size(); ASSERT(nw == wells.number_of_wells); - if (props.numPhases() != 2) { - THROW("WellReport for now assumes two phase flow."); - } + int np = props.numPhases(); + //if (props.numPhases() != 2) { + // THROW("WellReport for now assumes two phase flow."); + //} const double* visc = props.viscosity(); std::vector data_now; data_now.reserve(1 + 3*nw); @@ -586,7 +587,8 @@ namespace Opm double well_rate_total = 0.0; double well_rate_water = 0.0; for (int perf = wells.well_connpos[w]; perf < wells.well_connpos[w + 1]; ++perf) { - const double perf_rate = well_perfrates[perf]*(unit::day/unit::second); + const double perf_rate = unit::convert::to(well_perfrates[perf], + unit::cubic(unit::meter)/unit::day); well_rate_total += perf_rate; if (perf_rate > 0.0) { // Injection. @@ -594,11 +596,14 @@ namespace Opm } else { // Production. const int cell = wells.well_cells[perf]; - double mob[2]; + double mob[np]; props.relperm(1, &saturation[2*cell], &cell, mob, 0); - mob[0] /= visc[0]; - mob[1] /= visc[1]; - const double fracflow = mob[0]/(mob[0] + mob[1]); + double tmob=0; + for(int i=0; i < np; ++i){ + mob[i] /= visc[i]; + tmob += mob[i]; + } + const double fracflow = mob[0]/tmob; well_rate_water += perf_rate*fracflow; } } @@ -627,9 +632,10 @@ namespace Opm // TODO: refactor, since this is almost identical to the other push(). int nw = well_bhp.size(); ASSERT(nw == wells.number_of_wells); - if (props.numPhases() != 2) { - THROW("WellReport for now assumes two phase flow."); - } + int np = props.numPhases(); + //if (props.numPhases() != 2) { + // THROW("WellReport for now assumes two phase flow."); + //} std::vector data_now; data_now.reserve(1 + 3*nw); data_now.push_back(time/unit::day); @@ -640,20 +646,25 @@ namespace Opm for (int perf = wells.well_connpos[w]; perf < wells.well_connpos[w + 1]; ++perf) { const double perf_rate = well_perfrates[perf]*(unit::day/unit::second); well_rate_total += perf_rate; - if (perf_rate > 0.0) { + if (perf_rate > 0.0) { // Injection. well_rate_water += perf_rate*wells.comp_frac[0]; } else { // Production. const int cell = wells.well_cells[perf]; - double mob[2]; + double mob[np]; props.relperm(1, &s[2*cell], &cell, mob, 0); - double visc[2]; + double visc[np]; props.viscosity(1, &p[cell], &z[2*cell], &cell, visc, 0); - mob[0] /= visc[0]; - mob[1] /= visc[1]; - const double fracflow = mob[0]/(mob[0] + mob[1]); + double tmob=0; + for(int i=0; i < np; ++i){ + mob[i] /= visc[i]; + tmob += mob[i]; + } + const double fracflow = mob[0]/(tmob); well_rate_water += perf_rate*fracflow; + //const double fracflow = mob[0]/(tmob); + //well_rate_water += perf_rate*fracflow; } } data_now.push_back(well_rate_total); From c93380b52fa5e2e47c864b56e385c09b4bf540d9 Mon Sep 17 00:00:00 2001 From: Xavier Raynaud Date: Mon, 27 Aug 2012 13:19:04 +0200 Subject: [PATCH 04/32] Changed private->protected and added virtual to make class derivation. --- opm/core/pressure/CompressibleTpfa.hpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/opm/core/pressure/CompressibleTpfa.hpp b/opm/core/pressure/CompressibleTpfa.hpp index 9fc5c43f..affada84 100644 --- a/opm/core/pressure/CompressibleTpfa.hpp +++ b/opm/core/pressure/CompressibleTpfa.hpp @@ -90,16 +90,15 @@ namespace Opm bool singularPressure() const; private: - void computePerSolveDynamicData(const double dt, - const BlackoilState& state, - const WellState& well_state); - void computeWellPotentials(const BlackoilState& state); + virtual void computePerSolveDynamicData(const double dt, + const BlackoilState& state, + const WellState& well_state); void computePerIterationDynamicData(const double dt, const BlackoilState& state, const WellState& well_state); - void computeCellDynamicData(const double dt, - const BlackoilState& state, - const WellState& well_state); + virtual void computeCellDynamicData(const double dt, + const BlackoilState& state, + const WellState& well_state); void computeFaceDynamicData(const double dt, const BlackoilState& state, const WellState& well_state); @@ -114,6 +113,8 @@ namespace Opm double incrementNorm() const; void computeResults(BlackoilState& state, WellState& well_state) const; + protected: + void computeWellPotentials(const BlackoilState& state); // ------ Data that will remain unmodified after construction. ------ const UnstructuredGrid& grid_; From c920c83c76bf0559712d79dde23f6372bd06c2ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 27 Aug 2012 14:00:12 +0200 Subject: [PATCH 05/32] Renamed class SinglePvtDead -> SinglePvtDeadSpline. --- Makefile.am | 4 +- .../fluid/blackoil/BlackoilPvtProperties.cpp | 6 +-- ...glePvtDead.cpp => SinglePvtDeadSpline.cpp} | 50 +++++++++---------- ...glePvtDead.hpp => SinglePvtDeadSpline.hpp} | 12 ++--- 4 files changed, 36 insertions(+), 36 deletions(-) rename opm/core/fluid/blackoil/{SinglePvtDead.cpp => SinglePvtDeadSpline.cpp} (68%) rename opm/core/fluid/blackoil/{SinglePvtDead.hpp => SinglePvtDeadSpline.hpp} (90%) diff --git a/Makefile.am b/Makefile.am index 712d7c65..c30a6544 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,7 +51,7 @@ opm/core/fluid/RockFromDeck.cpp \ opm/core/fluid/SaturationPropsBasic.cpp \ opm/core/fluid/SaturationPropsFromDeck.cpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.cpp \ -opm/core/fluid/blackoil/SinglePvtDead.cpp \ +opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp \ opm/core/fluid/blackoil/SinglePvtInterface.cpp \ opm/core/fluid/blackoil/SinglePvtLiveGas.cpp \ opm/core/fluid/blackoil/SinglePvtLiveOil.cpp \ @@ -151,7 +151,7 @@ opm/core/fluid/SimpleFluid2p.hpp \ opm/core/fluid/blackoil/BlackoilPhases.hpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \ opm/core/fluid/blackoil/SinglePvtConstCompr.hpp \ -opm/core/fluid/blackoil/SinglePvtDead.hpp \ +opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp \ opm/core/fluid/blackoil/SinglePvtInterface.hpp \ opm/core/fluid/blackoil/SinglePvtLiveGas.hpp \ opm/core/fluid/blackoil/SinglePvtLiveOil.hpp \ diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp index 9fdaf445..c86724eb 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp @@ -20,7 +20,7 @@ #include -#include +#include #include #include #include @@ -78,7 +78,7 @@ namespace Opm // Oil PVT if (phase_usage_.phase_used[Liquid]) { if (deck.hasField("PVDO")) { - props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_)); + props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_)); } else if (deck.hasField("PVTO")) { props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_)); } else if (deck.hasField("PVCDO")) { @@ -90,7 +90,7 @@ namespace Opm // Gas PVT if (phase_usage_.phase_used[Vapour]) { if (deck.hasField("PVDG")) { - props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_)); + props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_)); } else if (deck.hasField("PVTG")) { props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_)); } else { diff --git a/opm/core/fluid/blackoil/SinglePvtDead.cpp b/opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp similarity index 68% rename from opm/core/fluid/blackoil/SinglePvtDead.cpp rename to opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp index 3d1a2740..c8e06656 100644 --- a/opm/core/fluid/blackoil/SinglePvtDead.cpp +++ b/opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp @@ -17,7 +17,7 @@ along with OPM. If not, see . */ -#include +#include #include #include @@ -34,7 +34,7 @@ namespace Opm //------------------------------------------------------------------------- /// Constructor - SinglePvtDead::SinglePvtDead(const table_t& pvd_table) + SinglePvtDeadSpline::SinglePvtDeadSpline(const table_t& pvd_table) { const int region_number = 0; if (pvd_table.size() != 1) { @@ -64,16 +64,16 @@ namespace Opm } // Destructor - SinglePvtDead::~SinglePvtDead() + SinglePvtDeadSpline::~SinglePvtDeadSpline() { } - void SinglePvtDead::mu(const int n, - const double* p, - const double* /*z*/, - double* output_mu) const + void SinglePvtDeadSpline::mu(const int n, + const double* p, + const double* /*z*/, + double* output_mu) const { // #pragma omp parallel for for (int i = 0; i < n; ++i) { @@ -81,10 +81,10 @@ namespace Opm } } - void SinglePvtDead::B(const int n, - const double* p, - const double* /*z*/, - double* output_B) const + void SinglePvtDeadSpline::B(const int n, + const double* p, + const double* /*z*/, + double* output_B) const { // #pragma omp parallel for for (int i = 0; i < n; ++i) { @@ -92,11 +92,11 @@ namespace Opm } } - void SinglePvtDead::dBdp(const int n, - const double* p, - const double* /*z*/, - double* output_B, - double* output_dBdp) const + void SinglePvtDeadSpline::dBdp(const int n, + const double* p, + const double* /*z*/, + double* output_B, + double* output_dBdp) const { B(n, p, 0, output_B); // #pragma omp parallel for @@ -107,19 +107,19 @@ namespace Opm } - void SinglePvtDead::R(const int n, - const double* /*p*/, - const double* /*z*/, - double* output_R) const + void SinglePvtDeadSpline::R(const int n, + const double* /*p*/, + const double* /*z*/, + double* output_R) const { std::fill(output_R, output_R + n, 0.0); } - void SinglePvtDead::dRdp(const int n, - const double* /*p*/, - const double* /*z*/, - double* output_R, - double* output_dRdp) const + void SinglePvtDeadSpline::dRdp(const int n, + const double* /*p*/, + const double* /*z*/, + double* output_R, + double* output_dRdp) const { std::fill(output_R, output_R + n, 0.0); std::fill(output_dRdp, output_dRdp + n, 0.0); diff --git a/opm/core/fluid/blackoil/SinglePvtDead.hpp b/opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp similarity index 90% rename from opm/core/fluid/blackoil/SinglePvtDead.hpp rename to opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp index 137e2e30..588ae554 100644 --- a/opm/core/fluid/blackoil/SinglePvtDead.hpp +++ b/opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp @@ -17,8 +17,8 @@ along with OPM. If not, see . */ -#ifndef OPM_SINGLEPVTDEAD_HEADER_INCLUDED -#define OPM_SINGLEPVTDEAD_HEADER_INCLUDED +#ifndef OPM_SINGLEPVTDEADSPLINE_HEADER_INCLUDED +#define OPM_SINGLEPVTDEADSPLINE_HEADER_INCLUDED #include @@ -33,13 +33,13 @@ namespace Opm /// are expected to be of size n and n*num_phases, respectively. /// Output arrays shall be of size n, and must be valid before /// calling the method. - class SinglePvtDead : public SinglePvtInterface + class SinglePvtDeadSpline : public SinglePvtInterface { public: typedef std::vector > > table_t; - SinglePvtDead(const table_t& pvd_table); - virtual ~SinglePvtDead(); + SinglePvtDeadSpline(const table_t& pvd_table); + virtual ~SinglePvtDeadSpline(); /// Viscosity as a function of p and z. virtual void mu(const int n, @@ -80,5 +80,5 @@ namespace Opm } -#endif // OPM_SINGLEPVTDEAD_HEADER_INCLUDED +#endif // OPM_SINGLEPVTDEADSPLINE_HEADER_INCLUDED From 547dc1648ccdb13aa5910624bb3dd3b3042148da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 27 Aug 2012 16:48:21 +0200 Subject: [PATCH 06/32] Added class SinglePvtDead, add parameter 'props_use_spline' to simulators. Recall that the class that used to be called SinglePvtDead has been renamed to SinglePvtDeadSpline. If 'props_use_spline' is true, that class is used (this is the default), which makes a monotone spline that is uniformly, densely sampled. The new class simply uses linear interpolation in the input tables. --- Makefile.am | 3 + examples/sim_2p_comp_reorder.cpp | 3 +- examples/sim_wateroil.cpp | 3 +- opm/core/fluid/BlackoilPropertiesFromDeck.cpp | 5 +- opm/core/fluid/BlackoilPropertiesFromDeck.hpp | 3 +- .../fluid/blackoil/BlackoilPvtProperties.cpp | 15 +- .../fluid/blackoil/BlackoilPvtProperties.hpp | 2 +- opm/core/fluid/blackoil/SinglePvtDead.cpp | 127 +++++++++ opm/core/fluid/blackoil/SinglePvtDead.hpp | 84 ++++++ opm/core/utility/NonuniformTableLinear.hpp | 244 ++++++++++++++++++ tests/bo_resprop_test.cpp | 3 +- 11 files changed, 482 insertions(+), 10 deletions(-) create mode 100644 opm/core/fluid/blackoil/SinglePvtDead.cpp create mode 100644 opm/core/fluid/blackoil/SinglePvtDead.hpp create mode 100644 opm/core/utility/NonuniformTableLinear.hpp diff --git a/Makefile.am b/Makefile.am index c30a6544..cb3d794e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,6 +51,7 @@ opm/core/fluid/RockFromDeck.cpp \ opm/core/fluid/SaturationPropsBasic.cpp \ opm/core/fluid/SaturationPropsFromDeck.cpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.cpp \ +opm/core/fluid/blackoil/SinglePvtDead.cpp \ opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp \ opm/core/fluid/blackoil/SinglePvtInterface.cpp \ opm/core/fluid/blackoil/SinglePvtLiveGas.cpp \ @@ -151,6 +152,7 @@ opm/core/fluid/SimpleFluid2p.hpp \ opm/core/fluid/blackoil/BlackoilPhases.hpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \ opm/core/fluid/blackoil/SinglePvtConstCompr.hpp \ +opm/core/fluid/blackoil/SinglePvtDead.hpp \ opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp \ opm/core/fluid/blackoil/SinglePvtInterface.hpp \ opm/core/fluid/blackoil/SinglePvtLiveGas.hpp \ @@ -226,6 +228,7 @@ opm/core/utility/ColumnExtract.hpp \ opm/core/utility/ErrorMacros.hpp \ opm/core/utility/Factory.hpp \ opm/core/utility/MonotCubicInterpolator.hpp \ +opm/core/utility/NonuniformTableLinear.hpp \ opm/core/utility/RootFinders.hpp \ opm/core/utility/SparseTable.hpp \ opm/core/utility/SparseVector.hpp \ diff --git a/examples/sim_2p_comp_reorder.cpp b/examples/sim_2p_comp_reorder.cpp index 9f2b516b..705812c5 100644 --- a/examples/sim_2p_comp_reorder.cpp +++ b/examples/sim_2p_comp_reorder.cpp @@ -94,7 +94,8 @@ main(int argc, char** argv) // Grid init grid.reset(new GridManager(*deck)); // Rock and fluid init - props.reset(new BlackoilPropertiesFromDeck(*deck, *grid->c_grid())); + bool props_use_spline = param.getDefault("props_use_spline", true); + props.reset(new BlackoilPropertiesFromDeck(*deck, *grid->c_grid(), props_use_spline)); // check_well_controls = param.getDefault("check_well_controls", false); // max_well_control_iterations = param.getDefault("max_well_control_iterations", 10); // Rock compressibility. diff --git a/examples/sim_wateroil.cpp b/examples/sim_wateroil.cpp index f7e0172f..bde2ecf9 100644 --- a/examples/sim_wateroil.cpp +++ b/examples/sim_wateroil.cpp @@ -175,7 +175,8 @@ main(int argc, char** argv) // Grid init grid.reset(new Opm::GridManager(deck)); // Rock and fluid init - props.reset(new Opm::BlackoilPropertiesFromDeck(deck, *grid->c_grid())); + bool props_use_spline = param.getDefault("props_use_spline", true); + props.reset(new BlackoilPropertiesFromDeck(deck, *grid->c_grid(), props_use_spline)); // Wells init. wells.reset(new Opm::WellsManager(deck, *grid->c_grid(), props->permeability())); check_well_controls = param.getDefault("check_well_controls", false); diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp index 004e6f88..e7244d87 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp @@ -23,10 +23,11 @@ namespace Opm { BlackoilPropertiesFromDeck::BlackoilPropertiesFromDeck(const EclipseGridParser& deck, - const UnstructuredGrid& grid) + const UnstructuredGrid& grid, + const bool use_spline) { rock_.init(deck, grid); - pvt_.init(deck); + pvt_.init(deck, use_spline); satprops_.init(deck, grid); if (pvt_.numPhases() != satprops_.numPhases()) { THROW("BlackoilPropertiesBasic::BlackoilPropertiesBasic() - Inconsistent number of phases in pvt data (" diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp index a2a6c3de..c434b7f4 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp @@ -43,7 +43,8 @@ namespace Opm /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, - const UnstructuredGrid& grid); + const UnstructuredGrid& grid, + const bool use_spline); /// Destructor. virtual ~BlackoilPropertiesFromDeck(); diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp index c86724eb..dd8ce720 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -39,7 +40,7 @@ namespace Opm } - void BlackoilPvtProperties::init(const EclipseGridParser& deck) + void BlackoilPvtProperties::init(const EclipseGridParser& deck, const bool use_spline) { typedef std::vector > > table_t; // If we need multiple regions, this class and the SinglePvt* classes must change. @@ -78,7 +79,11 @@ namespace Opm // Oil PVT if (phase_usage_.phase_used[Liquid]) { if (deck.hasField("PVDO")) { - props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_)); + if (use_spline) { + props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDeadSpline(deck.getPVDO().pvdo_)); + } else { + props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_)); + } } else if (deck.hasField("PVTO")) { props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_)); } else if (deck.hasField("PVCDO")) { @@ -90,7 +95,11 @@ namespace Opm // Gas PVT if (phase_usage_.phase_used[Vapour]) { if (deck.hasField("PVDG")) { - props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_)); + if (use_spline) { + props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDeadSpline(deck.getPVDG().pvdg_)); + } else { + props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_)); + } } else if (deck.hasField("PVTG")) { props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_)); } else { diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp index 627f266b..ca193a4d 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp @@ -47,7 +47,7 @@ namespace Opm BlackoilPvtProperties(); /// Initialize from deck. - void init(const EclipseGridParser& deck); + void init(const EclipseGridParser& deck, const bool use_spline); /// Number of active phases. int numPhases() const; diff --git a/opm/core/fluid/blackoil/SinglePvtDead.cpp b/opm/core/fluid/blackoil/SinglePvtDead.cpp new file mode 100644 index 00000000..f9bcd090 --- /dev/null +++ b/opm/core/fluid/blackoil/SinglePvtDead.cpp @@ -0,0 +1,127 @@ +/* + Copyright 2012 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 . +*/ + + +#include +#include + +// Extra includes for debug dumping of tables. +// #include +// #include +// #include + +namespace Opm +{ + + //------------------------------------------------------------------------ + // Member functions + //------------------------------------------------------------------------- + + /// Constructor + SinglePvtDead::SinglePvtDead(const table_t& pvd_table) + { + const int region_number = 0; + if (pvd_table.size() != 1) { + THROW("More than one PVT-region"); + } + + // Copy data + const int sz = pvd_table[region_number][0].size(); + std::vector press(sz); + std::vector B_inv(sz); + std::vector visc(sz); + for (int i = 0; i < sz; ++i) { + press[i] = pvd_table[region_number][0][i]; + B_inv[i] = 1.0 / pvd_table[region_number][1][i]; + visc[i] = pvd_table[region_number][2][i]; + } + one_over_B_ = NonuniformTableLinear(press, B_inv); + viscosity_ = NonuniformTableLinear(press, visc); + + // Dumping the created tables. +// static int count = 0; +// std::ofstream os((std::string("dump-") + boost::lexical_cast(count++)).c_str()); +// os.precision(15); +// os << "1/B\n\n" << one_over_B_ +// << "\n\nvisc\n\n" << viscosity_ << std::endl; + } + + // Destructor + SinglePvtDead::~SinglePvtDead() + { + } + + + + void SinglePvtDead::mu(const int n, + const double* p, + const double* /*z*/, + double* output_mu) const + { +// #pragma omp parallel for + for (int i = 0; i < n; ++i) { + output_mu[i] = viscosity_(p[i]); + } + } + + void SinglePvtDead::B(const int n, + const double* p, + const double* /*z*/, + double* output_B) const + { +// #pragma omp parallel for + for (int i = 0; i < n; ++i) { + output_B[i] = 1.0/one_over_B_(p[i]); + } + } + + void SinglePvtDead::dBdp(const int n, + const double* p, + const double* /*z*/, + double* output_B, + double* output_dBdp) const + { + B(n, p, 0, output_B); +// #pragma omp parallel for + for (int i = 0; i < n; ++i) { + double Bg = output_B[i]; + output_dBdp[i] = -Bg*Bg*one_over_B_.derivative(p[i]); + } + } + + + void SinglePvtDead::R(const int n, + const double* /*p*/, + const double* /*z*/, + double* output_R) const + { + std::fill(output_R, output_R + n, 0.0); + } + + void SinglePvtDead::dRdp(const int n, + const double* /*p*/, + const double* /*z*/, + double* output_R, + double* output_dRdp) const + { + std::fill(output_R, output_R + n, 0.0); + std::fill(output_dRdp, output_dRdp + n, 0.0); + } + +} diff --git a/opm/core/fluid/blackoil/SinglePvtDead.hpp b/opm/core/fluid/blackoil/SinglePvtDead.hpp new file mode 100644 index 00000000..629053fe --- /dev/null +++ b/opm/core/fluid/blackoil/SinglePvtDead.hpp @@ -0,0 +1,84 @@ +/* + Copyright 2012 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 . +*/ + +#ifndef OPM_SINGLEPVTDEAD_HEADER_INCLUDED +#define OPM_SINGLEPVTDEAD_HEADER_INCLUDED + + +#include +#include +#include + +namespace Opm +{ + + /// Class for immiscible dead oil and dry gas. + /// For all the virtual methods, the following apply: p and z + /// are expected to be of size n and n*num_phases, respectively. + /// Output arrays shall be of size n, and must be valid before + /// calling the method. + class SinglePvtDead : public SinglePvtInterface + { + public: + typedef std::vector > > table_t; + + SinglePvtDead(const table_t& pvd_table); + virtual ~SinglePvtDead(); + + /// Viscosity as a function of p and z. + virtual void mu(const int n, + const double* p, + const double* z, + double* output_mu) const; + + /// Formation volume factor as a function of p and z. + virtual void B(const int n, + const double* p, + const double* z, + double* output_B) const; + + /// Formation volume factor and p-derivative as functions of p and z. + virtual void dBdp(const int n, + const double* p, + const double* z, + double* output_B, + double* output_dBdp) const; + + /// Solution factor as a function of p and z. + virtual void R(const int n, + const double* p, + const double* z, + double* output_R) const; + + /// Solution factor and p-derivative as functions of p and z. + virtual void dRdp(const int n, + const double* p, + const double* z, + double* output_R, + double* output_dRdp) const; + private: + // PVT properties of dry gas or dead oil + NonuniformTableLinear one_over_B_; + NonuniformTableLinear viscosity_; + }; + +} + + +#endif // OPM_SINGLEPVTDEAD_HEADER_INCLUDED diff --git a/opm/core/utility/NonuniformTableLinear.hpp b/opm/core/utility/NonuniformTableLinear.hpp new file mode 100644 index 00000000..71334460 --- /dev/null +++ b/opm/core/utility/NonuniformTableLinear.hpp @@ -0,0 +1,244 @@ +/* + Copyright 2009, 2010, 2011, 2012 SINTEF ICT, Applied Mathematics. + Copyright 2009, 2010, 2011, 2012 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 . +*/ + +#ifndef OPM_NONUNIFORMTABLELINEAR_HEADER_INCLUDED +#define OPM_NONUNIFORMTABLELINEAR_HEADER_INCLUDED + +#include +#include +#include +#include + +#include +#include + +namespace Opm +{ + + + /// @brief Exception used for domain errors. + struct OutsideDomainException : public std::exception {}; + + + /// @brief This class uses linear interpolation to compute the value + /// (and its derivative) of a function f sampled at possibly + /// nonuniform points. + /// @tparam T the range type of the function (should be an algebraic ring type) + template + class NonuniformTableLinear + { + public: + /// @brief Default constructor. + NonuniformTableLinear(); + + /// @brief Construct from vectors of x and y values. + /// @param x_values vector of domain values + /// @param y_values vector of corresponding range values. + NonuniformTableLinear(const std::vector& x_values, + const std::vector& y_values); + + /// @brief Get the domain. + /// @return the domain as a pair of doubles. + std::pair domain(); + + /// @brief Rescale the domain. + /// @param new_domain the new domain as a pair of doubles. + void rescaleDomain(std::pair new_domain); + + /// @brief Evaluate the value at x. + /// @param x a domain value + /// @return f(x) + double operator()(const double x) const; + + /// @brief Evaluate the derivative at x. + /// @param x a domain value + /// @return f'(x) + double derivative(const double x) const; + + /// @brief Evaluate the inverse at y. Requires T to be a double. + /// @param y a range value + /// @return f^{-1}(y) + double inverse(const double y) const; + + /// @brief Equality operator. + /// @param other another NonuniformTableLinear. + /// @return true if they are represented exactly alike. + bool operator==(const NonuniformTableLinear& other) const; + + /// @brief Policies for how to behave when trying to evaluate outside the domain. + enum RangePolicy {Throw = 0, ClosestValue = 1, Extrapolate = 2}; + + /// @brief Sets the behavioural policy for evaluation to the left of the domain. + /// @param rp the policy + void setLeftPolicy(RangePolicy rp); + + /// @brief Sets the behavioural policy for evaluation to the right of the domain. + /// @param rp the policy + void setRightPolicy(RangePolicy rp); + + protected: + std::vector x_values_; + std::vector y_values_; + mutable std::vector x_values_reversed_; + mutable std::vector y_values_reversed_; + RangePolicy left_; + RangePolicy right_; + }; + + + // A utility function + /// @brief Detect if a sequence is nondecreasing. + /// @tparam FI a forward iterator whose value type has operator< defined. + /// @param beg start of sequence + /// @param end one-beyond-end of sequence + /// @return false if there exists two consecutive values (v1, v2) in the sequence + /// for which v2 < v1, else returns true. + template + bool isNondecreasing(const FI beg, const FI end) + { + if (beg == end) return true; + FI it = beg; + ++it; + FI prev = beg; + for (; it != end; ++it, ++prev) { + if (*it < *prev) { + return false; + } + } + return true; + } + + + + // Member implementations. + + template + inline + NonuniformTableLinear + ::NonuniformTableLinear() + : left_(ClosestValue), right_(ClosestValue) + { + } + + template + inline + NonuniformTableLinear + ::NonuniformTableLinear(const std::vector& x_values, + const std::vector& y_values) + : x_values_(x_values), y_values_(y_values), + left_(ClosestValue), right_(ClosestValue) + { + ASSERT(isNondecreasing(x_values.begin(), x_values.end())); + } + + template + inline std::pair + NonuniformTableLinear + ::domain() + { + return std::make_pair(x_values_[0], x_values_.back()); + } + + template + inline void + NonuniformTableLinear + ::rescaleDomain(std::pair new_domain) + { + const double a = x_values_[0]; + const double b = x_values_.back(); + const double c = new_domain.first; + const double d = new_domain.second; + // x in [a, b] -> x in [c, d] + for (int i = 0; i < int(x_values_.size()); ++i) { + x_values_[i] = (x_values_[i] - a)*(d - c)/(b - a) + c; + } + } + + template + inline double + NonuniformTableLinear + ::operator()(const double x) const + { + return Opm::linearInterpolation(x_values_, y_values_, x); + } + + template + inline double + NonuniformTableLinear + ::derivative(const double x) const + { + return Opm::linearInterpolationDerivative(x_values_, y_values_, x); + } + + template + inline double + NonuniformTableLinear + ::inverse(const double y) const + { + if (y_values_.front() < y_values_.back()) { + return Opm::linearInterpolation(y_values_, x_values_, y); + } else { + if (y_values_reversed_.empty()) { + y_values_reversed_ = y_values_; + std::reverse(y_values_reversed_.begin(), y_values_reversed_.end()); + ASSERT(isNondecreasing(y_values_reversed_.begin(), y_values_reversed_.end())); + x_values_reversed_ = x_values_; + std::reverse(x_values_reversed_.begin(), x_values_reversed_.end()); + } + return Opm::linearInterpolation(y_values_reversed_, x_values_reversed_, y); + } + } + + template + inline bool + NonuniformTableLinear + ::operator==(const NonuniformTableLinear& other) const + { + return x_values_ == other.x_values_ + && y_values_ == other.y_values_ + && left_ == other.left_ + && right_ == other.right_; + } + + template + inline void + NonuniformTableLinear + ::setLeftPolicy(RangePolicy rp) + { + if (rp != ClosestValue) { + THROW("Only ClosestValue RangePolicy implemented."); + } + left_ = rp; + } + + template + inline void + NonuniformTableLinear + ::setRightPolicy(RangePolicy rp) + { + if (rp != ClosestValue) { + THROW("Only ClosestValue RangePolicy implemented."); + } + right_ = rp; + } + +} // namespace Opm + +#endif // OPM_NONUNIFORMTABLELINEAR_HEADER_INCLUDED diff --git a/tests/bo_resprop_test.cpp b/tests/bo_resprop_test.cpp index 5bf3aea1..41baccbb 100644 --- a/tests/bo_resprop_test.cpp +++ b/tests/bo_resprop_test.cpp @@ -43,7 +43,8 @@ int main(int argc, char** argv) UnstructuredGrid grid; grid.number_of_cells = 1; grid.global_cell = NULL; - Opm::BlackoilPropertiesFromDeck props(deck, grid); + bool props_use_spline = param.getDefault("props_use_spline", true); + Opm::BlackoilPropertiesFromDeck props(deck, grid, props_use_spline); const int n = 1; double p[n] = { 150e5 }; From a74cd8e2c0609618e142bf3148dd26018deb5ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 27 Aug 2012 17:56:01 +0200 Subject: [PATCH 07/32] Enable choice of spline-smoothed saturation props (or not). --- Makefile.am | 2 + opm/core/fluid/BlackoilPropertiesFromDeck.cpp | 22 +- opm/core/fluid/BlackoilPropertiesFromDeck.hpp | 3 +- opm/core/fluid/IncompPropertiesFromDeck.hpp | 2 +- opm/core/fluid/SaturationPropsFromDeck.cpp | 380 +++++++++--------- opm/core/fluid/SaturationPropsFromDeck.hpp | 45 +-- .../fluid/SaturationPropsFromDeck_impl.hpp | 271 +++++++++++++ opm/core/fluid/SaturationPropsInterface.hpp | 85 ++++ 8 files changed, 598 insertions(+), 212 deletions(-) create mode 100644 opm/core/fluid/SaturationPropsFromDeck_impl.hpp create mode 100644 opm/core/fluid/SaturationPropsInterface.hpp diff --git a/Makefile.am b/Makefile.am index cb3d794e..5772b6b7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -148,6 +148,8 @@ opm/core/fluid/RockCompressibility.hpp \ opm/core/fluid/RockFromDeck.hpp \ opm/core/fluid/SaturationPropsBasic.hpp \ opm/core/fluid/SaturationPropsFromDeck.hpp \ +opm/core/fluid/SaturationPropsFromDeck_impl.hpp \ +opm/core/fluid/SaturationPropsInterface.hpp \ opm/core/fluid/SimpleFluid2p.hpp \ opm/core/fluid/blackoil/BlackoilPhases.hpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \ diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp index e7244d87..fdc9519c 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp @@ -28,10 +28,20 @@ namespace Opm { rock_.init(deck, grid); pvt_.init(deck, use_spline); - satprops_.init(deck, grid); - if (pvt_.numPhases() != satprops_.numPhases()) { + // Unfortunate lack of pointer smartness here... + if (use_spline) { + SaturationPropsFromDeck<>* ptr = new SaturationPropsFromDeck<>(); + ptr->init(deck, grid); + satprops_.reset(ptr); + } else { + SaturationPropsFromDeck* ptr + = new SaturationPropsFromDeck(); + ptr->init(deck, grid); + satprops_.reset(ptr); + } + if (pvt_.numPhases() != satprops_->numPhases()) { THROW("BlackoilPropertiesBasic::BlackoilPropertiesBasic() - Inconsistent number of phases in pvt data (" - << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); + << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_->numPhases() << ")."); } } @@ -236,7 +246,7 @@ namespace Opm double* kr, double* dkrds) const { - satprops_.relperm(n, s, cells, kr, dkrds); + satprops_->relperm(n, s, cells, kr, dkrds); } @@ -255,7 +265,7 @@ namespace Opm double* pc, double* dpcds) const { - satprops_.capPress(n, s, cells, pc, dpcds); + satprops_->capPress(n, s, cells, pc, dpcds); } @@ -271,7 +281,7 @@ namespace Opm double* smin, double* smax) const { - satprops_.satRange(n, cells, smin, smax); + satprops_->satRange(n, cells, smin, smax); } diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp index c434b7f4..60dc1e75 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp @@ -26,6 +26,7 @@ #include #include #include +#include struct UnstructuredGrid; @@ -166,7 +167,7 @@ namespace Opm private: RockFromDeck rock_; BlackoilPvtProperties pvt_; - SaturationPropsFromDeck satprops_; + boost::scoped_ptr satprops_; mutable std::vector B_; mutable std::vector dB_; mutable std::vector R_; diff --git a/opm/core/fluid/IncompPropertiesFromDeck.hpp b/opm/core/fluid/IncompPropertiesFromDeck.hpp index 68623e5c..5820bb66 100644 --- a/opm/core/fluid/IncompPropertiesFromDeck.hpp +++ b/opm/core/fluid/IncompPropertiesFromDeck.hpp @@ -135,7 +135,7 @@ namespace Opm private: RockFromDeck rock_; PvtPropertiesIncompFromDeck pvt_; - SaturationPropsFromDeck satprops_; + SaturationPropsFromDeck<> satprops_; }; diff --git a/opm/core/fluid/SaturationPropsFromDeck.cpp b/opm/core/fluid/SaturationPropsFromDeck.cpp index 36cf8364..9c7ccf9b 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.cpp +++ b/opm/core/fluid/SaturationPropsFromDeck.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -27,187 +26,15 @@ namespace Opm { - /// Default constructor. - SaturationPropsFromDeck::SaturationPropsFromDeck() - { - } - - /// Initialize from deck. - void SaturationPropsFromDeck::init(const EclipseGridParser& deck, - const UnstructuredGrid& grid) - { - phase_usage_ = phaseUsageFromDeck(deck); - - // Extract input data. - // Oil phase should be active. - if (!phase_usage_.phase_used[Liquid]) { - THROW("SaturationPropsFromDeck::init() -- oil phase must be active."); - } - - // Obtain SATNUM, if it exists, and create cell_to_func_. - // Otherwise, let the cell_to_func_ mapping be just empty. - int satfuncs_expected = 1; - if (deck.hasField("SATNUM")) { - const std::vector& satnum = deck.getIntegerValue("SATNUM"); - satfuncs_expected = *std::max_element(satnum.begin(), satnum.end()); - const int num_cells = grid.number_of_cells; - cell_to_func_.resize(num_cells); - const int* gc = grid.global_cell; - for (int cell = 0; cell < num_cells; ++cell) { - const int deck_pos = (gc == NULL) ? cell : gc[cell]; - cell_to_func_[cell] = satnum[deck_pos] - 1; - } - } - - // Find number of tables, check for consistency. - enum { Uninitialized = -1 }; - int num_tables = Uninitialized; - if (phase_usage_.phase_used[Aqua]) { - const SWOF::table_t& swof_table = deck.getSWOF().swof_; - num_tables = swof_table.size(); - if (num_tables < satfuncs_expected) { - THROW("Found " << num_tables << " SWOF tables, SATNUM specifies at least " << satfuncs_expected); - } - } - if (phase_usage_.phase_used[Vapour]) { - const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; - int num_sgof_tables = sgof_table.size(); - if (num_sgof_tables < satfuncs_expected) { - THROW("Found " << num_tables << " SGOF tables, SATNUM specifies at least " << satfuncs_expected); - } - if (num_tables == Uninitialized) { - num_tables = num_sgof_tables; - } else if (num_tables != num_sgof_tables) { - THROW("Inconsistent number of tables in SWOF and SGOF."); - } - } - - // Initialize tables. - satfuncset_.resize(num_tables); - for (int table = 0; table < num_tables; ++table) { - satfuncset_[table].init(deck, table, phase_usage_); - } - } - - /// \return P, the number of phases. - int SaturationPropsFromDeck::numPhases() const - { - return phase_usage_.num_phases; - } + // ----------- Methods of SatFuncSetUniform below ----------- - - - /// Relative permeability. - /// \param[in] n Number of data points. - /// \param[in] s Array of nP saturation values. - /// \param[in] cells Array of n cell indices to be associated with the s values. - /// \param[out] kr Array of nP relperm values, array must be valid before calling. - /// \param[out] dkrds If non-null: array of nP^2 relperm derivative values, - /// array must be valid before calling. - /// The P^2 derivative matrix is - /// m_{ij} = \frac{dkr_i}{ds^j}, - /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) - void SaturationPropsFromDeck::relperm(const int n, - const double* s, - const int* cells, - double* kr, - double* dkrds) const - { - ASSERT (cells != 0); - - const int np = phase_usage_.num_phases; - if (dkrds) { -// #pragma omp parallel for - for (int i = 0; i < n; ++i) { - funcForCell(cells[i]).evalKrDeriv(s + np*i, kr + np*i, dkrds + np*np*i); - } - } else { -// #pragma omp parallel for - for (int i = 0; i < n; ++i) { - funcForCell(cells[i]).evalKr(s + np*i, kr + np*i); - } - } - } - - - - - /// Capillary pressure. - /// \param[in] n Number of data points. - /// \param[in] s Array of nP saturation values. - /// \param[in] cells Array of n cell indices to be associated with the s values. - /// \param[out] pc Array of nP capillary pressure values, array must be valid before calling. - /// \param[out] dpcds If non-null: array of nP^2 derivative values, - /// array must be valid before calling. - /// The P^2 derivative matrix is - /// m_{ij} = \frac{dpc_i}{ds^j}, - /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) - void SaturationPropsFromDeck::capPress(const int n, - const double* s, - const int* cells, - double* pc, - double* dpcds) const - { - ASSERT (cells != 0); - - const int np = phase_usage_.num_phases; - if (dpcds) { -// #pragma omp parallel for - for (int i = 0; i < n; ++i) { - funcForCell(cells[i]).evalPcDeriv(s + np*i, pc + np*i, dpcds + np*np*i); - } - } else { -// #pragma omp parallel for - for (int i = 0; i < n; ++i) { - funcForCell(cells[i]).evalPc(s + np*i, pc + np*i); - } - } - } - - - - - /// Obtain the range of allowable saturation values. - /// \param[in] n Number of data points. - /// \param[in] cells Array of n cell indices. - /// \param[out] smin Array of nP minimum s values, array must be valid before calling. - /// \param[out] smax Array of nP maximum s values, array must be valid before calling. - void SaturationPropsFromDeck::satRange(const int n, - const int* cells, - double* smin, - double* smax) const - { - ASSERT (cells != 0); - - const int np = phase_usage_.num_phases; - for (int i = 0; i < n; ++i) { - for (int p = 0; p < np; ++p) { - smin[np*i + p] = funcForCell(cells[i]).smin_[p]; - smax[np*i + p] = funcForCell(cells[i]).smax_[p]; - } - } - } - - - // Map the cell number to the correct function set. - const SaturationPropsFromDeck::SatFuncSet& - SaturationPropsFromDeck::funcForCell(const int cell) const - { - return cell_to_func_.empty() ? satfuncset_[0] : satfuncset_[cell_to_func_[cell]]; - } - - - - // ----------- Methods of SatFuncSet below ----------- - - - void SaturationPropsFromDeck::SatFuncSet::init(const EclipseGridParser& deck, - const int table_num, - const PhaseUsage phase_usg) + void SatFuncSetUniform::init(const EclipseGridParser& deck, + const int table_num, + const PhaseUsage phase_usg) { phase_usage = phase_usg; const int samples = 200; @@ -250,7 +77,7 @@ namespace Opm } - void SaturationPropsFromDeck::SatFuncSet::evalKr(const double* s, double* kr) const + void SatFuncSetUniform::evalKr(const double* s, double* kr) const { if (phase_usage.num_phases == 3) { // Stone-II relative permeability model. @@ -291,7 +118,7 @@ namespace Opm } - void SaturationPropsFromDeck::SatFuncSet::evalKrDeriv(const double* s, double* kr, double* dkrds) const + void SatFuncSetUniform::evalKrDeriv(const double* s, double* kr, double* dkrds) const { const int np = phase_usage.num_phases; std::fill(dkrds, dkrds + np*np, 0.0); @@ -353,7 +180,7 @@ namespace Opm } - void SaturationPropsFromDeck::SatFuncSet::evalPc(const double* s, double* pc) const + void SatFuncSetUniform::evalPc(const double* s, double* pc) const { pc[phase_usage.phase_pos[Liquid]] = 0.0; if (phase_usage.phase_used[Aqua]) { @@ -366,7 +193,198 @@ namespace Opm } } - void SaturationPropsFromDeck::SatFuncSet::evalPcDeriv(const double* s, double* pc, double* dpcds) const + void SatFuncSetUniform::evalPcDeriv(const double* s, double* pc, double* dpcds) const + { + // The problem of determining three-phase capillary pressures + // is very hard experimentally, usually one extends two-phase + // data (as for relative permeability). + // In our approach the derivative matrix is quite sparse, only + // the diagonal elements corresponding to non-oil phases are + // (potentially) nonzero. + const int np = phase_usage.num_phases; + std::fill(dpcds, dpcds + np*np, 0.0); + pc[phase_usage.phase_pos[Liquid]] = 0.0; + if (phase_usage.phase_used[Aqua]) { + int pos = phase_usage.phase_pos[Aqua]; + pc[pos] = pcow_(s[pos]); + dpcds[np*pos + pos] = pcow_.derivative(s[pos]); + } + if (phase_usage.phase_used[Vapour]) { + int pos = phase_usage.phase_pos[Vapour]; + pc[pos] = pcog_(s[pos]); + dpcds[np*pos + pos] = pcog_.derivative(s[pos]); + } + } + + + + + + + // ----------- Methods of SatFuncSetNonuniform below ----------- + + + void SatFuncSetNonuniform::init(const EclipseGridParser& deck, + const int table_num, + const PhaseUsage phase_usg) + { + phase_usage = phase_usg; + double swco = 0.0; + double swmax = 1.0; + if (phase_usage.phase_used[Aqua]) { + const SWOF::table_t& swof_table = deck.getSWOF().swof_; + const std::vector& sw = swof_table[table_num][0]; + const std::vector& krw = swof_table[table_num][1]; + const std::vector& krow = swof_table[table_num][2]; + const std::vector& pcow = swof_table[table_num][3]; + krw_ = NonuniformTableLinear(sw, krw); + krow_ = NonuniformTableLinear(sw, krow); + pcow_ = NonuniformTableLinear(sw, pcow); + krocw_ = krow[0]; // At connate water -> ecl. SWOF + swco = sw[0]; + smin_[phase_usage.phase_pos[Aqua]] = sw[0]; + swmax = sw.back(); + smax_[phase_usage.phase_pos[Aqua]] = sw.back(); + } + if (phase_usage.phase_used[Vapour]) { + const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; + const std::vector& sg = sgof_table[table_num][0]; + const std::vector& krg = sgof_table[table_num][1]; + const std::vector& krog = sgof_table[table_num][2]; + const std::vector& pcog = sgof_table[table_num][3]; + krg_ = NonuniformTableLinear(sg, krg); + krog_ = NonuniformTableLinear(sg, krog); + pcog_ = NonuniformTableLinear(sg, pcog); + smin_[phase_usage.phase_pos[Vapour]] = sg[0]; + if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { + THROW("Gas maximum saturation in SGOF table = " << sg.back() << + ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); + } + smax_[phase_usage.phase_pos[Vapour]] = sg.back(); + } + // These only consider water min/max sats. Consider gas sats? + smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; + smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; + } + + + void SatFuncSetNonuniform::evalKr(const double* s, double* kr) const + { + if (phase_usage.num_phases == 3) { + // Stone-II relative permeability model. + double sw = s[Aqua]; + double sg = s[Vapour]; + double krw = krw_(sw); + double krg = krg_(sg); + double krow = krow_(sw + sg); // = 1 - so + double krog = krog_(sg); // = 1 - so - sw + double krocw = krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + return; + } + // We have a two-phase situation. We know that oil is active. + if (phase_usage.phase_used[Aqua]) { + int wpos = phase_usage.phase_pos[Aqua]; + int opos = phase_usage.phase_pos[Liquid]; + double sw = s[wpos]; + double krw = krw_(sw); + double krow = krow_(sw); + kr[wpos] = krw; + kr[opos] = krow; + } else { + ASSERT(phase_usage.phase_used[Vapour]); + int gpos = phase_usage.phase_pos[Vapour]; + int opos = phase_usage.phase_pos[Liquid]; + double sg = s[gpos]; + double krg = krg_(sg); + double krog = krog_(sg); + kr[gpos] = krg; + kr[opos] = krog; + } + } + + + void SatFuncSetNonuniform::evalKrDeriv(const double* s, double* kr, double* dkrds) const + { + const int np = phase_usage.num_phases; + std::fill(dkrds, dkrds + np*np, 0.0); + + if (np == 3) { + // Stone-II relative permeability model. + double sw = s[Aqua]; + double sg = s[Vapour]; + double krw = krw_(sw); + double dkrww = krw_.derivative(sw); + double krg = krg_(sg); + double dkrgg = krg_.derivative(sg); + double krow = krow_(sw + sg); + double dkrow = krow_.derivative(sw + sg); + double krog = krog_(sg); + double dkrog = krog_.derivative(sg); + double krocw = krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + dkrds[Aqua + Aqua*np] = dkrww; + dkrds[Vapour + Vapour*np] = dkrgg; + dkrds[Liquid + Aqua*np] = krocw*((dkrow/krocw + dkrww)*(krog/krocw + krg) - dkrww); + dkrds[Liquid + Vapour*np] = krocw*((krow/krocw + krw)*(dkrog/krocw + dkrgg) - dkrgg) + + krocw*((dkrow/krocw + krw)*(krog/krocw + krg) - dkrgg); + return; + } + // We have a two-phase situation. We know that oil is active. + if (phase_usage.phase_used[Aqua]) { + int wpos = phase_usage.phase_pos[Aqua]; + int opos = phase_usage.phase_pos[Liquid]; + double sw = s[wpos]; + double krw = krw_(sw); + double dkrww = krw_.derivative(sw); + double krow = krow_(sw); + double dkrow = krow_.derivative(sw); + kr[wpos] = krw; + kr[opos] = krow; + dkrds[wpos + wpos*np] = dkrww; + dkrds[opos + wpos*np] = dkrow; // Row opos, column wpos, fortran order. + } else { + ASSERT(phase_usage.phase_used[Vapour]); + int gpos = phase_usage.phase_pos[Vapour]; + int opos = phase_usage.phase_pos[Liquid]; + double sg = s[gpos]; + double krg = krg_(sg); + double dkrgg = krg_.derivative(sg); + double krog = krog_(sg); + double dkrog = krog_.derivative(sg); + kr[gpos] = krg; + kr[opos] = krog; + dkrds[gpos + gpos*np] = dkrgg; + dkrds[opos + gpos*np] = dkrog; + } + + } + + + void SatFuncSetNonuniform::evalPc(const double* s, double* pc) const + { + pc[phase_usage.phase_pos[Liquid]] = 0.0; + if (phase_usage.phase_used[Aqua]) { + int pos = phase_usage.phase_pos[Aqua]; + pc[pos] = pcow_(s[pos]); + } + if (phase_usage.phase_used[Vapour]) { + int pos = phase_usage.phase_pos[Vapour]; + pc[pos] = pcog_(s[pos]); + } + } + + void SatFuncSetNonuniform::evalPcDeriv(const double* s, double* pc, double* dpcds) const { // The problem of determining three-phase capillary pressures // is very hard experimentally, usually one extends two-phase diff --git a/opm/core/fluid/SaturationPropsFromDeck.hpp b/opm/core/fluid/SaturationPropsFromDeck.hpp index b83a1271..a978bbac 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.hpp +++ b/opm/core/fluid/SaturationPropsFromDeck.hpp @@ -20,8 +20,8 @@ #ifndef OPM_SATURATIONPROPSFROMDECK_HEADER_INCLUDED #define OPM_SATURATIONPROPSFROMDECK_HEADER_INCLUDED +#include #include -#include #include #include @@ -30,7 +30,23 @@ struct UnstructuredGrid; namespace Opm { - class SaturationPropsFromDeck : public BlackoilPhases + + /// Class storing saturation functions in a uniform table, + /// densely sampled from a monotone spline, + /// using linear interpolation. + class SatFuncSetUniform; + + /// Class storing saturation functions in a nonuniform table + /// using linear interpolation. + class SatFuncSetNonuniform; + + + /// Interface to saturation functions from deck. + /// Possible values for template argument: + /// SatFuncSetNonuniform, + /// SatFuncSetUniform (default). + template + class SaturationPropsFromDeck : public SaturationPropsInterface { public: /// Default constructor. @@ -88,30 +104,12 @@ namespace Opm private: PhaseUsage phase_usage_; - class SatFuncSet - { - public: - void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg); - void evalKr(const double* s, double* kr) const; - void evalKrDeriv(const double* s, double* kr, double* dkrds) const; - void evalPc(const double* s, double* pc) const; - void evalPcDeriv(const double* s, double* pc, double* dpcds) const; - double smin_[PhaseUsage::MaxNumPhases]; - double smax_[PhaseUsage::MaxNumPhases]; - private: - PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. - UniformTableLinear krw_; - UniformTableLinear krow_; - UniformTableLinear pcow_; - UniformTableLinear krg_; - UniformTableLinear krog_; - UniformTableLinear pcog_; - double krocw_; // = krow_(s_wc) - }; std::vector satfuncset_; std::vector cell_to_func_; // = SATNUM - 1 - const SatFuncSet& funcForCell(const int cell) const; + typedef SatFuncSet Funcs; + + const Funcs& funcForCell(const int cell) const; }; @@ -119,6 +117,7 @@ namespace Opm } // namespace Opm +#include #endif // OPM_SATURATIONPROPSFROMDECK_HEADER_INCLUDED diff --git a/opm/core/fluid/SaturationPropsFromDeck_impl.hpp b/opm/core/fluid/SaturationPropsFromDeck_impl.hpp new file mode 100644 index 00000000..f64f12bc --- /dev/null +++ b/opm/core/fluid/SaturationPropsFromDeck_impl.hpp @@ -0,0 +1,271 @@ +/* + Copyright 2012 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 . +*/ + +#ifndef OPM_SATURATIONPROPSFROMDECK_IMPL_HEADER_INCLUDED +#define OPM_SATURATIONPROPSFROMDECK_IMPL_HEADER_INCLUDED + + +#include +#include +#include +#include + +namespace Opm +{ + + /// Class storing saturation functions in a uniform table, + /// densely sampled from a monotone spline, + /// using linear interpolation. + class SatFuncSetUniform : public BlackoilPhases + { + public: + void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg); + void evalKr(const double* s, double* kr) const; + void evalKrDeriv(const double* s, double* kr, double* dkrds) const; + void evalPc(const double* s, double* pc) const; + void evalPcDeriv(const double* s, double* pc, double* dpcds) const; + double smin_[PhaseUsage::MaxNumPhases]; + double smax_[PhaseUsage::MaxNumPhases]; + private: + PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. + UniformTableLinear krw_; + UniformTableLinear krow_; + UniformTableLinear pcow_; + UniformTableLinear krg_; + UniformTableLinear krog_; + UniformTableLinear pcog_; + double krocw_; // = krow_(s_wc) + }; + + + + + /// Class storing saturation functions in a nonuniform table + /// using linear interpolation. + class SatFuncSetNonuniform : public BlackoilPhases + { + public: + void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg); + void evalKr(const double* s, double* kr) const; + void evalKrDeriv(const double* s, double* kr, double* dkrds) const; + void evalPc(const double* s, double* pc) const; + void evalPcDeriv(const double* s, double* pc, double* dpcds) const; + double smin_[PhaseUsage::MaxNumPhases]; + double smax_[PhaseUsage::MaxNumPhases]; + private: + PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. + NonuniformTableLinear krw_; + NonuniformTableLinear krow_; + NonuniformTableLinear pcow_; + NonuniformTableLinear krg_; + NonuniformTableLinear krog_; + NonuniformTableLinear pcog_; + double krocw_; // = krow_(s_wc) + }; + + + + // ----------- Methods of SaturationPropsFromDeck --------- + + + /// Default constructor. + template + SaturationPropsFromDeck::SaturationPropsFromDeck() + { + } + + /// Initialize from deck. + template + void SaturationPropsFromDeck::init(const EclipseGridParser& deck, + const UnstructuredGrid& grid) + { + phase_usage_ = phaseUsageFromDeck(deck); + + // Extract input data. + // Oil phase should be active. + if (!phase_usage_.phase_used[Liquid]) { + THROW("SaturationPropsFromDeck::init() -- oil phase must be active."); + } + + // Obtain SATNUM, if it exists, and create cell_to_func_. + // Otherwise, let the cell_to_func_ mapping be just empty. + int satfuncs_expected = 1; + if (deck.hasField("SATNUM")) { + const std::vector& satnum = deck.getIntegerValue("SATNUM"); + satfuncs_expected = *std::max_element(satnum.begin(), satnum.end()); + const int num_cells = grid.number_of_cells; + cell_to_func_.resize(num_cells); + const int* gc = grid.global_cell; + for (int cell = 0; cell < num_cells; ++cell) { + const int deck_pos = (gc == NULL) ? cell : gc[cell]; + cell_to_func_[cell] = satnum[deck_pos] - 1; + } + } + + // Find number of tables, check for consistency. + enum { Uninitialized = -1 }; + int num_tables = Uninitialized; + if (phase_usage_.phase_used[Aqua]) { + const SWOF::table_t& swof_table = deck.getSWOF().swof_; + num_tables = swof_table.size(); + if (num_tables < satfuncs_expected) { + THROW("Found " << num_tables << " SWOF tables, SATNUM specifies at least " << satfuncs_expected); + } + } + if (phase_usage_.phase_used[Vapour]) { + const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; + int num_sgof_tables = sgof_table.size(); + if (num_sgof_tables < satfuncs_expected) { + THROW("Found " << num_tables << " SGOF tables, SATNUM specifies at least " << satfuncs_expected); + } + if (num_tables == Uninitialized) { + num_tables = num_sgof_tables; + } else if (num_tables != num_sgof_tables) { + THROW("Inconsistent number of tables in SWOF and SGOF."); + } + } + + // Initialize tables. + satfuncset_.resize(num_tables); + for (int table = 0; table < num_tables; ++table) { + satfuncset_[table].init(deck, table, phase_usage_); + } + } + + + + + /// \return P, the number of phases. + template + int SaturationPropsFromDeck::numPhases() const + { + return phase_usage_.num_phases; + } + + + + + /// Relative permeability. + /// \param[in] n Number of data points. + /// \param[in] s Array of nP saturation values. + /// \param[in] cells Array of n cell indices to be associated with the s values. + /// \param[out] kr Array of nP relperm values, array must be valid before calling. + /// \param[out] dkrds If non-null: array of nP^2 relperm derivative values, + /// array must be valid before calling. + /// The P^2 derivative matrix is + /// m_{ij} = \frac{dkr_i}{ds^j}, + /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) + template + void SaturationPropsFromDeck::relperm(const int n, + const double* s, + const int* cells, + double* kr, + double* dkrds) const + { + ASSERT (cells != 0); + + const int np = phase_usage_.num_phases; + if (dkrds) { +// #pragma omp parallel for + for (int i = 0; i < n; ++i) { + funcForCell(cells[i]).evalKrDeriv(s + np*i, kr + np*i, dkrds + np*np*i); + } + } else { +// #pragma omp parallel for + for (int i = 0; i < n; ++i) { + funcForCell(cells[i]).evalKr(s + np*i, kr + np*i); + } + } + } + + + + + /// Capillary pressure. + /// \param[in] n Number of data points. + /// \param[in] s Array of nP saturation values. + /// \param[in] cells Array of n cell indices to be associated with the s values. + /// \param[out] pc Array of nP capillary pressure values, array must be valid before calling. + /// \param[out] dpcds If non-null: array of nP^2 derivative values, + /// array must be valid before calling. + /// The P^2 derivative matrix is + /// m_{ij} = \frac{dpc_i}{ds^j}, + /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) + template + void SaturationPropsFromDeck::capPress(const int n, + const double* s, + const int* cells, + double* pc, + double* dpcds) const + { + ASSERT (cells != 0); + + const int np = phase_usage_.num_phases; + if (dpcds) { +// #pragma omp parallel for + for (int i = 0; i < n; ++i) { + funcForCell(cells[i]).evalPcDeriv(s + np*i, pc + np*i, dpcds + np*np*i); + } + } else { +// #pragma omp parallel for + for (int i = 0; i < n; ++i) { + funcForCell(cells[i]).evalPc(s + np*i, pc + np*i); + } + } + } + + + + + /// Obtain the range of allowable saturation values. + /// \param[in] n Number of data points. + /// \param[in] cells Array of n cell indices. + /// \param[out] smin Array of nP minimum s values, array must be valid before calling. + /// \param[out] smax Array of nP maximum s values, array must be valid before calling. + template + void SaturationPropsFromDeck::satRange(const int n, + const int* cells, + double* smin, + double* smax) const + { + ASSERT (cells != 0); + + const int np = phase_usage_.num_phases; + for (int i = 0; i < n; ++i) { + for (int p = 0; p < np; ++p) { + smin[np*i + p] = funcForCell(cells[i]).smin_[p]; + smax[np*i + p] = funcForCell(cells[i]).smax_[p]; + } + } + } + + + // Map the cell number to the correct function set. + template + const typename SaturationPropsFromDeck::Funcs& + SaturationPropsFromDeck::funcForCell(const int cell) const + { + return cell_to_func_.empty() ? satfuncset_[0] : satfuncset_[cell_to_func_[cell]]; + } + + + +} // namespace Opm + +#endif // OPM_SATURATIONPROPSFROMDECK_IMPL_HEADER_INCLUDED diff --git a/opm/core/fluid/SaturationPropsInterface.hpp b/opm/core/fluid/SaturationPropsInterface.hpp new file mode 100644 index 00000000..e5599567 --- /dev/null +++ b/opm/core/fluid/SaturationPropsInterface.hpp @@ -0,0 +1,85 @@ +/* + Copyright 2012 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 . +*/ + +#ifndef OPM_SATURATIONPROPSINTERFACE_HEADER_INCLUDED +#define OPM_SATURATIONPROPSINTERFACE_HEADER_INCLUDED + +#include + + +namespace Opm +{ + + class SaturationPropsInterface : public BlackoilPhases + { + public: + /// Virtual destructor. + virtual ~SaturationPropsInterface() {}; + + /// \return P, the number of phases. + virtual int numPhases() const = 0; + + /// Relative permeability. + /// \param[in] n Number of data points. + /// \param[in] s Array of nP saturation values. + /// \param[out] kr Array of nP relperm values, array must be valid before calling. + /// \param[out] dkrds If non-null: array of nP^2 relperm derivative values, + /// array must be valid before calling. + /// The P^2 derivative matrix is + /// m_{ij} = \frac{dkr_i}{ds^j}, + /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) + virtual void relperm(const int n, + const double* s, + const int* cells, + double* kr, + double* dkrds) const = 0; + + /// Capillary pressure. + /// \param[in] n Number of data points. + /// \param[in] s Array of nP saturation values. + /// \param[out] pc Array of nP capillary pressure values, array must be valid before calling. + /// \param[out] dpcds If non-null: array of nP^2 derivative values, + /// array must be valid before calling. + /// The P^2 derivative matrix is + /// m_{ij} = \frac{dpc_i}{ds^j}, + /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) + virtual void capPress(const int n, + const double* s, + const int* cells, + double* pc, + double* dpcds) const = 0; + + /// Obtain the range of allowable saturation values. + /// \param[in] n Number of data points. + /// \param[out] smin Array of nP minimum s values, array must be valid before calling. + /// \param[out] smax Array of nP maximum s values, array must be valid before calling. + virtual void satRange(const int n, + const int* cells, + double* smin, + double* smax) const = 0; + + }; + + + +} // namespace Opm + + + +#endif // OPM_SATURATIONPROPSINTERFACE_HEADER_INCLUDED From 84c75c5045c77fd864ca259c304a62be77e73770 Mon Sep 17 00:00:00 2001 From: Xavier Raynaud Date: Tue, 28 Aug 2012 13:12:54 +0200 Subject: [PATCH 08/32] Corrected comment. --- .../transport/reorder/TransportModelCompressibleTwophase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp b/opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp index 697f94a5..01882053 100644 --- a/opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp +++ b/opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp @@ -124,7 +124,7 @@ namespace Opm // // [[ incompressible was: r(s) = s - s0 + dt/pv*( influx + outflux*f(s) ) ]] // - // r(s) = s - B*z0 + dt/pv*( influx + outflux*f(s) ) + // r(s) = s - B*z0 + s*(poro - poro0)/poro0 + dt/pv*( influx + outflux*f(s) ) // // @@@ What about the source term // From 48360d23a1330ed552b688be9312ab89ea2aac85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Tue, 28 Aug 2012 14:27:14 +0200 Subject: [PATCH 09/32] Added param initializer on fluids with param to addjust table length. Moved internal class SatFunc to SatFuncStone2. --- Makefile.am | 2 + opm/core/fluid/BlackoilPropertiesFromDeck.cpp | 16 +- opm/core/fluid/BlackoilPropertiesFromDeck.hpp | 7 +- opm/core/fluid/SatFuncStone2.cpp | 209 +++++++++++++++ opm/core/fluid/SatFuncStone2.hpp | 32 +++ opm/core/fluid/SaturationPropsFromDeck.cpp | 251 ++++-------------- opm/core/fluid/SaturationPropsFromDeck.hpp | 33 +-- tests/pvt_test.cpp | 2 +- tests/relperm_test.cpp | 4 +- 9 files changed, 331 insertions(+), 225 deletions(-) create mode 100644 opm/core/fluid/SatFuncStone2.cpp create mode 100644 opm/core/fluid/SatFuncStone2.hpp diff --git a/Makefile.am b/Makefile.am index c1c85dec..3f67b50f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -50,6 +50,7 @@ opm/core/fluid/RockCompressibility.cpp \ opm/core/fluid/RockFromDeck.cpp \ opm/core/fluid/SaturationPropsBasic.cpp \ opm/core/fluid/SaturationPropsFromDeck.cpp \ +opm/core/fluid/SatFuncStone2.cpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.cpp \ opm/core/fluid/blackoil/SinglePvtDead.cpp \ opm/core/fluid/blackoil/SinglePvtInterface.cpp \ @@ -146,6 +147,7 @@ opm/core/fluid/RockCompressibility.hpp \ opm/core/fluid/RockFromDeck.hpp \ opm/core/fluid/SaturationPropsBasic.hpp \ opm/core/fluid/SaturationPropsFromDeck.hpp \ +opm/core/fluid/SatFuncStone2.hpp \ opm/core/fluid/SimpleFluid2p.hpp \ opm/core/fluid/blackoil/BlackoilPhases.hpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \ diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp index 004e6f88..ae6a6130 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp @@ -18,7 +18,7 @@ */ #include - +#include namespace Opm { @@ -34,6 +34,20 @@ namespace Opm } } + BlackoilPropertiesFromDeck::BlackoilPropertiesFromDeck(const EclipseGridParser& deck, + const UnstructuredGrid& grid, + const parameter::ParameterGroup& param) + { + rock_.init(deck, grid); + pvt_.init(deck); + satprops_.init(deck, grid, param); + + if (pvt_.numPhases() != satprops_.numPhases()) { + THROW("BlackoilPropertiesBasic::BlackoilPropertiesBasic() - Inconsistent number of phases in pvt data (" + << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); + } + } + BlackoilPropertiesFromDeck::~BlackoilPropertiesFromDeck() { } diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp index a2a6c3de..1d0a0d38 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp @@ -26,6 +26,7 @@ #include #include #include +#include struct UnstructuredGrid; @@ -43,8 +44,10 @@ namespace Opm /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, - const UnstructuredGrid& grid); - + const UnstructuredGrid& grid); + BlackoilPropertiesFromDeck(const EclipseGridParser& deck, + const UnstructuredGrid& grid, + const parameter::ParameterGroup& param); /// Destructor. virtual ~BlackoilPropertiesFromDeck(); diff --git a/opm/core/fluid/SatFuncStone2.cpp b/opm/core/fluid/SatFuncStone2.cpp new file mode 100644 index 00000000..ed97595a --- /dev/null +++ b/opm/core/fluid/SatFuncStone2.cpp @@ -0,0 +1,209 @@ +#include +#include +#include +#include +#include +#include +#include +#include +namespace Opm +{ + + + + +// ----------- Methods of SatFuncSet below ----------- +void SatFuncStone2::init(const EclipseGridParser& deck, + const int table_num, + const PhaseUsage phase_usg){ + init(deck, table_num, phase_usg, 200); +} + +void SatFuncStone2::init(const EclipseGridParser& deck, + const int table_num, + const PhaseUsage phase_usg, + const int samples) +{ + phase_usage = phase_usg; + double swco = 0.0; + double swmax = 1.0; + if (phase_usage.phase_used[Aqua]) { + const SWOF::table_t& swof_table = deck.getSWOF().swof_; + const std::vector& sw = swof_table[table_num][0]; + const std::vector& krw = swof_table[table_num][1]; + const std::vector& krow = swof_table[table_num][2]; + const std::vector& pcow = swof_table[table_num][3]; + buildUniformMonotoneTable(sw, krw, samples, krw_); + buildUniformMonotoneTable(sw, krow, samples, krow_); + buildUniformMonotoneTable(sw, pcow, samples, pcow_); + krocw_ = krow[0]; // At connate water -> ecl. SWOF + swco = sw[0]; + smin_[phase_usage.phase_pos[Aqua]] = sw[0]; + swmax = sw.back(); + smax_[phase_usage.phase_pos[Aqua]] = sw.back(); + } + if (phase_usage.phase_used[Vapour]) { + const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; + const std::vector& sg = sgof_table[table_num][0]; + const std::vector& krg = sgof_table[table_num][1]; + const std::vector& krog = sgof_table[table_num][2]; + const std::vector& pcog = sgof_table[table_num][3]; + buildUniformMonotoneTable(sg, krg, samples, krg_); + buildUniformMonotoneTable(sg, krog, samples, krog_); + buildUniformMonotoneTable(sg, pcog, samples, pcog_); + smin_[phase_usage.phase_pos[Vapour]] = sg[0]; + if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { + THROW("Gas maximum saturation in SGOF table = " << sg.back() << + ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); + } + smax_[phase_usage.phase_pos[Vapour]] = sg.back(); + } + // These only consider water min/max sats. Consider gas sats? + smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; + smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; +} + + +void SatFuncStone2::evalKr(const double* s, double* kr) const +{ + if (phase_usage.num_phases == 3) { + // Stone-II relative permeability model. + double sw = s[Aqua]; + double sg = s[Vapour]; + double krw = krw_(sw); + double krg = krg_(sg); + double krow = krow_(sw + sg); // = 1 - so + double krog = krog_(sg); // = 1 - so - sw + double krocw = krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + return; + } + // We have a two-phase situation. We know that oil is active. + if (phase_usage.phase_used[Aqua]) { + int wpos = phase_usage.phase_pos[Aqua]; + int opos = phase_usage.phase_pos[Liquid]; + double sw = s[wpos]; + double krw = krw_(sw); + double krow = krow_(sw); + kr[wpos] = krw; + kr[opos] = krow; + } else { + ASSERT(phase_usage.phase_used[Vapour]); + int gpos = phase_usage.phase_pos[Vapour]; + int opos = phase_usage.phase_pos[Liquid]; + double sg = s[gpos]; + double krg = krg_(sg); + double krog = krog_(sg); + kr[gpos] = krg; + kr[opos] = krog; + } +} + + +void SatFuncStone2::evalKrDeriv(const double* s, double* kr, double* dkrds) const +{ + const int np = phase_usage.num_phases; + std::fill(dkrds, dkrds + np*np, 0.0); + + if (np == 3) { + // Stone-II relative permeability model. + double sw = s[Aqua]; + double sg = s[Vapour]; + double krw = krw_(sw); + double dkrww = krw_.derivative(sw); + double krg = krg_(sg); + double dkrgg = krg_.derivative(sg); + double krow = krow_(sw + sg); + double dkrow = krow_.derivative(sw + sg); + double krog = krog_(sg); + double dkrog = krog_.derivative(sg); + double krocw = krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + dkrds[Aqua + Aqua*np] = dkrww; + dkrds[Vapour + Vapour*np] = dkrgg; + dkrds[Liquid + Aqua*np] = krocw*((dkrow/krocw + dkrww)*(krog/krocw + krg) - dkrww); + dkrds[Liquid + Vapour*np] = krocw*((krow/krocw + krw)*(dkrog/krocw + dkrgg) - dkrgg) + + krocw*((dkrow/krocw + krw)*(krog/krocw + krg) - dkrgg); + return; + } + // We have a two-phase situation. We know that oil is active. + if (phase_usage.phase_used[Aqua]) { + int wpos = phase_usage.phase_pos[Aqua]; + int opos = phase_usage.phase_pos[Liquid]; + double sw = s[wpos]; + double krw = krw_(sw); + double dkrww = krw_.derivative(sw); + double krow = krow_(sw); + double dkrow = krow_.derivative(sw); + kr[wpos] = krw; + kr[opos] = krow; + dkrds[wpos + wpos*np] = dkrww; + dkrds[opos + wpos*np] = dkrow; // Row opos, column wpos, fortran order. + } else { + ASSERT(phase_usage.phase_used[Vapour]); + int gpos = phase_usage.phase_pos[Vapour]; + int opos = phase_usage.phase_pos[Liquid]; + double sg = s[gpos]; + double krg = krg_(sg); + double dkrgg = krg_.derivative(sg); + double krog = krog_(sg); + double dkrog = krog_.derivative(sg); + kr[gpos] = krg; + kr[opos] = krog; + dkrds[gpos + gpos*np] = dkrgg; + dkrds[opos + gpos*np] = dkrog; + } + +} + + +void SatFuncStone2::evalPc(const double* s, double* pc) const +{ + pc[phase_usage.phase_pos[Liquid]] = 0.0; + if (phase_usage.phase_used[Aqua]) { + int pos = phase_usage.phase_pos[Aqua]; + pc[pos] = pcow_(s[pos]); + } + if (phase_usage.phase_used[Vapour]) { + int pos = phase_usage.phase_pos[Vapour]; + pc[pos] = pcog_(s[pos]); + } +} + +void SatFuncStone2::evalPcDeriv(const double* s, double* pc, double* dpcds) const +{ + // The problem of determining three-phase capillary pressures + // is very hard experimentally, usually one extends two-phase + // data (as for relative permeability). + // In our approach the derivative matrix is quite sparse, only + // the diagonal elements corresponding to non-oil phases are + // (potentially) nonzero. + const int np = phase_usage.num_phases; + std::fill(dpcds, dpcds + np*np, 0.0); + pc[phase_usage.phase_pos[Liquid]] = 0.0; + if (phase_usage.phase_used[Aqua]) { + int pos = phase_usage.phase_pos[Aqua]; + pc[pos] = pcow_(s[pos]); + dpcds[np*pos + pos] = pcow_.derivative(s[pos]); + } + if (phase_usage.phase_used[Vapour]) { + int pos = phase_usage.phase_pos[Vapour]; + pc[pos] = pcog_(s[pos]); + dpcds[np*pos + pos] = pcog_.derivative(s[pos]); + } +} + + + + +} // namespace Opm diff --git a/opm/core/fluid/SatFuncStone2.hpp b/opm/core/fluid/SatFuncStone2.hpp new file mode 100644 index 00000000..86f0ec53 --- /dev/null +++ b/opm/core/fluid/SatFuncStone2.hpp @@ -0,0 +1,32 @@ +#ifndef SATFUNCSTONE2_HPP +#define SATFUNCSTONE2_HPP +#include +#include +#include +#include +namespace Opm +{ +class SatFuncStone2: public BlackoilPhases +{ +public: + void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg); + void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg, + const int samples); + void evalKr(const double* s, double* kr) const; + void evalKrDeriv(const double* s, double* kr, double* dkrds) const; + void evalPc(const double* s, double* pc) const; + void evalPcDeriv(const double* s, double* pc, double* dpcds) const; + double smin_[PhaseUsage::MaxNumPhases]; + double smax_[PhaseUsage::MaxNumPhases]; +private: + PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. + UniformTableLinear krw_; + UniformTableLinear krow_; + UniformTableLinear pcow_; + UniformTableLinear krg_; + UniformTableLinear krog_; + UniformTableLinear pcog_; + double krocw_; // = krow_(s_wc) +}; +} // namespace Opm +#endif // SATFUNCSTONE2_HPP diff --git a/opm/core/fluid/SaturationPropsFromDeck.cpp b/opm/core/fluid/SaturationPropsFromDeck.cpp index 36cf8364..818a3832 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.cpp +++ b/opm/core/fluid/SaturationPropsFromDeck.cpp @@ -88,7 +88,62 @@ namespace Opm satfuncset_[table].init(deck, table, phase_usage_); } } + void SaturationPropsFromDeck::init(const EclipseGridParser& deck, + const UnstructuredGrid& grid, + const parameter::ParameterGroup& param){ + phase_usage_ = phaseUsageFromDeck(deck); + // Extract input data. + // Oil phase should be active. + if (!phase_usage_.phase_used[Liquid]) { + THROW("SaturationPropsFromDeck::init() -- oil phase must be active."); + } + + // Obtain SATNUM, if it exists, and create cell_to_func_. + // Otherwise, let the cell_to_func_ mapping be just empty. + int satfuncs_expected = 1; + if (deck.hasField("SATNUM")) { + const std::vector& satnum = deck.getIntegerValue("SATNUM"); + satfuncs_expected = *std::max_element(satnum.begin(), satnum.end()); + const int num_cells = grid.number_of_cells; + cell_to_func_.resize(num_cells); + const int* gc = grid.global_cell; + for (int cell = 0; cell < num_cells; ++cell) { + const int deck_pos = (gc == NULL) ? cell : gc[cell]; + cell_to_func_[cell] = satnum[deck_pos] - 1; + } + } + + // Find number of tables, check for consistency. + enum { Uninitialized = -1 }; + int num_tables = Uninitialized; + if (phase_usage_.phase_used[Aqua]) { + const SWOF::table_t& swof_table = deck.getSWOF().swof_; + num_tables = swof_table.size(); + if (num_tables < satfuncs_expected) { + THROW("Found " << num_tables << " SWOF tables, SATNUM specifies at least " << satfuncs_expected); + } + } + if (phase_usage_.phase_used[Vapour]) { + const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; + int num_sgof_tables = sgof_table.size(); + if (num_sgof_tables < satfuncs_expected) { + THROW("Found " << num_tables << " SGOF tables, SATNUM specifies at least " << satfuncs_expected); + } + if (num_tables == Uninitialized) { + num_tables = num_sgof_tables; + } else if (num_tables != num_sgof_tables) { + THROW("Inconsistent number of tables in SWOF and SGOF."); + } + } + + // Initialize tables. + int tab_size=param.getDefault("tab_size",200); + satfuncset_.resize(num_tables); + for (int table = 0; table < num_tables; ++table) { + satfuncset_[table].init(deck, table, phase_usage_,tab_size); + } + } @@ -192,206 +247,12 @@ namespace Opm } } - // Map the cell number to the correct function set. - const SaturationPropsFromDeck::SatFuncSet& + const SatFuncStone2& SaturationPropsFromDeck::funcForCell(const int cell) const { return cell_to_func_.empty() ? satfuncset_[0] : satfuncset_[cell_to_func_[cell]]; } - - - - // ----------- Methods of SatFuncSet below ----------- - - - void SaturationPropsFromDeck::SatFuncSet::init(const EclipseGridParser& deck, - const int table_num, - const PhaseUsage phase_usg) - { - phase_usage = phase_usg; - const int samples = 200; - double swco = 0.0; - double swmax = 1.0; - if (phase_usage.phase_used[Aqua]) { - const SWOF::table_t& swof_table = deck.getSWOF().swof_; - const std::vector& sw = swof_table[table_num][0]; - const std::vector& krw = swof_table[table_num][1]; - const std::vector& krow = swof_table[table_num][2]; - const std::vector& pcow = swof_table[table_num][3]; - buildUniformMonotoneTable(sw, krw, samples, krw_); - buildUniformMonotoneTable(sw, krow, samples, krow_); - buildUniformMonotoneTable(sw, pcow, samples, pcow_); - krocw_ = krow[0]; // At connate water -> ecl. SWOF - swco = sw[0]; - smin_[phase_usage.phase_pos[Aqua]] = sw[0]; - swmax = sw.back(); - smax_[phase_usage.phase_pos[Aqua]] = sw.back(); - } - if (phase_usage.phase_used[Vapour]) { - const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; - const std::vector& sg = sgof_table[table_num][0]; - const std::vector& krg = sgof_table[table_num][1]; - const std::vector& krog = sgof_table[table_num][2]; - const std::vector& pcog = sgof_table[table_num][3]; - buildUniformMonotoneTable(sg, krg, samples, krg_); - buildUniformMonotoneTable(sg, krog, samples, krog_); - buildUniformMonotoneTable(sg, pcog, samples, pcog_); - smin_[phase_usage.phase_pos[Vapour]] = sg[0]; - if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { - THROW("Gas maximum saturation in SGOF table = " << sg.back() << - ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); - } - smax_[phase_usage.phase_pos[Vapour]] = sg.back(); - } - // These only consider water min/max sats. Consider gas sats? - smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; - smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; - } - - - void SaturationPropsFromDeck::SatFuncSet::evalKr(const double* s, double* kr) const - { - if (phase_usage.num_phases == 3) { - // Stone-II relative permeability model. - double sw = s[Aqua]; - double sg = s[Vapour]; - double krw = krw_(sw); - double krg = krg_(sg); - double krow = krow_(sw + sg); // = 1 - so - double krog = krog_(sg); // = 1 - so - sw - double krocw = krocw_; - kr[Aqua] = krw; - kr[Vapour] = krg; - kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); - if (kr[Liquid] < 0.0) { - kr[Liquid] = 0.0; - } - return; - } - // We have a two-phase situation. We know that oil is active. - if (phase_usage.phase_used[Aqua]) { - int wpos = phase_usage.phase_pos[Aqua]; - int opos = phase_usage.phase_pos[Liquid]; - double sw = s[wpos]; - double krw = krw_(sw); - double krow = krow_(sw); - kr[wpos] = krw; - kr[opos] = krow; - } else { - ASSERT(phase_usage.phase_used[Vapour]); - int gpos = phase_usage.phase_pos[Vapour]; - int opos = phase_usage.phase_pos[Liquid]; - double sg = s[gpos]; - double krg = krg_(sg); - double krog = krog_(sg); - kr[gpos] = krg; - kr[opos] = krog; - } - } - - - void SaturationPropsFromDeck::SatFuncSet::evalKrDeriv(const double* s, double* kr, double* dkrds) const - { - const int np = phase_usage.num_phases; - std::fill(dkrds, dkrds + np*np, 0.0); - - if (np == 3) { - // Stone-II relative permeability model. - double sw = s[Aqua]; - double sg = s[Vapour]; - double krw = krw_(sw); - double dkrww = krw_.derivative(sw); - double krg = krg_(sg); - double dkrgg = krg_.derivative(sg); - double krow = krow_(sw + sg); - double dkrow = krow_.derivative(sw + sg); - double krog = krog_(sg); - double dkrog = krog_.derivative(sg); - double krocw = krocw_; - kr[Aqua] = krw; - kr[Vapour] = krg; - kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); - if (kr[Liquid] < 0.0) { - kr[Liquid] = 0.0; - } - dkrds[Aqua + Aqua*np] = dkrww; - dkrds[Vapour + Vapour*np] = dkrgg; - dkrds[Liquid + Aqua*np] = krocw*((dkrow/krocw + dkrww)*(krog/krocw + krg) - dkrww); - dkrds[Liquid + Vapour*np] = krocw*((krow/krocw + krw)*(dkrog/krocw + dkrgg) - dkrgg) - + krocw*((dkrow/krocw + krw)*(krog/krocw + krg) - dkrgg); - return; - } - // We have a two-phase situation. We know that oil is active. - if (phase_usage.phase_used[Aqua]) { - int wpos = phase_usage.phase_pos[Aqua]; - int opos = phase_usage.phase_pos[Liquid]; - double sw = s[wpos]; - double krw = krw_(sw); - double dkrww = krw_.derivative(sw); - double krow = krow_(sw); - double dkrow = krow_.derivative(sw); - kr[wpos] = krw; - kr[opos] = krow; - dkrds[wpos + wpos*np] = dkrww; - dkrds[opos + wpos*np] = dkrow; // Row opos, column wpos, fortran order. - } else { - ASSERT(phase_usage.phase_used[Vapour]); - int gpos = phase_usage.phase_pos[Vapour]; - int opos = phase_usage.phase_pos[Liquid]; - double sg = s[gpos]; - double krg = krg_(sg); - double dkrgg = krg_.derivative(sg); - double krog = krog_(sg); - double dkrog = krog_.derivative(sg); - kr[gpos] = krg; - kr[opos] = krog; - dkrds[gpos + gpos*np] = dkrgg; - dkrds[opos + gpos*np] = dkrog; - } - - } - - - void SaturationPropsFromDeck::SatFuncSet::evalPc(const double* s, double* pc) const - { - pc[phase_usage.phase_pos[Liquid]] = 0.0; - if (phase_usage.phase_used[Aqua]) { - int pos = phase_usage.phase_pos[Aqua]; - pc[pos] = pcow_(s[pos]); - } - if (phase_usage.phase_used[Vapour]) { - int pos = phase_usage.phase_pos[Vapour]; - pc[pos] = pcog_(s[pos]); - } - } - - void SaturationPropsFromDeck::SatFuncSet::evalPcDeriv(const double* s, double* pc, double* dpcds) const - { - // The problem of determining three-phase capillary pressures - // is very hard experimentally, usually one extends two-phase - // data (as for relative permeability). - // In our approach the derivative matrix is quite sparse, only - // the diagonal elements corresponding to non-oil phases are - // (potentially) nonzero. - const int np = phase_usage.num_phases; - std::fill(dpcds, dpcds + np*np, 0.0); - pc[phase_usage.phase_pos[Liquid]] = 0.0; - if (phase_usage.phase_used[Aqua]) { - int pos = phase_usage.phase_pos[Aqua]; - pc[pos] = pcow_(s[pos]); - dpcds[np*pos + pos] = pcow_.derivative(s[pos]); - } - if (phase_usage.phase_used[Vapour]) { - int pos = phase_usage.phase_pos[Vapour]; - pc[pos] = pcog_(s[pos]); - dpcds[np*pos + pos] = pcog_.derivative(s[pos]); - } - } - - - - } // namespace Opm diff --git a/opm/core/fluid/SaturationPropsFromDeck.hpp b/opm/core/fluid/SaturationPropsFromDeck.hpp index b83a1271..2c6a89a0 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.hpp +++ b/opm/core/fluid/SaturationPropsFromDeck.hpp @@ -19,10 +19,11 @@ #ifndef OPM_SATURATIONPROPSFROMDECK_HEADER_INCLUDED #define OPM_SATURATIONPROPSFROMDECK_HEADER_INCLUDED - +#include #include #include #include +#include #include struct UnstructuredGrid; @@ -44,6 +45,10 @@ namespace Opm void init(const EclipseGridParser& deck, const UnstructuredGrid& grid); + void init(const EclipseGridParser& deck, + const UnstructuredGrid& grid, + const parameter::ParameterGroup& param); + /// \return P, the number of phases. int numPhases() const; @@ -87,31 +92,11 @@ namespace Opm double* smax) const; private: - PhaseUsage phase_usage_; - class SatFuncSet - { - public: - void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg); - void evalKr(const double* s, double* kr) const; - void evalKrDeriv(const double* s, double* kr, double* dkrds) const; - void evalPc(const double* s, double* pc) const; - void evalPcDeriv(const double* s, double* pc, double* dpcds) const; - double smin_[PhaseUsage::MaxNumPhases]; - double smax_[PhaseUsage::MaxNumPhases]; - private: - PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. - UniformTableLinear krw_; - UniformTableLinear krow_; - UniformTableLinear pcow_; - UniformTableLinear krg_; - UniformTableLinear krog_; - UniformTableLinear pcog_; - double krocw_; // = krow_(s_wc) - }; - std::vector satfuncset_; + PhaseUsage phase_usage_; + std::vector satfuncset_; std::vector cell_to_func_; // = SATNUM - 1 - const SatFuncSet& funcForCell(const int cell) const; + const SatFuncStone2& funcForCell(const int cell) const; }; diff --git a/tests/pvt_test.cpp b/tests/pvt_test.cpp index 45e2775d..39183b2d 100644 --- a/tests/pvt_test.cpp +++ b/tests/pvt_test.cpp @@ -18,7 +18,7 @@ */ -#include "config.h" +//#include "config.h" #include #include diff --git a/tests/relperm_test.cpp b/tests/relperm_test.cpp index 64897289..69d7e2ff 100644 --- a/tests/relperm_test.cpp +++ b/tests/relperm_test.cpp @@ -18,7 +18,7 @@ */ -#include "config.h" +//#include "config.h" #include #include @@ -47,7 +47,7 @@ int main(int argc, char** argv) UnstructuredGrid grid; grid.number_of_cells = 1; grid.global_cell = NULL; - Opm::BlackoilPropertiesFromDeck props(deck, grid); + Opm::BlackoilPropertiesFromDeck props(deck, grid, param); std::fstream inos(input_file.c_str());//, std::fstream::in); if(!inos.good()){ From 16f6d71a4eb6f9fe32f7ee9607725caeea36aa54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Tue, 28 Aug 2012 14:31:54 +0200 Subject: [PATCH 10/32] Changed cmake file from listing all files to glob. Due to structure of the code some files need to be removed. This is not optimal. AGMG support is not integrated. The CMakeFile make it easy to use opm-core in qtcreator. --- CMakeLists.txt | 104 +++++++++++----------------------------------- FindUmfPack.cmake | 56 +++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 79 deletions(-) create mode 100644 FindUmfPack.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a6e3b690..45a94490 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6) project (opm-core) enable_language(Fortran) - +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) set(Boost_USE_STATIC_LIBS ON) @@ -16,94 +16,40 @@ include_directories(${PROJECT_SOURCE_DIR} ${Boost_INCLUDE_DIRS}) # The opmcore library -add_library(opmcore -opm/core/eclipse/EclipseGridInspector.cpp -opm/core/eclipse/EclipseGridParser.cpp -opm/core/fluid/blackoil/BlackoilPvtProperties.cpp -opm/core/fluid/blackoil/SinglePvtDead.cpp -opm/core/fluid/blackoil/SinglePvtLiveGas.cpp -opm/core/fluid/blackoil/SinglePvtLiveOil.cpp -opm/core/fluid/blackoil/SinglePvtInterface.cpp -opm/core/fluid/BlackoilPropertiesBasic.cpp -opm/core/fluid/BlackoilPropertiesFromDeck.cpp -opm/core/fluid/IncompPropertiesBasic.cpp -opm/core/fluid/IncompPropertiesFromDeck.cpp -opm/core/fluid/PvtPropertiesBasic.cpp -opm/core/fluid/PvtPropertiesIncompFromDeck.cpp -opm/core/fluid/RockBasic.cpp -opm/core/fluid/RockFromDeck.cpp -opm/core/fluid/SaturationPropsBasic.cpp -opm/core/fluid/SaturationPropsFromDeck.cpp -opm/core/utility/MonotCubicInterpolator.cpp -opm/core/utility/parameters/Parameter.cpp -opm/core/utility/parameters/ParameterGroup.cpp -opm/core/utility/parameters/ParameterTools.cpp -opm/core/utility/parameters/ParameterXML.cpp -opm/core/utility/parameters/tinyxml/tinystr.cpp -opm/core/utility/parameters/tinyxml/tinyxml.cpp -opm/core/utility/parameters/tinyxml/tinyxmlerror.cpp -opm/core/utility/parameters/tinyxml/tinyxmlparser.cpp -opm/core/utility/cart_grid.c -opm/core/utility/cpgpreprocess/geometry.c -opm/core/utility/cpgpreprocess/preprocess.c -opm/core/utility/cpgpreprocess/readvector.cpp -opm/core/utility/cpgpreprocess/cgridinterface.c -opm/core/utility/cpgpreprocess/sparsetable.c -opm/core/utility/cpgpreprocess/facetopology.c -opm/core/utility/cpgpreprocess/uniquepoints.c -opm/core/utility/StopWatch.cpp -opm/core/utility/newwells.c -opm/core/utility/writeVtkData.cpp -opm/core/GridManager.cpp -opm/core/linalg/sparse_sys.c -opm/core/pressure/cfsh.c -opm/core/pressure/flow_bc.c -opm/core/pressure/well.c -opm/core/pressure/fsh_common_impl.c -opm/core/pressure/fsh.c -opm/core/pressure/tpfa/ifs_tpfa.c -opm/core/pressure/tpfa/compr_source.c -opm/core/pressure/tpfa/cfs_tpfa.c -opm/core/pressure/tpfa/compr_bc.c -opm/core/pressure/tpfa/compr_quant.c -opm/core/pressure/tpfa/compr_quant_general.c -opm/core/pressure/tpfa/cfs_tpfa_residual.c -opm/core/pressure/tpfa/trans_tpfa.c -opm/core/pressure/msmfem/coarse_conn.c -opm/core/pressure/msmfem/partition.c -opm/core/pressure/msmfem/hash_set.c -opm/core/pressure/msmfem/ifsh_ms.c -opm/core/pressure/msmfem/dfs.c -opm/core/pressure/msmfem/coarse_sys.c -opm/core/pressure/ifsh.c -opm/core/pressure/IncompTpfa.cpp -opm/core/pressure/mimetic/mimetic.c -opm/core/pressure/mimetic/hybsys_global.c -opm/core/pressure/mimetic/hybsys.c -opm/core/transport/spu_explicit.c -opm/core/transport/spu_implicit.c -opm/core/transport/transport_source.c -opm/core/transport/reorder/TransportModelInterface.cpp -opm/core/transport/reorder/TransportModelTwophase.cpp -opm/core/transport/reorder/reordersequence.cpp -opm/core/transport/reorder/nlsolvers.c -opm/core/transport/reorder/tarjan.c -opm/core/linalg/call_umfpack.c -opm/core/pressure/IncompTpfa.cpp -opm/core/linalg/LinearSolverInterface.cpp -opm/core/linalg/LinearSolverIstl.cpp -opm/core/linalg/LinearSolverUmfpack.cpp -) +FILE(GLOB_RECURSE C_FILES_CORE "opm/core/*.c") +FILE(GLOB_RECURSE CPP_FILES_CORE "opm/core/*.cpp") +FILE(GLOB_RECURSE REMOVE_FILES "processgrid.c") +FILE(GLOB_RECURSE REMOVE_FILESMX "mx*.c") +FILE(GLOB_RECURSE REMOVE_FILESAGMG "*AGMG.cpp" "*test*") +list(REMOVE_ITEM C_FILES_CORE ${REMOVE_FILES} ${REMOVE_FILESMX} ) +list(REMOVE_ITEM CPP_FILES_CORE ${REMOVE_FILES} ${REMOVE_FILESAGMG}) +add_library(opmcore ${C_FILES_CORE} ${CPP_FILES_CORE} ) + target_link_libraries(opmcore ${UMFPACK_LIBRARIES} ${LAPACK_LINKER_FLAGS} ${LAPACK_LIBRARIES} ${Boost_LIBRARIES} -lcholmod -lcamd -lccolamd -lmetis -ldunecommon ) +FILE(GLOB CPP_EXAMPLES "examples/*.cpp") +FILE(GLOB CPP_tests "tests/*.cpp") add_executable(spu_2p examples/spu_2p.cpp) +#add_executable(sim_2p_incomp_reorder examples/sim_2p_incomp_reorder.cpp) +#add_executable(sim_water_oil examples/sim_water_oil.cpp) + +add_executable(pvt_test tests/pvt_test.cpp) +add_executable(relperm_test tests/relperm_test.cpp) target_link_libraries(spu_2p opmcore ) +target_link_libraries(pvt_test + opmcore +) +target_link_libraries(relperm_test + opmcore +) set_target_properties(opmcore spu_2p PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) +set_target_properties(opmcore pvt_test PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) +set_target_properties(opmcore relperm_test PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) diff --git a/FindUmfPack.cmake b/FindUmfPack.cmake new file mode 100644 index 00000000..5fe5db16 --- /dev/null +++ b/FindUmfPack.cmake @@ -0,0 +1,56 @@ +if (UMFPACK_INCLUDES AND UMFPACK_LIBRARIES) + set(UMFPACK_FIND_QUIETLY TRUE) +endif (UMFPACK_INCLUDES AND UMFPACK_LIBRARIES) + +find_package(BLAS) + +if(BLAS_FOUND) + + find_path(UMFPACK_INCLUDES + NAMES + umfpack.h + PATHS + $ENV{UMFPACKDIR} + ${INCLUDE_INSTALL_DIR} + PATH_SUFFIXES + suitesparse + ) + + find_library(UMFPACK_LIBRARIES umfpack PATHS $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) + + if(UMFPACK_LIBRARIES) + + get_filename_component(UMFPACK_LIBDIR ${UMFPACK_LIBRARIES} PATH) + + find_library(AMD_LIBRARY amd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) + if (AMD_LIBRARY) + set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${AMD_LIBRARY}) + #else (AMD_LIBRARY) + # set(UMFPACK_LIBRARIES FALSE) + endif (AMD_LIBRARY) + + endif(UMFPACK_LIBRARIES) + + if(UMFPACK_LIBRARIES) + + find_library(COLAMD_LIBRARY colamd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) + if (COLAMD_LIBRARY) + set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${COLAMD_LIBRARY}) + #else (COLAMD_LIBRARY) + # set(UMFPACK_LIBRARIES FALSE) + endif (COLAMD_LIBRARY) + + endif(UMFPACK_LIBRARIES) + + if(UMFPACK_LIBRARIES) + set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES}) + endif(UMFPACK_LIBRARIES) + +endif(BLAS_FOUND) + + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(UMFPACK DEFAULT_MSG + UMFPACK_INCLUDES UMFPACK_LIBRARIES) + +mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY) \ No newline at end of file From 7b1501ceadcb1ccdddca410ebc95b88649ee3e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Tue, 28 Aug 2012 16:41:06 +0200 Subject: [PATCH 11/32] Added new SatFuncSimple fluid. Introduced a simple fluid which has no problem with strange black oil behavior. Intended for testing, but for now it is used in SaturationPropsFromDeck. --- CMakeLists.txt | 14 +- Makefile.am | 2 + opm/core/fluid/SatFuncSimple.cpp | 213 +++++++++++++ opm/core/fluid/SatFuncSimple.hpp | 32 ++ opm/core/fluid/SatFuncStone2.cpp | 352 ++++++++++----------- opm/core/fluid/SatFuncStone2.hpp | 62 ++-- opm/core/fluid/SaturationPropsFromDeck.cpp | 2 +- opm/core/fluid/SaturationPropsFromDeck.hpp | 8 +- tests/pvt_test.cpp | 9 +- tests/relperm_test.cpp | 9 +- 10 files changed, 497 insertions(+), 206 deletions(-) create mode 100644 opm/core/fluid/SatFuncSimple.cpp create mode 100644 opm/core/fluid/SatFuncSimple.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 45a94490..50dd33ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,8 +34,8 @@ target_link_libraries(opmcore FILE(GLOB CPP_EXAMPLES "examples/*.cpp") FILE(GLOB CPP_tests "tests/*.cpp") add_executable(spu_2p examples/spu_2p.cpp) -#add_executable(sim_2p_incomp_reorder examples/sim_2p_incomp_reorder.cpp) -#add_executable(sim_water_oil examples/sim_water_oil.cpp) +add_executable(sim_2p_incomp_reorder examples/sim_2p_incomp_reorder.cpp) +add_executable(sim_wateroil examples/sim_wateroil.cpp) add_executable(pvt_test tests/pvt_test.cpp) add_executable(relperm_test tests/relperm_test.cpp) @@ -43,6 +43,14 @@ add_executable(relperm_test tests/relperm_test.cpp) target_link_libraries(spu_2p opmcore ) +target_link_libraries(sim_2p_incomp_reorder + opmcore +) + +target_link_libraries(sim_wateroil + opmcore +) + target_link_libraries(pvt_test opmcore ) @@ -51,5 +59,7 @@ target_link_libraries(relperm_test ) set_target_properties(opmcore spu_2p PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) +set_target_properties(opmcore sim_2p_incomp_reorder PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) +set_target_properties(opmcore sim_wateroil PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) set_target_properties(opmcore pvt_test PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) set_target_properties(opmcore relperm_test PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) diff --git a/Makefile.am b/Makefile.am index 3f67b50f..928b5c20 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,6 +51,7 @@ opm/core/fluid/RockFromDeck.cpp \ opm/core/fluid/SaturationPropsBasic.cpp \ opm/core/fluid/SaturationPropsFromDeck.cpp \ opm/core/fluid/SatFuncStone2.cpp \ +opm/core/fluid/SatFuncSimple.cpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.cpp \ opm/core/fluid/blackoil/SinglePvtDead.cpp \ opm/core/fluid/blackoil/SinglePvtInterface.cpp \ @@ -148,6 +149,7 @@ opm/core/fluid/RockFromDeck.hpp \ opm/core/fluid/SaturationPropsBasic.hpp \ opm/core/fluid/SaturationPropsFromDeck.hpp \ opm/core/fluid/SatFuncStone2.hpp \ +opm/core/fluid/SatFuncSimple.hpp \ opm/core/fluid/SimpleFluid2p.hpp \ opm/core/fluid/blackoil/BlackoilPhases.hpp \ opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \ diff --git a/opm/core/fluid/SatFuncSimple.cpp b/opm/core/fluid/SatFuncSimple.cpp new file mode 100644 index 00000000..90ca0e56 --- /dev/null +++ b/opm/core/fluid/SatFuncSimple.cpp @@ -0,0 +1,213 @@ +#include +#include +#include +#include +#include +#include +#include +#include +namespace Opm +{ + + + + + // ----------- Methods of SatFuncSet below ----------- + void SatFuncSimple::init(const EclipseGridParser& deck, + const int table_num, + const PhaseUsage phase_usg){ + init(deck, table_num, phase_usg, 200); + } + + void SatFuncSimple::init(const EclipseGridParser& deck, + const int table_num, + const PhaseUsage phase_usg, + const int samples) + { + phase_usage = phase_usg; + double swco = 0.0; + double swmax = 1.0; + if (phase_usage.phase_used[Aqua]) { + const SWOF::table_t& swof_table = deck.getSWOF().swof_; + const std::vector& sw = swof_table[table_num][0]; + const std::vector& krw = swof_table[table_num][1]; + const std::vector& krow = swof_table[table_num][2]; + const std::vector& pcow = swof_table[table_num][3]; + buildUniformMonotoneTable(sw, krw, samples, krw_); + buildUniformMonotoneTable(sw, krow, samples, krow_); + buildUniformMonotoneTable(sw, pcow, samples, pcow_); + krocw_ = krow[0]; // At connate water -> ecl. SWOF + swco = sw[0]; + smin_[phase_usage.phase_pos[Aqua]] = sw[0]; + swmax = sw.back(); + smax_[phase_usage.phase_pos[Aqua]] = sw.back(); + } + if (phase_usage.phase_used[Vapour]) { + const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; + const std::vector& sg = sgof_table[table_num][0]; + const std::vector& krg = sgof_table[table_num][1]; + const std::vector& krog = sgof_table[table_num][2]; + const std::vector& pcog = sgof_table[table_num][3]; + buildUniformMonotoneTable(sg, krg, samples, krg_); + buildUniformMonotoneTable(sg, krog, samples, krog_); + buildUniformMonotoneTable(sg, pcog, samples, pcog_); + smin_[phase_usage.phase_pos[Vapour]] = sg[0]; + if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { + THROW("Gas maximum saturation in SGOF table = " << sg.back() << + ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); + } + smax_[phase_usage.phase_pos[Vapour]] = sg.back(); + } + // These only consider water min/max sats. Consider gas sats? + smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; + smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; + } + + + void SatFuncSimple::evalKr(const double* s, double* kr) const + { + if (phase_usage.num_phases == 3) { + // Stone-II relative permeability model. + double sw = s[Aqua]; + double sg = s[Vapour]; + double krw = krw_(sw); + double krg = krg_(sg); + double krow = krow_(sw + sg); // = 1 - so + double krog = krog_(sg); // = 1 - so - sw + double krocw = krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krow; + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + return; + } + // We have a two-phase situation. We know that oil is active. + if (phase_usage.phase_used[Aqua]) { + int wpos = phase_usage.phase_pos[Aqua]; + int opos = phase_usage.phase_pos[Liquid]; + double sw = s[wpos]; + double krw = krw_(sw); + double krow = krow_(sw); + kr[wpos] = krw; + kr[opos] = krow; + } else { + ASSERT(phase_usage.phase_used[Vapour]); + int gpos = phase_usage.phase_pos[Vapour]; + int opos = phase_usage.phase_pos[Liquid]; + double sg = s[gpos]; + double krg = krg_(sg); + double krog = krog_(sg); + kr[gpos] = krg; + kr[opos] = krog; + } + } + + + void SatFuncSimple::evalKrDeriv(const double* s, double* kr, double* dkrds) const + { + const int np = phase_usage.num_phases; + std::fill(dkrds, dkrds + np*np, 0.0); + + if (np == 3) { + // Stone-II relative permeability model. + double sw = s[Aqua]; + double sg = s[Vapour]; + double krw = krw_(sw); + double dkrww = krw_.derivative(sw); + double krg = krg_(sg); + double dkrgg = krg_.derivative(sg); + double krow = krow_(sw + sg); + double dkrow = krow_.derivative(sw + sg); + double krog = krog_(sg); + double dkrog = krog_.derivative(sg); + double krocw = krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krow; + //krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + dkrds[Aqua + Aqua*np] = dkrww; + dkrds[Vapour + Vapour*np] = dkrgg; + //dkrds[Liquid + Aqua*np] = dkrow; + dkrds[Liquid + Liquid*np] = -dkrow; + //krocw*((dkrow/krocw + dkrww)*(krog/krocw + krg) - dkrww); + dkrds[Liquid + Vapour*np] = 0.0; + //krocw*((krow/krocw + krw)*(dkrog/krocw + dkrgg) - dkrgg) + //+ krocw*((dkrow/krocw + krw)*(krog/krocw + krg) - dkrgg); + return; + } + // We have a two-phase situation. We know that oil is active. + if (phase_usage.phase_used[Aqua]) { + int wpos = phase_usage.phase_pos[Aqua]; + int opos = phase_usage.phase_pos[Liquid]; + double sw = s[wpos]; + double krw = krw_(sw); + double dkrww = krw_.derivative(sw); + double krow = krow_(sw); + double dkrow = krow_.derivative(sw); + kr[wpos] = krw; + kr[opos] = krow; + dkrds[wpos + wpos*np] = dkrww; + dkrds[opos + wpos*np] = dkrow; // Row opos, column wpos, fortran order. + } else { + ASSERT(phase_usage.phase_used[Vapour]); + int gpos = phase_usage.phase_pos[Vapour]; + int opos = phase_usage.phase_pos[Liquid]; + double sg = s[gpos]; + double krg = krg_(sg); + double dkrgg = krg_.derivative(sg); + double krog = krog_(sg); + double dkrog = krog_.derivative(sg); + kr[gpos] = krg; + kr[opos] = krog; + dkrds[gpos + gpos*np] = dkrgg; + dkrds[opos + gpos*np] = dkrog; + } + + } + + + void SatFuncSimple::evalPc(const double* s, double* pc) const + { + pc[phase_usage.phase_pos[Liquid]] = 0.0; + if (phase_usage.phase_used[Aqua]) { + int pos = phase_usage.phase_pos[Aqua]; + pc[pos] = pcow_(s[pos]); + } + if (phase_usage.phase_used[Vapour]) { + int pos = phase_usage.phase_pos[Vapour]; + pc[pos] = pcog_(s[pos]); + } + } + + void SatFuncSimple::evalPcDeriv(const double* s, double* pc, double* dpcds) const + { + // The problem of determining three-phase capillary pressures + // is very hard experimentally, usually one extends two-phase + // data (as for relative permeability). + // In our approach the derivative matrix is quite sparse, only + // the diagonal elements corresponding to non-oil phases are + // (potentially) nonzero. + const int np = phase_usage.num_phases; + std::fill(dpcds, dpcds + np*np, 0.0); + pc[phase_usage.phase_pos[Liquid]] = 0.0; + if (phase_usage.phase_used[Aqua]) { + int pos = phase_usage.phase_pos[Aqua]; + pc[pos] = pcow_(s[pos]); + dpcds[np*pos + pos] = pcow_.derivative(s[pos]); + } + if (phase_usage.phase_used[Vapour]) { + int pos = phase_usage.phase_pos[Vapour]; + pc[pos] = pcog_(s[pos]); + dpcds[np*pos + pos] = pcog_.derivative(s[pos]); + } + } + + + + +} // namespace Opm diff --git a/opm/core/fluid/SatFuncSimple.hpp b/opm/core/fluid/SatFuncSimple.hpp new file mode 100644 index 00000000..93ba7a31 --- /dev/null +++ b/opm/core/fluid/SatFuncSimple.hpp @@ -0,0 +1,32 @@ +#ifndef SATFUNCSIMPLE_HPP +#define SATFUNCSIMPLE_HPP +#include +#include +#include +#include +namespace Opm +{ + class SatFuncSimple: public BlackoilPhases + { + public: + void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg); + void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg, + const int samples); + void evalKr(const double* s, double* kr) const; + void evalKrDeriv(const double* s, double* kr, double* dkrds) const; + void evalPc(const double* s, double* pc) const; + void evalPcDeriv(const double* s, double* pc, double* dpcds) const; + double smin_[PhaseUsage::MaxNumPhases]; + double smax_[PhaseUsage::MaxNumPhases]; + private: + PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. + UniformTableLinear krw_; + UniformTableLinear krow_; + UniformTableLinear pcow_; + UniformTableLinear krg_; + UniformTableLinear krog_; + UniformTableLinear pcog_; + double krocw_; // = krow_(s_wc) + }; +} // namespace Opm +#endif // SATFUNCSIMPLE_HPP diff --git a/opm/core/fluid/SatFuncStone2.cpp b/opm/core/fluid/SatFuncStone2.cpp index ed97595a..c43238c1 100644 --- a/opm/core/fluid/SatFuncStone2.cpp +++ b/opm/core/fluid/SatFuncStone2.cpp @@ -12,196 +12,196 @@ namespace Opm -// ----------- Methods of SatFuncSet below ----------- -void SatFuncStone2::init(const EclipseGridParser& deck, - const int table_num, - const PhaseUsage phase_usg){ - init(deck, table_num, phase_usg, 200); -} - -void SatFuncStone2::init(const EclipseGridParser& deck, - const int table_num, - const PhaseUsage phase_usg, - const int samples) -{ - phase_usage = phase_usg; - double swco = 0.0; - double swmax = 1.0; - if (phase_usage.phase_used[Aqua]) { - const SWOF::table_t& swof_table = deck.getSWOF().swof_; - const std::vector& sw = swof_table[table_num][0]; - const std::vector& krw = swof_table[table_num][1]; - const std::vector& krow = swof_table[table_num][2]; - const std::vector& pcow = swof_table[table_num][3]; - buildUniformMonotoneTable(sw, krw, samples, krw_); - buildUniformMonotoneTable(sw, krow, samples, krow_); - buildUniformMonotoneTable(sw, pcow, samples, pcow_); - krocw_ = krow[0]; // At connate water -> ecl. SWOF - swco = sw[0]; - smin_[phase_usage.phase_pos[Aqua]] = sw[0]; - swmax = sw.back(); - smax_[phase_usage.phase_pos[Aqua]] = sw.back(); + // ----------- Methods of SatFuncSet below ----------- + void SatFuncStone2::init(const EclipseGridParser& deck, + const int table_num, + const PhaseUsage phase_usg){ + init(deck, table_num, phase_usg, 200); } - if (phase_usage.phase_used[Vapour]) { - const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; - const std::vector& sg = sgof_table[table_num][0]; - const std::vector& krg = sgof_table[table_num][1]; - const std::vector& krog = sgof_table[table_num][2]; - const std::vector& pcog = sgof_table[table_num][3]; - buildUniformMonotoneTable(sg, krg, samples, krg_); - buildUniformMonotoneTable(sg, krog, samples, krog_); - buildUniformMonotoneTable(sg, pcog, samples, pcog_); - smin_[phase_usage.phase_pos[Vapour]] = sg[0]; - if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { - THROW("Gas maximum saturation in SGOF table = " << sg.back() << - ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); + + void SatFuncStone2::init(const EclipseGridParser& deck, + const int table_num, + const PhaseUsage phase_usg, + const int samples) + { + phase_usage = phase_usg; + double swco = 0.0; + double swmax = 1.0; + if (phase_usage.phase_used[Aqua]) { + const SWOF::table_t& swof_table = deck.getSWOF().swof_; + const std::vector& sw = swof_table[table_num][0]; + const std::vector& krw = swof_table[table_num][1]; + const std::vector& krow = swof_table[table_num][2]; + const std::vector& pcow = swof_table[table_num][3]; + buildUniformMonotoneTable(sw, krw, samples, krw_); + buildUniformMonotoneTable(sw, krow, samples, krow_); + buildUniformMonotoneTable(sw, pcow, samples, pcow_); + krocw_ = krow[0]; // At connate water -> ecl. SWOF + swco = sw[0]; + smin_[phase_usage.phase_pos[Aqua]] = sw[0]; + swmax = sw.back(); + smax_[phase_usage.phase_pos[Aqua]] = sw.back(); } - smax_[phase_usage.phase_pos[Vapour]] = sg.back(); - } - // These only consider water min/max sats. Consider gas sats? - smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; - smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; -} - - -void SatFuncStone2::evalKr(const double* s, double* kr) const -{ - if (phase_usage.num_phases == 3) { - // Stone-II relative permeability model. - double sw = s[Aqua]; - double sg = s[Vapour]; - double krw = krw_(sw); - double krg = krg_(sg); - double krow = krow_(sw + sg); // = 1 - so - double krog = krog_(sg); // = 1 - so - sw - double krocw = krocw_; - kr[Aqua] = krw; - kr[Vapour] = krg; - kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); - if (kr[Liquid] < 0.0) { - kr[Liquid] = 0.0; + if (phase_usage.phase_used[Vapour]) { + const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; + const std::vector& sg = sgof_table[table_num][0]; + const std::vector& krg = sgof_table[table_num][1]; + const std::vector& krog = sgof_table[table_num][2]; + const std::vector& pcog = sgof_table[table_num][3]; + buildUniformMonotoneTable(sg, krg, samples, krg_); + buildUniformMonotoneTable(sg, krog, samples, krog_); + buildUniformMonotoneTable(sg, pcog, samples, pcog_); + smin_[phase_usage.phase_pos[Vapour]] = sg[0]; + if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { + THROW("Gas maximum saturation in SGOF table = " << sg.back() << + ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); + } + smax_[phase_usage.phase_pos[Vapour]] = sg.back(); } - return; + // These only consider water min/max sats. Consider gas sats? + smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; + smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; } - // We have a two-phase situation. We know that oil is active. - if (phase_usage.phase_used[Aqua]) { - int wpos = phase_usage.phase_pos[Aqua]; - int opos = phase_usage.phase_pos[Liquid]; - double sw = s[wpos]; - double krw = krw_(sw); - double krow = krow_(sw); - kr[wpos] = krw; - kr[opos] = krow; - } else { - ASSERT(phase_usage.phase_used[Vapour]); - int gpos = phase_usage.phase_pos[Vapour]; - int opos = phase_usage.phase_pos[Liquid]; - double sg = s[gpos]; - double krg = krg_(sg); - double krog = krog_(sg); - kr[gpos] = krg; - kr[opos] = krog; - } -} -void SatFuncStone2::evalKrDeriv(const double* s, double* kr, double* dkrds) const -{ - const int np = phase_usage.num_phases; - std::fill(dkrds, dkrds + np*np, 0.0); - - if (np == 3) { - // Stone-II relative permeability model. - double sw = s[Aqua]; - double sg = s[Vapour]; - double krw = krw_(sw); - double dkrww = krw_.derivative(sw); - double krg = krg_(sg); - double dkrgg = krg_.derivative(sg); - double krow = krow_(sw + sg); - double dkrow = krow_.derivative(sw + sg); - double krog = krog_(sg); - double dkrog = krog_.derivative(sg); - double krocw = krocw_; - kr[Aqua] = krw; - kr[Vapour] = krg; - kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); - if (kr[Liquid] < 0.0) { - kr[Liquid] = 0.0; + void SatFuncStone2::evalKr(const double* s, double* kr) const + { + if (phase_usage.num_phases == 3) { + // Stone-II relative permeability model. + double sw = s[Aqua]; + double sg = s[Vapour]; + double krw = krw_(sw); + double krg = krg_(sg); + double krow = krow_(sw + sg); // = 1 - so + double krog = krog_(sg); // = 1 - so - sw + double krocw = krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + return; + } + // We have a two-phase situation. We know that oil is active. + if (phase_usage.phase_used[Aqua]) { + int wpos = phase_usage.phase_pos[Aqua]; + int opos = phase_usage.phase_pos[Liquid]; + double sw = s[wpos]; + double krw = krw_(sw); + double krow = krow_(sw); + kr[wpos] = krw; + kr[opos] = krow; + } else { + ASSERT(phase_usage.phase_used[Vapour]); + int gpos = phase_usage.phase_pos[Vapour]; + int opos = phase_usage.phase_pos[Liquid]; + double sg = s[gpos]; + double krg = krg_(sg); + double krog = krog_(sg); + kr[gpos] = krg; + kr[opos] = krog; } - dkrds[Aqua + Aqua*np] = dkrww; - dkrds[Vapour + Vapour*np] = dkrgg; - dkrds[Liquid + Aqua*np] = krocw*((dkrow/krocw + dkrww)*(krog/krocw + krg) - dkrww); - dkrds[Liquid + Vapour*np] = krocw*((krow/krocw + krw)*(dkrog/krocw + dkrgg) - dkrgg) - + krocw*((dkrow/krocw + krw)*(krog/krocw + krg) - dkrgg); - return; - } - // We have a two-phase situation. We know that oil is active. - if (phase_usage.phase_used[Aqua]) { - int wpos = phase_usage.phase_pos[Aqua]; - int opos = phase_usage.phase_pos[Liquid]; - double sw = s[wpos]; - double krw = krw_(sw); - double dkrww = krw_.derivative(sw); - double krow = krow_(sw); - double dkrow = krow_.derivative(sw); - kr[wpos] = krw; - kr[opos] = krow; - dkrds[wpos + wpos*np] = dkrww; - dkrds[opos + wpos*np] = dkrow; // Row opos, column wpos, fortran order. - } else { - ASSERT(phase_usage.phase_used[Vapour]); - int gpos = phase_usage.phase_pos[Vapour]; - int opos = phase_usage.phase_pos[Liquid]; - double sg = s[gpos]; - double krg = krg_(sg); - double dkrgg = krg_.derivative(sg); - double krog = krog_(sg); - double dkrog = krog_.derivative(sg); - kr[gpos] = krg; - kr[opos] = krog; - dkrds[gpos + gpos*np] = dkrgg; - dkrds[opos + gpos*np] = dkrog; } -} + + void SatFuncStone2::evalKrDeriv(const double* s, double* kr, double* dkrds) const + { + const int np = phase_usage.num_phases; + std::fill(dkrds, dkrds + np*np, 0.0); + + if (np == 3) { + // Stone-II relative permeability model. + double sw = s[Aqua]; + double sg = s[Vapour]; + double krw = krw_(sw); + double dkrww = krw_.derivative(sw); + double krg = krg_(sg); + double dkrgg = krg_.derivative(sg); + double krow = krow_(sw + sg); + double dkrow = krow_.derivative(sw + sg); + double krog = krog_(sg); + double dkrog = krog_.derivative(sg); + double krocw = krocw_; + kr[Aqua] = krw; + kr[Vapour] = krg; + kr[Liquid] = krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); + if (kr[Liquid] < 0.0) { + kr[Liquid] = 0.0; + } + dkrds[Aqua + Aqua*np] = dkrww; + dkrds[Vapour + Vapour*np] = dkrgg; + dkrds[Liquid + Aqua*np] = krocw*((dkrow/krocw + dkrww)*(krog/krocw + krg) - dkrww); + dkrds[Liquid + Vapour*np] = krocw*((krow/krocw + krw)*(dkrog/krocw + dkrgg) - dkrgg) + + krocw*((dkrow/krocw + krw)*(krog/krocw + krg) - dkrgg); + return; + } + // We have a two-phase situation. We know that oil is active. + if (phase_usage.phase_used[Aqua]) { + int wpos = phase_usage.phase_pos[Aqua]; + int opos = phase_usage.phase_pos[Liquid]; + double sw = s[wpos]; + double krw = krw_(sw); + double dkrww = krw_.derivative(sw); + double krow = krow_(sw); + double dkrow = krow_.derivative(sw); + kr[wpos] = krw; + kr[opos] = krow; + dkrds[wpos + wpos*np] = dkrww; + dkrds[opos + wpos*np] = dkrow; // Row opos, column wpos, fortran order. + } else { + ASSERT(phase_usage.phase_used[Vapour]); + int gpos = phase_usage.phase_pos[Vapour]; + int opos = phase_usage.phase_pos[Liquid]; + double sg = s[gpos]; + double krg = krg_(sg); + double dkrgg = krg_.derivative(sg); + double krog = krog_(sg); + double dkrog = krog_.derivative(sg); + kr[gpos] = krg; + kr[opos] = krog; + dkrds[gpos + gpos*np] = dkrgg; + dkrds[opos + gpos*np] = dkrog; + } + + } -void SatFuncStone2::evalPc(const double* s, double* pc) const -{ - pc[phase_usage.phase_pos[Liquid]] = 0.0; - if (phase_usage.phase_used[Aqua]) { - int pos = phase_usage.phase_pos[Aqua]; - pc[pos] = pcow_(s[pos]); + void SatFuncStone2::evalPc(const double* s, double* pc) const + { + pc[phase_usage.phase_pos[Liquid]] = 0.0; + if (phase_usage.phase_used[Aqua]) { + int pos = phase_usage.phase_pos[Aqua]; + pc[pos] = pcow_(s[pos]); + } + if (phase_usage.phase_used[Vapour]) { + int pos = phase_usage.phase_pos[Vapour]; + pc[pos] = pcog_(s[pos]); + } } - if (phase_usage.phase_used[Vapour]) { - int pos = phase_usage.phase_pos[Vapour]; - pc[pos] = pcog_(s[pos]); - } -} -void SatFuncStone2::evalPcDeriv(const double* s, double* pc, double* dpcds) const -{ - // The problem of determining three-phase capillary pressures - // is very hard experimentally, usually one extends two-phase - // data (as for relative permeability). - // In our approach the derivative matrix is quite sparse, only - // the diagonal elements corresponding to non-oil phases are - // (potentially) nonzero. - const int np = phase_usage.num_phases; - std::fill(dpcds, dpcds + np*np, 0.0); - pc[phase_usage.phase_pos[Liquid]] = 0.0; - if (phase_usage.phase_used[Aqua]) { - int pos = phase_usage.phase_pos[Aqua]; - pc[pos] = pcow_(s[pos]); - dpcds[np*pos + pos] = pcow_.derivative(s[pos]); + void SatFuncStone2::evalPcDeriv(const double* s, double* pc, double* dpcds) const + { + // The problem of determining three-phase capillary pressures + // is very hard experimentally, usually one extends two-phase + // data (as for relative permeability). + // In our approach the derivative matrix is quite sparse, only + // the diagonal elements corresponding to non-oil phases are + // (potentially) nonzero. + const int np = phase_usage.num_phases; + std::fill(dpcds, dpcds + np*np, 0.0); + pc[phase_usage.phase_pos[Liquid]] = 0.0; + if (phase_usage.phase_used[Aqua]) { + int pos = phase_usage.phase_pos[Aqua]; + pc[pos] = pcow_(s[pos]); + dpcds[np*pos + pos] = pcow_.derivative(s[pos]); + } + if (phase_usage.phase_used[Vapour]) { + int pos = phase_usage.phase_pos[Vapour]; + pc[pos] = pcog_(s[pos]); + dpcds[np*pos + pos] = pcog_.derivative(s[pos]); + } } - if (phase_usage.phase_used[Vapour]) { - int pos = phase_usage.phase_pos[Vapour]; - pc[pos] = pcog_(s[pos]); - dpcds[np*pos + pos] = pcog_.derivative(s[pos]); - } -} diff --git a/opm/core/fluid/SatFuncStone2.hpp b/opm/core/fluid/SatFuncStone2.hpp index 86f0ec53..ae4a6d38 100644 --- a/opm/core/fluid/SatFuncStone2.hpp +++ b/opm/core/fluid/SatFuncStone2.hpp @@ -1,3 +1,21 @@ +/* + Copyright 2012 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 . +*/ #ifndef SATFUNCSTONE2_HPP #define SATFUNCSTONE2_HPP #include @@ -6,27 +24,27 @@ #include namespace Opm { -class SatFuncStone2: public BlackoilPhases -{ -public: - void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg); - void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg, - const int samples); - void evalKr(const double* s, double* kr) const; - void evalKrDeriv(const double* s, double* kr, double* dkrds) const; - void evalPc(const double* s, double* pc) const; - void evalPcDeriv(const double* s, double* pc, double* dpcds) const; - double smin_[PhaseUsage::MaxNumPhases]; - double smax_[PhaseUsage::MaxNumPhases]; -private: - PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. - UniformTableLinear krw_; - UniformTableLinear krow_; - UniformTableLinear pcow_; - UniformTableLinear krg_; - UniformTableLinear krog_; - UniformTableLinear pcog_; - double krocw_; // = krow_(s_wc) -}; + class SatFuncStone2: public BlackoilPhases + { + public: + void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg); + void init(const EclipseGridParser& deck, const int table_num, PhaseUsage phase_usg, + const int samples); + void evalKr(const double* s, double* kr) const; + void evalKrDeriv(const double* s, double* kr, double* dkrds) const; + void evalPc(const double* s, double* pc) const; + void evalPcDeriv(const double* s, double* pc, double* dpcds) const; + double smin_[PhaseUsage::MaxNumPhases]; + double smax_[PhaseUsage::MaxNumPhases]; + private: + PhaseUsage phase_usage; // A copy of the outer class' phase_usage_. + UniformTableLinear krw_; + UniformTableLinear krow_; + UniformTableLinear pcow_; + UniformTableLinear krg_; + UniformTableLinear krog_; + UniformTableLinear pcog_; + double krocw_; // = krow_(s_wc) + }; } // namespace Opm #endif // SATFUNCSTONE2_HPP diff --git a/opm/core/fluid/SaturationPropsFromDeck.cpp b/opm/core/fluid/SaturationPropsFromDeck.cpp index 818a3832..a1661756 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.cpp +++ b/opm/core/fluid/SaturationPropsFromDeck.cpp @@ -248,7 +248,7 @@ namespace Opm } // Map the cell number to the correct function set. - const SatFuncStone2& + const SaturationPropsFromDeck::satfunc_t& SaturationPropsFromDeck::funcForCell(const int cell) const { return cell_to_func_.empty() ? satfuncset_[0] : satfuncset_[cell_to_func_[cell]]; diff --git a/opm/core/fluid/SaturationPropsFromDeck.hpp b/opm/core/fluid/SaturationPropsFromDeck.hpp index 2c6a89a0..bd70d802 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.hpp +++ b/opm/core/fluid/SaturationPropsFromDeck.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include struct UnstructuredGrid; @@ -92,11 +93,12 @@ namespace Opm double* smax) const; private: - PhaseUsage phase_usage_; - std::vector satfuncset_; + PhaseUsage phase_usage_; + typedef SatFuncSimple satfunc_t; + std::vector satfuncset_; std::vector cell_to_func_; // = SATNUM - 1 - const SatFuncStone2& funcForCell(const int cell) const; + const satfunc_t& funcForCell(const int cell) const; }; diff --git a/tests/pvt_test.cpp b/tests/pvt_test.cpp index 39183b2d..a15f5f89 100644 --- a/tests/pvt_test.cpp +++ b/tests/pvt_test.cpp @@ -17,8 +17,10 @@ along with OPM. If not, see . */ +#if HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H -//#include "config.h" #include #include @@ -84,4 +86,9 @@ int main(int argc, char** argv) std::copy(b, drs + np, std::ostream_iterator(rsos, " ")); std::cout << std::endl; } + if (param.anyUnused()) { + std::cout << "-------------------- Unused parameters: --------------------\n"; + param.displayUsage(); + std::cout << "----------------------------------------------------------------" << std::endl; + } } diff --git a/tests/relperm_test.cpp b/tests/relperm_test.cpp index 69d7e2ff..2ff134e2 100644 --- a/tests/relperm_test.cpp +++ b/tests/relperm_test.cpp @@ -18,7 +18,9 @@ */ -//#include "config.h" +#if HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H #include #include @@ -79,4 +81,9 @@ int main(int argc, char** argv) kros << "\n"; } } + if (param.anyUnused()) { + std::cout << "-------------------- Unused parameters: --------------------\n"; + param.displayUsage(); + std::cout << "----------------------------------------------------------------" << std::endl; + } } From 4d800cad3d4d2c6c08ef2b47e631c0c9ff4b2433 Mon Sep 17 00:00:00 2001 From: Xavier Raynaud Date: Wed, 29 Aug 2012 10:54:21 +0200 Subject: [PATCH 12/32] Added functionality to compute porosity for compressible fluid. --- opm/core/utility/miscUtilities.cpp | 19 +++++++++++++++++++ opm/core/utility/miscUtilities.hpp | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/opm/core/utility/miscUtilities.cpp b/opm/core/utility/miscUtilities.cpp index 16c59b17..ac9552dc 100644 --- a/opm/core/utility/miscUtilities.cpp +++ b/opm/core/utility/miscUtilities.cpp @@ -70,6 +70,25 @@ namespace Opm } } + /// @brief Computes porosity of all cells in a grid, with rock compressibility effects. + /// @param[in] grid a grid + /// @param[in] porosity_standard array of grid.number_of_cells porosity values (at standard conditions) + /// @param[in] rock_comp rock compressibility properties + /// @param[in] pressure pressure by cell + /// @param[out] porosity porosity (at reservoir condition) + void computePorosity(const UnstructuredGrid& grid, + const double* porosity_standard, + const RockCompressibility& rock_comp, + const std::vector& pressure, + std::vector& porosity) + { + int num_cells = grid.number_of_cells; + porosity.resize(num_cells); + for (int i = 0; i < num_cells; ++i) { + porosity[i] = porosity_standard[i]*rock_comp.poroMult(pressure[i]); + } + } + /// @brief Computes total saturated volumes over all grid cells. /// @param[in] pv the pore volume by cell. diff --git a/opm/core/utility/miscUtilities.hpp b/opm/core/utility/miscUtilities.hpp index 37b252bc..de452fba 100644 --- a/opm/core/utility/miscUtilities.hpp +++ b/opm/core/utility/miscUtilities.hpp @@ -54,6 +54,17 @@ namespace Opm const std::vector& pressure, std::vector& porevol); + /// @brief Computes porosity of all cells in a grid, with rock compressibility effects. + /// @param[in] grid a grid + /// @param[in] porosity_standard array of grid.number_of_cells porosity values (at standard conditions) + /// @param[in] rock_comp rock compressibility properties + /// @param[in] pressure pressure by cell + /// @param[out] porosity porosity (at reservoir condition) + void computePorosity(const UnstructuredGrid& grid, + const double* porosity_standard, + const RockCompressibility& rock_comp, + const std::vector& pressure, + std::vector& porosity); /// @brief Computes total saturated volumes over all grid cells. /// @param[in] pv the pore volume by cell. From ed2aa9da3853d4b42508849ee51ff78909c24179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Fri, 31 Aug 2012 17:01:07 +0200 Subject: [PATCH 13/32] Introduced posibility to change number of sample points for pvt. Did change the PVTW calculation so derivatives are exact. Extended the test functions for pvt and relperm --- CMakeLists.txt | 12 ++- opm/core/fluid/BlackoilPropertiesFromDeck.cpp | 3 +- opm/core/fluid/SaturationPropsFromDeck.cpp | 2 +- .../fluid/blackoil/BlackoilPvtProperties.cpp | 6 +- .../fluid/blackoil/BlackoilPvtProperties.hpp | 2 +- .../fluid/blackoil/SinglePvtConstCompr.hpp | 9 +- opm/core/fluid/blackoil/SinglePvtDead.cpp | 4 +- opm/core/fluid/blackoil/SinglePvtDead.hpp | 3 +- opm/core/utility/UniformTableLinear.hpp | 13 ++- tests/pvt_test.cpp | 92 ++++++++++++++----- tests/relperm_test.cpp | 24 ++--- 11 files changed, 113 insertions(+), 57 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50dd33ac..eec84d9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,9 @@ project (opm-core) enable_language(Fortran) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) - +SET(CMAKE_BUILD_TYPE "debug") +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG -pg -Wall -fopenmp -ggdb") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -pg -Wall -fopenmp -ggdb") set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) @@ -58,8 +60,8 @@ target_link_libraries(relperm_test opmcore ) -set_target_properties(opmcore spu_2p PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) -set_target_properties(opmcore sim_2p_incomp_reorder PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) -set_target_properties(opmcore sim_wateroil PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) -set_target_properties(opmcore pvt_test PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) +#set_target_properties(opmcore spu_2p PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) +#set_target_properties(opmcore sim_2p_incomp_reorder PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) +#set_target_properties(opmcore sim_wateroil PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) +#set_target_properties(opmcore pvt_test PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) set_target_properties(opmcore relperm_test PROPERTIES COMPILE_FLAGS -m64 LINKER_LANGUAGE CXX LINK_FLAGS -m64) diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp index ae6a6130..67943fc7 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp @@ -39,7 +39,8 @@ namespace Opm const parameter::ParameterGroup& param) { rock_.init(deck, grid); - pvt_.init(deck); + int samples = param.getDefault("dead_tab_size", 1025); + pvt_.init(deck, samples); satprops_.init(deck, grid, param); if (pvt_.numPhases() != satprops_.numPhases()) { diff --git a/opm/core/fluid/SaturationPropsFromDeck.cpp b/opm/core/fluid/SaturationPropsFromDeck.cpp index a1661756..582c29db 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.cpp +++ b/opm/core/fluid/SaturationPropsFromDeck.cpp @@ -138,7 +138,7 @@ namespace Opm } // Initialize tables. - int tab_size=param.getDefault("tab_size",200); + int tab_size=param.getDefault("tab_size_kr",200); satfuncset_.resize(num_tables); for (int table = 0; table < num_tables; ++table) { satfuncset_[table].init(deck, table, phase_usage_,tab_size); diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp index 9fdaf445..6278d1bd 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp @@ -39,7 +39,7 @@ namespace Opm } - void BlackoilPvtProperties::init(const EclipseGridParser& deck) + void BlackoilPvtProperties::init(const EclipseGridParser& deck,const int samples) { typedef std::vector > > table_t; // If we need multiple regions, this class and the SinglePvt* classes must change. @@ -78,7 +78,7 @@ namespace Opm // Oil PVT if (phase_usage_.phase_used[Liquid]) { if (deck.hasField("PVDO")) { - props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_)); + props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtDead(deck.getPVDO().pvdo_, samples)); } else if (deck.hasField("PVTO")) { props_[phase_usage_.phase_pos[Liquid]].reset(new SinglePvtLiveOil(deck.getPVTO().pvto_)); } else if (deck.hasField("PVCDO")) { @@ -90,7 +90,7 @@ namespace Opm // Gas PVT if (phase_usage_.phase_used[Vapour]) { if (deck.hasField("PVDG")) { - props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_)); + props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtDead(deck.getPVDG().pvdg_, samples)); } else if (deck.hasField("PVTG")) { props_[phase_usage_.phase_pos[Vapour]].reset(new SinglePvtLiveGas(deck.getPVTG().pvtg_)); } else { diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp index 627f266b..99fd5b8f 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp @@ -47,7 +47,7 @@ namespace Opm BlackoilPvtProperties(); /// Initialize from deck. - void init(const EclipseGridParser& deck); + void init(const EclipseGridParser& deck,const int samples = 16); /// Number of active phases. int numPhases() const; diff --git a/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp b/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp index 1bc5638f..3044bdb2 100644 --- a/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp +++ b/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp @@ -106,13 +106,18 @@ namespace Opm double* output_B, double* output_dBdp) const { - B(n, p, 0, output_B); + //B(n, p, 0, output_B); if (comp_) { // #pragma omp parallel for for (int i = 0; i < n; ++i) { - output_dBdp[i] = -comp_*output_B[i]; + //output_dBdp[i] = -comp_*output_B[i]; + double x = comp_*(p[i] - ref_press_); + double d= (1.0 + x + 0.5*x*x); + output_B[i] = ref_B_/d;//(1.0 + x + 0.5*x*x); + output_dBdp[i] = (- ref_B_/(d*d))*(1 + x) *comp_; } } else { + std::fill(output_B, output_B + n, ref_B_); std::fill(output_dBdp, output_dBdp + n, 0.0); } } diff --git a/opm/core/fluid/blackoil/SinglePvtDead.cpp b/opm/core/fluid/blackoil/SinglePvtDead.cpp index 3d1a2740..b37fdc2d 100644 --- a/opm/core/fluid/blackoil/SinglePvtDead.cpp +++ b/opm/core/fluid/blackoil/SinglePvtDead.cpp @@ -32,9 +32,8 @@ namespace Opm //------------------------------------------------------------------------ // Member functions //------------------------------------------------------------------------- - /// Constructor - SinglePvtDead::SinglePvtDead(const table_t& pvd_table) + SinglePvtDead::SinglePvtDead(const table_t& pvd_table,const int samples) { const int region_number = 0; if (pvd_table.size() != 1) { @@ -51,7 +50,6 @@ namespace Opm B_inv[i] = 1.0 / pvd_table[region_number][1][i]; visc[i] = pvd_table[region_number][2][i]; } - int samples = 1025; buildUniformMonotoneTable(press, B_inv, samples, one_over_B_); buildUniformMonotoneTable(press, visc, samples, viscosity_); diff --git a/opm/core/fluid/blackoil/SinglePvtDead.hpp b/opm/core/fluid/blackoil/SinglePvtDead.hpp index 137e2e30..5a8f6971 100644 --- a/opm/core/fluid/blackoil/SinglePvtDead.hpp +++ b/opm/core/fluid/blackoil/SinglePvtDead.hpp @@ -37,8 +37,7 @@ namespace Opm { public: typedef std::vector > > table_t; - - SinglePvtDead(const table_t& pvd_table); + SinglePvtDead(const table_t& pvd_table,const int samples = 16); virtual ~SinglePvtDead(); /// Viscosity as a function of p and z. diff --git a/opm/core/utility/UniformTableLinear.hpp b/opm/core/utility/UniformTableLinear.hpp index 11c2d4ca..60b3433d 100644 --- a/opm/core/utility/UniformTableLinear.hpp +++ b/opm/core/utility/UniformTableLinear.hpp @@ -188,9 +188,14 @@ namespace Opm { UniformTableLinear ::derivative(const double xparam) const { - // Implements ClosestValue policy. + // Implements derivative consistent + // with ClosestValue policy for function + double value; + if(xparam > xmax_ || xparam < xmin_){ + value=0.0; + }else{ double x = std::min(xparam, xmax_); - x = std::max(x, xmin_); + x = std::max(x, xmin_); // Lookup is easy since we are uniform in x. double pos = (x - xmin_)/xdelta_; @@ -200,7 +205,9 @@ namespace Opm { // We are at xmax_ --left; } - return (y_values_[left + 1] - y_values_[left])/xdelta_; + value = (y_values_[left + 1] - y_values_[left])/xdelta_; + } + return value; } diff --git a/tests/pvt_test.cpp b/tests/pvt_test.cpp index a15f5f89..b8cc3528 100644 --- a/tests/pvt_test.cpp +++ b/tests/pvt_test.cpp @@ -30,34 +30,68 @@ #include #include +#include #include #include #include int main(int argc, char** argv) { + using namespace std; // Parameters. Opm::parameter::ParameterGroup param(argc, argv); // Parser. std::string ecl_file = param.get("deck_filename"); std::string input_file = param.get("input_filename"); - std::string matrix_output = param.get("matrix_outout"); + std::string matrix_output = param.get("matrix_output"); std::string rs_output = param.get("rs_output"); std::string b_output = param.get("b_output"); + std::string mu_output = param.get("mu_output"); Opm::EclipseGridParser deck(ecl_file); UnstructuredGrid grid; grid.number_of_cells = 1; grid.global_cell = NULL; - Opm::BlackoilPropertiesFromDeck props(deck, grid); + Opm::BlackoilPropertiesFromDeck props(deck, grid, param); Opm::BlackoilPvtProperties pvt; - pvt.init(deck); + int samples = param.getDefault("dead_tab_size", 1025); + pvt.init(deck, samples); const int n = 1; std::fstream inos(input_file.c_str()); + if(!inos.good()){ + std::cout << "Could not open :" << input_file << std::endl; + exit(3); + } + std::fstream aos(matrix_output.c_str(), std::fstream::out | std::fstream::trunc); + aos << setiosflags(ios::scientific) << setprecision(12); + if(!(aos.good())){ + std::cout << "Could not open"<< matrix_output << std::endl; + exit(3); + } + std::fstream bos(b_output.c_str(), std::fstream::out | std::fstream::trunc); + bos << setiosflags(ios::scientific) << setprecision(12); + if(!(bos.good())){ + std::cout << "Could not open"<< b_output << std::endl; + exit(3); + } + std::fstream rsos(rs_output.c_str(), std::fstream::out | std::fstream::trunc); + rsos << setiosflags(ios::scientific) << setprecision(12); + if(!(rsos.good())){ + std::cout << "Could not open"<< rs_output << std::endl; + exit(3); + } + std::fstream muos(mu_output.c_str(), std::fstream::out | std::fstream::trunc); + if(!(muos.good())){ + std::cout << "Could not open"<< rs_output << std::endl; + exit(3); + } + + + int np=props.numPhases(); - while(inos.good()){ + while((inos.good()) && (!inos.eof())){ double p[n]; double z[np*n]; int cells[n] = { 0 }; @@ -65,26 +99,36 @@ int main(int argc, char** argv) for(int i=0; i < np; ++i){ inos >> z[i]; } - double A[np*np*n]; - props.matrix(n, p, z, cells, A, 0); - std::fstream aos(matrix_output.c_str()); - std::copy(A, A + np*np, std::ostream_iterator(aos, " ")); - std::cout << std::endl; - double b[np]; - double dbdp[np]; - pvt.dBdp(n, p, z, b, dbdp); - std::fstream bos(b_output.c_str()); - std::copy(b, b + np, std::ostream_iterator(bos, " ")); - std::copy(b, dbdp + np, std::ostream_iterator(bos, " ")); - std::cout << std::endl; - double rs[np]; - double drs[np]; - //pvt.R(n, p, z, rs); - pvt.dRdp(n, p, z, rs,drs); - std::fstream rsos(rs_output.c_str()); - std::copy(b, rs + np, std::ostream_iterator(rsos, " ")); - std::copy(b, drs + np, std::ostream_iterator(rsos, " ")); - std::cout << std::endl; + + if(inos.good()){ + double A[np*np*n]; + double dA[np*np*n]; + props.matrix(n, p, z, cells, A, dA); + std::copy(A, A + np*np, std::ostream_iterator(aos, " ")); + std::copy(dA, dA + np*np, std::ostream_iterator(aos, " ")); + aos << std::endl; + double mu[np]; + //double dmu[np];//not implemented + props.viscosity(n, p, z, cells, mu, 0); + std::copy(mu, mu + np, std::ostream_iterator(muos, " ")); + //std::copy(dmu, dmu + np, std::ostream_iterator(muos, " ")); + aos << std::endl; + + double b[np]; + double dbdp[np]; + pvt.dBdp(n, p, z, b, dbdp); + std::copy(b, b + np, std::ostream_iterator(bos, " ")); + std::copy(dbdp, dbdp + np, std::ostream_iterator(bos, " ")); + bos << std::endl; + + double rs[np]; + double drs[np]; + //pvt.R(n, p, z, rs); + pvt.dRdp(n, p, z, rs,drs); + std::copy(rs, rs + np, std::ostream_iterator(rsos, " ")); + std::copy(drs, drs + np, std::ostream_iterator(rsos, " ")); + rsos << std::endl; + } } if (param.anyUnused()) { std::cout << "-------------------- Unused parameters: --------------------\n"; diff --git a/tests/relperm_test.cpp b/tests/relperm_test.cpp index 2ff134e2..f521a483 100644 --- a/tests/relperm_test.cpp +++ b/tests/relperm_test.cpp @@ -65,20 +65,20 @@ int main(int argc, char** argv) while((inos.good()) && (!inos.eof())){ double s[np]; for(int i=0; i < np; ++i){ - inos >> s[i]; + inos >> s[i]; } if(inos.good()){ - double kr[np]; - double dkr[np*np]; - int cell[1]; - cell[0]=1; - props.relperm(1,s, cell, kr, dkr); - std::copy(s, s + np, std::ostream_iterator(kros, " ")); - kros << " "; - std::copy(kr, kr + np, std::ostream_iterator(kros, " ")); - kros << " "; - std::copy(dkr, dkr + np*np, std::ostream_iterator(kros, " ")); - kros << "\n"; + double kr[np]; + double dkr[np*np]; + int cell[1]; + cell[0]=1; + props.relperm(1,s, cell, kr, dkr); + std::copy(s, s + np, std::ostream_iterator(kros, " ")); + kros << " "; + std::copy(kr, kr + np, std::ostream_iterator(kros, " ")); + kros << " "; + std::copy(dkr, dkr + np*np, std::ostream_iterator(kros, " ")); + kros << "\n"; } } if (param.anyUnused()) { From 596c988126099d51130f28cc9ee08f095e724761 Mon Sep 17 00:00:00 2001 From: Xavier Raynaud Date: Mon, 3 Sep 2012 11:29:48 +0200 Subject: [PATCH 14/32] Improve documentation. --- opm/core/utility/miscUtilities.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/core/utility/miscUtilities.hpp b/opm/core/utility/miscUtilities.hpp index de452fba..74cdc674 100644 --- a/opm/core/utility/miscUtilities.hpp +++ b/opm/core/utility/miscUtilities.hpp @@ -44,7 +44,7 @@ namespace Opm /// @brief Computes pore volume of all cells in a grid, with rock compressibility effects. /// @param[in] grid a grid - /// @param[in] porosity array of grid.number_of_cells porosity values + /// @param[in] porosity array of grid.number_of_cells porosity values (at reference pressure) /// @param[in] rock_comp rock compressibility properties /// @param[in] pressure pressure by cell /// @param[out] porevol the pore volume by cell. From 87dc7affc562069d919fab65483aeaca7fa2b6c2 Mon Sep 17 00:00:00 2001 From: Xavier Raynaud Date: Mon, 3 Sep 2012 12:26:22 +0200 Subject: [PATCH 15/32] Fixed comment. --- opm/core/utility/miscUtilities.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/core/utility/miscUtilities.hpp b/opm/core/utility/miscUtilities.hpp index 74cdc674..2def319a 100644 --- a/opm/core/utility/miscUtilities.hpp +++ b/opm/core/utility/miscUtilities.hpp @@ -56,7 +56,7 @@ namespace Opm /// @brief Computes porosity of all cells in a grid, with rock compressibility effects. /// @param[in] grid a grid - /// @param[in] porosity_standard array of grid.number_of_cells porosity values (at standard conditions) + /// @param[in] porosity_standard array of grid.number_of_cells porosity values (at reference presure) /// @param[in] rock_comp rock compressibility properties /// @param[in] pressure pressure by cell /// @param[out] porosity porosity (at reservoir condition) From e37f003cb5985e9b4cdfbe0a953b119da0a06787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 13:54:50 +0200 Subject: [PATCH 16/32] Added more checks in 3-phase init code. --- opm/core/utility/initState_impl.hpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/opm/core/utility/initState_impl.hpp b/opm/core/utility/initState_impl.hpp index f6670434..9a635e93 100644 --- a/opm/core/utility/initState_impl.hpp +++ b/opm/core/utility/initState_impl.hpp @@ -512,11 +512,10 @@ namespace Opm State& state) { const int num_phases = props.numPhases(); - state.init(grid, num_phases); if (deck.hasField("EQUIL")) { if (num_phases != 2) { - THROW("initStateFromDeck(): currently handling only two-phase scenarios."); + THROW("initStateFromDeck(): EQUIL-based init currently handling only two-phase scenarios."); } // Set saturations depending on oil-water contact. const EQUIL& equil= deck.getEQUIL(); @@ -536,22 +535,27 @@ namespace Opm const std::vector& sw_deck = deck.getFloatingPointValue("SWAT"); const std::vector& p_deck = deck.getFloatingPointValue("PRESSURE"); const int num_cells = grid.number_of_cells; - if(num_phases == 2){ + if (num_phases == 2) { for (int c = 0; c < num_cells; ++c) { int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c]; s[2*c] = sw_deck[c_deck]; s[2*c + 1] = 1.0 - s[2*c]; p[c] = p_deck[c_deck]; } - }else{ + } else if (num_phases == 3) { + if (!deck.hasField("SGAS")) { + THROW("initStateFromDeck(): missing SGAS keyword in 3-phase init (only SWAT and PRESSURE found)."); + } const std::vector& sg_deck = deck.getFloatingPointValue("SGAS"); - for (int c = 0; c < num_cells; ++c) { + for (int c = 0; c < num_cells; ++c) { int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c]; s[2*c] = sw_deck[c_deck]; s[2*c + 1] = 1.0 - (sw_deck[c_deck] + sg_deck[c_deck]); s[2*c + 2] = sg_deck[c_deck]; p[c] = p_deck[c_deck]; } + } else { + THROW("initStateFromDeck(): init with SWAT etc. only available with 2 or 3 phases."); } } else { THROW("initStateFromDeck(): we must either have EQUIL, or both SWAT and PRESSURE."); From 055f2d5f193b60a01faa9170d372acf704a86307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 14:04:52 +0200 Subject: [PATCH 17/32] Whitespace cleanup and adding a check for #phases <= 3. --- opm/core/utility/miscUtilities.cpp | 340 ++++++++++++++--------------- 1 file changed, 170 insertions(+), 170 deletions(-) diff --git a/opm/core/utility/miscUtilities.cpp b/opm/core/utility/miscUtilities.cpp index 0b8d2010..e1658b83 100644 --- a/opm/core/utility/miscUtilities.cpp +++ b/opm/core/utility/miscUtilities.cpp @@ -40,14 +40,14 @@ namespace Opm /// @param[out] porevol the pore volume by cell. void computePorevolume(const UnstructuredGrid& grid, const double* porosity, - std::vector& porevol) + std::vector& porevol) { - int num_cells = grid.number_of_cells; - porevol.resize(num_cells); - std::transform(porosity, porosity + num_cells, - grid.cell_volumes, - porevol.begin(), - std::multiplies()); + int num_cells = grid.number_of_cells; + porevol.resize(num_cells); + std::transform(porosity, porosity + num_cells, + grid.cell_volumes, + porevol.begin(), + std::multiplies()); } @@ -98,20 +98,20 @@ namespace Opm /// For each phase p, we compute /// sat_vol_p = sum_i s_p_i pv_i void computeSaturatedVol(const std::vector& pv, - const std::vector& s, - double* sat_vol) + const std::vector& s, + double* sat_vol) { - const int num_cells = pv.size(); - const int np = s.size()/pv.size(); - if (int(s.size()) != num_cells*np) { - THROW("Sizes of s and pv vectors do not match."); - } - std::fill(sat_vol, sat_vol + np, 0.0); - for (int c = 0; c < num_cells; ++c) { - for (int p = 0; p < np; ++p) { - sat_vol[p] += pv[c]*s[np*c + p]; - } - } + const int num_cells = pv.size(); + const int np = s.size()/pv.size(); + if (int(s.size()) != num_cells*np) { + THROW("Sizes of s and pv vectors do not match."); + } + std::fill(sat_vol, sat_vol + np, 0.0); + for (int c = 0; c < num_cells; ++c) { + for (int p = 0; p < np; ++p) { + sat_vol[p] += pv[c]*s[np*c + p]; + } + } } @@ -123,28 +123,28 @@ namespace Opm /// For each phase p, we compute /// aver_sat_p = (sum_i s_p_i pv_i) / (sum_i pv_i). void computeAverageSat(const std::vector& pv, - const std::vector& s, - double* aver_sat) + const std::vector& s, + double* aver_sat) { - const int num_cells = pv.size(); - const int np = s.size()/pv.size(); - if (int(s.size()) != num_cells*np) { - THROW("Sizes of s and pv vectors do not match."); - } - double tot_pv = 0.0; - // Note that we abuse the output array to accumulate the - // saturated pore volumes. - std::fill(aver_sat, aver_sat + np, 0.0); - for (int c = 0; c < num_cells; ++c) { - tot_pv += pv[c]; - for (int p = 0; p < np; ++p) { - aver_sat[p] += pv[c]*s[np*c + p]; - } - } - // Must divide by pore volumes to get saturations. - for (int p = 0; p < np; ++p) { - aver_sat[p] /= tot_pv; - } + const int num_cells = pv.size(); + const int np = s.size()/pv.size(); + if (int(s.size()) != num_cells*np) { + THROW("Sizes of s and pv vectors do not match."); + } + double tot_pv = 0.0; + // Note that we abuse the output array to accumulate the + // saturated pore volumes. + std::fill(aver_sat, aver_sat + np, 0.0); + for (int c = 0; c < num_cells; ++c) { + tot_pv += pv[c]; + for (int p = 0; p < np; ++p) { + aver_sat[p] += pv[c]*s[np*c + p]; + } + } + // Must divide by pore volumes to get saturations. + for (int p = 0; p < np; ++p) { + aver_sat[p] /= tot_pv; + } } @@ -161,38 +161,38 @@ namespace Opm /// where P = s.size()/src.size(). /// @param[out] produced must also point to a valid array with P elements. void computeInjectedProduced(const IncompPropertiesInterface& props, - const std::vector& s, - const std::vector& src, - const double dt, - double* injected, - double* produced) + const std::vector& s, + const std::vector& src, + const double dt, + double* injected, + double* produced) { - const int num_cells = src.size(); - const int np = s.size()/src.size(); - if (int(s.size()) != num_cells*np) { - THROW("Sizes of s and src vectors do not match."); - } - std::fill(injected, injected + np, 0.0); - std::fill(produced, produced + np, 0.0); - const double* visc = props.viscosity(); - std::vector mob(np); - for (int c = 0; c < num_cells; ++c) { - if (src[c] > 0.0) { - injected[0] += src[c]*dt; - } else if (src[c] < 0.0) { - const double flux = -src[c]*dt; - const double* sat = &s[np*c]; - props.relperm(1, sat, &c, &mob[0], 0); - double totmob = 0.0; - for (int p = 0; p < np; ++p) { - mob[p] /= visc[p]; - totmob += mob[p]; - } - for (int p = 0; p < np; ++p) { - produced[p] += (mob[p]/totmob)*flux; - } - } - } + const int num_cells = src.size(); + const int np = s.size()/src.size(); + if (int(s.size()) != num_cells*np) { + THROW("Sizes of s and src vectors do not match."); + } + std::fill(injected, injected + np, 0.0); + std::fill(produced, produced + np, 0.0); + const double* visc = props.viscosity(); + std::vector mob(np); + for (int c = 0; c < num_cells; ++c) { + if (src[c] > 0.0) { + injected[0] += src[c]*dt; + } else if (src[c] < 0.0) { + const double flux = -src[c]*dt; + const double* sat = &s[np*c]; + props.relperm(1, sat, &c, &mob[0], 0); + double totmob = 0.0; + for (int p = 0; p < np; ++p) { + mob[p] /= visc[p]; + totmob += mob[p]; + } + for (int p = 0; p < np; ++p) { + produced[p] += (mob[p]/totmob)*flux; + } + } + } } @@ -203,9 +203,9 @@ namespace Opm /// @param[in] s saturation values (for all phases) /// @param[out] totmob total mobilities. void computeTotalMobility(const Opm::IncompPropertiesInterface& props, - const std::vector& cells, - const std::vector& s, - std::vector& totmob) + const std::vector& cells, + const std::vector& s, + std::vector& totmob) { std::vector pmobc; @@ -231,10 +231,10 @@ namespace Opm /// @param[out] totmob total mobility /// @param[out] omega fractional-flow weighted fluid densities. void computeTotalMobilityOmega(const Opm::IncompPropertiesInterface& props, - const std::vector& cells, - const std::vector& s, - std::vector& totmob, - std::vector& omega) + const std::vector& cells, + const std::vector& s, + std::vector& totmob, + std::vector& omega) { std::vector pmobc; @@ -331,33 +331,33 @@ namespace Opm /// (+) positive inflow of first phase (water) /// (-) negative total outflow of both phases void computeTransportSource(const UnstructuredGrid& grid, - const std::vector& src, - const std::vector& faceflux, - const double inflow_frac, + const std::vector& src, + const std::vector& faceflux, + const double inflow_frac, const Wells* wells, const std::vector& well_perfrates, - std::vector& transport_src) + std::vector& transport_src) { - int nc = grid.number_of_cells; - transport_src.resize(nc); + int nc = grid.number_of_cells; + transport_src.resize(nc); // Source term and boundary contributions. - for (int c = 0; c < nc; ++c) { - transport_src[c] = 0.0; - transport_src[c] += src[c] > 0.0 ? inflow_frac*src[c] : src[c]; - for (int hf = grid.cell_facepos[c]; hf < grid.cell_facepos[c + 1]; ++hf) { - int f = grid.cell_faces[hf]; - const int* f2c = &grid.face_cells[2*f]; - double bdy_influx = 0.0; - if (f2c[0] == c && f2c[1] == -1) { - bdy_influx = -faceflux[f]; - } else if (f2c[0] == -1 && f2c[1] == c) { - bdy_influx = faceflux[f]; - } - if (bdy_influx != 0.0) { - transport_src[c] += bdy_influx > 0.0 ? inflow_frac*bdy_influx : bdy_influx; - } - } - } + for (int c = 0; c < nc; ++c) { + transport_src[c] = 0.0; + transport_src[c] += src[c] > 0.0 ? inflow_frac*src[c] : src[c]; + for (int hf = grid.cell_facepos[c]; hf < grid.cell_facepos[c + 1]; ++hf) { + int f = grid.cell_faces[hf]; + const int* f2c = &grid.face_cells[2*f]; + double bdy_influx = 0.0; + if (f2c[0] == c && f2c[1] == -1) { + bdy_influx = -faceflux[f]; + } else if (f2c[0] == -1 && f2c[1] == c) { + bdy_influx = faceflux[f]; + } + if (bdy_influx != 0.0) { + transport_src[c] += bdy_influx > 0.0 ? inflow_frac*bdy_influx : bdy_influx; + } + } + } // Well contributions. if (wells) { @@ -392,52 +392,52 @@ namespace Opm /// @param[in] face_flux signed per-face fluxes /// @param[out] cell_velocity the estimated velocities. void estimateCellVelocity(const UnstructuredGrid& grid, - const std::vector& face_flux, - std::vector& cell_velocity) + const std::vector& face_flux, + std::vector& cell_velocity) { - const int dim = grid.dimensions; - cell_velocity.clear(); - cell_velocity.resize(grid.number_of_cells*dim, 0.0); - for (int face = 0; face < grid.number_of_faces; ++face) { - int c[2] = { grid.face_cells[2*face], grid.face_cells[2*face + 1] }; - const double* fc = &grid.face_centroids[face*dim]; - double flux = face_flux[face]; - for (int i = 0; i < 2; ++i) { - if (c[i] >= 0) { - const double* cc = &grid.cell_centroids[c[i]*dim]; - for (int d = 0; d < dim; ++d) { - double v_contrib = fc[d] - cc[d]; - v_contrib *= flux/grid.cell_volumes[c[i]]; - cell_velocity[c[i]*dim + d] += (i == 0) ? v_contrib : -v_contrib; - } - } - } - } + const int dim = grid.dimensions; + cell_velocity.clear(); + cell_velocity.resize(grid.number_of_cells*dim, 0.0); + for (int face = 0; face < grid.number_of_faces; ++face) { + int c[2] = { grid.face_cells[2*face], grid.face_cells[2*face + 1] }; + const double* fc = &grid.face_centroids[face*dim]; + double flux = face_flux[face]; + for (int i = 0; i < 2; ++i) { + if (c[i] >= 0) { + const double* cc = &grid.cell_centroids[c[i]*dim]; + for (int d = 0; d < dim; ++d) { + double v_contrib = fc[d] - cc[d]; + v_contrib *= flux/grid.cell_volumes[c[i]]; + cell_velocity[c[i]*dim + d] += (i == 0) ? v_contrib : -v_contrib; + } + } + } + } } /// Extract a vector of water saturations from a vector of /// interleaved water and oil saturations. void toWaterSat(const std::vector& sboth, - std::vector& sw) + std::vector& sw) { - int num = sboth.size()/2; - sw.resize(num); - for (int i = 0; i < num; ++i) { - sw[i] = sboth[2*i]; - } + int num = sboth.size()/2; + sw.resize(num); + for (int i = 0; i < num; ++i) { + sw[i] = sboth[2*i]; + } } /// Make a a vector of interleaved water and oil saturations from /// a vector of water saturations. void toBothSat(const std::vector& sw, - std::vector& sboth) + std::vector& sboth) { - int num = sw.size(); - sboth.resize(2*num); - for (int i = 0; i < num; ++i) { - sboth[2*i] = sw[i]; - sboth[2*i + 1] = 1.0 - sw[i]; - } + int num = sw.size(); + sboth.resize(2*num); + for (int i = 0; i < num; ++i) { + sboth[2*i] = sw[i]; + sboth[2*i + 1] = 1.0 - sw[i]; + } } @@ -450,30 +450,30 @@ namespace Opm if (np != 2) { THROW("wellsToSrc() requires a 2 phase case."); } - src.resize(num_cells); - for (int w = 0; w < wells.number_of_wells; ++w) { + src.resize(num_cells); + for (int w = 0; w < wells.number_of_wells; ++w) { const int cur = wells.ctrls[w]->current; - if (wells.ctrls[w]->num != 1) { - MESSAGE("In wellsToSrc(): well has more than one control, all but current control will be ignored."); - } - if (wells.ctrls[w]->type[cur] != RESERVOIR_RATE) { - THROW("In wellsToSrc(): well is something other than RESERVOIR_RATE."); - } - if (wells.well_connpos[w+1] - wells.well_connpos[w] != 1) { - THROW("In wellsToSrc(): well has multiple perforations."); - } + if (wells.ctrls[w]->num != 1) { + MESSAGE("In wellsToSrc(): well has more than one control, all but current control will be ignored."); + } + if (wells.ctrls[w]->type[cur] != RESERVOIR_RATE) { + THROW("In wellsToSrc(): well is something other than RESERVOIR_RATE."); + } + if (wells.well_connpos[w+1] - wells.well_connpos[w] != 1) { + THROW("In wellsToSrc(): well has multiple perforations."); + } for (int p = 0; p < np; ++p) { if (wells.ctrls[w]->distr[np*cur + p] != 1.0) { THROW("In wellsToSrc(): well not controlled on total rate."); } } - double flow = wells.ctrls[w]->target[cur]; + double flow = wells.ctrls[w]->target[cur]; if (wells.type[w] == INJECTOR) { flow *= wells.comp_frac[np*w + 0]; // Obtaining water rate for inflow source. } - const double cell = wells.well_cells[wells.well_connpos[w]]; - src[cell] = flow; - } + const double cell = wells.well_cells[wells.well_connpos[w]]; + src[cell] = flow; + } } @@ -594,9 +594,10 @@ namespace Opm int nw = well_bhp.size(); ASSERT(nw == wells.number_of_wells); int np = props.numPhases(); - //if (props.numPhases() != 2) { - // THROW("WellReport for now assumes two phase flow."); - //} + const int max_np = 3; + if (np > max_np) { + THROW("WellReport for now assumes #phases <= " << max_np); + } const double* visc = props.viscosity(); std::vector data_now; data_now.reserve(1 + 3*nw); @@ -606,8 +607,8 @@ namespace Opm double well_rate_total = 0.0; double well_rate_water = 0.0; for (int perf = wells.well_connpos[w]; perf < wells.well_connpos[w + 1]; ++perf) { - const double perf_rate = unit::convert::to(well_perfrates[perf], - unit::cubic(unit::meter)/unit::day); + const double perf_rate = unit::convert::to(well_perfrates[perf], + unit::cubic(unit::meter)/unit::day); well_rate_total += perf_rate; if (perf_rate > 0.0) { // Injection. @@ -615,13 +616,13 @@ namespace Opm } else { // Production. const int cell = wells.well_cells[perf]; - double mob[np]; + double mob[max_np]; props.relperm(1, &saturation[2*cell], &cell, mob, 0); - double tmob=0; - for(int i=0; i < np; ++i){ + double tmob = 0; + for(int i = 0; i < np; ++i) { mob[i] /= visc[i]; tmob += mob[i]; - } + } const double fracflow = mob[0]/tmob; well_rate_water += perf_rate*fracflow; } @@ -652,9 +653,10 @@ namespace Opm int nw = well_bhp.size(); ASSERT(nw == wells.number_of_wells); int np = props.numPhases(); - //if (props.numPhases() != 2) { - // THROW("WellReport for now assumes two phase flow."); - //} + const int max_np = 3; + if (np > max_np) { + THROW("WellReport for now assumes #phases <= " << max_np); + } std::vector data_now; data_now.reserve(1 + 3*nw); data_now.push_back(time/unit::day); @@ -665,25 +667,23 @@ namespace Opm for (int perf = wells.well_connpos[w]; perf < wells.well_connpos[w + 1]; ++perf) { const double perf_rate = well_perfrates[perf]*(unit::day/unit::second); well_rate_total += perf_rate; - if (perf_rate > 0.0) { + if (perf_rate > 0.0) { // Injection. well_rate_water += perf_rate*wells.comp_frac[0]; } else { // Production. const int cell = wells.well_cells[perf]; - double mob[np]; + double mob[max_np]; props.relperm(1, &s[2*cell], &cell, mob, 0); - double visc[np]; + double visc[max_np]; props.viscosity(1, &p[cell], &z[2*cell], &cell, visc, 0); - double tmob=0; - for(int i=0; i < np; ++i){ + double tmob = 0; + for(int i = 0; i < np; ++i) { mob[i] /= visc[i]; tmob += mob[i]; - } + } const double fracflow = mob[0]/(tmob); well_rate_water += perf_rate*fracflow; - //const double fracflow = mob[0]/(tmob); - //well_rate_water += perf_rate*fracflow; } } data_now.push_back(well_rate_total); From dff5716718dcd66f4d273cf6e030f38a0ce4ce8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 14:16:54 +0200 Subject: [PATCH 18/32] Documented new constructor. Fixed layout. --- opm/core/fluid/BlackoilPropertiesFromDeck.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp index 1d0a0d38..e6b9c5b4 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp @@ -45,9 +45,18 @@ namespace Opm /// to logical cartesian indices consistent with the deck. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, const UnstructuredGrid& grid); + + /// Initialize from deck, grid and parameters. + /// \param deck Deck input parser + /// \param grid Grid to which property object applies, needed for the + /// mapping from cell indices (typically from a processed grid) + /// to logical cartesian indices consistent with the deck. + /// \param param Parameters. Accepted parameters include: + /// tab_size (200) number of uniform sample points for saturation tables. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, const UnstructuredGrid& grid, const parameter::ParameterGroup& param); + /// Destructor. virtual ~BlackoilPropertiesFromDeck(); From 5dd3b2a6734667bb851b000d51eb46ec0bcf1556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 14:17:36 +0200 Subject: [PATCH 19/32] Minor formatting fixes. --- opm/core/fluid/SatFuncStone2.cpp | 4 ++-- opm/core/fluid/SaturationPropsFromDeck.cpp | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/opm/core/fluid/SatFuncStone2.cpp b/opm/core/fluid/SatFuncStone2.cpp index c43238c1..a03bfb66 100644 --- a/opm/core/fluid/SatFuncStone2.cpp +++ b/opm/core/fluid/SatFuncStone2.cpp @@ -12,10 +12,10 @@ namespace Opm - // ----------- Methods of SatFuncSet below ----------- void SatFuncStone2::init(const EclipseGridParser& deck, const int table_num, - const PhaseUsage phase_usg){ + const PhaseUsage phase_usg) + { init(deck, table_num, phase_usg, 200); } diff --git a/opm/core/fluid/SaturationPropsFromDeck.cpp b/opm/core/fluid/SaturationPropsFromDeck.cpp index 582c29db..bfef312c 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.cpp +++ b/opm/core/fluid/SaturationPropsFromDeck.cpp @@ -88,9 +88,13 @@ namespace Opm satfuncset_[table].init(deck, table, phase_usage_); } } + + + /// Initialize from deck, grid and parameters void SaturationPropsFromDeck::init(const EclipseGridParser& deck, - const UnstructuredGrid& grid, - const parameter::ParameterGroup& param){ + const UnstructuredGrid& grid, + const parameter::ParameterGroup& param) + { phase_usage_ = phaseUsageFromDeck(deck); // Extract input data. @@ -138,10 +142,10 @@ namespace Opm } // Initialize tables. - int tab_size=param.getDefault("tab_size_kr",200); + int tab_size = param.getDefault("tab_size_kr", 200); satfuncset_.resize(num_tables); for (int table = 0; table < num_tables; ++table) { - satfuncset_[table].init(deck, table, phase_usage_,tab_size); + satfuncset_[table].init(deck, table, phase_usage_, tab_size); } } From 592b1cf7435cce8e0c1d860ea2724b70b8b1fdbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 14:31:02 +0200 Subject: [PATCH 20/32] Minor warning, formatting and comment fixes. --- opm/core/fluid/SatFuncSimple.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/opm/core/fluid/SatFuncSimple.cpp b/opm/core/fluid/SatFuncSimple.cpp index 90ca0e56..740af43c 100644 --- a/opm/core/fluid/SatFuncSimple.cpp +++ b/opm/core/fluid/SatFuncSimple.cpp @@ -12,13 +12,14 @@ namespace Opm - // ----------- Methods of SatFuncSet below ----------- void SatFuncSimple::init(const EclipseGridParser& deck, const int table_num, - const PhaseUsage phase_usg){ + const PhaseUsage phase_usg) + { init(deck, table_num, phase_usg, 200); } + void SatFuncSimple::init(const EclipseGridParser& deck, const int table_num, const PhaseUsage phase_usg, @@ -67,14 +68,14 @@ namespace Opm void SatFuncSimple::evalKr(const double* s, double* kr) const { if (phase_usage.num_phases == 3) { - // Stone-II relative permeability model. + // A simplified relative permeability model. double sw = s[Aqua]; double sg = s[Vapour]; double krw = krw_(sw); double krg = krg_(sg); double krow = krow_(sw + sg); // = 1 - so - double krog = krog_(sg); // = 1 - so - sw - double krocw = krocw_; + // double krog = krog_(sg); // = 1 - so - sw + // double krocw = krocw_; kr[Aqua] = krw; kr[Vapour] = krg; kr[Liquid] = krow; @@ -111,7 +112,7 @@ namespace Opm std::fill(dkrds, dkrds + np*np, 0.0); if (np == 3) { - // Stone-II relative permeability model. + // A simplified relative permeability model. double sw = s[Aqua]; double sg = s[Vapour]; double krw = krw_(sw); @@ -120,12 +121,12 @@ namespace Opm double dkrgg = krg_.derivative(sg); double krow = krow_(sw + sg); double dkrow = krow_.derivative(sw + sg); - double krog = krog_(sg); - double dkrog = krog_.derivative(sg); - double krocw = krocw_; + // double krog = krog_(sg); + // double dkrog = krog_.derivative(sg); + // double krocw = krocw_; kr[Aqua] = krw; kr[Vapour] = krg; - kr[Liquid] = krow; + kr[Liquid] = krow; //krocw*((krow/krocw + krw)*(krog/krocw + krg) - krw - krg); if (kr[Liquid] < 0.0) { kr[Liquid] = 0.0; From b93bb4fcf926d29161701ce93371a240390b698a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 14:37:28 +0200 Subject: [PATCH 21/32] Added copyright and license statement. --- opm/core/fluid/SatFuncSimple.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/opm/core/fluid/SatFuncSimple.hpp b/opm/core/fluid/SatFuncSimple.hpp index 93ba7a31..a3388848 100644 --- a/opm/core/fluid/SatFuncSimple.hpp +++ b/opm/core/fluid/SatFuncSimple.hpp @@ -1,3 +1,21 @@ +/* + Copyright 2012 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 . +*/ #ifndef SATFUNCSIMPLE_HPP #define SATFUNCSIMPLE_HPP #include From 3e294a4a81eae1f81f0c60de2fc4a090048ddee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 15:07:03 +0200 Subject: [PATCH 22/32] Formatting fixes. --- .../fluid/blackoil/BlackoilPvtProperties.cpp | 2 +- .../fluid/blackoil/BlackoilPvtProperties.hpp | 2 +- .../fluid/blackoil/SinglePvtConstCompr.hpp | 8 ++-- opm/core/fluid/blackoil/SinglePvtDead.cpp | 2 +- opm/core/fluid/blackoil/SinglePvtDead.hpp | 2 +- opm/core/utility/UniformTableLinear.hpp | 37 +++++++++---------- 6 files changed, 25 insertions(+), 28 deletions(-) diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp index 6278d1bd..39b4ba05 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp @@ -39,7 +39,7 @@ namespace Opm } - void BlackoilPvtProperties::init(const EclipseGridParser& deck,const int samples) + void BlackoilPvtProperties::init(const EclipseGridParser& deck, const int samples) { typedef std::vector > > table_t; // If we need multiple regions, this class and the SinglePvt* classes must change. diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp index 99fd5b8f..191c6fa8 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp @@ -47,7 +47,7 @@ namespace Opm BlackoilPvtProperties(); /// Initialize from deck. - void init(const EclipseGridParser& deck,const int samples = 16); + void init(const EclipseGridParser& deck, const int samples = 16); /// Number of active phases. int numPhases() const; diff --git a/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp b/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp index 3044bdb2..557bc1e8 100644 --- a/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp +++ b/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp @@ -106,15 +106,13 @@ namespace Opm double* output_B, double* output_dBdp) const { - //B(n, p, 0, output_B); if (comp_) { // #pragma omp parallel for for (int i = 0; i < n; ++i) { - //output_dBdp[i] = -comp_*output_B[i]; double x = comp_*(p[i] - ref_press_); - double d= (1.0 + x + 0.5*x*x); - output_B[i] = ref_B_/d;//(1.0 + x + 0.5*x*x); - output_dBdp[i] = (- ref_B_/(d*d))*(1 + x) *comp_; + double d = (1.0 + x + 0.5*x*x); + output_B[i] = ref_B_/d; + output_dBdp[i] = (-ref_B_/(d*d))*(1 + x) * comp_; } } else { std::fill(output_B, output_B + n, ref_B_); diff --git a/opm/core/fluid/blackoil/SinglePvtDead.cpp b/opm/core/fluid/blackoil/SinglePvtDead.cpp index b37fdc2d..1a0993be 100644 --- a/opm/core/fluid/blackoil/SinglePvtDead.cpp +++ b/opm/core/fluid/blackoil/SinglePvtDead.cpp @@ -33,7 +33,7 @@ namespace Opm // Member functions //------------------------------------------------------------------------- /// Constructor - SinglePvtDead::SinglePvtDead(const table_t& pvd_table,const int samples) + SinglePvtDead::SinglePvtDead(const table_t& pvd_table, const int samples) { const int region_number = 0; if (pvd_table.size() != 1) { diff --git a/opm/core/fluid/blackoil/SinglePvtDead.hpp b/opm/core/fluid/blackoil/SinglePvtDead.hpp index 5a8f6971..90a7d695 100644 --- a/opm/core/fluid/blackoil/SinglePvtDead.hpp +++ b/opm/core/fluid/blackoil/SinglePvtDead.hpp @@ -37,7 +37,7 @@ namespace Opm { public: typedef std::vector > > table_t; - SinglePvtDead(const table_t& pvd_table,const int samples = 16); + SinglePvtDead(const table_t& pvd_table, const int samples = 16); virtual ~SinglePvtDead(); /// Viscosity as a function of p and z. diff --git a/opm/core/utility/UniformTableLinear.hpp b/opm/core/utility/UniformTableLinear.hpp index 60b3433d..2a0fc55f 100644 --- a/opm/core/utility/UniformTableLinear.hpp +++ b/opm/core/utility/UniformTableLinear.hpp @@ -188,26 +188,25 @@ namespace Opm { UniformTableLinear ::derivative(const double xparam) const { - // Implements derivative consistent - // with ClosestValue policy for function - double value; - if(xparam > xmax_ || xparam < xmin_){ - value=0.0; - }else{ - double x = std::min(xparam, xmax_); - x = std::max(x, xmin_); - - // Lookup is easy since we are uniform in x. - double pos = (x - xmin_)/xdelta_; - double posi = std::floor(pos); - int left = int(posi); - if (left == int(y_values_.size()) - 1) { - // We are at xmax_ - --left; + // Implements derivative consistent + // with ClosestValue policy for function + double value; + if (xparam > xmax_ || xparam < xmin_) { + value = 0.0; + } else { + double x = std::min(xparam, xmax_); + x = std::max(x, xmin_); + // Lookup is easy since we are uniform in x. + double pos = (x - xmin_)/xdelta_; + double posi = std::floor(pos); + int left = int(posi); + if (left == int(y_values_.size()) - 1) { + // We are at xmax_ + --left; + } + value = (y_values_[left + 1] - y_values_[left])/xdelta_; } - value = (y_values_[left + 1] - y_values_[left])/xdelta_; - } - return value; + return value; } From 7adeb9b84a9648297dc3d77d19235d21656af67f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 15:09:55 +0200 Subject: [PATCH 23/32] Documented parameters. --- opm/core/fluid/BlackoilPropertiesFromDeck.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp index e6b9c5b4..b63c0af8 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp @@ -52,7 +52,8 @@ namespace Opm /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. /// \param param Parameters. Accepted parameters include: - /// tab_size (200) number of uniform sample points for saturation tables. + /// dead_tab_size (1025) number of uniform sample points for dead-oil pvt tables. + /// tab_size_kr (200) number of uniform sample points for saturation tables. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, const UnstructuredGrid& grid, const parameter::ParameterGroup& param); From 47b40c034e5e7122e9a5f861cb821b1a14734159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 3 Sep 2012 16:01:07 +0200 Subject: [PATCH 24/32] Fixed spontaneous grid structs, avoid variable-sized arrays. --- tests/pvt_test.cpp | 28 ++++++++++++++++++---------- tests/relperm_test.cpp | 16 ++++++++++++---- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/tests/pvt_test.cpp b/tests/pvt_test.cpp index b8cc3528..a986eb93 100644 --- a/tests/pvt_test.cpp +++ b/tests/pvt_test.cpp @@ -52,6 +52,10 @@ int main(int argc, char** argv) UnstructuredGrid grid; grid.number_of_cells = 1; grid.global_cell = NULL; + grid.dimensions = 3; + grid.cartdims[0] = 1; + grid.cartdims[1] = 1; + grid.cartdims[2] = 1; Opm::BlackoilPropertiesFromDeck props(deck, grid, param); Opm::BlackoilPvtProperties pvt; int samples = param.getDefault("dead_tab_size", 1025); @@ -90,10 +94,14 @@ int main(int argc, char** argv) - int np=props.numPhases(); + const int np = props.numPhases(); + const int max_np = 3; + if (np > max_np) { + THROW("Max #phases is 3."); + } while((inos.good()) && (!inos.eof())){ double p[n]; - double z[np*n]; + double z[max_np*n]; int cells[n] = { 0 }; inos >> p[0]; for(int i=0; i < np; ++i){ @@ -101,28 +109,28 @@ int main(int argc, char** argv) } if(inos.good()){ - double A[np*np*n]; - double dA[np*np*n]; + double A[max_np*max_np*n]; + double dA[max_np*max_np*n]; props.matrix(n, p, z, cells, A, dA); std::copy(A, A + np*np, std::ostream_iterator(aos, " ")); std::copy(dA, dA + np*np, std::ostream_iterator(aos, " ")); aos << std::endl; - double mu[np]; - //double dmu[np];//not implemented + double mu[max_np]; + //double dmu[max_np];//not implemented props.viscosity(n, p, z, cells, mu, 0); std::copy(mu, mu + np, std::ostream_iterator(muos, " ")); //std::copy(dmu, dmu + np, std::ostream_iterator(muos, " ")); aos << std::endl; - double b[np]; - double dbdp[np]; + double b[max_np]; + double dbdp[max_np]; pvt.dBdp(n, p, z, b, dbdp); std::copy(b, b + np, std::ostream_iterator(bos, " ")); std::copy(dbdp, dbdp + np, std::ostream_iterator(bos, " ")); bos << std::endl; - double rs[np]; - double drs[np]; + double rs[max_np]; + double drs[max_np]; //pvt.R(n, p, z, rs); pvt.dRdp(n, p, z, rs,drs); std::copy(rs, rs + np, std::ostream_iterator(rsos, " ")); diff --git a/tests/relperm_test.cpp b/tests/relperm_test.cpp index f521a483..4c777071 100644 --- a/tests/relperm_test.cpp +++ b/tests/relperm_test.cpp @@ -49,6 +49,10 @@ int main(int argc, char** argv) UnstructuredGrid grid; grid.number_of_cells = 1; grid.global_cell = NULL; + grid.dimensions = 3; + grid.cartdims[0] = 1; + grid.cartdims[1] = 1; + grid.cartdims[2] = 1; Opm::BlackoilPropertiesFromDeck props(deck, grid, param); std::fstream inos(input_file.c_str());//, std::fstream::in); @@ -61,15 +65,19 @@ int main(int argc, char** argv) std::cout << "Could not open :" << input_file << std::endl; exit(3); } - int np=props.numPhases(); + const int np = props.numPhases(); + const int max_np = 3; + if (np > max_np) { + THROW("Max #phases is 3."); + } while((inos.good()) && (!inos.eof())){ - double s[np]; + double s[max_np]; for(int i=0; i < np; ++i){ inos >> s[i]; } if(inos.good()){ - double kr[np]; - double dkr[np*np]; + double kr[max_np]; + double dkr[max_np*max_np]; int cell[1]; cell[0]=1; props.relperm(1,s, cell, kr, dkr); From d0ade9c7ad620ed841ebc7d88a52c0bf19a31355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 4 Sep 2012 11:49:05 +0200 Subject: [PATCH 25/32] Updated doc to match new parameter names. New parameters are (default): pvt_tab_size (200) sat_tab_size (200) threephase_model ("simple") [also accepts "stone2"]. --- opm/core/fluid/BlackoilPropertiesFromDeck.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp index 97a29d0a..80a8d819 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp @@ -53,8 +53,9 @@ namespace Opm /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. /// \param[in] param Parameters. Accepted parameters include: - /// dead_tab_size (1025) number of uniform sample points for dead-oil pvt tables. - /// tab_size_kr (200) number of uniform sample points for saturation tables. + /// pvt_tab_size (200) number of uniform sample points for dead-oil pvt tables. + /// sat_tab_size (200) number of uniform sample points for saturation tables. + /// threephase_model("simple") three-phase relperm model (accepts "simple" and "stone2"). /// For both parameters, a 0 or negative value indicates that no spline fitting is to /// be done, and the input fluid data used directly for linear interpolation. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, From 846f2a534eba438dcf87039fb5c043f8aa1b8420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 4 Sep 2012 12:52:17 +0200 Subject: [PATCH 26/32] Added proper Doxygen tags. --- opm/core/fluid/BlackoilPropertiesFromDeck.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp index b63c0af8..13f5799d 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp @@ -39,19 +39,19 @@ namespace Opm { public: /// Initialize from deck and grid. - /// \param deck Deck input parser - /// \param grid Grid to which property object applies, needed for the + /// \param[in] deck Deck input parser + /// \param[in] grid Grid to which property object applies, needed for the /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, const UnstructuredGrid& grid); /// Initialize from deck, grid and parameters. - /// \param deck Deck input parser - /// \param grid Grid to which property object applies, needed for the + /// \param[in] deck Deck input parser + /// \param[in] grid Grid to which property object applies, needed for the /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. - /// \param param Parameters. Accepted parameters include: + /// \param[in] param Parameters. Accepted parameters include: /// dead_tab_size (1025) number of uniform sample points for dead-oil pvt tables. /// tab_size_kr (200) number of uniform sample points for saturation tables. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, From e25512a646852f67469ea95b51d70d64bc21fe2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 4 Sep 2012 13:00:51 +0200 Subject: [PATCH 27/32] Changed std::copy() statements to account for n != 1. However, there are more changes needed to make the program support n != 1, this is just to reduce the surprise factor a little. --- tests/pvt_test.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/pvt_test.cpp b/tests/pvt_test.cpp index a986eb93..a175885a 100644 --- a/tests/pvt_test.cpp +++ b/tests/pvt_test.cpp @@ -112,29 +112,29 @@ int main(int argc, char** argv) double A[max_np*max_np*n]; double dA[max_np*max_np*n]; props.matrix(n, p, z, cells, A, dA); - std::copy(A, A + np*np, std::ostream_iterator(aos, " ")); - std::copy(dA, dA + np*np, std::ostream_iterator(aos, " ")); + std::copy(A, A + np*np*n, std::ostream_iterator(aos, " ")); + std::copy(dA, dA + np*np*n, std::ostream_iterator(aos, " ")); aos << std::endl; double mu[max_np]; //double dmu[max_np];//not implemented props.viscosity(n, p, z, cells, mu, 0); - std::copy(mu, mu + np, std::ostream_iterator(muos, " ")); - //std::copy(dmu, dmu + np, std::ostream_iterator(muos, " ")); + std::copy(mu, mu + np*n, std::ostream_iterator(muos, " ")); + //std::copy(dmu, dmu + np*n, std::ostream_iterator(muos, " ")); aos << std::endl; double b[max_np]; double dbdp[max_np]; pvt.dBdp(n, p, z, b, dbdp); - std::copy(b, b + np, std::ostream_iterator(bos, " ")); - std::copy(dbdp, dbdp + np, std::ostream_iterator(bos, " ")); + std::copy(b, b + np*n, std::ostream_iterator(bos, " ")); + std::copy(dbdp, dbdp + np*n, std::ostream_iterator(bos, " ")); bos << std::endl; double rs[max_np]; double drs[max_np]; //pvt.R(n, p, z, rs); pvt.dRdp(n, p, z, rs,drs); - std::copy(rs, rs + np, std::ostream_iterator(rsos, " ")); - std::copy(drs, drs + np, std::ostream_iterator(rsos, " ")); + std::copy(rs, rs + np*n, std::ostream_iterator(rsos, " ")); + std::copy(drs, drs + np*n, std::ostream_iterator(rsos, " ")); rsos << std::endl; } } From 72e13ffd0d2ef50627cac0104708cd94d0518934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 4 Sep 2012 13:06:13 +0200 Subject: [PATCH 28/32] Fix stride bug in SGAS/SWAT init. --- opm/core/utility/initState_impl.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opm/core/utility/initState_impl.hpp b/opm/core/utility/initState_impl.hpp index 9a635e93..7d01ade0 100644 --- a/opm/core/utility/initState_impl.hpp +++ b/opm/core/utility/initState_impl.hpp @@ -549,9 +549,9 @@ namespace Opm const std::vector& sg_deck = deck.getFloatingPointValue("SGAS"); for (int c = 0; c < num_cells; ++c) { int c_deck = (grid.global_cell == NULL) ? c : grid.global_cell[c]; - s[2*c] = sw_deck[c_deck]; - s[2*c + 1] = 1.0 - (sw_deck[c_deck] + sg_deck[c_deck]); - s[2*c + 2] = sg_deck[c_deck]; + s[3*c] = sw_deck[c_deck]; + s[3*c + 1] = 1.0 - (sw_deck[c_deck] + sg_deck[c_deck]); + s[3*c + 2] = sg_deck[c_deck]; p[c] = p_deck[c_deck]; } } else { From d8bc45863117c9e0d312d507bbc13e34056ba35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 4 Sep 2012 13:08:30 +0200 Subject: [PATCH 29/32] Minor cleanup. --- tests/Makefile.am | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 4181eaea..43812479 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -12,6 +12,8 @@ noinst_PROGRAMS = \ bo_resprop_test \ monotcubicinterpolator_test \ param_test \ +pvt_test \ +relperm_test \ sparsetable_test \ sparsevector_test \ test_cartgrid \ @@ -21,9 +23,7 @@ test_read_vag \ test_readpolymer \ test_sf2p \ test_writeVtkData \ -unit_test \ -pvt_test \ -relperm_test +unit_test bo_resprop_test_SOURCES = bo_resprop_test.cpp @@ -33,6 +33,10 @@ monotcubicinterpolator_test_SOURCES = monotcubicinterpolator_test.cpp param_test_SOURCES = param_test.cpp param_test_LDADD = $(LDADD) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) +pvt_test_SOURCES = pvt_test.cpp + +relperm_test_SOURCES = relperm_test.cpp + sparsetable_test_SOURCES = sparsetable_test.cpp sparsetable_test_LDADD = $(LDADD) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) @@ -56,12 +60,6 @@ test_writeVtkData_SOURCES = test_writeVtkData.cpp unit_test_SOURCES = unit_test.cpp -pvt_test_SOURCES = pvt_test.cpp -pvt_test_LDADD = $(LDADD) - -relperm_test_SOURCES = relperm_test.cpp -relperm_test_LDADD = $(LDADD) - if UMFPACK noinst_PROGRAMS += test_cfs_tpfa From 3fa259496beef554b46cad0f25971320f7a1da47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 4 Sep 2012 13:12:06 +0200 Subject: [PATCH 30/32] Fix stride bug in WellReport::push(). Use convert::to(). --- opm/core/utility/miscUtilities.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/opm/core/utility/miscUtilities.cpp b/opm/core/utility/miscUtilities.cpp index e1658b83..aeafbfca 100644 --- a/opm/core/utility/miscUtilities.cpp +++ b/opm/core/utility/miscUtilities.cpp @@ -665,7 +665,8 @@ namespace Opm double well_rate_total = 0.0; double well_rate_water = 0.0; for (int perf = wells.well_connpos[w]; perf < wells.well_connpos[w + 1]; ++perf) { - const double perf_rate = well_perfrates[perf]*(unit::day/unit::second); + const double perf_rate = unit::convert::to(well_perfrates[perf], + unit::cubic(unit::meter)/unit::day); well_rate_total += perf_rate; if (perf_rate > 0.0) { // Injection. @@ -674,9 +675,9 @@ namespace Opm // Production. const int cell = wells.well_cells[perf]; double mob[max_np]; - props.relperm(1, &s[2*cell], &cell, mob, 0); + props.relperm(1, &s[np*cell], &cell, mob, 0); double visc[max_np]; - props.viscosity(1, &p[cell], &z[2*cell], &cell, visc, 0); + props.viscosity(1, &p[cell], &z[np*cell], &cell, visc, 0); double tmob = 0; for(int i = 0; i < np; ++i) { mob[i] /= visc[i]; From 95fac1074b6d913b994693b2ba7887b6c767448f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 4 Sep 2012 13:15:26 +0200 Subject: [PATCH 31/32] Constified some local variables. --- opm/core/fluid/BlackoilPropertiesFromDeck.cpp | 2 +- opm/core/fluid/SaturationPropsFromDeck.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp index 67943fc7..5c834fe8 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp @@ -39,7 +39,7 @@ namespace Opm const parameter::ParameterGroup& param) { rock_.init(deck, grid); - int samples = param.getDefault("dead_tab_size", 1025); + const int samples = param.getDefault("dead_tab_size", 1025); pvt_.init(deck, samples); satprops_.init(deck, grid, param); diff --git a/opm/core/fluid/SaturationPropsFromDeck.cpp b/opm/core/fluid/SaturationPropsFromDeck.cpp index bfef312c..3481b874 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.cpp +++ b/opm/core/fluid/SaturationPropsFromDeck.cpp @@ -142,7 +142,7 @@ namespace Opm } // Initialize tables. - int tab_size = param.getDefault("tab_size_kr", 200); + const int tab_size = param.getDefault("tab_size_kr", 200); satfuncset_.resize(num_tables); for (int table = 0; table < num_tables; ++table) { satfuncset_[table].init(deck, table, phase_usage_, tab_size); From 2653a695bfd2129f5dd1b798e410230c36427041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 5 Sep 2012 11:28:54 +0200 Subject: [PATCH 32/32] Massive whitespace cleanup: entire fluid subdir. --- opm/core/fluid/BlackoilPropertiesBasic.cpp | 72 ++-- opm/core/fluid/BlackoilPropertiesBasic.hpp | 20 +- opm/core/fluid/BlackoilPropertiesFromDeck.cpp | 10 +- opm/core/fluid/BlackoilPropertiesFromDeck.hpp | 12 +- .../fluid/BlackoilPropertiesInterface.hpp | 6 +- opm/core/fluid/IncompPropertiesBasic.cpp | 70 ++-- opm/core/fluid/IncompPropertiesBasic.hpp | 34 +- opm/core/fluid/IncompPropertiesFromDeck.cpp | 42 +- opm/core/fluid/IncompPropertiesFromDeck.hpp | 14 +- opm/core/fluid/IncompPropertiesInterface.hpp | 6 +- opm/core/fluid/PvtPropertiesBasic.cpp | 112 +++--- opm/core/fluid/PvtPropertiesBasic.hpp | 18 +- .../fluid/PvtPropertiesIncompFromDeck.cpp | 70 ++-- .../fluid/PvtPropertiesIncompFromDeck.hpp | 12 +- opm/core/fluid/RockBasic.cpp | 30 +- opm/core/fluid/RockBasic.hpp | 8 +- opm/core/fluid/RockCompressibility.cpp | 6 +- opm/core/fluid/RockFromDeck.cpp | 2 +- opm/core/fluid/RockFromDeck.hpp | 2 +- opm/core/fluid/SaturationPropsBasic.cpp | 204 +++++----- opm/core/fluid/SaturationPropsBasic.hpp | 22 +- opm/core/fluid/SaturationPropsFromDeck.hpp | 10 +- .../fluid/SaturationPropsFromDeck_impl.hpp | 20 +- opm/core/fluid/SaturationPropsInterface.hpp | 4 +- .../fluid/blackoil/BlackoilPvtProperties.cpp | 18 +- .../fluid/blackoil/BlackoilPvtProperties.hpp | 6 +- .../fluid/blackoil/SinglePvtConstCompr.hpp | 14 +- opm/core/fluid/blackoil/SinglePvtDead.cpp | 16 +- opm/core/fluid/blackoil/SinglePvtDead.hpp | 6 +- .../fluid/blackoil/SinglePvtDeadSpline.cpp | 16 +- .../fluid/blackoil/SinglePvtDeadSpline.hpp | 8 +- .../fluid/blackoil/SinglePvtInterface.hpp | 2 +- opm/core/fluid/blackoil/SinglePvtLiveGas.cpp | 250 ++++++------ opm/core/fluid/blackoil/SinglePvtLiveGas.hpp | 18 +- opm/core/fluid/blackoil/SinglePvtLiveOil.cpp | 366 +++++++++--------- opm/core/fluid/blackoil/SinglePvtLiveOil.hpp | 18 +- 36 files changed, 772 insertions(+), 772 deletions(-) diff --git a/opm/core/fluid/BlackoilPropertiesBasic.cpp b/opm/core/fluid/BlackoilPropertiesBasic.cpp index be8211c1..2496d98e 100644 --- a/opm/core/fluid/BlackoilPropertiesBasic.cpp +++ b/opm/core/fluid/BlackoilPropertiesBasic.cpp @@ -26,20 +26,20 @@ namespace Opm { BlackoilPropertiesBasic::BlackoilPropertiesBasic(const parameter::ParameterGroup& param, - const int dim, - const int num_cells) + const int dim, + const int num_cells) { - double poro = param.getDefault("porosity", 1.0); - using namespace Opm::unit; - using namespace Opm::prefix; - double perm = param.getDefault("permeability", 100.0)*milli*darcy; + double poro = param.getDefault("porosity", 1.0); + using namespace Opm::unit; + using namespace Opm::prefix; + double perm = param.getDefault("permeability", 100.0)*milli*darcy; rock_.init(dim, num_cells, poro, perm); - pvt_.init(param); + pvt_.init(param); satprops_.init(param); - if (pvt_.numPhases() != satprops_.numPhases()) { - THROW("BlackoilPropertiesBasic::BlackoilPropertiesBasic() - Inconsistent number of phases in pvt data (" - << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); - } + if (pvt_.numPhases() != satprops_.numPhases()) { + THROW("BlackoilPropertiesBasic::BlackoilPropertiesBasic() - Inconsistent number of phases in pvt data (" + << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); + } } BlackoilPropertiesBasic::~BlackoilPropertiesBasic() @@ -90,11 +90,11 @@ namespace Opm /// \param[out] dmudp If non-null: array of nP viscosity derivative values, /// array must be valid before calling. void BlackoilPropertiesBasic::viscosity(const int n, - const double* p, - const double* z, - const int* /*cells*/, - double* mu, - double* dmudp) const + const double* p, + const double* z, + const int* /*cells*/, + double* mu, + double* dmudp) const { if (dmudp) { THROW("BlackoilPropertiesBasic::viscosity() -- derivatives of viscosity not yet implemented."); @@ -114,16 +114,16 @@ namespace Opm /// array must be valid before calling. The matrices are output /// in Fortran order. void BlackoilPropertiesBasic::matrix(const int n, - const double* /*p*/, - const double* /*z*/, - const int* /*cells*/, - double* A, - double* dAdp) const + const double* /*p*/, + const double* /*z*/, + const int* /*cells*/, + double* A, + double* dAdp) const { - const int np = numPhases(); - ASSERT(np <= 2); - double B[2]; // Must be enough since component classes do not handle more than 2. - pvt_.B(1, 0, 0, B); + const int np = numPhases(); + ASSERT(np <= 2); + double B[2]; // Must be enough since component classes do not handle more than 2. + pvt_.B(1, 0, 0, B); // Compute A matrix // #pragma omp parallel for for (int i = 0; i < n; ++i) { @@ -152,8 +152,8 @@ namespace Opm /// of a call to the method matrix(). /// \param[out] rho Array of nP density values, array must be valid before calling. void BlackoilPropertiesBasic::density(const int n, - const double* A, - double* rho) const + const double* A, + double* rho) const { const int np = numPhases(); const double* sdens = pvt_.surfaceDensities(); @@ -186,10 +186,10 @@ namespace Opm /// m_{ij} = \frac{dkr_i}{ds^j}, /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) void BlackoilPropertiesBasic::relperm(const int n, - const double* s, - const int* /*cells*/, - double* kr, - double* dkrds) const + const double* s, + const int* /*cells*/, + double* kr, + double* dkrds) const { satprops_.relperm(n, s, kr, dkrds); } @@ -205,10 +205,10 @@ namespace Opm /// m_{ij} = \frac{dpc_i}{ds^j}, /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) void BlackoilPropertiesBasic::capPress(const int n, - const double* s, - const int* /*cells*/, - double* pc, - double* dpcds) const + const double* s, + const int* /*cells*/, + double* pc, + double* dpcds) const { satprops_.capPress(n, s, pc, dpcds); } @@ -226,7 +226,7 @@ namespace Opm double* smin, double* smax) const { - satprops_.satRange(n, smin, smax); + satprops_.satRange(n, smin, smax); } diff --git a/opm/core/fluid/BlackoilPropertiesBasic.hpp b/opm/core/fluid/BlackoilPropertiesBasic.hpp index d879036e..44a76013 100644 --- a/opm/core/fluid/BlackoilPropertiesBasic.hpp +++ b/opm/core/fluid/BlackoilPropertiesBasic.hpp @@ -35,16 +35,16 @@ namespace Opm { public: /// Construct from parameters. - /// The following parameters are accepted (defaults): - /// num_phases (2) Must be 1 or 2. - /// relperm_func ("Linear") Must be "Constant", "Linear" or "Quadratic". - /// rho1 [rho2, rho3] (1.0e3) Density in kg/m^3 - /// mu1 [mu2, mu3] (1.0) Viscosity in cP - /// porosity (1.0) Porosity - /// permeability (100.0) Permeability in mD + /// The following parameters are accepted (defaults): + /// num_phases (2) Must be 1 or 2. + /// relperm_func ("Linear") Must be "Constant", "Linear" or "Quadratic". + /// rho1 [rho2, rho3] (1.0e3) Density in kg/m^3 + /// mu1 [mu2, mu3] (1.0) Viscosity in cP + /// porosity (1.0) Porosity + /// permeability (100.0) Permeability in mD BlackoilPropertiesBasic(const parameter::ParameterGroup& param, - const int dim, - const int num_cells); + const int dim, + const int num_cells); /// Destructor. virtual ~BlackoilPropertiesBasic(); @@ -151,7 +151,7 @@ namespace Opm double* dpcds) const; - /// Obtain the range of allowable saturation values. +/// Obtain the range of allowable saturation values. /// In cell cells[i], saturation of phase p is allowed to be /// in the interval [smin[i*P + p], smax[i*P + p]]. /// \param[in] n Number of data points. diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp index 7cdae4ae..e2457f39 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.cpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.cpp @@ -33,10 +33,10 @@ namespace Opm satprops_.reset(ptr); ptr->init(deck, grid, 200); - if (pvt_.numPhases() != satprops_->numPhases()) { - THROW("BlackoilPropertiesFromDeck::BlackoilPropertiesFromDeck() - Inconsistent number of phases in pvt data (" - << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_->numPhases() << ")."); - } + if (pvt_.numPhases() != satprops_->numPhases()) { + THROW("BlackoilPropertiesFromDeck::BlackoilPropertiesFromDeck() - Inconsistent number of phases in pvt data (" + << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_->numPhases() << ")."); + } } BlackoilPropertiesFromDeck::BlackoilPropertiesFromDeck(const EclipseGridParser& deck, @@ -319,7 +319,7 @@ namespace Opm double* smin, double* smax) const { - satprops_->satRange(n, cells, smin, smax); + satprops_->satRange(n, cells, smin, smax); } diff --git a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp index aceb534b..eb8b947b 100644 --- a/opm/core/fluid/BlackoilPropertiesFromDeck.hpp +++ b/opm/core/fluid/BlackoilPropertiesFromDeck.hpp @@ -41,15 +41,15 @@ namespace Opm public: /// Initialize from deck and grid. /// \param[in] deck Deck input parser - /// \param[in] grid Grid to which property object applies, needed for the + /// \param[in] grid Grid to which property object applies, needed for the /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. BlackoilPropertiesFromDeck(const EclipseGridParser& deck, - const UnstructuredGrid& grid); + const UnstructuredGrid& grid); /// Initialize from deck, grid and parameters. /// \param[in] deck Deck input parser - /// \param[in] grid Grid to which property object applies, needed for the + /// \param[in] grid Grid to which property object applies, needed for the /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. /// \param[in] param Parameters. Accepted parameters include: @@ -167,9 +167,9 @@ namespace Opm double* dpcds) const; - /// Obtain the range of allowable saturation values. - /// In cell cells[i], saturation of phase p is allowed to be - /// in the interval [smin[i*P + p], smax[i*P + p]]. + /// Obtain the range of allowable saturation values. + /// In cell cells[i], saturation of phase p is allowed to be + /// in the interval [smin[i*P + p], smax[i*P + p]]. /// \param[in] n Number of data points. /// \param[in] cells Array of n cell indices. /// \param[out] smin Array of nP minimum s values, array must be valid before calling. diff --git a/opm/core/fluid/BlackoilPropertiesInterface.hpp b/opm/core/fluid/BlackoilPropertiesInterface.hpp index dd8a857f..501c8a40 100644 --- a/opm/core/fluid/BlackoilPropertiesInterface.hpp +++ b/opm/core/fluid/BlackoilPropertiesInterface.hpp @@ -138,9 +138,9 @@ namespace Opm double* dpcds) const = 0; - /// Obtain the range of allowable saturation values. - /// In cell cells[i], saturation of phase p is allowed to be - /// in the interval [smin[i*P + p], smax[i*P + p]]. + /// Obtain the range of allowable saturation values. + /// In cell cells[i], saturation of phase p is allowed to be + /// in the interval [smin[i*P + p], smax[i*P + p]]. /// \param[in] n Number of data points. /// \param[in] cells Array of n cell indices. /// \param[out] smin Array of nP minimum s values, array must be valid before calling. diff --git a/opm/core/fluid/IncompPropertiesBasic.cpp b/opm/core/fluid/IncompPropertiesBasic.cpp index 0ce3c88a..ab68017c 100644 --- a/opm/core/fluid/IncompPropertiesBasic.cpp +++ b/opm/core/fluid/IncompPropertiesBasic.cpp @@ -28,22 +28,22 @@ namespace Opm { IncompPropertiesBasic::IncompPropertiesBasic(const parameter::ParameterGroup& param, - const int dim, - const int num_cells) + const int dim, + const int num_cells) { - double poro = param.getDefault("porosity", 1.0); - using namespace Opm::unit; - using namespace Opm::prefix; - double perm = param.getDefault("permeability", 100.0)*milli*darcy; + double poro = param.getDefault("porosity", 1.0); + using namespace Opm::unit; + using namespace Opm::prefix; + double perm = param.getDefault("permeability", 100.0)*milli*darcy; rock_.init(dim, num_cells, poro, perm); - pvt_.init(param); + pvt_.init(param); satprops_.init(param); - if (pvt_.numPhases() != satprops_.numPhases()) { - THROW("IncompPropertiesBasic::IncompPropertiesBasic() - Inconsistent number of phases in pvt data (" - << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); - } - viscosity_.resize(pvt_.numPhases()); - pvt_.mu(1, 0, 0, &viscosity_[0]); + if (pvt_.numPhases() != satprops_.numPhases()) { + THROW("IncompPropertiesBasic::IncompPropertiesBasic() - Inconsistent number of phases in pvt data (" + << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); + } + viscosity_.resize(pvt_.numPhases()); + pvt_.mu(1, 0, 0, &viscosity_[0]); } IncompPropertiesBasic::IncompPropertiesBasic(const int num_phases, @@ -56,14 +56,14 @@ namespace Opm const int num_cells) { rock_.init(dim, num_cells, por, perm); - pvt_.init(num_phases, rho, mu); + pvt_.init(num_phases, rho, mu); satprops_.init(num_phases, relpermfunc); - if (pvt_.numPhases() != satprops_.numPhases()) { - THROW("IncompPropertiesBasic::IncompPropertiesBasic() - Inconsistent number of phases in pvt data (" - << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); - } - viscosity_.resize(pvt_.numPhases()); - pvt_.mu(1, 0, 0, &viscosity_[0]); + if (pvt_.numPhases() != satprops_.numPhases()) { + THROW("IncompPropertiesBasic::IncompPropertiesBasic() - Inconsistent number of phases in pvt data (" + << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); + } + viscosity_.resize(pvt_.numPhases()); + pvt_.mu(1, 0, 0, &viscosity_[0]); } IncompPropertiesBasic::~IncompPropertiesBasic() @@ -109,7 +109,7 @@ namespace Opm /// \return Array of P viscosity values. const double* IncompPropertiesBasic::viscosity() const { - return &viscosity_[0]; + return &viscosity_[0]; } /// \return Array of P density values. @@ -117,7 +117,7 @@ namespace Opm { // No difference between reservoir and surface densities // modelled by this class. - return pvt_.surfaceDensities(); + return pvt_.surfaceDensities(); } /// \return Array of P density values. @@ -125,7 +125,7 @@ namespace Opm { // No difference between reservoir and surface densities // modelled by this class. - return pvt_.surfaceDensities(); + return pvt_.surfaceDensities(); } /// \param[in] n Number of data points. @@ -138,10 +138,10 @@ namespace Opm /// m_{ij} = \frac{dkr_i}{ds^j}, /// and is output in Fortran order (m_00 m_10 m_20 m_01 ...) void IncompPropertiesBasic::relperm(const int n, - const double* s, - const int* /*cells*/, - double* kr, - double* dkrds) const + const double* s, + const int* /*cells*/, + double* kr, + double* dkrds) const { satprops_.relperm(n, s, kr, dkrds); } @@ -157,10 +157,10 @@ namespace Opm /// m_{ij} = \frac{dpc_i}{ds^j}, /// and is output in Fortran order (m_00 m_10 m_20 m_01 ...) void IncompPropertiesBasic::capPress(const int n, - const double* s, - const int* /*cells*/, - double* pc, - double* dpcds) const + const double* s, + const int* /*cells*/, + double* pc, + double* dpcds) const { satprops_.capPress(n, s, pc, dpcds); } @@ -174,11 +174,11 @@ namespace Opm /// \param[out] smin Array of nP minimum s values, array must be valid before calling. /// \param[out] smax Array of nP maximum s values, array must be valid before calling. void IncompPropertiesBasic::satRange(const int n, - const int* /*cells*/, - double* smin, - double* smax) const + const int* /*cells*/, + double* smin, + double* smax) const { - satprops_.satRange(n, smin, smax); + satprops_.satRange(n, smin, smax); } } // namespace Opm diff --git a/opm/core/fluid/IncompPropertiesBasic.hpp b/opm/core/fluid/IncompPropertiesBasic.hpp index b90b0876..72c39b1b 100644 --- a/opm/core/fluid/IncompPropertiesBasic.hpp +++ b/opm/core/fluid/IncompPropertiesBasic.hpp @@ -42,29 +42,29 @@ namespace Opm { public: /// Construct from parameters. - /// The following parameters are accepted (defaults): - /// num_phases (2) Must be 1 or 2. - /// relperm_func ("Linear") Must be "Constant", "Linear" or "Quadratic". - /// rho1 [rho2, rho3] (1.0e3) Density in kg/m^3 - /// mu1 [mu2, mu3] (1.0) Viscosity in cP - /// porosity (1.0) Porosity - /// permeability (100.0) Permeability in mD + /// The following parameters are accepted (defaults): + /// num_phases (2) Must be 1 or 2. + /// relperm_func ("Linear") Must be "Constant", "Linear" or "Quadratic". + /// rho1 [rho2, rho3] (1.0e3) Density in kg/m^3 + /// mu1 [mu2, mu3] (1.0) Viscosity in cP + /// porosity (1.0) Porosity + /// permeability (100.0) Permeability in mD IncompPropertiesBasic(const parameter::ParameterGroup& param, - const int dim, - const int num_cells); + const int dim, + const int num_cells); /// Construct from arguments a basic two phase fluid. IncompPropertiesBasic(const int num_phases, const SaturationPropsBasic::RelPermFunc& relpermfunc, const std::vector& rho, - const std::vector& mu, + const std::vector& mu, const double porosity, const double permeability, const int dim, - const int num_cells); + const int num_cells); - /// Destructor. + /// Destructor. virtual ~IncompPropertiesBasic(); // ---- Rock interface ---- @@ -132,9 +132,9 @@ namespace Opm double* dpcds) const; - /// Obtain the range of allowable saturation values. - /// In cell cells[i], saturation of phase p is allowed to be - /// in the interval [smin[i*P + p], smax[i*P + p]]. + /// Obtain the range of allowable saturation values. + /// In cell cells[i], saturation of phase p is allowed to be + /// in the interval [smin[i*P + p], smax[i*P + p]]. /// \param[in] n Number of data points. /// \param[in] cells Array of n cell indices. /// \param[out] smin Array of nP minimum s values, array must be valid before calling. @@ -145,9 +145,9 @@ namespace Opm double* smax) const; private: RockBasic rock_; - PvtPropertiesBasic pvt_; + PvtPropertiesBasic pvt_; SaturationPropsBasic satprops_; - std::vector viscosity_; + std::vector viscosity_; }; diff --git a/opm/core/fluid/IncompPropertiesFromDeck.cpp b/opm/core/fluid/IncompPropertiesFromDeck.cpp index 45e49791..9aa69098 100644 --- a/opm/core/fluid/IncompPropertiesFromDeck.cpp +++ b/opm/core/fluid/IncompPropertiesFromDeck.cpp @@ -27,15 +27,15 @@ namespace Opm { IncompPropertiesFromDeck::IncompPropertiesFromDeck(const EclipseGridParser& deck, - const UnstructuredGrid& grid) + const UnstructuredGrid& grid) { rock_.init(deck, grid); - pvt_.init(deck); + pvt_.init(deck); satprops_.init(deck, grid, 200); - if (pvt_.numPhases() != satprops_.numPhases()) { - THROW("IncompPropertiesFromDeck::IncompPropertiesFromDeck() - Inconsistent number of phases in pvt data (" - << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); - } + if (pvt_.numPhases() != satprops_.numPhases()) { + THROW("IncompPropertiesFromDeck::IncompPropertiesFromDeck() - Inconsistent number of phases in pvt data (" + << pvt_.numPhases() << ") and saturation-dependent function data (" << satprops_.numPhases() << ")."); + } } IncompPropertiesFromDeck::~IncompPropertiesFromDeck() @@ -81,19 +81,19 @@ namespace Opm /// \return Array of P viscosity values. const double* IncompPropertiesFromDeck::viscosity() const { - return pvt_.viscosity(); + return pvt_.viscosity(); } /// \return Array of P density values. const double* IncompPropertiesFromDeck::density() const { - return pvt_.reservoirDensities(); + return pvt_.reservoirDensities(); } /// \return Array of P density values. const double* IncompPropertiesFromDeck::surfaceDensity() const { - return pvt_.surfaceDensities(); + return pvt_.surfaceDensities(); } /// \param[in] n Number of data points. @@ -106,10 +106,10 @@ namespace Opm /// m_{ij} = \frac{dkr_i}{ds^j}, /// and is output in Fortran order (m_00 m_10 m_20 m_01 ...) void IncompPropertiesFromDeck::relperm(const int n, - const double* s, - const int* cells, - double* kr, - double* dkrds) const + const double* s, + const int* cells, + double* kr, + double* dkrds) const { satprops_.relperm(n, s, cells, kr, dkrds); } @@ -125,10 +125,10 @@ namespace Opm /// m_{ij} = \frac{dpc_i}{ds^j}, /// and is output in Fortran order (m_00 m_10 m_20 m_01 ...) void IncompPropertiesFromDeck::capPress(const int n, - const double* s, - const int* cells, - double* pc, - double* dpcds) const + const double* s, + const int* cells, + double* pc, + double* dpcds) const { satprops_.capPress(n, s, cells, pc, dpcds); } @@ -142,11 +142,11 @@ namespace Opm /// \param[out] smin Array of nP minimum s values, array must be valid before calling. /// \param[out] smax Array of nP maximum s values, array must be valid before calling. void IncompPropertiesFromDeck::satRange(const int n, - const int* cells, - double* smin, - double* smax) const + const int* cells, + double* smin, + double* smax) const { - satprops_.satRange(n, cells, smin, smax); + satprops_.satRange(n, cells, smin, smax); } } // namespace Opm diff --git a/opm/core/fluid/IncompPropertiesFromDeck.hpp b/opm/core/fluid/IncompPropertiesFromDeck.hpp index 8f917d3b..6680eaa4 100644 --- a/opm/core/fluid/IncompPropertiesFromDeck.hpp +++ b/opm/core/fluid/IncompPropertiesFromDeck.hpp @@ -47,13 +47,13 @@ namespace Opm public: /// Initialize from deck and grid. /// \param deck Deck input parser - /// \param grid Grid to which property object applies, needed for the + /// \param grid Grid to which property object applies, needed for the /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. IncompPropertiesFromDeck(const EclipseGridParser& deck, - const UnstructuredGrid& grid); + const UnstructuredGrid& grid); - /// Destructor. + /// Destructor. virtual ~IncompPropertiesFromDeck(); // ---- Rock interface ---- @@ -121,9 +121,9 @@ namespace Opm double* dpcds) const; - /// Obtain the range of allowable saturation values. - /// In cell cells[i], saturation of phase p is allowed to be - /// in the interval [smin[i*P + p], smax[i*P + p]]. + /// Obtain the range of allowable saturation values. + /// In cell cells[i], saturation of phase p is allowed to be + /// in the interval [smin[i*P + p], smax[i*P + p]]. /// \param[in] n Number of data points. /// \param[in] cells Array of n cell indices. /// \param[out] smin Array of nP minimum s values, array must be valid before calling. @@ -134,7 +134,7 @@ namespace Opm double* smax) const; private: RockFromDeck rock_; - PvtPropertiesIncompFromDeck pvt_; + PvtPropertiesIncompFromDeck pvt_; SaturationPropsFromDeck satprops_; }; diff --git a/opm/core/fluid/IncompPropertiesInterface.hpp b/opm/core/fluid/IncompPropertiesInterface.hpp index a5025e8a..4f8bfb51 100644 --- a/opm/core/fluid/IncompPropertiesInterface.hpp +++ b/opm/core/fluid/IncompPropertiesInterface.hpp @@ -109,9 +109,9 @@ namespace Opm double* pc, double* dpcds) const = 0; - /// Obtain the range of allowable saturation values. - /// In cell cells[i], saturation of phase p is allowed to be - /// in the interval [smin[i*P + p], smax[i*P + p]]. + /// Obtain the range of allowable saturation values. + /// In cell cells[i], saturation of phase p is allowed to be + /// in the interval [smin[i*P + p], smax[i*P + p]]. /// \param[in] n Number of data points. /// \param[in] cells Array of n cell indices. /// \param[out] smin Array of nP minimum s values, array must be valid before calling. diff --git a/opm/core/fluid/PvtPropertiesBasic.cpp b/opm/core/fluid/PvtPropertiesBasic.cpp index 3d7d7bb2..5220502a 100644 --- a/opm/core/fluid/PvtPropertiesBasic.cpp +++ b/opm/core/fluid/PvtPropertiesBasic.cpp @@ -34,41 +34,41 @@ namespace Opm void PvtPropertiesBasic::init(const parameter::ParameterGroup& param) { - int num_phases = param.getDefault("num_phases", 2); - if (num_phases > 3 || num_phases < 1) { - THROW("PvtPropertiesBasic::init() illegal num_phases: " << num_phases); - } - density_.resize(num_phases); - viscosity_.resize(num_phases); - // We currently do not allow the user to set B. - formation_volume_factor_.clear(); - formation_volume_factor_.resize(num_phases, 1.0); + int num_phases = param.getDefault("num_phases", 2); + if (num_phases > 3 || num_phases < 1) { + THROW("PvtPropertiesBasic::init() illegal num_phases: " << num_phases); + } + density_.resize(num_phases); + viscosity_.resize(num_phases); + // We currently do not allow the user to set B. + formation_volume_factor_.clear(); + formation_volume_factor_.resize(num_phases, 1.0); - // Setting mu and rho from parameters - using namespace Opm::prefix; - using namespace Opm::unit; - const double kgpm3 = kilogram/cubic(meter); - const double cP = centi*Poise; - std::string rname[3] = { "rho1", "rho2", "rho3" }; - double rdefault[3] = { 1.0e3, 1.0e3, 1.0e3 }; - std::string vname[3] = { "mu1", "mu2", "mu3" }; - double vdefault[3] = { 1.0, 1.0, 1.0 }; - for (int phase = 0; phase < num_phases; ++phase) { - density_[phase] = kgpm3*param.getDefault(rname[phase], rdefault[phase]); - viscosity_[phase] = cP*param.getDefault(vname[phase], vdefault[phase]); - } + // Setting mu and rho from parameters + using namespace Opm::prefix; + using namespace Opm::unit; + const double kgpm3 = kilogram/cubic(meter); + const double cP = centi*Poise; + std::string rname[3] = { "rho1", "rho2", "rho3" }; + double rdefault[3] = { 1.0e3, 1.0e3, 1.0e3 }; + std::string vname[3] = { "mu1", "mu2", "mu3" }; + double vdefault[3] = { 1.0, 1.0, 1.0 }; + for (int phase = 0; phase < num_phases; ++phase) { + density_[phase] = kgpm3*param.getDefault(rname[phase], rdefault[phase]); + viscosity_[phase] = cP*param.getDefault(vname[phase], vdefault[phase]); + } } void PvtPropertiesBasic::init(const int num_phases, const std::vector& rho, const std::vector& visc) { - if (num_phases > 3 || num_phases < 1) { - THROW("PvtPropertiesBasic::init() illegal num_phases: " << num_phases); - } - // We currently do not allow the user to set B. - formation_volume_factor_.clear(); - formation_volume_factor_.resize(num_phases, 1.0); + if (num_phases > 3 || num_phases < 1) { + THROW("PvtPropertiesBasic::init() illegal num_phases: " << num_phases); + } + // We currently do not allow the user to set B. + formation_volume_factor_.clear(); + formation_volume_factor_.resize(num_phases, 1.0); density_ = rho; viscosity_ = visc; } @@ -87,69 +87,69 @@ namespace Opm void PvtPropertiesBasic::mu(const int n, - const double* /*p*/, - const double* /*z*/, - double* output_mu) const + const double* /*p*/, + const double* /*z*/, + double* output_mu) const { - const int np = numPhases(); + const int np = numPhases(); for (int phase = 0; phase < np; ++phase) { // #pragma omp parallel for for (int i = 0; i < n; ++i) { output_mu[np*i + phase] = viscosity_[phase]; } - } + } } void PvtPropertiesBasic::B(const int n, - const double* /*p*/, - const double* /*z*/, - double* output_B) const + const double* /*p*/, + const double* /*z*/, + double* output_B) const { - const int np = numPhases(); + const int np = numPhases(); for (int phase = 0; phase < np; ++phase) { // #pragma omp parallel for for (int i = 0; i < n; ++i) { output_B[np*i + phase] = formation_volume_factor_[phase]; } - } + } } void PvtPropertiesBasic::dBdp(const int n, - const double* /*p*/, - const double* /*z*/, - double* output_B, - double* output_dBdp) const + const double* /*p*/, + const double* /*z*/, + double* output_B, + double* output_dBdp) const { - const int np = numPhases(); + const int np = numPhases(); for (int phase = 0; phase < np; ++phase) { // #pragma omp parallel for for (int i = 0; i < n; ++i) { output_B[np*i + phase] = formation_volume_factor_[phase]; output_dBdp[np*i + phase] = 0.0; } - } + } } void PvtPropertiesBasic::R(const int n, - const double* /*p*/, - const double* /*z*/, - double* output_R) const + const double* /*p*/, + const double* /*z*/, + double* output_R) const { - const int np = numPhases(); - std::fill(output_R, output_R + n*np, 0.0); + const int np = numPhases(); + std::fill(output_R, output_R + n*np, 0.0); } void PvtPropertiesBasic::dRdp(const int n, - const double* /*p*/, - const double* /*z*/, - double* output_R, - double* output_dRdp) const + const double* /*p*/, + const double* /*z*/, + double* output_R, + double* output_dRdp) const { - const int np = numPhases(); - std::fill(output_R, output_R + n*np, 0.0); - std::fill(output_dRdp, output_dRdp + n*np, 0.0); + const int np = numPhases(); + std::fill(output_R, output_R + n*np, 0.0); + std::fill(output_dRdp, output_dRdp + n*np, 0.0); } } // namespace Opm diff --git a/opm/core/fluid/PvtPropertiesBasic.hpp b/opm/core/fluid/PvtPropertiesBasic.hpp index d1a3e9f3..3e30e807 100644 --- a/opm/core/fluid/PvtPropertiesBasic.hpp +++ b/opm/core/fluid/PvtPropertiesBasic.hpp @@ -38,11 +38,11 @@ namespace Opm PvtPropertiesBasic(); /// Initialize from parameters. - /// The following parameters are accepted (defaults): - /// num_phases (2) Must be 1, 2 or 3. - /// rho1 [rho2, rho3] (1.0e3) Density in kg/m^3 - /// mu1 [mu2, mu3] (1.0) Viscosity in cP - void init(const parameter::ParameterGroup& param); + /// The following parameters are accepted (defaults): + /// num_phases (2) Must be 1, 2 or 3. + /// rho1 [rho2, rho3] (1.0e3) Density in kg/m^3 + /// mu1 [mu2, mu3] (1.0) Viscosity in cP + void init(const parameter::ParameterGroup& param); /// Initialize from arguments. /// Basic multi phase fluid pvt properties. @@ -55,7 +55,7 @@ namespace Opm /// Densities of stock components at surface conditions. /// \return Array of size numPhases(). - const double* surfaceDensities() const; + const double* surfaceDensities() const; /// Viscosity as a function of p and z. void mu(const int n, @@ -90,9 +90,9 @@ namespace Opm double* output_dRdp) const; private: - std::vector density_; - std::vector viscosity_; - std::vector formation_volume_factor_; + std::vector density_; + std::vector viscosity_; + std::vector formation_volume_factor_; }; } diff --git a/opm/core/fluid/PvtPropertiesIncompFromDeck.cpp b/opm/core/fluid/PvtPropertiesIncompFromDeck.cpp index 62cc1b23..34a4ba00 100644 --- a/opm/core/fluid/PvtPropertiesIncompFromDeck.cpp +++ b/opm/core/fluid/PvtPropertiesIncompFromDeck.cpp @@ -38,54 +38,54 @@ namespace Opm { typedef std::vector > > table_t; // If we need multiple regions, this class and the SinglePvt* classes must change. - int region_number = 0; + int region_number = 0; PhaseUsage phase_usage = phaseUsageFromDeck(deck); - if (phase_usage.phase_used[PhaseUsage::Vapour] || - !phase_usage.phase_used[PhaseUsage::Aqua] || - !phase_usage.phase_used[PhaseUsage::Liquid]) { - THROW("PvtPropertiesIncompFromDeck::init() -- must have gas and oil phases (only) in deck input.\n"); - } + if (phase_usage.phase_used[PhaseUsage::Vapour] || + !phase_usage.phase_used[PhaseUsage::Aqua] || + !phase_usage.phase_used[PhaseUsage::Liquid]) { + THROW("PvtPropertiesIncompFromDeck::init() -- must have gas and oil phases (only) in deck input.\n"); + } - // Surface densities. Accounting for different orders in eclipse and our code. - if (deck.hasField("DENSITY")) { - const std::vector& d = deck.getDENSITY().densities_[region_number]; - enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; - surface_density_[phase_usage.phase_pos[PhaseUsage::Aqua]] = d[ECL_water]; - surface_density_[phase_usage.phase_pos[PhaseUsage::Liquid]] = d[ECL_oil]; - } else { - THROW("Input is missing DENSITY\n"); - } + // Surface densities. Accounting for different orders in eclipse and our code. + if (deck.hasField("DENSITY")) { + const std::vector& d = deck.getDENSITY().densities_[region_number]; + enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; + surface_density_[phase_usage.phase_pos[PhaseUsage::Aqua]] = d[ECL_water]; + surface_density_[phase_usage.phase_pos[PhaseUsage::Liquid]] = d[ECL_oil]; + } else { + THROW("Input is missing DENSITY\n"); + } // Make reservoir densities the same as surface densities initially. // We will modify them with formation volume factors if found. reservoir_density_ = surface_density_; // Water viscosity. - if (deck.hasField("PVTW")) { - const std::vector& pvtw = deck.getPVTW().pvtw_[region_number]; - if (pvtw[2] != 0.0 || pvtw[4] != 0.0) { - MESSAGE("Compressibility effects in PVTW are ignored."); - } + if (deck.hasField("PVTW")) { + const std::vector& pvtw = deck.getPVTW().pvtw_[region_number]; + if (pvtw[2] != 0.0 || pvtw[4] != 0.0) { + MESSAGE("Compressibility effects in PVTW are ignored."); + } reservoir_density_[phase_usage.phase_pos[PhaseUsage::Aqua]] /= pvtw[1]; - viscosity_[phase_usage.phase_pos[PhaseUsage::Aqua]] = pvtw[3]; - } else { - // Eclipse 100 default. - // viscosity_[phase_usage.phase_pos[PhaseUsage::Aqua]] = 0.5*Opm::prefix::centi*Opm::unit::Poise; - THROW("Input is missing PVTW\n"); - } + viscosity_[phase_usage.phase_pos[PhaseUsage::Aqua]] = pvtw[3]; + } else { + // Eclipse 100 default. + // viscosity_[phase_usage.phase_pos[PhaseUsage::Aqua]] = 0.5*Opm::prefix::centi*Opm::unit::Poise; + THROW("Input is missing PVTW\n"); + } // Oil viscosity. - if (deck.hasField("PVCDO")) { - const std::vector& pvcdo = deck.getPVCDO().pvcdo_[region_number]; - if (pvcdo[2] != 0.0 || pvcdo[4] != 0.0) { - MESSAGE("Compressibility effects in PVCDO are ignored."); - } + if (deck.hasField("PVCDO")) { + const std::vector& pvcdo = deck.getPVCDO().pvcdo_[region_number]; + if (pvcdo[2] != 0.0 || pvcdo[4] != 0.0) { + MESSAGE("Compressibility effects in PVCDO are ignored."); + } reservoir_density_[phase_usage.phase_pos[PhaseUsage::Liquid]] /= pvcdo[1]; - viscosity_[phase_usage.phase_pos[PhaseUsage::Liquid]] = pvcdo[3]; - } else { - THROW("Input is missing PVCDO\n"); - } + viscosity_[phase_usage.phase_pos[PhaseUsage::Liquid]] = pvcdo[3]; + } else { + THROW("Input is missing PVCDO\n"); + } } const double* PvtPropertiesIncompFromDeck::surfaceDensities() const diff --git a/opm/core/fluid/PvtPropertiesIncompFromDeck.hpp b/opm/core/fluid/PvtPropertiesIncompFromDeck.hpp index acbabaa4..01bbeed1 100644 --- a/opm/core/fluid/PvtPropertiesIncompFromDeck.hpp +++ b/opm/core/fluid/PvtPropertiesIncompFromDeck.hpp @@ -39,14 +39,14 @@ namespace Opm PvtPropertiesIncompFromDeck(); /// Initialize from deck. - void init(const EclipseGridParser& deck); + void init(const EclipseGridParser& deck); /// Number of active phases. int numPhases() const; /// Densities of stock components at surface conditions. /// \return Array of size numPhases(). - const double* surfaceDensities() const; + const double* surfaceDensities() const; /// Densities of stock components at reservoir conditions. /// Note: a reasonable question to ask is why there can be @@ -58,15 +58,15 @@ namespace Opm /// reporting and using data given in terms of surface values, /// we need to handle this difference. /// \return Array of size numPhases(). - const double* reservoirDensities() const; + const double* reservoirDensities() const; /// Viscosities. const double* viscosity() const; private: - std::tr1::array surface_density_; - std::tr1::array reservoir_density_; - std::tr1::array viscosity_; + std::tr1::array surface_density_; + std::tr1::array reservoir_density_; + std::tr1::array viscosity_; }; } diff --git a/opm/core/fluid/RockBasic.cpp b/opm/core/fluid/RockBasic.cpp index a1423b76..b66cccce 100644 --- a/opm/core/fluid/RockBasic.cpp +++ b/opm/core/fluid/RockBasic.cpp @@ -25,29 +25,29 @@ namespace Opm /// Default constructor. RockBasic::RockBasic() - : dimensions_(-1) + : dimensions_(-1) { } /// Initialize with homogenous porosity and permeability. void RockBasic::init(const int dimensions, - const int num_cells, - const double poro, - const double perm) + const int num_cells, + const double poro, + const double perm) { - dimensions_ = dimensions; - porosity_.clear(); - porosity_.resize(num_cells, poro); - permeability_.clear(); - const int dsq = dimensions*dimensions; - permeability_.resize(num_cells*dsq, 0.0); + dimensions_ = dimensions; + porosity_.clear(); + porosity_.resize(num_cells, poro); + permeability_.clear(); + const int dsq = dimensions*dimensions; + permeability_.resize(num_cells*dsq, 0.0); // #pragma omp parallel for - for (int i = 0; i < num_cells; ++i) { - for (int d = 0; d < dimensions; ++d) { - permeability_[dsq*i + dimensions*d + d] = perm; - } - } + for (int i = 0; i < num_cells; ++i) { + for (int d = 0; d < dimensions; ++d) { + permeability_[dsq*i + dimensions*d + d] = perm; + } + } } diff --git a/opm/core/fluid/RockBasic.hpp b/opm/core/fluid/RockBasic.hpp index 96563780..2adc3ffd 100644 --- a/opm/core/fluid/RockBasic.hpp +++ b/opm/core/fluid/RockBasic.hpp @@ -35,9 +35,9 @@ namespace Opm /// Initialize with homogenous porosity and permeability. void init(const int dimensions, - const int num_cells, - const double poro, - const double perm); + const int num_cells, + const double poro, + const double perm); /// \return D, the number of spatial dimensions. int numDimensions() const @@ -66,7 +66,7 @@ namespace Opm } private: - int dimensions_; + int dimensions_; std::vector porosity_; std::vector permeability_; }; diff --git a/opm/core/fluid/RockCompressibility.cpp b/opm/core/fluid/RockCompressibility.cpp index 10486101..af65d852 100644 --- a/opm/core/fluid/RockCompressibility.cpp +++ b/opm/core/fluid/RockCompressibility.cpp @@ -69,8 +69,8 @@ namespace Opm const double cpnorm = rock_comp_*(pressure - pref_); return (1.0 + cpnorm + 0.5*cpnorm*cpnorm); } else { - // return Opm::linearInterpolation(p_, poromult_, pressure); - return Opm::linearInterpolationExtrap(p_, poromult_, pressure); + // return Opm::linearInterpolation(p_, poromult_, pressure); + return Opm::linearInterpolationExtrap(p_, poromult_, pressure); } } @@ -81,7 +81,7 @@ namespace Opm } else { //const double poromult = Opm::linearInterpolation(p_, poromult_, pressure); //const double dporomultdp = Opm::linearInterpolationDerivative(p_, poromult_, pressure); - const double poromult = Opm::linearInterpolationExtrap(p_, poromult_, pressure); + const double poromult = Opm::linearInterpolationExtrap(p_, poromult_, pressure); const double dporomultdp = Opm::linearInterpolationDerivativeExtrap(p_, poromult_, pressure); return dporomultdp/poromult; diff --git a/opm/core/fluid/RockFromDeck.cpp b/opm/core/fluid/RockFromDeck.cpp index 7ba8903f..ec7db9a6 100644 --- a/opm/core/fluid/RockFromDeck.cpp +++ b/opm/core/fluid/RockFromDeck.cpp @@ -51,7 +51,7 @@ namespace Opm /// Initialize from deck and cell mapping. /// \param deck Deck input parser - /// \param grid grid to which property object applies, needed for the + /// \param grid grid to which property object applies, needed for the /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. void RockFromDeck::init(const EclipseGridParser& deck, diff --git a/opm/core/fluid/RockFromDeck.hpp b/opm/core/fluid/RockFromDeck.hpp index 65027e42..63e71a6e 100644 --- a/opm/core/fluid/RockFromDeck.hpp +++ b/opm/core/fluid/RockFromDeck.hpp @@ -37,7 +37,7 @@ namespace Opm /// Initialize from deck and grid. /// \param deck Deck input parser - /// \param grid Grid to which property object applies, needed for the + /// \param grid Grid to which property object applies, needed for the /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. void init(const EclipseGridParser& deck, diff --git a/opm/core/fluid/SaturationPropsBasic.cpp b/opm/core/fluid/SaturationPropsBasic.cpp index 760f934d..10ddf23d 100644 --- a/opm/core/fluid/SaturationPropsBasic.cpp +++ b/opm/core/fluid/SaturationPropsBasic.cpp @@ -29,64 +29,64 @@ namespace Opm namespace { - struct KrFunConstant - { - double kr(double) - { - return 1.0; - } - double dkrds(double) - { - return 0.0; - } - }; + struct KrFunConstant + { + double kr(double) + { + return 1.0; + } + double dkrds(double) + { + return 0.0; + } + }; - struct KrFunLinear - { - double kr(double s) - { - return s; - } - double dkrds(double) - { - return 1.0; - } - }; + struct KrFunLinear + { + double kr(double s) + { + return s; + } + double dkrds(double) + { + return 1.0; + } + }; - struct KrFunQuadratic - { - double kr(double s) - { - return s*s; - } - double dkrds(double s) - { - return 2.0*s; - } - }; + struct KrFunQuadratic + { + double kr(double s) + { + return s*s; + } + double dkrds(double s) + { + return 2.0*s; + } + }; - template - static inline void evalAllKrDeriv(const int n, const int np, - const double* s, double* kr, double* dkrds, Fun fun) - { - if (dkrds == 0) { + template + static inline void evalAllKrDeriv(const int n, const int np, + const double* s, double* kr, double* dkrds, Fun fun) + { + if (dkrds == 0) { // #pragma omp parallel for - for (int i = 0; i < n*np; ++i) { - kr[i] = fun.kr(s[i]); - } - return; - } + for (int i = 0; i < n*np; ++i) { + kr[i] = fun.kr(s[i]); + } + return; + } // #pragma omp parallel for - for (int i = 0; i < n; ++i) { - std::fill(dkrds + i*np*np, dkrds + (i+1)*np*np, 0.0); - for (int phase = 0; phase < np; ++phase) { - kr[i*np + phase] = fun.kr(s[i*np + phase]); - // Only diagonal elements in derivative. - dkrds[i*np*np + phase*np + phase] = fun.dkrds(s[i*np + phase]); - } - } - } + for (int i = 0; i < n; ++i) { + std::fill(dkrds + i*np*np, dkrds + (i+1)*np*np, 0.0); + for (int phase = 0; phase < np; ++phase) { + kr[i*np + phase] = fun.kr(s[i*np + phase]); + // Only diagonal elements in derivative. + dkrds[i*np*np + phase*np + phase] = fun.dkrds(s[i*np + phase]); + } + } + } } // anon namespace @@ -109,25 +109,25 @@ namespace Opm /// Initialize from parameters. void SaturationPropsBasic::init(const parameter::ParameterGroup& param) { - int num_phases = param.getDefault("num_phases", 2); - if (num_phases > 2 || num_phases < 1) { - THROW("SaturationPropsBasic::init() illegal num_phases: " << num_phases); - } + int num_phases = param.getDefault("num_phases", 2); + if (num_phases > 2 || num_phases < 1) { + THROW("SaturationPropsBasic::init() illegal num_phases: " << num_phases); + } num_phases_ = num_phases; - //std::string rpf = param.getDefault("relperm_func", std::string("Unset")); - std::string rpf = param.getDefault("relperm_func", std::string("Linear")); - if (rpf == "Constant") { - relperm_func_ = Constant; - if(num_phases!=1){ - THROW("Constant relperm with more than one phase???"); - } - } else if (rpf == "Linear") { - relperm_func_ = Linear; - } else if (rpf == "Quadratic") { - relperm_func_ = Quadratic; - } else { - THROW("SaturationPropsBasic::init() illegal relperm_func: " << rpf); - } + //std::string rpf = param.getDefault("relperm_func", std::string("Unset")); + std::string rpf = param.getDefault("relperm_func", std::string("Linear")); + if (rpf == "Constant") { + relperm_func_ = Constant; + if(num_phases!=1){ + THROW("Constant relperm with more than one phase???"); + } + } else if (rpf == "Linear") { + relperm_func_ = Linear; + } else if (rpf == "Quadratic") { + relperm_func_ = Quadratic; + } else { + THROW("SaturationPropsBasic::init() illegal relperm_func: " << rpf); + } } @@ -136,7 +136,7 @@ namespace Opm /// \return P, the number of phases. int SaturationPropsBasic::numPhases() const { - return num_phases_; + return num_phases_; } @@ -152,29 +152,29 @@ namespace Opm /// m_{ij} = \frac{dkr_i}{ds^j}, /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) void SaturationPropsBasic::relperm(const int n, - const double* s, - double* kr, - double* dkrds) const + const double* s, + double* kr, + double* dkrds) const { - switch (relperm_func_) { - case Constant: - { - evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunConstant()); - break; - } - case Linear: - { - evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunLinear()); - break; - } - case Quadratic: - { - evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunQuadratic()); - break; - } - default: - THROW("SaturationPropsBasic::relperm() unhandled relperm func type: " << relperm_func_); - } + switch (relperm_func_) { + case Constant: + { + evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunConstant()); + break; + } + case Linear: + { + evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunLinear()); + break; + } + case Quadratic: + { + evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunQuadratic()); + break; + } + default: + THROW("SaturationPropsBasic::relperm() unhandled relperm func type: " << relperm_func_); + } } @@ -190,13 +190,13 @@ namespace Opm /// m_{ij} = \frac{dpc_i}{ds^j}, /// and is output in Fortran order (m_00 m_10 m_20 m01 ...) void SaturationPropsBasic::capPress(const int n, - const double* /*s*/, - double* pc, - double* dpcds) const + const double* /*s*/, + double* pc, + double* dpcds) const { - std::fill(pc, pc + num_phases_*n, 0.0); + std::fill(pc, pc + num_phases_*n, 0.0); if (dpcds) { - std::fill(dpcds, dpcds + num_phases_*num_phases_*n, 0.0); + std::fill(dpcds, dpcds + num_phases_*num_phases_*n, 0.0); } } @@ -207,11 +207,11 @@ namespace Opm /// \param[out] smin Array of nP minimum s values, array must be valid before calling. /// \param[out] smax Array of nP maximum s values, array must be valid before calling. void SaturationPropsBasic::satRange(const int n, - double* smin, - double* smax) const + double* smin, + double* smax) const { - std::fill(smin, smin + num_phases_*n, 0.0); - std::fill(smax, smax + num_phases_*n, 1.0); + std::fill(smin, smin + num_phases_*n, 0.0); + std::fill(smax, smax + num_phases_*n, 1.0); } diff --git a/opm/core/fluid/SaturationPropsBasic.hpp b/opm/core/fluid/SaturationPropsBasic.hpp index 789e0a35..2f90672d 100644 --- a/opm/core/fluid/SaturationPropsBasic.hpp +++ b/opm/core/fluid/SaturationPropsBasic.hpp @@ -40,16 +40,16 @@ namespace Opm SaturationPropsBasic(); /// Initialize from parameters. - /// The following parameters are accepted (defaults): - /// num_phases (2) Must be 1 or 2. - /// relperm_func ("Linear") Must be "Constant", "Linear" or "Quadratic". + /// The following parameters are accepted (defaults): + /// num_phases (2) Must be 1 or 2. + /// relperm_func ("Linear") Must be "Constant", "Linear" or "Quadratic". void init(const parameter::ParameterGroup& param); - enum RelPermFunc { Constant, Linear, Quadratic }; + enum RelPermFunc { Constant, Linear, Quadratic }; /// Initialize from arguments a basic Saturation property. void init(const int num_phases, - const RelPermFunc& relperm_func) + const RelPermFunc& relperm_func) { num_phases_ = num_phases; relperm_func_ = relperm_func; @@ -86,18 +86,18 @@ namespace Opm double* pc, double* dpcds) const; - /// Obtain the range of allowable saturation values. + /// Obtain the range of allowable saturation values. /// \param[in] n Number of data points. /// \param[out] smin Array of nP minimum s values, array must be valid before calling. /// \param[out] smax Array of nP maximum s values, array must be valid before calling. - void satRange(const int n, - double* smin, - double* smax) const; + void satRange(const int n, + double* smin, + double* smax) const; private: - int num_phases_; - RelPermFunc relperm_func_; + int num_phases_; + RelPermFunc relperm_func_; }; diff --git a/opm/core/fluid/SaturationPropsFromDeck.hpp b/opm/core/fluid/SaturationPropsFromDeck.hpp index 42461985..0a0599ec 100644 --- a/opm/core/fluid/SaturationPropsFromDeck.hpp +++ b/opm/core/fluid/SaturationPropsFromDeck.hpp @@ -50,7 +50,7 @@ namespace Opm /// Initialize from deck and grid. /// \param[in] deck Deck input parser - /// \param[in] grid Grid to which property object applies, needed for the + /// \param[in] grid Grid to which property object applies, needed for the /// mapping from cell indices (typically from a processed grid) /// to logical cartesian indices consistent with the deck. /// \param[in] samples Number of uniform sample points for saturation tables. @@ -92,14 +92,14 @@ namespace Opm double* pc, double* dpcds) const; - /// Obtain the range of allowable saturation values. + /// Obtain the range of allowable saturation values. /// \param[in] n Number of data points. /// \param[out] smin Array of nP minimum s values, array must be valid before calling. /// \param[out] smax Array of nP maximum s values, array must be valid before calling. - void satRange(const int n, + void satRange(const int n, const int* cells, - double* smin, - double* smax) const; + double* smin, + double* smax) const; private: PhaseUsage phase_usage_; diff --git a/opm/core/fluid/SaturationPropsFromDeck_impl.hpp b/opm/core/fluid/SaturationPropsFromDeck_impl.hpp index a4df7f42..f7a80b45 100644 --- a/opm/core/fluid/SaturationPropsFromDeck_impl.hpp +++ b/opm/core/fluid/SaturationPropsFromDeck_impl.hpp @@ -105,7 +105,7 @@ namespace Opm template int SaturationPropsFromDeck::numPhases() const { - return phase_usage_.num_phases; + return phase_usage_.num_phases; } @@ -191,18 +191,18 @@ namespace Opm template void SaturationPropsFromDeck::satRange(const int n, const int* cells, - double* smin, - double* smax) const + double* smin, + double* smax) const { ASSERT (cells != 0); - const int np = phase_usage_.num_phases; - for (int i = 0; i < n; ++i) { - for (int p = 0; p < np; ++p) { - smin[np*i + p] = funcForCell(cells[i]).smin_[p]; - smax[np*i + p] = funcForCell(cells[i]).smax_[p]; - } - } + const int np = phase_usage_.num_phases; + for (int i = 0; i < n; ++i) { + for (int p = 0; p < np; ++p) { + smin[np*i + p] = funcForCell(cells[i]).smin_[p]; + smax[np*i + p] = funcForCell(cells[i]).smax_[p]; + } + } } diff --git a/opm/core/fluid/SaturationPropsInterface.hpp b/opm/core/fluid/SaturationPropsInterface.hpp index e5599567..30f277cc 100644 --- a/opm/core/fluid/SaturationPropsInterface.hpp +++ b/opm/core/fluid/SaturationPropsInterface.hpp @@ -65,11 +65,11 @@ namespace Opm double* pc, double* dpcds) const = 0; - /// Obtain the range of allowable saturation values. + /// Obtain the range of allowable saturation values. /// \param[in] n Number of data points. /// \param[out] smin Array of nP minimum s values, array must be valid before calling. /// \param[out] smax Array of nP maximum s values, array must be valid before calling. - virtual void satRange(const int n, + virtual void satRange(const int n, const int* cells, double* smin, double* smax) const = 0; diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp index b53fcfd3..4a0004ee 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.cpp @@ -44,14 +44,14 @@ namespace Opm { typedef std::vector > > table_t; // If we need multiple regions, this class and the SinglePvt* classes must change. - region_number_ = 0; + region_number_ = 0; phase_usage_ = phaseUsageFromDeck(deck); - // Surface densities. Accounting for different orders in eclipse and our code. - if (deck.hasField("DENSITY")) { - const std::vector& d = deck.getDENSITY().densities_[region_number_]; - enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; + // Surface densities. Accounting for different orders in eclipse and our code. + if (deck.hasField("DENSITY")) { + const std::vector& d = deck.getDENSITY().densities_[region_number_]; + enum { ECL_oil = 0, ECL_water = 1, ECL_gas = 2 }; if (phase_usage_.phase_used[Aqua]) { densities_[phase_usage_.phase_pos[Aqua]] = d[ECL_water]; } @@ -61,9 +61,9 @@ namespace Opm if (phase_usage_.phase_used[Liquid]) { densities_[phase_usage_.phase_pos[Liquid]] = d[ECL_oil]; } - } else { - THROW("Input is missing DENSITY\n"); - } + } else { + THROW("Input is missing DENSITY\n"); + } // Set the properties. props_.resize(phase_usage_.num_phases); @@ -92,7 +92,7 @@ namespace Opm THROW("Input is missing PVDO or PVTO\n"); } } - // Gas PVT + // Gas PVT if (phase_usage_.phase_used[Vapour]) { if (deck.hasField("PVDG")) { if (samples > 0) { diff --git a/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp b/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp index d3a42e32..8633fd9e 100644 --- a/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp +++ b/opm/core/fluid/blackoil/BlackoilPvtProperties.hpp @@ -70,7 +70,7 @@ namespace Opm /// Densities of stock components at surface conditions. /// \return Array of size numPhases(). - const double* surfaceDensities() const; + const double* surfaceDensities() const; /// Viscosity as a function of p and z. void mu(const int n, @@ -111,11 +111,11 @@ namespace Opm PhaseUsage phase_usage_; - int region_number_; + int region_number_; std::vector > props_; - double densities_[MaxNumPhases]; + double densities_[MaxNumPhases]; mutable std::vector data1_; mutable std::vector data2_; }; diff --git a/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp b/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp index 557bc1e8..9226d0d8 100644 --- a/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp +++ b/opm/core/fluid/blackoil/SinglePvtConstCompr.hpp @@ -40,12 +40,12 @@ namespace Opm public: typedef std::vector > table_t; - SinglePvtConstCompr(const table_t& pvtw) + SinglePvtConstCompr(const table_t& pvtw) { - const int region_number = 0; - if (pvtw.size() != 1) { - THROW("More than one PVD-region"); - } + const int region_number = 0; + if (pvtw.size() != 1) { + THROW("More than one PVD-region"); + } ref_press_ = pvtw[region_number][0]; ref_B_ = pvtw[region_number][1]; comp_ = pvtw[region_number][2]; @@ -53,7 +53,7 @@ namespace Opm visc_comp_ = pvtw[region_number][4]; } - SinglePvtConstCompr(double visc) + SinglePvtConstCompr(double visc) : ref_press_(0.0), ref_B_(1.0), comp_(0.0), @@ -62,7 +62,7 @@ namespace Opm { } - virtual ~SinglePvtConstCompr() + virtual ~SinglePvtConstCompr() { } diff --git a/opm/core/fluid/blackoil/SinglePvtDead.cpp b/opm/core/fluid/blackoil/SinglePvtDead.cpp index 5d3c1a31..34aeaf6e 100644 --- a/opm/core/fluid/blackoil/SinglePvtDead.cpp +++ b/opm/core/fluid/blackoil/SinglePvtDead.cpp @@ -35,21 +35,21 @@ namespace Opm /// Constructor SinglePvtDead::SinglePvtDead(const table_t& pvd_table) { - const int region_number = 0; - if (pvd_table.size() != 1) { - THROW("More than one PVT-region"); - } + const int region_number = 0; + if (pvd_table.size() != 1) { + THROW("More than one PVT-region"); + } - // Copy data - const int sz = pvd_table[region_number][0].size(); + // Copy data + const int sz = pvd_table[region_number][0].size(); std::vector press(sz); std::vector B_inv(sz); std::vector visc(sz); - for (int i = 0; i < sz; ++i) { + for (int i = 0; i < sz; ++i) { press[i] = pvd_table[region_number][0][i]; B_inv[i] = 1.0 / pvd_table[region_number][1][i]; visc[i] = pvd_table[region_number][2][i]; - } + } one_over_B_ = NonuniformTableLinear(press, B_inv); viscosity_ = NonuniformTableLinear(press, visc); diff --git a/opm/core/fluid/blackoil/SinglePvtDead.hpp b/opm/core/fluid/blackoil/SinglePvtDead.hpp index cc8e6232..db86b39d 100644 --- a/opm/core/fluid/blackoil/SinglePvtDead.hpp +++ b/opm/core/fluid/blackoil/SinglePvtDead.hpp @@ -36,9 +36,9 @@ namespace Opm class SinglePvtDead : public SinglePvtInterface { public: - typedef std::vector > > table_t; + typedef std::vector > > table_t; SinglePvtDead(const table_t& pvd_table); - virtual ~SinglePvtDead(); + virtual ~SinglePvtDead(); /// Viscosity as a function of p and z. virtual void mu(const int n, @@ -72,7 +72,7 @@ namespace Opm double* output_R, double* output_dRdp) const; private: - // PVT properties of dry gas or dead oil + // PVT properties of dry gas or dead oil NonuniformTableLinear one_over_B_; NonuniformTableLinear viscosity_; }; diff --git a/opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp b/opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp index 6e359e6a..132ffa51 100644 --- a/opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp +++ b/opm/core/fluid/blackoil/SinglePvtDeadSpline.cpp @@ -36,21 +36,21 @@ namespace Opm /// Constructor SinglePvtDeadSpline::SinglePvtDeadSpline(const table_t& pvd_table, const int samples) { - const int region_number = 0; - if (pvd_table.size() != 1) { - THROW("More than one PVT-region"); - } + const int region_number = 0; + if (pvd_table.size() != 1) { + THROW("More than one PVT-region"); + } - // Copy data - const int sz = pvd_table[region_number][0].size(); + // Copy data + const int sz = pvd_table[region_number][0].size(); std::vector press(sz); std::vector B_inv(sz); std::vector visc(sz); - for (int i = 0; i < sz; ++i) { + for (int i = 0; i < sz; ++i) { press[i] = pvd_table[region_number][0][i]; B_inv[i] = 1.0 / pvd_table[region_number][1][i]; visc[i] = pvd_table[region_number][2][i]; - } + } buildUniformMonotoneTable(press, B_inv, samples, one_over_B_); buildUniformMonotoneTable(press, visc, samples, viscosity_); diff --git a/opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp b/opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp index 79e143c5..18d7ecfe 100644 --- a/opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp +++ b/opm/core/fluid/blackoil/SinglePvtDeadSpline.hpp @@ -36,10 +36,10 @@ namespace Opm class SinglePvtDeadSpline : public SinglePvtInterface { public: - typedef std::vector > > table_t; + typedef std::vector > > table_t; - SinglePvtDeadSpline(const table_t& pvd_table, const int samples); - virtual ~SinglePvtDeadSpline(); + SinglePvtDeadSpline(const table_t& pvd_table, const int samples); + virtual ~SinglePvtDeadSpline(); /// Viscosity as a function of p and z. virtual void mu(const int n, @@ -73,7 +73,7 @@ namespace Opm double* output_R, double* output_dRdp) const; private: - // PVT properties of dry gas or dead oil + // PVT properties of dry gas or dead oil UniformTableLinear one_over_B_; UniformTableLinear viscosity_; }; diff --git a/opm/core/fluid/blackoil/SinglePvtInterface.hpp b/opm/core/fluid/blackoil/SinglePvtInterface.hpp index d9369d33..7bcbd44b 100644 --- a/opm/core/fluid/blackoil/SinglePvtInterface.hpp +++ b/opm/core/fluid/blackoil/SinglePvtInterface.hpp @@ -32,7 +32,7 @@ namespace Opm public: SinglePvtInterface(); - virtual ~SinglePvtInterface(); + virtual ~SinglePvtInterface(); /// \param[in] num_phases The number of active phases. /// \param[in] phase_pos Array of BlackpoilPhases::MaxNumPhases diff --git a/opm/core/fluid/blackoil/SinglePvtLiveGas.cpp b/opm/core/fluid/blackoil/SinglePvtLiveGas.cpp index 2526d34c..a6785467 100644 --- a/opm/core/fluid/blackoil/SinglePvtLiveGas.cpp +++ b/opm/core/fluid/blackoil/SinglePvtLiveGas.cpp @@ -1,13 +1,13 @@ //=========================================================================== -// -// File: MiscibilityLiveGas.cpp -// -// Created: Wed Feb 10 09:21:53 2010 -// +// +// File: MiscibilityLiveGas.cpp +// +// Created: Wed Feb 10 09:21:53 2010 +// // Author: Bjørn Spjelkavik -// +// // Revision: $Id$ -// +// //=========================================================================== /* Copyright 2010 SINTEF ICT, Applied Mathematics. @@ -47,37 +47,37 @@ namespace Opm /// Constructor SinglePvtLiveGas::SinglePvtLiveGas(const table_t& pvtg) { - // GAS, PVTG - const int region_number = 0; - if (pvtg.size() != 1) { - THROW("More than one PVD-region"); - } - saturated_gas_table_.resize(4); - const int sz = pvtg[region_number].size(); - for (int k=0; k<4; ++k) { - saturated_gas_table_[k].resize(sz); - } + // GAS, PVTG + const int region_number = 0; + if (pvtg.size() != 1) { + THROW("More than one PVD-region"); + } + saturated_gas_table_.resize(4); + const int sz = pvtg[region_number].size(); + for (int k=0; k<4; ++k) { + saturated_gas_table_[k].resize(sz); + } - for (int i=0; i saturated_gas_table_[0][ltp]) { - return linearInterpolationExtrap(undersat_gas_tables_[ltp][0], - undersat_gas_tables_[ltp][item], - maxR); - } + // Extrapolate from last table section + int ltp = saturated_gas_table_[0].size() - 1; + if (is+1 == ltp && press > saturated_gas_table_[0][ltp]) { + return linearInterpolationExtrap(undersat_gas_tables_[ltp][0], + undersat_gas_tables_[ltp][item], + maxR); + } - // Interpolate between table sections - double w = (press - saturated_gas_table_[0][is]) / - (saturated_gas_table_[0][is+1] - - saturated_gas_table_[0][is]); - if (undersat_gas_tables_[is][0].size() < 2) { - double val = saturated_gas_table_[item][is] + - w*(saturated_gas_table_[item][is+1] - - saturated_gas_table_[item][is]); - return val; - } - double val1 = - linearInterpolationExtrap(undersat_gas_tables_[is][0], - undersat_gas_tables_[is][item], - maxR); - double val2 = - linearInterpolationExtrap(undersat_gas_tables_[is+1][0], - undersat_gas_tables_[is+1][item], - maxR); - double val = val1 + w*(val2 - val1); - return val; - } - } + // Interpolate between table sections + double w = (press - saturated_gas_table_[0][is]) / + (saturated_gas_table_[0][is+1] - + saturated_gas_table_[0][is]); + if (undersat_gas_tables_[is][0].size() < 2) { + double val = saturated_gas_table_[item][is] + + w*(saturated_gas_table_[item][is+1] - + saturated_gas_table_[item][is]); + return val; + } + double val1 = + linearInterpolationExtrap(undersat_gas_tables_[is][0], + undersat_gas_tables_[is][item], + maxR); + double val2 = + linearInterpolationExtrap(undersat_gas_tables_[is+1][0], + undersat_gas_tables_[is+1][item], + maxR); + double val = val1 + w*(val2 - val1); + return val; + } + } } diff --git a/opm/core/fluid/blackoil/SinglePvtLiveGas.hpp b/opm/core/fluid/blackoil/SinglePvtLiveGas.hpp index 3eff52f4..c7761551 100644 --- a/opm/core/fluid/blackoil/SinglePvtLiveGas.hpp +++ b/opm/core/fluid/blackoil/SinglePvtLiveGas.hpp @@ -33,10 +33,10 @@ namespace Opm class SinglePvtLiveGas : public SinglePvtInterface { public: - typedef std::vector > > table_t; + typedef std::vector > > table_t; - SinglePvtLiveGas(const table_t& pvto); - virtual ~SinglePvtLiveGas(); + SinglePvtLiveGas(const table_t& pvto); + virtual ~SinglePvtLiveGas(); /// Viscosity as a function of p and z. virtual void mu(const int n, @@ -76,14 +76,14 @@ namespace Opm double evalR(double press, const double* surfvol) const; void evalRDeriv(double press, const double* surfvol, double& R, double& dRdp) const; - // item: 1=>B 2=>mu; - double miscible_gas(const double press, + // item: 1=>B 2=>mu; + double miscible_gas(const double press, const double* surfvol, const int item, - const bool deriv = false) const; - // PVT properties of wet gas (with vaporised oil) - std::vector > saturated_gas_table_; - std::vector > > undersat_gas_tables_; + const bool deriv = false) const; + // PVT properties of wet gas (with vaporised oil) + std::vector > saturated_gas_table_; + std::vector > > undersat_gas_tables_; }; diff --git a/opm/core/fluid/blackoil/SinglePvtLiveOil.cpp b/opm/core/fluid/blackoil/SinglePvtLiveOil.cpp index 2a393839..990ae114 100644 --- a/opm/core/fluid/blackoil/SinglePvtLiveOil.cpp +++ b/opm/core/fluid/blackoil/SinglePvtLiveOil.cpp @@ -38,122 +38,122 @@ namespace Opm /// Constructor SinglePvtLiveOil::SinglePvtLiveOil(const table_t& pvto) { - // OIL, PVTO - const int region_number = 0; - if (pvto.size() != 1) { - THROW("More than one PVD-region"); - } - saturated_oil_table_.resize(4); - const int sz = pvto[region_number].size(); - for (int k=0; k<4; ++k) { - saturated_oil_table_[k].resize(sz); - } - for (int i=0; i 1) { - iPrev = i; - continue; - } - - bool flagPrev = (iPrev >= 0); - bool flagNext = true; - if (iNext < i) { - iPrev = iNext; - flagPrev = true; - iNext = i+1; - while (undersat_oil_tables_[iNext][0].size() < 2) { - ++iNext; - } - } - double slopePrevBinv = 0.0; - double slopePrevVisc = 0.0; - double slopeNextBinv = 0.0; - double slopeNextVisc = 0.0; - while (flagPrev || flagNext) { - double pressure0 = undersat_oil_tables_[i][0].back(); - double pressure = 1.0e47; - if (flagPrev) { - std::vector::iterator itPrev = upper_bound(undersat_oil_tables_[iPrev][0].begin(), - undersat_oil_tables_[iPrev][0].end(),pressure0+1.); - if (itPrev == undersat_oil_tables_[iPrev][0].end()) { - --itPrev; // Extrapolation ... - } else if (itPrev == undersat_oil_tables_[iPrev][0].begin()) { - ++itPrev; - } - if (itPrev == undersat_oil_tables_[iPrev][0].end()-1) { - flagPrev = false; // Last data set for "prev" ... - } - double dPPrev = *itPrev - *(itPrev-1); - pressure = *itPrev; - int index = int(itPrev - undersat_oil_tables_[iPrev][0].begin()); - slopePrevBinv = (undersat_oil_tables_[iPrev][1][index] - undersat_oil_tables_[iPrev][1][index-1])/dPPrev; - slopePrevVisc = (undersat_oil_tables_[iPrev][2][index] - undersat_oil_tables_[iPrev][2][index-1])/dPPrev; - } - if (flagNext) { - std::vector::iterator itNext = upper_bound(undersat_oil_tables_[iNext][0].begin(), - undersat_oil_tables_[iNext][0].end(),pressure0+1.); - if (itNext == undersat_oil_tables_[iNext][0].end()) { - --itNext; // Extrapolation ... - } else if (itNext == undersat_oil_tables_[iNext][0].begin()) { - ++itNext; - } - if (itNext == undersat_oil_tables_[iNext][0].end()-1) { - flagNext = false; // Last data set for "next" ... - } - double dPNext = *itNext - *(itNext-1); - if (flagPrev) { - pressure = std::min(pressure,*itNext); - } else { - pressure = *itNext; - } - int index = int(itNext - undersat_oil_tables_[iNext][0].begin()); - slopeNextBinv = (undersat_oil_tables_[iNext][1][index] - undersat_oil_tables_[iNext][1][index-1])/dPNext; - slopeNextVisc = (undersat_oil_tables_[iNext][2][index] - undersat_oil_tables_[iNext][2][index-1])/dPNext; - } - double dP = pressure - pressure0; - if (iPrev >= 0) { - double w = (saturated_oil_table_[3][i] - saturated_oil_table_[3][iPrev]) / - (saturated_oil_table_[3][iNext] - saturated_oil_table_[3][iPrev]); - undersat_oil_tables_[i][0].push_back(pressure0+dP); - undersat_oil_tables_[i][1].push_back(undersat_oil_tables_[i][1].back() + - dP*(slopePrevBinv+w*(slopeNextBinv-slopePrevBinv))); - undersat_oil_tables_[i][2].push_back(undersat_oil_tables_[i][2].back() + - dP*(slopePrevVisc+w*(slopeNextVisc-slopePrevVisc))); - } else { - undersat_oil_tables_[i][0].push_back(pressure0+dP); - undersat_oil_tables_[i][1].push_back(undersat_oil_tables_[i][1].back()+dP*slopeNextBinv); - undersat_oil_tables_[i][2].push_back(undersat_oil_tables_[i][2].back()+dP*slopeNextVisc); - } - } - } + // OIL, PVTO + const int region_number = 0; + if (pvto.size() != 1) { + THROW("More than one PVD-region"); + } + saturated_oil_table_.resize(4); + const int sz = pvto[region_number].size(); + for (int k=0; k<4; ++k) { + saturated_oil_table_[k].resize(sz); + } + for (int i=0; i 1) { + iPrev = i; + continue; + } + + bool flagPrev = (iPrev >= 0); + bool flagNext = true; + if (iNext < i) { + iPrev = iNext; + flagPrev = true; + iNext = i+1; + while (undersat_oil_tables_[iNext][0].size() < 2) { + ++iNext; + } + } + double slopePrevBinv = 0.0; + double slopePrevVisc = 0.0; + double slopeNextBinv = 0.0; + double slopeNextVisc = 0.0; + while (flagPrev || flagNext) { + double pressure0 = undersat_oil_tables_[i][0].back(); + double pressure = 1.0e47; + if (flagPrev) { + std::vector::iterator itPrev = upper_bound(undersat_oil_tables_[iPrev][0].begin(), + undersat_oil_tables_[iPrev][0].end(),pressure0+1.); + if (itPrev == undersat_oil_tables_[iPrev][0].end()) { + --itPrev; // Extrapolation ... + } else if (itPrev == undersat_oil_tables_[iPrev][0].begin()) { + ++itPrev; + } + if (itPrev == undersat_oil_tables_[iPrev][0].end()-1) { + flagPrev = false; // Last data set for "prev" ... + } + double dPPrev = *itPrev - *(itPrev-1); + pressure = *itPrev; + int index = int(itPrev - undersat_oil_tables_[iPrev][0].begin()); + slopePrevBinv = (undersat_oil_tables_[iPrev][1][index] - undersat_oil_tables_[iPrev][1][index-1])/dPPrev; + slopePrevVisc = (undersat_oil_tables_[iPrev][2][index] - undersat_oil_tables_[iPrev][2][index-1])/dPPrev; + } + if (flagNext) { + std::vector::iterator itNext = upper_bound(undersat_oil_tables_[iNext][0].begin(), + undersat_oil_tables_[iNext][0].end(),pressure0+1.); + if (itNext == undersat_oil_tables_[iNext][0].end()) { + --itNext; // Extrapolation ... + } else if (itNext == undersat_oil_tables_[iNext][0].begin()) { + ++itNext; + } + if (itNext == undersat_oil_tables_[iNext][0].end()-1) { + flagNext = false; // Last data set for "next" ... + } + double dPNext = *itNext - *(itNext-1); + if (flagPrev) { + pressure = std::min(pressure,*itNext); + } else { + pressure = *itNext; + } + int index = int(itNext - undersat_oil_tables_[iNext][0].begin()); + slopeNextBinv = (undersat_oil_tables_[iNext][1][index] - undersat_oil_tables_[iNext][1][index-1])/dPNext; + slopeNextVisc = (undersat_oil_tables_[iNext][2][index] - undersat_oil_tables_[iNext][2][index-1])/dPNext; + } + double dP = pressure - pressure0; + if (iPrev >= 0) { + double w = (saturated_oil_table_[3][i] - saturated_oil_table_[3][iPrev]) / + (saturated_oil_table_[3][iNext] - saturated_oil_table_[3][iPrev]); + undersat_oil_tables_[i][0].push_back(pressure0+dP); + undersat_oil_tables_[i][1].push_back(undersat_oil_tables_[i][1].back() + + dP*(slopePrevBinv+w*(slopeNextBinv-slopePrevBinv))); + undersat_oil_tables_[i][2].push_back(undersat_oil_tables_[i][2].back() + + dP*(slopePrevVisc+w*(slopeNextVisc-slopePrevVisc))); + } else { + undersat_oil_tables_[i][0].push_back(pressure0+dP); + undersat_oil_tables_[i][1].push_back(undersat_oil_tables_[i][1].back()+dP*slopeNextBinv); + undersat_oil_tables_[i][2].push_back(undersat_oil_tables_[i][2].back()+dP*slopeNextVisc); + } + } + } } /// Destructor. @@ -238,30 +238,30 @@ namespace Opm double SinglePvtLiveOil::evalB(double press, const double* surfvol) const { // if (surfvol[phase_pos_[Liquid]] == 0.0) return 1.0; // To handle no-oil case. - return 1.0/miscible_oil(press, surfvol, 1, false); + return 1.0/miscible_oil(press, surfvol, 1, false); } void SinglePvtLiveOil::evalBDeriv(const double press, const double* surfvol, double& Bval, double& dBdpval) const { - Bval = evalB(press, surfvol); - dBdpval = -Bval*Bval*miscible_oil(press, surfvol, 1, true); + Bval = evalB(press, surfvol); + dBdpval = -Bval*Bval*miscible_oil(press, surfvol, 1, true); } double SinglePvtLiveOil::evalR(double press, const double* surfvol) const { if (surfvol[phase_pos_[Vapour]] == 0.0) { return 0.0; - } - double Rval = linearInterpolationExtrap(saturated_oil_table_[0], - saturated_oil_table_[3], press); - double maxR = surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]]; - if (Rval < maxR ) { // Saturated case - return Rval; - } else { - return maxR; // Undersaturated case - } + } + double Rval = linearInterpolationExtrap(saturated_oil_table_[0], + saturated_oil_table_[3], press); + double maxR = surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]]; + if (Rval < maxR ) { // Saturated case + return Rval; + } else { + return maxR; // Undersaturated case + } } void SinglePvtLiveOil::evalRDeriv(const double press, const double* surfvol, @@ -272,19 +272,19 @@ namespace Opm dRdpval = 0.0; return; } - Rval = linearInterpolationExtrap(saturated_oil_table_[0], + Rval = linearInterpolationExtrap(saturated_oil_table_[0], saturated_oil_table_[3], press); - double maxR = surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]]; - if (Rval < maxR ) { + double maxR = surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]]; + if (Rval < maxR ) { // Saturated case - dRdpval = linearInterpolDerivative(saturated_oil_table_[0], - saturated_oil_table_[3], - press); - } else { + dRdpval = linearInterpolDerivative(saturated_oil_table_[0], + saturated_oil_table_[3], + press); + } else { // Undersaturated case Rval = maxR; - dRdpval = 0.0; - } + dRdpval = 0.0; + } } @@ -293,57 +293,57 @@ namespace Opm const int item, const bool deriv) const { - int section; - double Rval = linearInterpolationExtrap(saturated_oil_table_[0], + int section; + double Rval = linearInterpolationExtrap(saturated_oil_table_[0], saturated_oil_table_[3], press, section); - double maxR = (surfvol[phase_pos_[Liquid]] == 0.0) ? 0.0 : surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]]; - if (deriv) { - if (Rval < maxR ) { // Saturated case - return linearInterpolDerivative(saturated_oil_table_[0], - saturated_oil_table_[item], - press); - } else { // Undersaturated case - int is = tableIndex(saturated_oil_table_[3], maxR); - double w = (maxR - saturated_oil_table_[3][is]) / - (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); - ASSERT(undersat_oil_tables_[is][0].size() >= 2); - ASSERT(undersat_oil_tables_[is+1][0].size() >= 2); - double val1 = - linearInterpolDerivative(undersat_oil_tables_[is][0], - undersat_oil_tables_[is][item], - press); - double val2 = - linearInterpolDerivative(undersat_oil_tables_[is+1][0], - undersat_oil_tables_[is+1][item], - press); - double val = val1 + w*(val2 - val1); - return val; - } - } else { - if (Rval < maxR ) { // Saturated case - return linearInterpolationExtrap(saturated_oil_table_[0], - saturated_oil_table_[item], - press); - } else { // Undersaturated case - // Interpolate between table sections + double maxR = (surfvol[phase_pos_[Liquid]] == 0.0) ? 0.0 : surfvol[phase_pos_[Vapour]]/surfvol[phase_pos_[Liquid]]; + if (deriv) { + if (Rval < maxR ) { // Saturated case + return linearInterpolDerivative(saturated_oil_table_[0], + saturated_oil_table_[item], + press); + } else { // Undersaturated case int is = tableIndex(saturated_oil_table_[3], maxR); - double w = (maxR - saturated_oil_table_[3][is]) / - (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); + double w = (maxR - saturated_oil_table_[3][is]) / + (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); ASSERT(undersat_oil_tables_[is][0].size() >= 2); ASSERT(undersat_oil_tables_[is+1][0].size() >= 2); - double val1 = - linearInterpolationExtrap(undersat_oil_tables_[is][0], - undersat_oil_tables_[is][item], - press); - double val2 = - linearInterpolationExtrap(undersat_oil_tables_[is+1][0], - undersat_oil_tables_[is+1][item], - press); - double val = val1 + w*(val2 - val1); - return val; - } - } + double val1 = + linearInterpolDerivative(undersat_oil_tables_[is][0], + undersat_oil_tables_[is][item], + press); + double val2 = + linearInterpolDerivative(undersat_oil_tables_[is+1][0], + undersat_oil_tables_[is+1][item], + press); + double val = val1 + w*(val2 - val1); + return val; + } + } else { + if (Rval < maxR ) { // Saturated case + return linearInterpolationExtrap(saturated_oil_table_[0], + saturated_oil_table_[item], + press); + } else { // Undersaturated case + // Interpolate between table sections + int is = tableIndex(saturated_oil_table_[3], maxR); + double w = (maxR - saturated_oil_table_[3][is]) / + (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]); + ASSERT(undersat_oil_tables_[is][0].size() >= 2); + ASSERT(undersat_oil_tables_[is+1][0].size() >= 2); + double val1 = + linearInterpolationExtrap(undersat_oil_tables_[is][0], + undersat_oil_tables_[is][item], + press); + double val2 = + linearInterpolationExtrap(undersat_oil_tables_[is+1][0], + undersat_oil_tables_[is+1][item], + press); + double val = val1 + w*(val2 - val1); + return val; + } + } } } // namespace Opm diff --git a/opm/core/fluid/blackoil/SinglePvtLiveOil.hpp b/opm/core/fluid/blackoil/SinglePvtLiveOil.hpp index f8be6353..cef9595e 100644 --- a/opm/core/fluid/blackoil/SinglePvtLiveOil.hpp +++ b/opm/core/fluid/blackoil/SinglePvtLiveOil.hpp @@ -34,10 +34,10 @@ namespace Opm class SinglePvtLiveOil : public SinglePvtInterface { public: - typedef std::vector > > table_t; + typedef std::vector > > table_t; - SinglePvtLiveOil(const table_t& pvto); - virtual ~SinglePvtLiveOil(); + SinglePvtLiveOil(const table_t& pvto); + virtual ~SinglePvtLiveOil(); /// Viscosity as a function of p and z. virtual void mu(const int n, @@ -77,15 +77,15 @@ namespace Opm double evalR(double press, const double* surfvol) const; void evalRDeriv(double press, const double* surfvol, double& R, double& dRdp) const; - // item: 1=>1/B 2=>mu; - double miscible_oil(const double press, + // item: 1=>1/B 2=>mu; + double miscible_oil(const double press, const double* surfvol, const int item, - const bool deriv = false) const; + const bool deriv = false) const; - // PVT properties of live oil (with dissolved gas) - std::vector > saturated_oil_table_; - std::vector > > undersat_oil_tables_; + // PVT properties of live oil (with dissolved gas) + std::vector > saturated_oil_table_; + std::vector > > undersat_oil_tables_; }; }