mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-25 10:40:21 -06:00
Add computeFluidInPlace function.
This commit is contained in:
parent
78a5381f5d
commit
28583e4237
@ -260,6 +260,10 @@ namespace Opm {
|
||||
WellModel& wellModel() { return well_model_; }
|
||||
const WellModel& wellModel() const { return well_model_; }
|
||||
|
||||
/// Calculate FIP
|
||||
V computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw);
|
||||
|
||||
protected:
|
||||
|
||||
// --------- 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
|
||||
|
||||
#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)
|
||||
{
|
||||
// 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().
|
||||
int wellIterationsLastStep() const;
|
||||
|
||||
/// Compute fluid in place.
|
||||
V computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw) const;
|
||||
|
||||
/// Reference to physical model.
|
||||
const PhysicalModel& model() const;
|
||||
|
||||
|
@ -99,6 +99,14 @@ namespace Opm
|
||||
return wellIterationsLast_;
|
||||
}
|
||||
|
||||
template <class PhysicalModel>
|
||||
V NonlinearSolver<PhysicalModel>::computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw) const
|
||||
{
|
||||
return model_->computeFluidInPlace(x, xw);
|
||||
}
|
||||
|
||||
|
||||
template <class PhysicalModel>
|
||||
int
|
||||
NonlinearSolver<PhysicalModel>::
|
||||
|
@ -135,12 +135,10 @@ namespace Opm
|
||||
std::vector<double> well_potentials;
|
||||
DynamicListEconLimited dynamic_list_econ_limited;
|
||||
|
||||
OpmLog::info("PORV: " + std::to_string(unit::convert::to(geo_.poreVolume().sum(), unit::stb)));
|
||||
V OOIP = asImpl().computeFIP(state);
|
||||
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));
|
||||
|
||||
const auto& units = eclipse_state_->getUnits();
|
||||
bool ooip_computed = false;
|
||||
V OOIP;
|
||||
double pv = geo_.poreVolume().sum();
|
||||
// Main simulation loop.
|
||||
while (!timer.done()) {
|
||||
// Report timestep.
|
||||
@ -191,6 +189,20 @@ namespace Opm
|
||||
|
||||
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_ )
|
||||
{
|
||||
std::ostringstream step_msg;
|
||||
@ -254,15 +266,19 @@ namespace Opm
|
||||
|
||||
// Report timing.
|
||||
const double st = solver_timer.secsSinceStart();
|
||||
|
||||
V COIP = asImpl().computeFIP(state);
|
||||
COIP[0] = unit::convert::to(COIP[0], unit::stb);
|
||||
COIP[1] = unit::convert::to(COIP[1], unit::stb);
|
||||
COIP[2] = unit::convert::to(COIP[2], 1000*unit::cubic(unit::feet));
|
||||
V COIP = solver->computeFluidInPlace(state, well_state);
|
||||
if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) {
|
||||
COIP[0] = unit::convert::to(COIP[0], unit::stb);
|
||||
COIP[1] = unit::convert::to(COIP[1], unit::stb);
|
||||
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("----------Oil--------Wat---------Gas");
|
||||
OpmLog::info("Currently : " + std::to_string(COIP[0]) + " " + std::to_string(COIP[1]) + " " + std::to_string(COIP[2]));
|
||||
OpmLog::info("Originally: " + std::to_string(OOIP[0]) + " " + std::to_string(OOIP[1]) + " " + std::to_string(OOIP[2]));
|
||||
OpmLog::info("PORV : " + std::to_string(pv));
|
||||
OpmLog::info("----------Oil--------VapOil-------Wat---------Gas--------DisGas");
|
||||
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
|
||||
stime += st;
|
||||
|
||||
@ -655,6 +671,7 @@ namespace Opm
|
||||
sw[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Aqua]];
|
||||
sg[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Vapour]];
|
||||
}
|
||||
// Get Bo, Bw, Bg.
|
||||
V fip(V::Zero(np));
|
||||
fip[0] = (geo_.poreVolume() * so).sum();
|
||||
fip[1] = (geo_.poreVolume() * sw).sum();
|
||||
|
@ -520,7 +520,7 @@ namespace {
|
||||
}
|
||||
rq_[0].accum[aix] = pv_mult * rq_[0].b * sat[0];
|
||||
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 double rho_rock = polymer_props_ad_.rockDensity();
|
||||
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
|
||||
FullyImplicitCompressiblePolymerSolver::
|
||||
|
@ -54,6 +54,13 @@ namespace Opm {
|
||||
class FullyImplicitCompressiblePolymerSolver
|
||||
{
|
||||
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
|
||||
/// arguments of this functions, and they are expected to
|
||||
/// remain in scope for the lifetime of the solver.
|
||||
@ -102,14 +109,12 @@ namespace Opm {
|
||||
double relativeChange(const PolymerBlackoilState& previous,
|
||||
const PolymerBlackoilState& current ) const;
|
||||
|
||||
/// Compute fluid in place.
|
||||
V computeFluidInPlace(const PolymerBlackoilState& x,
|
||||
const WellStateFullyImplicitBlackoilPolymer& xw);
|
||||
|
||||
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 {
|
||||
ReservoirResidualQuant();
|
||||
|
Loading…
Reference in New Issue
Block a user