mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-12-19 05:53:28 -06:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
7c69fc31d0
@ -429,7 +429,7 @@ namespace Opm
|
|||||||
for (int phase = 0; phase < np; ++phase) {
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
int upwindc = -1;
|
int upwindc = -1;
|
||||||
if (c[0] >=0 && c[1] >= 0) {
|
if (c[0] >=0 && c[1] >= 0) {
|
||||||
upwindc = (pot[0] < pot[1]) ? c[1] : c[0];
|
upwindc = (pot[0][phase] < pot[1][phase]) ? c[1] : c[0];
|
||||||
} else {
|
} else {
|
||||||
upwindc = (c[0] >= 0) ? c[0] : c[1];
|
upwindc = (c[0] >= 0) ? c[0] : c[1];
|
||||||
}
|
}
|
||||||
|
@ -42,12 +42,16 @@ namespace Opm
|
|||||||
{
|
{
|
||||||
if (deck.hasField("ROCKTAB")) {
|
if (deck.hasField("ROCKTAB")) {
|
||||||
const table_t& rt = deck.getROCKTAB().rocktab_;
|
const table_t& rt = deck.getROCKTAB().rocktab_;
|
||||||
int n = rt[0][0].size();
|
if (rt.size() != 1) {
|
||||||
|
THROW("Can only handle a single region in ROCKTAB.");
|
||||||
|
}
|
||||||
|
const int n = rt[0][0].size();
|
||||||
p_.resize(n);
|
p_.resize(n);
|
||||||
poromult_.resize(n);
|
poromult_.resize(n);
|
||||||
for (int i = 0; i < n; ++i) {
|
for (int i = 0; i < n; ++i) {
|
||||||
p_[i] = rt[0][0][i];
|
p_[i] = rt[0][0][i];
|
||||||
poromult_[i] = rt[0][1][i];
|
poromult_[i] = rt[0][1][i];
|
||||||
|
transmult_[i] = rt[0][2][i];
|
||||||
}
|
}
|
||||||
} else if (deck.hasField("ROCK")) {
|
} else if (deck.hasField("ROCK")) {
|
||||||
const ROCK& r = deck.getROCK();
|
const ROCK& r = deck.getROCK();
|
||||||
@ -70,11 +74,39 @@ namespace Opm
|
|||||||
const double cpnorm = rock_comp_*(pressure - pref_);
|
const double cpnorm = rock_comp_*(pressure - pref_);
|
||||||
return (1.0 + cpnorm + 0.5*cpnorm*cpnorm);
|
return (1.0 + cpnorm + 0.5*cpnorm*cpnorm);
|
||||||
} else {
|
} else {
|
||||||
// return Opm::linearInterpolation(p_, poromult_, pressure);
|
|
||||||
return Opm::linearInterpolation(p_, poromult_, pressure);
|
return Opm::linearInterpolation(p_, poromult_, pressure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double RockCompressibility::poroMultDeriv(double pressure) const
|
||||||
|
{
|
||||||
|
if (p_.empty()) {
|
||||||
|
// Approximating poro multiplier with a quadratic curve,
|
||||||
|
// we must use its derivative.
|
||||||
|
return rock_comp_ + 2 * rock_comp_ * rock_comp_ * (pressure - pref_);
|
||||||
|
} else {
|
||||||
|
return Opm::linearInterpolationDerivative(p_, poromult_, pressure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double RockCompressibility::transMult(double pressure) const
|
||||||
|
{
|
||||||
|
if (p_.empty()) {
|
||||||
|
return 1.0;
|
||||||
|
} else {
|
||||||
|
return Opm::linearInterpolation(p_, transmult_, pressure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double RockCompressibility::transMultDeriv(double pressure) const
|
||||||
|
{
|
||||||
|
if (p_.empty()) {
|
||||||
|
return 0.0;
|
||||||
|
} else {
|
||||||
|
return Opm::linearInterpolationDerivative(p_, transmult_, pressure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double RockCompressibility::rockComp(double pressure) const
|
double RockCompressibility::rockComp(double pressure) const
|
||||||
{
|
{
|
||||||
if (p_.empty()) {
|
if (p_.empty()) {
|
||||||
|
@ -47,12 +47,22 @@ namespace Opm
|
|||||||
/// Porosity multiplier.
|
/// Porosity multiplier.
|
||||||
double poroMult(double pressure) const;
|
double poroMult(double pressure) const;
|
||||||
|
|
||||||
|
/// Derivative of porosity multiplier with respect to pressure.
|
||||||
|
double poroMultDeriv(double pressure) const;
|
||||||
|
|
||||||
|
/// Transmissibility multiplier.
|
||||||
|
double transMult(double pressure) const;
|
||||||
|
|
||||||
|
/// Derivative of transmissibility multiplier with respect to pressure.
|
||||||
|
double transMultDeriv(double pressure) const;
|
||||||
|
|
||||||
/// Rock compressibility = (d poro / d p)*(1 / poro).
|
/// Rock compressibility = (d poro / d p)*(1 / poro).
|
||||||
double rockComp(double pressure) const;
|
double rockComp(double pressure) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<double> p_;
|
std::vector<double> p_;
|
||||||
std::vector<double> poromult_;
|
std::vector<double> poromult_;
|
||||||
|
std::vector<double> transmult_;
|
||||||
double pref_;
|
double pref_;
|
||||||
double rock_comp_;
|
double rock_comp_;
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <opm/core/grid.h>
|
#include <opm/core/grid.h>
|
||||||
#include <opm/core/props/BlackoilPropertiesInterface.hpp>
|
#include <opm/core/props/BlackoilPropertiesInterface.hpp>
|
||||||
|
#include <opm/core/utility/ErrorMacros.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm
|
||||||
@ -47,6 +48,7 @@ namespace Opm
|
|||||||
// but use available phase information instead.
|
// but use available phase information instead.
|
||||||
sat_[num_phases*cell + 1] = 1.0;
|
sat_[num_phases*cell + 1] = 1.0;
|
||||||
}
|
}
|
||||||
|
gor_.resize(g.number_of_cells, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ExtremalSat { MinSat, MaxSat };
|
enum ExtremalSat { MinSat, MaxSat };
|
||||||
@ -59,7 +61,11 @@ namespace Opm
|
|||||||
const Opm::BlackoilPropertiesInterface& props,
|
const Opm::BlackoilPropertiesInterface& props,
|
||||||
ExtremalSat es)
|
ExtremalSat es)
|
||||||
{
|
{
|
||||||
|
if (cells.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const int n = cells.size();
|
const int n = cells.size();
|
||||||
|
ASSERT(n > 0);
|
||||||
std::vector<double> smin(num_phases_*n);
|
std::vector<double> smin(num_phases_*n);
|
||||||
std::vector<double> smax(num_phases_*n);
|
std::vector<double> smax(num_phases_*n);
|
||||||
props.satRange(n, &cells[0], &smin[0], &smax[0]);
|
props.satRange(n, &cells[0], &smin[0], &smax[0]);
|
||||||
@ -81,12 +87,14 @@ namespace Opm
|
|||||||
std::vector<double>& faceflux () { return flux_ ; }
|
std::vector<double>& faceflux () { return flux_ ; }
|
||||||
std::vector<double>& surfacevol () { return surfvol_; }
|
std::vector<double>& surfacevol () { return surfvol_; }
|
||||||
std::vector<double>& saturation () { return sat_ ; }
|
std::vector<double>& saturation () { return sat_ ; }
|
||||||
|
std::vector<double>& gasoilratio () { return gor_ ; }
|
||||||
|
|
||||||
const std::vector<double>& pressure () const { return press_ ; }
|
const std::vector<double>& pressure () const { return press_ ; }
|
||||||
const std::vector<double>& facepressure() const { return fpress_; }
|
const std::vector<double>& facepressure() const { return fpress_; }
|
||||||
const std::vector<double>& faceflux () const { return flux_ ; }
|
const std::vector<double>& faceflux () const { return flux_ ; }
|
||||||
const std::vector<double>& surfacevol () const { return surfvol_; }
|
const std::vector<double>& surfacevol () const { return surfvol_; }
|
||||||
const std::vector<double>& saturation () const { return sat_ ; }
|
const std::vector<double>& saturation () const { return sat_ ; }
|
||||||
|
const std::vector<double>& gasoilratio () const { return gor_ ; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int num_phases_;
|
int num_phases_;
|
||||||
@ -95,6 +103,7 @@ namespace Opm
|
|||||||
std::vector<double> flux_ ;
|
std::vector<double> flux_ ;
|
||||||
std::vector<double> surfvol_;
|
std::vector<double> surfvol_;
|
||||||
std::vector<double> sat_ ;
|
std::vector<double> sat_ ;
|
||||||
|
std::vector<double> gor_ ;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
@ -31,27 +31,46 @@ namespace Opm
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Allocate and initialize if wells is non-null.
|
/// Allocate and initialize if wells is non-null.
|
||||||
|
/// Also tries to give useful initial values to the bhp() and
|
||||||
|
/// wellRates() fields, depending on controls. The
|
||||||
|
/// perfRates() field is filled with zero, and perfPress()
|
||||||
|
/// with -1e100.
|
||||||
template <class State>
|
template <class State>
|
||||||
void init(const Wells* wells, const State& state)
|
void init(const Wells* wells, const State& state)
|
||||||
{
|
{
|
||||||
if (wells) {
|
if (wells) {
|
||||||
const int nw = wells->number_of_wells;
|
const int nw = wells->number_of_wells;
|
||||||
|
const int np = wells->number_of_phases;
|
||||||
bhp_.resize(nw);
|
bhp_.resize(nw);
|
||||||
// Initialize bhp to be target pressure
|
wellrates_.resize(nw * np, 0.0);
|
||||||
// if bhp-controlled well, otherwise set
|
|
||||||
// to pressure in first perforation cell.
|
|
||||||
for (int w = 0; w < nw; ++w) {
|
for (int w = 0; w < nw; ++w) {
|
||||||
const WellControls* ctrl = wells->ctrls[w];
|
const WellControls* ctrl = wells->ctrls[w];
|
||||||
|
// Initialize bhp to be target pressure if
|
||||||
|
// bhp-controlled well, otherwise set to a little
|
||||||
|
// above or below (depending on if the well is an
|
||||||
|
// injector or producer) pressure in first perforation
|
||||||
|
// cell.
|
||||||
if ((ctrl->current < 0) || // SHUT
|
if ((ctrl->current < 0) || // SHUT
|
||||||
(ctrl->type[ctrl->current] != BHP)) {
|
(ctrl->type[ctrl->current] != BHP)) {
|
||||||
const int cell = wells->well_cells[wells->well_connpos[w]];
|
const int first_cell = wells->well_cells[wells->well_connpos[w]];
|
||||||
bhp_[w] = state.pressure()[cell];
|
const double safety_factor = (wells->type[w] == INJECTOR) ? 1.01 : 0.99;
|
||||||
}
|
bhp_[w] = safety_factor*state.pressure()[first_cell];
|
||||||
else {
|
} else {
|
||||||
bhp_[w] = ctrl->target[ctrl->current];
|
bhp_[w] = ctrl->target[ctrl->current];
|
||||||
}
|
}
|
||||||
|
// Initialize well rates to match controls if type is SURFACE_RATE
|
||||||
|
if ((ctrl->current >= 0) && // open well
|
||||||
|
(ctrl->type[ctrl->current] == SURFACE_RATE)) {
|
||||||
|
const double rate_target = ctrl->target[ctrl->current];
|
||||||
|
for (int p = 0; p < np; ++p) {
|
||||||
|
const double phase_distr = ctrl->distr[np * ctrl->current + p];
|
||||||
|
wellrates_[np*w + p] = rate_target * phase_distr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The perforation rates and perforation pressures are
|
||||||
|
// not expected to be consistent with bhp_ and wellrates_
|
||||||
|
// after init().
|
||||||
perfrates_.resize(wells->well_connpos[nw], 0.0);
|
perfrates_.resize(wells->well_connpos[nw], 0.0);
|
||||||
perfpress_.resize(wells->well_connpos[nw], -1e100);
|
perfpress_.resize(wells->well_connpos[nw], -1e100);
|
||||||
}
|
}
|
||||||
@ -61,6 +80,10 @@ namespace Opm
|
|||||||
std::vector<double>& bhp() { return bhp_; }
|
std::vector<double>& bhp() { return bhp_; }
|
||||||
const std::vector<double>& bhp() const { return bhp_; }
|
const std::vector<double>& bhp() const { return bhp_; }
|
||||||
|
|
||||||
|
/// One rate per well and phase.
|
||||||
|
std::vector<double>& wellRates() { return wellrates_; }
|
||||||
|
const std::vector<double>& wellRates() const { return wellrates_; }
|
||||||
|
|
||||||
/// One rate per well connection.
|
/// One rate per well connection.
|
||||||
std::vector<double>& perfRates() { return perfrates_; }
|
std::vector<double>& perfRates() { return perfrates_; }
|
||||||
const std::vector<double>& perfRates() const { return perfrates_; }
|
const std::vector<double>& perfRates() const { return perfrates_; }
|
||||||
@ -71,6 +94,7 @@ namespace Opm
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<double> bhp_;
|
std::vector<double> bhp_;
|
||||||
|
std::vector<double> wellrates_;
|
||||||
std::vector<double> perfrates_;
|
std::vector<double> perfrates_;
|
||||||
std::vector<double> perfpress_;
|
std::vector<double> perfpress_;
|
||||||
};
|
};
|
||||||
|
@ -599,6 +599,29 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Initialize a blackoil state from input deck.
|
||||||
|
template <class Props, class State>
|
||||||
|
void initBlackoilStateFromDeck(const UnstructuredGrid& grid,
|
||||||
|
const Props& props,
|
||||||
|
const EclipseGridParser& deck,
|
||||||
|
const double gravity,
|
||||||
|
State& state)
|
||||||
|
{
|
||||||
|
initStateFromDeck(grid, props, deck, gravity, state);
|
||||||
|
initBlackoilSurfvol(grid, props, state);
|
||||||
|
if (deck.hasField("RS")) {
|
||||||
|
const std::vector<double>& rs_deck = deck.getFloatingPointValue("RS");
|
||||||
|
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];
|
||||||
|
state.gasoilratio()[c] = rs_deck[c_deck];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
THROW("Temporarily, we require the RS field.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
|
|
||||||
|
@ -505,13 +505,33 @@ namespace Opm
|
|||||||
int control_pos[5] = { -1, -1, -1, -1, -1 };
|
int control_pos[5] = { -1, -1, -1, -1, -1 };
|
||||||
if (ok && wci_line.surface_flow_max_rate_ >= 0.0) {
|
if (ok && wci_line.surface_flow_max_rate_ >= 0.0) {
|
||||||
control_pos[InjectionControl::RATE] = w_->ctrls[wix]->num;
|
control_pos[InjectionControl::RATE] = w_->ctrls[wix]->num;
|
||||||
const double distr[3] = { 1.0, 1.0, 1.0 };
|
double distr[3] = { 0.0, 0.0, 0.0 };
|
||||||
|
if (wci_line.injector_type_ == "WATER") {
|
||||||
|
distr[pu.phase_pos[BlackoilPhases::Aqua]] = 1.0;
|
||||||
|
} else if (wci_line.injector_type_ == "OIL") {
|
||||||
|
distr[pu.phase_pos[BlackoilPhases::Liquid]] = 1.0;
|
||||||
|
} else if (wci_line.injector_type_ == "GAS") {
|
||||||
|
distr[pu.phase_pos[BlackoilPhases::Vapour]] = 1.0;
|
||||||
|
} else {
|
||||||
|
THROW("Injector type " << wci_line.injector_type_ << " not supported."
|
||||||
|
"WellsManager only supports WATER, OIL and GAS injector types.");
|
||||||
|
}
|
||||||
ok = append_well_controls(SURFACE_RATE, wci_line.surface_flow_max_rate_,
|
ok = append_well_controls(SURFACE_RATE, wci_line.surface_flow_max_rate_,
|
||||||
distr, wix, w_);
|
distr, wix, w_);
|
||||||
}
|
}
|
||||||
if (ok && wci_line.reservoir_flow_max_rate_ >= 0.0) {
|
if (ok && wci_line.reservoir_flow_max_rate_ >= 0.0) {
|
||||||
control_pos[InjectionControl::RESV] = w_->ctrls[wix]->num;
|
control_pos[InjectionControl::RESV] = w_->ctrls[wix]->num;
|
||||||
const double distr[3] = { 1.0, 1.0, 1.0 };
|
double distr[3] = { 0.0, 0.0, 0.0 };
|
||||||
|
if (wci_line.injector_type_ == "WATER") {
|
||||||
|
distr[pu.phase_pos[BlackoilPhases::Aqua]] = 1.0;
|
||||||
|
} else if (wci_line.injector_type_ == "OIL") {
|
||||||
|
distr[pu.phase_pos[BlackoilPhases::Liquid]] = 1.0;
|
||||||
|
} else if (wci_line.injector_type_ == "GAS") {
|
||||||
|
distr[pu.phase_pos[BlackoilPhases::Vapour]] = 1.0;
|
||||||
|
} else {
|
||||||
|
THROW("Injector type " << wci_line.injector_type_ << " not supported."
|
||||||
|
"WellsManager only supports WATER, OIL and GAS injector types.");
|
||||||
|
}
|
||||||
ok = append_well_controls(RESERVOIR_RATE, wci_line.reservoir_flow_max_rate_,
|
ok = append_well_controls(RESERVOIR_RATE, wci_line.reservoir_flow_max_rate_,
|
||||||
distr, wix, w_);
|
distr, wix, w_);
|
||||||
}
|
}
|
||||||
|
44
tests/testFluid.DATA
Normal file
44
tests/testFluid.DATA
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
OIL
|
||||||
|
WATER
|
||||||
|
GAS
|
||||||
|
|
||||||
|
FIELD
|
||||||
|
|
||||||
|
PVTO
|
||||||
|
-- Rs Pbub Bo Vo
|
||||||
|
.0 14.7 1.0000 1.20 /
|
||||||
|
.165 400. 1.0120 1.17 /
|
||||||
|
.335 800. 1.0255 1.14 /
|
||||||
|
.500 1200. 1.0380 1.11 /
|
||||||
|
.665 1600. 1.0510 1.08 /
|
||||||
|
.828 2000. 1.0630 1.06 /
|
||||||
|
.985 2400. 1.0750 1.03 /
|
||||||
|
1.130 2800. 1.0870 1.00 /
|
||||||
|
1.270 3200. 1.0985 .98 /
|
||||||
|
1.390 3600. 1.1100 .95 /
|
||||||
|
1.500 4000. 1.1200 .94
|
||||||
|
5000. 1.1189 .94 /
|
||||||
|
/
|
||||||
|
|
||||||
|
PVDG
|
||||||
|
-- Pg Bg Vg
|
||||||
|
14.7 178.08 .0125
|
||||||
|
400. 5.4777 .0130
|
||||||
|
800. 2.7392 .0135
|
||||||
|
1200. 1.8198 .0140
|
||||||
|
1600. 1.3648 .0145
|
||||||
|
2000. 1.0957 .0150
|
||||||
|
2400. 0.9099 .0155
|
||||||
|
2800. 0.7799 .0160
|
||||||
|
3200. 0.6871 .0165
|
||||||
|
3600. 0.6035 .0170
|
||||||
|
4000. 0.5432 .0175 /
|
||||||
|
|
||||||
|
PVTW
|
||||||
|
--Depth Bw Comp Vw Cv
|
||||||
|
3600. 1.0034 1.0E-6 0.96 0.0 /
|
||||||
|
|
||||||
|
|
||||||
|
DENSITY
|
||||||
|
-- Oil Water Gas
|
||||||
|
44.98 63.01 0.0702 /
|
Loading…
Reference in New Issue
Block a user