mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Add computeFluidInPlace function.
This commit is contained in:
committed by
Atgeirr Flø Rasmussen
parent
78a5381f5d
commit
28583e4237
@@ -260,6 +260,10 @@ namespace Opm {
|
|||||||
WellModel& wellModel() { return well_model_; }
|
WellModel& wellModel() { return well_model_; }
|
||||||
const WellModel& wellModel() const { return well_model_; }
|
const WellModel& wellModel() const { return well_model_; }
|
||||||
|
|
||||||
|
/// Calculate FIP
|
||||||
|
V computeFluidInPlace(const ReservoirState& x,
|
||||||
|
const WellState& xw);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// --------- Types and enums ---------
|
// --------- Types and enums ---------
|
||||||
|
|||||||
@@ -2295,6 +2295,57 @@ namespace detail {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class Grid, class WellModel, class Implementation>
|
||||||
|
V
|
||||||
|
BlackoilModelBase<Grid, WellModel, Implementation>::
|
||||||
|
computeFluidInPlace(const ReservoirState& x,
|
||||||
|
const WellState& xw)
|
||||||
|
{
|
||||||
|
SolutionState state = asImpl().variableState(x, xw);
|
||||||
|
const Opm::PhaseUsage& pu = fluid_.phaseUsage();
|
||||||
|
using namespace Opm::AutoDiffGrid;
|
||||||
|
const int nc = numCells(grid_);
|
||||||
|
const ADB& press = state.pressure;
|
||||||
|
const ADB& temp = state.temperature;
|
||||||
|
const std::vector<ADB>& sat = state.saturation;
|
||||||
|
const ADB& rs = state.rs;
|
||||||
|
const ADB& rv = state.rv;
|
||||||
|
|
||||||
|
const std::vector<PhasePresence> cond = phaseCondition();
|
||||||
|
|
||||||
|
const ADB pv_mult = poroMult(press);
|
||||||
|
const V& pv = geo_.poreVolume();
|
||||||
|
const int maxnp = Opm::BlackoilPhases::MaxNumPhases;
|
||||||
|
std::vector<V> fip(5, V::Zero(nc));
|
||||||
|
// std::cout << "Oil sat: \n";
|
||||||
|
//std::cout << sat[pu.phase_pos[Oil]].value() << std::endl;
|
||||||
|
//std::cout << "Gas sat: \n";
|
||||||
|
//std::cout << sat[pu.phase_pos[Gas]].value() << std::endl;
|
||||||
|
for (int phase = 0; phase < maxnp; ++phase) {
|
||||||
|
if (active_[ phase ]) {
|
||||||
|
const int pos = pu.phase_pos[ phase ];
|
||||||
|
const auto& b = asImpl().fluidReciprocFVF(phase, state.canonical_phase_pressures[phase], temp, rs, rv, cond);
|
||||||
|
fip[phase] = ((pv_mult * b * sat[pos] * pv).value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active_[ Oil ] && active_[ Gas ]) {
|
||||||
|
// Account for gas dissolved in oil and vaporized oil
|
||||||
|
const int po = pu.phase_pos[Oil];
|
||||||
|
const int pg = pu.phase_pos[Gas];
|
||||||
|
fip[3] = state.rs.value() * fip[po];
|
||||||
|
fip[4] = state.rv.value() * fip[pg];
|
||||||
|
}
|
||||||
|
|
||||||
|
V values(5);
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
values[i] = int(fip[i].sum());
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
#endif // OPM_BLACKOILMODELBASE_IMPL_HEADER_INCLUDED
|
#endif // OPM_BLACKOILMODELBASE_IMPL_HEADER_INCLUDED
|
||||||
|
|||||||
@@ -247,7 +247,12 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Compute fluid in place.
|
||||||
|
V computeFluidInPlace(const ReservoirState& x,
|
||||||
|
const WellState& xw) const
|
||||||
|
{
|
||||||
|
return transport_solver_.computeFluidInPlace(x, xw);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,11 @@ namespace Opm {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
V computeFluidInPlace(const ReservoirState& x,
|
||||||
|
const WellState& xw)
|
||||||
|
{
|
||||||
|
return asImpl().computeFluidInPlace(x, xw);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -275,6 +280,10 @@ namespace Opm {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void assembleMassBalanceEq(const SolutionState& state)
|
void assembleMassBalanceEq(const SolutionState& state)
|
||||||
{
|
{
|
||||||
// Compute b_p and the accumulation term b_p*s_p for each phase,
|
// Compute b_p and the accumulation term b_p*s_p for each phase,
|
||||||
|
|||||||
@@ -125,6 +125,10 @@ namespace Opm {
|
|||||||
/// Number of well iterations used in all calls to step().
|
/// Number of well iterations used in all calls to step().
|
||||||
int wellIterationsLastStep() const;
|
int wellIterationsLastStep() const;
|
||||||
|
|
||||||
|
/// Compute fluid in place.
|
||||||
|
V computeFluidInPlace(const ReservoirState& x,
|
||||||
|
const WellState& xw) const;
|
||||||
|
|
||||||
/// Reference to physical model.
|
/// Reference to physical model.
|
||||||
const PhysicalModel& model() const;
|
const PhysicalModel& model() const;
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,14 @@ namespace Opm
|
|||||||
return wellIterationsLast_;
|
return wellIterationsLast_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class PhysicalModel>
|
||||||
|
V NonlinearSolver<PhysicalModel>::computeFluidInPlace(const ReservoirState& x,
|
||||||
|
const WellState& xw) const
|
||||||
|
{
|
||||||
|
return model_->computeFluidInPlace(x, xw);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class PhysicalModel>
|
template <class PhysicalModel>
|
||||||
int
|
int
|
||||||
NonlinearSolver<PhysicalModel>::
|
NonlinearSolver<PhysicalModel>::
|
||||||
|
|||||||
@@ -135,12 +135,10 @@ namespace Opm
|
|||||||
std::vector<double> well_potentials;
|
std::vector<double> well_potentials;
|
||||||
DynamicListEconLimited dynamic_list_econ_limited;
|
DynamicListEconLimited dynamic_list_econ_limited;
|
||||||
|
|
||||||
OpmLog::info("PORV: " + std::to_string(unit::convert::to(geo_.poreVolume().sum(), unit::stb)));
|
const auto& units = eclipse_state_->getUnits();
|
||||||
V OOIP = asImpl().computeFIP(state);
|
bool ooip_computed = false;
|
||||||
OOIP[0] = unit::convert::to(OOIP[0], unit::stb);
|
V OOIP;
|
||||||
OOIP[1] = unit::convert::to(OOIP[1], unit::stb);
|
double pv = geo_.poreVolume().sum();
|
||||||
OOIP[2] = unit::convert::to(OOIP[2], 1000*unit::cubic(unit::feet));
|
|
||||||
|
|
||||||
// Main simulation loop.
|
// Main simulation loop.
|
||||||
while (!timer.done()) {
|
while (!timer.done()) {
|
||||||
// Report timestep.
|
// Report timestep.
|
||||||
@@ -191,6 +189,20 @@ namespace Opm
|
|||||||
|
|
||||||
auto solver = asImpl().createSolver(well_model);
|
auto solver = asImpl().createSolver(well_model);
|
||||||
|
|
||||||
|
// Compute FIP;
|
||||||
|
if (!ooip_computed) {
|
||||||
|
OOIP = solver->computeFluidInPlace(state, well_state);
|
||||||
|
if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) {
|
||||||
|
pv = unit::convert::to(pv, unit::stb);
|
||||||
|
OOIP[0] = unit::convert::to(OOIP[0], unit::stb);
|
||||||
|
OOIP[1] = unit::convert::to(OOIP[1], unit::stb);
|
||||||
|
OOIP[2] = unit::convert::to(OOIP[2], 1000*unit::cubic(unit::feet));
|
||||||
|
OOIP[3] = unit::convert::to(OOIP[3], 1000*unit::cubic(unit::feet));
|
||||||
|
OOIP[4] = unit::convert::to(OOIP[4], unit::stb);
|
||||||
|
ooip_computed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( terminal_output_ )
|
if( terminal_output_ )
|
||||||
{
|
{
|
||||||
std::ostringstream step_msg;
|
std::ostringstream step_msg;
|
||||||
@@ -254,15 +266,19 @@ namespace Opm
|
|||||||
|
|
||||||
// Report timing.
|
// Report timing.
|
||||||
const double st = solver_timer.secsSinceStart();
|
const double st = solver_timer.secsSinceStart();
|
||||||
|
V COIP = solver->computeFluidInPlace(state, well_state);
|
||||||
V COIP = asImpl().computeFIP(state);
|
if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) {
|
||||||
COIP[0] = unit::convert::to(COIP[0], unit::stb);
|
COIP[0] = unit::convert::to(COIP[0], unit::stb);
|
||||||
COIP[1] = unit::convert::to(COIP[1], unit::stb);
|
COIP[1] = unit::convert::to(COIP[1], unit::stb);
|
||||||
COIP[2] = unit::convert::to(COIP[2], 1000*unit::cubic(unit::feet));
|
COIP[2] = unit::convert::to(COIP[2], 1000*unit::cubic(unit::feet));
|
||||||
|
COIP[3] = unit::convert::to(COIP[3], 1000*unit::cubic(unit::feet));
|
||||||
|
COIP[4] = unit::convert::to(COIP[4], unit::stb);
|
||||||
|
}
|
||||||
OpmLog::info("*********************Fluid in Place******************");
|
OpmLog::info("*********************Fluid in Place******************");
|
||||||
OpmLog::info("----------Oil--------Wat---------Gas");
|
OpmLog::info("PORV : " + std::to_string(pv));
|
||||||
OpmLog::info("Currently : " + std::to_string(COIP[0]) + " " + std::to_string(COIP[1]) + " " + std::to_string(COIP[2]));
|
OpmLog::info("----------Oil--------VapOil-------Wat---------Gas--------DisGas");
|
||||||
OpmLog::info("Originally: " + std::to_string(OOIP[0]) + " " + std::to_string(OOIP[1]) + " " + std::to_string(OOIP[2]));
|
OpmLog::info("Currently : " + std::to_string(COIP[1]) + " " + std::to_string(COIP[4]) + " " + std::to_string(COIP[0]) + " " + std::to_string(COIP[2]) + " " + std::to_string(COIP[3]));
|
||||||
|
OpmLog::info("Originally: " + std::to_string(OOIP[1]) + " " + std::to_string(OOIP[4]) + " " + std::to_string(OOIP[0]) + " " + std::to_string(OOIP[2]) + " " + std::to_string(OOIP[3]));
|
||||||
// accumulate total time
|
// accumulate total time
|
||||||
stime += st;
|
stime += st;
|
||||||
|
|
||||||
@@ -655,6 +671,7 @@ namespace Opm
|
|||||||
sw[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Aqua]];
|
sw[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Aqua]];
|
||||||
sg[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Vapour]];
|
sg[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Vapour]];
|
||||||
}
|
}
|
||||||
|
// Get Bo, Bw, Bg.
|
||||||
V fip(V::Zero(np));
|
V fip(V::Zero(np));
|
||||||
fip[0] = (geo_.poreVolume() * so).sum();
|
fip[0] = (geo_.poreVolume() * so).sum();
|
||||||
fip[1] = (geo_.poreVolume() * sw).sum();
|
fip[1] = (geo_.poreVolume() * sw).sum();
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
rq_[0].accum[aix] = pv_mult * rq_[0].b * sat[0];
|
rq_[0].accum[aix] = pv_mult * rq_[0].b * sat[0];
|
||||||
rq_[1].accum[aix] = pv_mult * rq_[1].b * sat[1];
|
rq_[1].accum[aix] = pv_mult * rq_[1].b * sat[1];
|
||||||
const ADB cmax = ADB::constant(cmax_, state.concentration.blockPattern());
|
const ADB cmax = ADB::constant(cmax_, state.concentration.blockPattern());
|
||||||
const ADB ads = polymer_props_ad_.adsorption(state.concentration, cmax);
|
const ADB ads = polymer_props_ad_.adsorption(state.concentration, cmax);
|
||||||
const double rho_rock = polymer_props_ad_.rockDensity();
|
const double rho_rock = polymer_props_ad_.rockDensity();
|
||||||
const V phi = Eigen::Map<const V>(&fluid_.porosity()[0], grid_.number_of_cells, 1);
|
const V phi = Eigen::Map<const V>(&fluid_.porosity()[0], grid_.number_of_cells, 1);
|
||||||
@@ -532,6 +532,39 @@ namespace {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
V
|
||||||
|
FullyImplicitCompressiblePolymerSolver::computeFluidInPlace(const PolymerBlackoilState& x,
|
||||||
|
const WellStateFullyImplicitBlackoilPolymer& xw)
|
||||||
|
{
|
||||||
|
const SolutionState state = variableState(x, xw);
|
||||||
|
const int nc = grid_.number_of_cells;
|
||||||
|
|
||||||
|
const ADB& press = state.pressure;
|
||||||
|
const ADB& temp = state.temperature;
|
||||||
|
const std::vector<ADB>& sat = state.saturation;
|
||||||
|
|
||||||
|
const std::vector<PhasePresence> cond = phaseCondition();
|
||||||
|
std::vector<ADB> pressure = computePressures(state);
|
||||||
|
|
||||||
|
const ADB pv_mult = poroMult(press);
|
||||||
|
const V& pv = geo_.poreVolume();
|
||||||
|
std::vector<V> fip(5, V::Zero(nc));
|
||||||
|
for (int phase = 0; phase < 2; ++phase) {
|
||||||
|
const ADB& b = fluidReciprocFVF(phase, pressure[phase], temp, cond, cells_);
|
||||||
|
fip[phase] = (pv_mult * b * sat[phase] * pv).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
V values(5);
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
values[i] = fip[i].sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FullyImplicitCompressiblePolymerSolver::
|
FullyImplicitCompressiblePolymerSolver::
|
||||||
|
|||||||
@@ -54,6 +54,13 @@ namespace Opm {
|
|||||||
class FullyImplicitCompressiblePolymerSolver
|
class FullyImplicitCompressiblePolymerSolver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef AutoDiffBlock<double> ADB;
|
||||||
|
typedef ADB::V V;
|
||||||
|
typedef ADB::M M;
|
||||||
|
typedef Eigen::Array<double,
|
||||||
|
Eigen::Dynamic,
|
||||||
|
Eigen::Dynamic,
|
||||||
|
Eigen::RowMajor> DataBlock;
|
||||||
/// Construct a solver. It will retain references to the
|
/// Construct a solver. It will retain references to the
|
||||||
/// arguments of this functions, and they are expected to
|
/// arguments of this functions, and they are expected to
|
||||||
/// remain in scope for the lifetime of the solver.
|
/// remain in scope for the lifetime of the solver.
|
||||||
@@ -102,14 +109,12 @@ namespace Opm {
|
|||||||
double relativeChange(const PolymerBlackoilState& previous,
|
double relativeChange(const PolymerBlackoilState& previous,
|
||||||
const PolymerBlackoilState& current ) const;
|
const PolymerBlackoilState& current ) const;
|
||||||
|
|
||||||
|
/// Compute fluid in place.
|
||||||
|
V computeFluidInPlace(const PolymerBlackoilState& x,
|
||||||
|
const WellStateFullyImplicitBlackoilPolymer& xw);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef AutoDiffBlock<double> ADB;
|
|
||||||
typedef ADB::V V;
|
|
||||||
typedef ADB::M M;
|
|
||||||
typedef Eigen::Array<double,
|
|
||||||
Eigen::Dynamic,
|
|
||||||
Eigen::Dynamic,
|
|
||||||
Eigen::RowMajor> DataBlock;
|
|
||||||
|
|
||||||
struct ReservoirResidualQuant {
|
struct ReservoirResidualQuant {
|
||||||
ReservoirResidualQuant();
|
ReservoirResidualQuant();
|
||||||
|
|||||||
Reference in New Issue
Block a user