mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #3 from atgeirr/master
Use transport source term properly in compressible sim.
This commit is contained in:
commit
ec427e914d
@ -270,10 +270,10 @@ namespace Opm
|
|||||||
Opm::time::StopWatch total_timer;
|
Opm::time::StopWatch total_timer;
|
||||||
total_timer.start();
|
total_timer.start();
|
||||||
double init_surfvol[2] = { 0.0 };
|
double init_surfvol[2] = { 0.0 };
|
||||||
double init_polymass = 0.0;
|
|
||||||
double inplace_surfvol[2] = { 0.0 };
|
double inplace_surfvol[2] = { 0.0 };
|
||||||
double polymass = 0.0;
|
double polymass = computePolymerMass(porevol, state.saturation(), state.concentration(), poly_props_.deadPoreVol());
|
||||||
double polymass_adsorbed = 0.0;
|
double polymass_adsorbed = computePolymerAdsorbed(grid_, props_, poly_props_, state, rock_comp_props_);
|
||||||
|
double init_polymass = polymass + polymass_adsorbed;
|
||||||
double tot_injected[2] = { 0.0 };
|
double tot_injected[2] = { 0.0 };
|
||||||
double tot_produced[2] = { 0.0 };
|
double tot_produced[2] = { 0.0 };
|
||||||
double tot_polyinj = 0.0;
|
double tot_polyinj = 0.0;
|
||||||
@ -318,8 +318,7 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process transport sources (to include bdy terms and well flows).
|
// Process transport sources (to include bdy terms and well flows).
|
||||||
Opm::computeTransportSource(grid_, src_, state.faceflux(), 1.0,
|
Opm::computeTransportSource(props_, wells_, well_state, transport_src);
|
||||||
wells_, well_state.perfRates(), transport_src);
|
|
||||||
|
|
||||||
// Find inflow rate.
|
// Find inflow rate.
|
||||||
const double current_time = timer.currentTime();
|
const double current_time = timer.currentTime();
|
||||||
@ -347,8 +346,7 @@ namespace Opm
|
|||||||
double substep_polyinj = 0.0;
|
double substep_polyinj = 0.0;
|
||||||
double substep_polyprod = 0.0;
|
double substep_polyprod = 0.0;
|
||||||
Opm::computeInjectedProduced(props_, poly_props_,
|
Opm::computeInjectedProduced(props_, poly_props_,
|
||||||
state.pressure(), state.surfacevol(), state.saturation(),
|
state,
|
||||||
state.concentration(), state.maxconcentration(),
|
|
||||||
transport_src, polymer_inflow_c, stepsize,
|
transport_src, polymer_inflow_c, stepsize,
|
||||||
substep_injected, substep_produced,
|
substep_injected, substep_produced,
|
||||||
substep_polyinj, substep_polyprod);
|
substep_polyinj, substep_polyprod);
|
||||||
|
@ -264,10 +264,10 @@ namespace Opm
|
|||||||
Opm::time::StopWatch total_timer;
|
Opm::time::StopWatch total_timer;
|
||||||
total_timer.start();
|
total_timer.start();
|
||||||
double init_satvol[2] = { 0.0 };
|
double init_satvol[2] = { 0.0 };
|
||||||
double init_polymass = 0.0;
|
|
||||||
double satvol[2] = { 0.0 };
|
double satvol[2] = { 0.0 };
|
||||||
double polymass = 0.0;
|
double polymass = computePolymerMass(porevol, state.saturation(), state.concentration(), poly_props_.deadPoreVol());
|
||||||
double polymass_adsorbed = 0.0;
|
double polymass_adsorbed = computePolymerAdsorbed(props_, poly_props_, porevol, state.maxconcentration());
|
||||||
|
double init_polymass = polymass + polymass_adsorbed;
|
||||||
double injected[2] = { 0.0 };
|
double injected[2] = { 0.0 };
|
||||||
double produced[2] = { 0.0 };
|
double produced[2] = { 0.0 };
|
||||||
double polyinj = 0.0;
|
double polyinj = 0.0;
|
||||||
@ -337,7 +337,7 @@ namespace Opm
|
|||||||
tsolver_.solve(&state.faceflux()[0], &porevol[0], &transport_src[0], &polymer_inflow_c[0], stepsize,
|
tsolver_.solve(&state.faceflux()[0], &porevol[0], &transport_src[0], &polymer_inflow_c[0], stepsize,
|
||||||
state.saturation(), state.concentration(), state.maxconcentration());
|
state.saturation(), state.concentration(), state.maxconcentration());
|
||||||
Opm::computeInjectedProduced(props_, poly_props_,
|
Opm::computeInjectedProduced(props_, poly_props_,
|
||||||
state.saturation(), state.concentration(), state.maxconcentration(),
|
state,
|
||||||
transport_src, polymer_inflow_c, stepsize,
|
transport_src, polymer_inflow_c, stepsize,
|
||||||
substep_injected, substep_produced, substep_polyinj, substep_polyprod);
|
substep_injected, substep_produced, substep_polyinj, substep_polyprod);
|
||||||
injected[0] += substep_injected[0];
|
injected[0] += substep_injected[0];
|
||||||
|
@ -363,8 +363,7 @@ namespace Opm
|
|||||||
bool src_is_inflow = src_flux < 0.0;
|
bool src_is_inflow = src_flux < 0.0;
|
||||||
B_cell0 = 1.0/tm.A0_[np*np*cell + 0];
|
B_cell0 = 1.0/tm.A0_[np*np*cell + 0];
|
||||||
B_cell = 1.0/tm.A_[np*np*cell + 0];
|
B_cell = 1.0/tm.A_[np*np*cell + 0];
|
||||||
// influx = src_is_inflow ? B_cell*src_flux : 0.0; // Use this after changing transport source.
|
influx = src_is_inflow ? B_cell*src_flux : 0.0;
|
||||||
influx = src_is_inflow ? src_flux : 0.0;
|
|
||||||
outflux = !src_is_inflow ? src_flux : 0.0;
|
outflux = !src_is_inflow ? src_flux : 0.0;
|
||||||
porevolume0 = tm.porevolume0_[cell];
|
porevolume0 = tm.porevolume0_[cell];
|
||||||
porevolume = tm.porevolume_[cell];
|
porevolume = tm.porevolume_[cell];
|
||||||
|
@ -99,10 +99,9 @@ namespace Opm
|
|||||||
/// gives the mobilities used for the preceding timestep.
|
/// gives the mobilities used for the preceding timestep.
|
||||||
/// @param[in] props fluid and rock properties.
|
/// @param[in] props fluid and rock properties.
|
||||||
/// @param[in] polyprops polymer properties
|
/// @param[in] polyprops polymer properties
|
||||||
/// @param[in] s saturation values (for all P phases)
|
/// @param[in] state state variables (pressure, fluxes etc.)
|
||||||
/// @param[in] c polymer concentration
|
/// @param[in] src if < 0: total reservoir volume outflow,
|
||||||
/// @param[in] cmax polymer maximum concentration
|
/// if > 0: first phase reservoir volume inflow.
|
||||||
/// @param[in] src if < 0: total outflow, if > 0: first phase inflow.
|
|
||||||
/// @param[in] inj_c injected concentration by cell
|
/// @param[in] inj_c injected concentration by cell
|
||||||
/// @param[in] dt timestep used
|
/// @param[in] dt timestep used
|
||||||
/// @param[out] injected must point to a valid array with P elements,
|
/// @param[out] injected must point to a valid array with P elements,
|
||||||
@ -112,22 +111,27 @@ namespace Opm
|
|||||||
/// @param[out] polyprod produced mass of polymer
|
/// @param[out] polyprod produced mass of polymer
|
||||||
void computeInjectedProduced(const IncompPropertiesInterface& props,
|
void computeInjectedProduced(const IncompPropertiesInterface& props,
|
||||||
const Opm::PolymerProperties& polyprops,
|
const Opm::PolymerProperties& polyprops,
|
||||||
const std::vector<double>& s,
|
const PolymerState& state,
|
||||||
const std::vector<double>& c,
|
const std::vector<double>& transport_src,
|
||||||
const std::vector<double>& cmax,
|
const std::vector<double>& inj_c,
|
||||||
const std::vector<double>& src,
|
|
||||||
const std::vector<double>& inj_c,
|
|
||||||
const double dt,
|
const double dt,
|
||||||
double* injected,
|
double* injected,
|
||||||
double* produced,
|
double* produced,
|
||||||
double& polyinj,
|
double& polyinj,
|
||||||
double& polyprod)
|
double& polyprod)
|
||||||
{
|
{
|
||||||
const int num_cells = src.size();
|
|
||||||
const int np = s.size()/src.size();
|
const int num_cells = transport_src.size();
|
||||||
if (int(s.size()) != num_cells*np) {
|
if (props.numCells() != num_cells) {
|
||||||
THROW("Sizes of s and src vectors do not match.");
|
THROW("Size of transport_src vector does not match number of cells in props.");
|
||||||
}
|
}
|
||||||
|
const int np = props.numPhases();
|
||||||
|
if (int(state.saturation().size()) != num_cells*np) {
|
||||||
|
THROW("Sizes of state vectors do not match number of cells.");
|
||||||
|
}
|
||||||
|
const std::vector<double>& s = state.saturation();
|
||||||
|
const std::vector<double>& c = state.concentration();
|
||||||
|
const std::vector<double>& cmax = state.maxconcentration();
|
||||||
std::fill(injected, injected + np, 0.0);
|
std::fill(injected, injected + np, 0.0);
|
||||||
std::fill(produced, produced + np, 0.0);
|
std::fill(produced, produced + np, 0.0);
|
||||||
polyinj = 0.0;
|
polyinj = 0.0;
|
||||||
@ -137,11 +141,11 @@ namespace Opm
|
|||||||
double mob[2];
|
double mob[2];
|
||||||
double mc;
|
double mc;
|
||||||
for (int cell = 0; cell < num_cells; ++cell) {
|
for (int cell = 0; cell < num_cells; ++cell) {
|
||||||
if (src[cell] > 0.0) {
|
if (transport_src[cell] > 0.0) {
|
||||||
injected[0] += src[cell]*dt;
|
injected[0] += transport_src[cell]*dt;
|
||||||
polyinj += src[cell]*dt*inj_c[cell];
|
polyinj += transport_src[cell]*dt*inj_c[cell];
|
||||||
} else if (src[cell] < 0.0) {
|
} else if (transport_src[cell] < 0.0) {
|
||||||
const double flux = -src[cell]*dt;
|
const double flux = -transport_src[cell]*dt;
|
||||||
const double* sat = &s[np*cell];
|
const double* sat = &s[np*cell];
|
||||||
props.relperm(1, sat, &cell, &kr_cell[0], 0);
|
props.relperm(1, sat, &cell, &kr_cell[0], 0);
|
||||||
polyprops.effectiveMobilities(c[cell], cmax[cell], visc,
|
polyprops.effectiveMobilities(c[cell], cmax[cell], visc,
|
||||||
@ -164,27 +168,20 @@ namespace Opm
|
|||||||
/// gives the mobilities used for the preceding timestep.
|
/// gives the mobilities used for the preceding timestep.
|
||||||
/// @param[in] props fluid and rock properties.
|
/// @param[in] props fluid and rock properties.
|
||||||
/// @param[in] polyprops polymer properties
|
/// @param[in] polyprops polymer properties
|
||||||
/// @param[in] press pressure (one value per cell)
|
/// @param[in] state state variables (pressure, fluxes etc.)
|
||||||
/// @param[in] z surface-volume values (for all P phases)
|
/// @param[in] transport_src if < 0: total reservoir volume outflow,
|
||||||
/// @param[in] s saturation values (for all P phases)
|
/// if > 0: first phase *surface volume* inflow.
|
||||||
/// @param[in] c polymer concentration
|
|
||||||
/// @param[in] cmax polymer maximum concentration
|
|
||||||
/// @param[in] src if < 0: total outflow, if > 0: first phase inflow.
|
|
||||||
/// @param[in] inj_c injected concentration by cell
|
/// @param[in] inj_c injected concentration by cell
|
||||||
/// @param[in] dt timestep used
|
/// @param[in] dt timestep used
|
||||||
/// @param[out] injected must point to a valid array with P elements,
|
/// @param[out] injected must point to a valid array with P elements,
|
||||||
/// where P = s.size()/src.size().
|
/// where P = s.size()/transport_src.size().
|
||||||
/// @param[out] produced must also point to a valid array with P elements.
|
/// @param[out] produced must also point to a valid array with P elements.
|
||||||
/// @param[out] polyinj injected mass of polymer
|
/// @param[out] polyinj injected mass of polymer
|
||||||
/// @param[out] polyprod produced mass of polymer
|
/// @param[out] polyprod produced mass of polymer
|
||||||
void computeInjectedProduced(const BlackoilPropertiesInterface& props,
|
void computeInjectedProduced(const BlackoilPropertiesInterface& props,
|
||||||
const Opm::PolymerProperties& polyprops,
|
const Opm::PolymerProperties& polyprops,
|
||||||
const std::vector<double>& press,
|
const PolymerBlackoilState& state,
|
||||||
const std::vector<double>& z,
|
const std::vector<double>& transport_src,
|
||||||
const std::vector<double>& s,
|
|
||||||
const std::vector<double>& c,
|
|
||||||
const std::vector<double>& cmax,
|
|
||||||
const std::vector<double>& src,
|
|
||||||
const std::vector<double>& inj_c,
|
const std::vector<double>& inj_c,
|
||||||
const double dt,
|
const double dt,
|
||||||
double* injected,
|
double* injected,
|
||||||
@ -192,11 +189,19 @@ namespace Opm
|
|||||||
double& polyinj,
|
double& polyinj,
|
||||||
double& polyprod)
|
double& polyprod)
|
||||||
{
|
{
|
||||||
const int num_cells = src.size();
|
const int num_cells = transport_src.size();
|
||||||
const int np = s.size()/src.size();
|
if (props.numCells() != num_cells) {
|
||||||
if (int(s.size()) != num_cells*np) {
|
THROW("Size of transport_src vector does not match number of cells in props.");
|
||||||
THROW("Sizes of s and src vectors do not match.");
|
|
||||||
}
|
}
|
||||||
|
const int np = props.numPhases();
|
||||||
|
if (int(state.saturation().size()) != num_cells*np) {
|
||||||
|
THROW("Sizes of state vectors do not match number of cells.");
|
||||||
|
}
|
||||||
|
const std::vector<double>& press = state.pressure();
|
||||||
|
const std::vector<double>& s = state.saturation();
|
||||||
|
const std::vector<double>& z = state.surfacevol();
|
||||||
|
const std::vector<double>& c = state.concentration();
|
||||||
|
const std::vector<double>& cmax = state.maxconcentration();
|
||||||
std::fill(injected, injected + np, 0.0);
|
std::fill(injected, injected + np, 0.0);
|
||||||
std::fill(produced, produced + np, 0.0);
|
std::fill(produced, produced + np, 0.0);
|
||||||
polyinj = 0.0;
|
polyinj = 0.0;
|
||||||
@ -204,27 +209,42 @@ namespace Opm
|
|||||||
std::vector<double> visc(np);
|
std::vector<double> visc(np);
|
||||||
std::vector<double> kr_cell(np);
|
std::vector<double> kr_cell(np);
|
||||||
std::vector<double> mob(np);
|
std::vector<double> mob(np);
|
||||||
|
std::vector<double> A(np*np);
|
||||||
|
std::vector<double> prod_resv_phase(np);
|
||||||
|
std::vector<double> prod_surfvol(np);
|
||||||
double mc;
|
double mc;
|
||||||
for (int cell = 0; cell < num_cells; ++cell) {
|
for (int cell = 0; cell < num_cells; ++cell) {
|
||||||
if (src[cell] > 0.0) {
|
if (transport_src[cell] > 0.0) {
|
||||||
injected[0] += src[cell]*dt;
|
// Inflowing transport source is a surface volume flux
|
||||||
polyinj += src[cell]*dt*inj_c[cell];
|
// for the first phase.
|
||||||
} else if (src[cell] < 0.0) {
|
injected[0] += transport_src[cell]*dt;
|
||||||
const double flux = -src[cell]*dt;
|
polyinj += transport_src[cell]*dt*inj_c[cell];
|
||||||
|
} else if (transport_src[cell] < 0.0) {
|
||||||
|
// Outflowing transport source is a total reservoir
|
||||||
|
// volume flux.
|
||||||
|
const double flux = -transport_src[cell]*dt;
|
||||||
const double* sat = &s[np*cell];
|
const double* sat = &s[np*cell];
|
||||||
props.relperm(1, sat, &cell, &kr_cell[0], 0);
|
props.relperm(1, sat, &cell, &kr_cell[0], 0);
|
||||||
props.viscosity(1, &press[cell], &z[np*cell], &cell, &visc[0], 0);
|
props.viscosity(1, &press[cell], &z[np*cell], &cell, &visc[0], 0);
|
||||||
|
props.matrix(1, &press[cell], &z[np*cell], &cell, &A[0], 0);
|
||||||
polyprops.effectiveMobilities(c[cell], cmax[cell], &visc[0],
|
polyprops.effectiveMobilities(c[cell], cmax[cell], &visc[0],
|
||||||
&kr_cell[0], &mob[0]);
|
&kr_cell[0], &mob[0]);
|
||||||
double totmob = 0.0;
|
double totmob = 0.0;
|
||||||
for (int p = 0; p < np; ++p) {
|
for (int p = 0; p < np; ++p) {
|
||||||
totmob += mob[p];
|
totmob += mob[p];
|
||||||
}
|
}
|
||||||
|
std::fill(prod_surfvol.begin(), prod_surfvol.end(), 0.0);
|
||||||
for (int p = 0; p < np; ++p) {
|
for (int p = 0; p < np; ++p) {
|
||||||
produced[p] += (mob[p]/totmob)*flux;
|
prod_resv_phase[p] = (mob[p]/totmob)*flux;
|
||||||
|
for (int q = 0; q < np; ++q) {
|
||||||
|
prod_surfvol[q] += prod_resv_phase[p]*A[q + np*p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int p = 0; p < np; ++p) {
|
||||||
|
produced[p] += prod_surfvol[p];
|
||||||
}
|
}
|
||||||
polyprops.computeMc(c[cell], mc);
|
polyprops.computeMc(c[cell], mc);
|
||||||
polyprod += (mob[0]/totmob)*flux*mc;
|
polyprod += produced[0]*mc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <opm/core/fluid/IncompPropertiesInterface.hpp>
|
#include <opm/core/fluid/IncompPropertiesInterface.hpp>
|
||||||
#include <opm/core/fluid/BlackoilPropertiesInterface.hpp>
|
#include <opm/core/fluid/BlackoilPropertiesInterface.hpp>
|
||||||
#include <opm/polymer/PolymerProperties.hpp>
|
#include <opm/polymer/PolymerProperties.hpp>
|
||||||
|
#include <opm/polymer/PolymerState.hpp>
|
||||||
#include <opm/polymer/PolymerBlackoilState.hpp>
|
#include <opm/polymer/PolymerBlackoilState.hpp>
|
||||||
#include <opm/core/fluid/RockCompressibility.hpp>
|
#include <opm/core/fluid/RockCompressibility.hpp>
|
||||||
#include <opm/core/utility/SparseVector.hpp>
|
#include <opm/core/utility/SparseVector.hpp>
|
||||||
@ -75,9 +76,9 @@ namespace Opm
|
|||||||
/// gives the mobilities used for the preceding timestep.
|
/// gives the mobilities used for the preceding timestep.
|
||||||
/// @param[in] props fluid and rock properties.
|
/// @param[in] props fluid and rock properties.
|
||||||
/// @param[in] polyprops polymer properties
|
/// @param[in] polyprops polymer properties
|
||||||
/// @param[in] s saturation values (for all P phases)
|
/// @param[in] state state variables (pressure, fluxes etc.)
|
||||||
/// @param[in] c polymer concentration
|
/// @param[in] src if < 0: total reservoir volume outflow,
|
||||||
/// @param[in] src if < 0: total outflow, if > 0: first phase inflow.
|
/// if > 0: first phase reservoir volume inflow.
|
||||||
/// @param[in] inj_c injected concentration by cell
|
/// @param[in] inj_c injected concentration by cell
|
||||||
/// @param[in] dt timestep used
|
/// @param[in] dt timestep used
|
||||||
/// @param[out] injected must point to a valid array with P elements,
|
/// @param[out] injected must point to a valid array with P elements,
|
||||||
@ -87,10 +88,8 @@ namespace Opm
|
|||||||
/// @param[out] polyprod produced mass of polymer
|
/// @param[out] polyprod produced mass of polymer
|
||||||
void computeInjectedProduced(const IncompPropertiesInterface& props,
|
void computeInjectedProduced(const IncompPropertiesInterface& props,
|
||||||
const Opm::PolymerProperties& polyprops,
|
const Opm::PolymerProperties& polyprops,
|
||||||
const std::vector<double>& s,
|
const PolymerState& state,
|
||||||
const std::vector<double>& c,
|
const std::vector<double>& transport_src,
|
||||||
const std::vector<double>& cmax,
|
|
||||||
const std::vector<double>& src,
|
|
||||||
const std::vector<double>& inj_c,
|
const std::vector<double>& inj_c,
|
||||||
const double dt,
|
const double dt,
|
||||||
double* injected,
|
double* injected,
|
||||||
@ -106,29 +105,20 @@ namespace Opm
|
|||||||
/// gives the mobilities used for the preceding timestep.
|
/// gives the mobilities used for the preceding timestep.
|
||||||
/// @param[in] props fluid and rock properties.
|
/// @param[in] props fluid and rock properties.
|
||||||
/// @param[in] polyprops polymer properties
|
/// @param[in] polyprops polymer properties
|
||||||
/// @param[in] press pressure (one value per cell)
|
/// @param[in] state state variables (pressure, fluxes etc.)
|
||||||
/// @param[in] z surface-volume values (for all P phases)
|
/// @param[in] src if < 0: total reservoir volume outflow,
|
||||||
/// @param[in] s saturation values (for all P phases)
|
/// if > 0: first phase *surface volume* inflow.
|
||||||
/// @param[in] c polymer concentration
|
|
||||||
/// @param[in] cmax polymer maximum concentration
|
|
||||||
/// @param[in] src if < 0: total outflow, if > 0: first phase inflow.
|
|
||||||
/// @param[in] inj_c injected concentration by cell
|
/// @param[in] inj_c injected concentration by cell
|
||||||
/// @param[in] dt timestep used
|
/// @param[in] dt timestep used
|
||||||
///
|
|
||||||
/// @param[out] injected must point to a valid array with P elements,
|
/// @param[out] injected must point to a valid array with P elements,
|
||||||
/// where P = s.size()/src.size().
|
/// where P = s.size()/src.size().
|
||||||
/// @param[out] produced must also point to a valid array with P elements.
|
/// @param[out] produced must also point to a valid array with P elements.
|
||||||
/// @param[out] polyinj injected mass of polymer
|
/// @param[out] polyinj injected mass of polymer
|
||||||
/// @param[out] polyprod produced mass of polymer
|
/// @param[out] polyprod produced mass of polymer
|
||||||
|
|
||||||
void computeInjectedProduced(const BlackoilPropertiesInterface& props,
|
void computeInjectedProduced(const BlackoilPropertiesInterface& props,
|
||||||
const Opm::PolymerProperties& polyprops,
|
const Opm::PolymerProperties& polyprops,
|
||||||
const std::vector<double>& press,
|
const PolymerBlackoilState& state,
|
||||||
const std::vector<double>& z,
|
const std::vector<double>& transport_src,
|
||||||
const std::vector<double>& s,
|
|
||||||
const std::vector<double>& c,
|
|
||||||
const std::vector<double>& cmax,
|
|
||||||
const std::vector<double>& src,
|
|
||||||
const std::vector<double>& inj_c,
|
const std::vector<double>& inj_c,
|
||||||
const double dt,
|
const double dt,
|
||||||
double* injected,
|
double* injected,
|
||||||
|
Loading…
Reference in New Issue
Block a user