mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-12-28 02:00:59 -06:00
compute fluid in place by regions.
This commit is contained in:
parent
28583e4237
commit
056708574c
@ -261,8 +261,10 @@ namespace Opm {
|
||||
const WellModel& wellModel() const { return well_model_; }
|
||||
|
||||
/// Calculate FIP
|
||||
V computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw);
|
||||
std::vector<V>
|
||||
computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw,
|
||||
const std::vector<int>& fipnum);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -2297,36 +2297,45 @@ namespace detail {
|
||||
|
||||
|
||||
template <class Grid, class WellModel, class Implementation>
|
||||
V
|
||||
std::vector<V>
|
||||
BlackoilModelBase<Grid, WellModel, Implementation>::
|
||||
computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw)
|
||||
const WellState& xw,
|
||||
const std::vector<int>& fipnum)
|
||||
{
|
||||
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 int np = x.numPhases();
|
||||
|
||||
SolutionState state(np);
|
||||
const DataBlock s = Eigen::Map<const DataBlock>(& x.saturation()[0], nc, np);
|
||||
state.pressure = ADB::constant(Eigen::Map<const V>(& x.pressure()[0], nc, 1));
|
||||
state.temperature = ADB::constant(Eigen::Map<const V>(& x.temperature()[0], nc, 1));
|
||||
state.saturation[Water] = ADB::constant(s.col(Water));
|
||||
state.saturation[Oil] = ADB::constant(s.col(Oil));
|
||||
state.saturation[Gas] = ADB::constant(s.col(Gas));
|
||||
state.rs = ADB::constant(Eigen::Map<const V>(& x.gasoilratio()[0], nc, 1));
|
||||
state.rv = ADB::constant(Eigen::Map<const V>(& x.rv()[0], nc, 1));
|
||||
state.canonical_phase_pressures = computePressures(state.pressure,
|
||||
state.saturation[Water],
|
||||
state.saturation[Oil],
|
||||
state.saturation[Gas]);
|
||||
|
||||
const Opm::PhaseUsage& pu = fluid_.phaseUsage();
|
||||
|
||||
const std::vector<PhasePresence> cond = phaseCondition();
|
||||
|
||||
const ADB pv_mult = poroMult(press);
|
||||
|
||||
|
||||
const ADB pv_mult = poroMult(state.pressure);
|
||||
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());
|
||||
const auto& b = asImpl().fluidReciprocFVF(phase, state.canonical_phase_pressures[phase], state.temperature, state.rs, state.rv, cond);
|
||||
fip[phase] = ((pv_mult * b * state.saturation[pos] * pv).value());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2338,10 +2347,19 @@ namespace detail {
|
||||
fip[4] = state.rv.value() * fip[pg];
|
||||
}
|
||||
|
||||
V values(5);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
values[i] = int(fip[i].sum());
|
||||
const int dims = *std::max_element(fipnum.begin(), fipnum.end()) + 1;
|
||||
std::vector<V> values(dims, V::Zero(5));
|
||||
|
||||
for (int d = 0; d < dims; ++d) {
|
||||
for (int c = 0; c < nc; ++c) {
|
||||
if (fipnum[c] == d) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
values[d][i] += fip[i][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
|
||||
}
|
||||
|
@ -248,10 +248,12 @@ namespace Opm {
|
||||
|
||||
|
||||
/// Compute fluid in place.
|
||||
V computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw) const
|
||||
std::vector<V>
|
||||
computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw,
|
||||
const std::vector<int>& fipnum) const
|
||||
{
|
||||
return transport_solver_.computeFluidInPlace(x, xw);
|
||||
return transport_solver_.computeFluidInPlace(x, xw, fipnum);
|
||||
}
|
||||
|
||||
|
||||
|
@ -159,10 +159,12 @@ namespace Opm {
|
||||
|
||||
|
||||
|
||||
V computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw)
|
||||
std::vector<V>
|
||||
computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw,
|
||||
const std::vector<int>& fipnum)
|
||||
{
|
||||
return asImpl().computeFluidInPlace(x, xw);
|
||||
return asImpl().computeFluidInPlace(x, xw, fipnum);
|
||||
}
|
||||
|
||||
|
||||
|
@ -126,8 +126,10 @@ namespace Opm {
|
||||
int wellIterationsLastStep() const;
|
||||
|
||||
/// Compute fluid in place.
|
||||
V computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw) const;
|
||||
std::vector<V>
|
||||
computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw,
|
||||
const std::vector<int>& fipnum) const;
|
||||
|
||||
/// Reference to physical model.
|
||||
const PhysicalModel& model() const;
|
||||
|
@ -100,10 +100,12 @@ namespace Opm
|
||||
}
|
||||
|
||||
template <class PhysicalModel>
|
||||
V NonlinearSolver<PhysicalModel>::computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw) const
|
||||
std::vector<V>
|
||||
NonlinearSolver<PhysicalModel>::computeFluidInPlace(const ReservoirState& x,
|
||||
const WellState& xw,
|
||||
const std::vector<int>& fipnum) const
|
||||
{
|
||||
return model_->computeFluidInPlace(x, xw);
|
||||
return model_->computeFluidInPlace(x, xw, fipnum);
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,7 +157,13 @@ namespace Opm
|
||||
const Wells* wells,
|
||||
const BlackoilState& x,
|
||||
WellState& xw);
|
||||
V computeFIP(const ReservoirState& state);
|
||||
|
||||
void
|
||||
FIPUnitConvert(const UnitSystem& units,
|
||||
std::vector<V>& fip);
|
||||
|
||||
V
|
||||
FIPTotals(const std::vector<V>& fip);
|
||||
|
||||
|
||||
void computeWellPotentials(const Wells* wells,
|
||||
|
@ -135,10 +135,13 @@ namespace Opm
|
||||
std::vector<double> well_potentials;
|
||||
DynamicListEconLimited dynamic_list_econ_limited;
|
||||
|
||||
const auto& units = eclipse_state_->getUnits();
|
||||
bool ooip_computed = false;
|
||||
V OOIP;
|
||||
double pv = geo_.poreVolume().sum();
|
||||
std::vector<int> fipnum = eclipse_state_->get3DProperties().getRegions("FIPNUM");
|
||||
if (fipnum.empty()) {
|
||||
fipnum.resize(AutoDiffGrid::numCells(grid_));
|
||||
std::fill(fipnum.begin(), fipnum.end(), 0);
|
||||
}
|
||||
std::vector<V> OOIP;
|
||||
// Main simulation loop.
|
||||
while (!timer.done()) {
|
||||
// Report timestep.
|
||||
@ -189,18 +192,11 @@ namespace Opm
|
||||
|
||||
auto solver = asImpl().createSolver(well_model);
|
||||
|
||||
// Compute FIP;
|
||||
// Compute orignal 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;
|
||||
}
|
||||
OOIP = solver->computeFluidInPlace(state, well_state, fipnum);
|
||||
FIPUnitConvert(eclipse_state_->getUnits(), OOIP);
|
||||
ooip_computed = true;
|
||||
}
|
||||
|
||||
if( terminal_output_ )
|
||||
@ -266,19 +262,17 @@ namespace Opm
|
||||
|
||||
// Report timing.
|
||||
const double st = solver_timer.secsSinceStart();
|
||||
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("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]));
|
||||
// Compute current FIP.
|
||||
std::vector<V> COIP;
|
||||
COIP = solver->computeFluidInPlace(state, well_state, fipnum);
|
||||
FIPUnitConvert(eclipse_state_->getUnits(), COIP);
|
||||
V OOIP_totals = FIPTotals(OOIP);
|
||||
V COIP_totals = FIPTotals(COIP);
|
||||
OpmLog::info("*****************************Field Totals**************************");
|
||||
OpmLog::info(" Liquid VAPOUR Water Free Gas Dissolved Gas");
|
||||
OpmLog::info("Currently in place: " + std::to_string(COIP_totals[1]) + " " + std::to_string(COIP_totals[4]) + " " + std::to_string(COIP_totals[0]) + " " + std::to_string(COIP_totals[2]) + " " + std::to_string(COIP_totals[3]));
|
||||
OpmLog::info("Originally in place: " + std::to_string(OOIP_totals[1]) + " " + std::to_string(OOIP_totals[4]) + " " + std::to_string(OOIP_totals[0]) + " " + std::to_string(OOIP_totals[2]) + " " + std::to_string(OOIP_totals[3]) + "\n");
|
||||
|
||||
// accumulate total time
|
||||
stime += st;
|
||||
|
||||
@ -657,29 +651,38 @@ namespace Opm
|
||||
|
||||
|
||||
template <class Implementation>
|
||||
V SimulatorBase<Implementation>::computeFIP(const ReservoirState& state)
|
||||
void
|
||||
SimulatorBase<Implementation>::FIPUnitConvert(const UnitSystem& units,
|
||||
std::vector<V>& fip)
|
||||
{
|
||||
using namespace Opm::AutoDiffGrid;
|
||||
const int np = state.numPhases();
|
||||
const int nc = numCells(grid_);
|
||||
const Opm::PhaseUsage& pu = props_.phaseUsage();
|
||||
V so = V::Zero(nc);
|
||||
V sw = V::Zero(nc);
|
||||
V sg = V::Zero(nc);
|
||||
for (int c = 0; c < nc; ++c) {
|
||||
so[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Liquid]];
|
||||
sw[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Aqua]];
|
||||
sg[c] = state.saturation()[c*np + pu.phase_pos[BlackoilPhases::Vapour]];
|
||||
if (units.getType() == UnitSystem::UnitType::UNIT_TYPE_FIELD) {
|
||||
for (int i = 0; i < fip.size(); ++i) {
|
||||
fip[i][0] = unit::convert::to(fip[i][0], unit::stb);
|
||||
fip[i][1] = unit::convert::to(fip[i][1], unit::stb);
|
||||
fip[i][2] = unit::convert::to(fip[i][2], 1000*unit::cubic(unit::feet));
|
||||
fip[i][3] = unit::convert::to(fip[i][3], 1000*unit::cubic(unit::feet));
|
||||
fip[i][4] = unit::convert::to(fip[i][4], unit::stb);
|
||||
}
|
||||
}
|
||||
// Get Bo, Bw, Bg.
|
||||
V fip(V::Zero(np));
|
||||
fip[0] = (geo_.poreVolume() * so).sum();
|
||||
fip[1] = (geo_.poreVolume() * sw).sum();
|
||||
fip[2] = (geo_.poreVolume() * sg).sum();
|
||||
return fip;
|
||||
}
|
||||
|
||||
|
||||
template <class Implementation>
|
||||
V
|
||||
SimulatorBase<Implementation>::FIPTotals(const std::vector<V>& fip)
|
||||
{
|
||||
V totals(V::Zero(5));
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
for (size_t reg = 0; reg < fip.size(); ++reg) {
|
||||
totals[i] += fip[reg][i];
|
||||
}
|
||||
}
|
||||
|
||||
return totals;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class Implementation>
|
||||
void
|
||||
SimulatorBase<Implementation>::
|
||||
|
@ -532,11 +532,12 @@ namespace {
|
||||
|
||||
|
||||
|
||||
V
|
||||
std::vector<V>
|
||||
FullyImplicitCompressiblePolymerSolver::computeFluidInPlace(const PolymerBlackoilState& x,
|
||||
const WellStateFullyImplicitBlackoilPolymer& xw)
|
||||
const WellStateFullyImplicitBlackoilPolymer& xw,
|
||||
const std::vector<int>& fipnum)
|
||||
{
|
||||
const SolutionState state = variableState(x, xw);
|
||||
const SolutionState state = constantState(x, xw);
|
||||
const int nc = grid_.number_of_cells;
|
||||
|
||||
const ADB& press = state.pressure;
|
||||
@ -554,12 +555,21 @@ namespace {
|
||||
fip[phase] = (pv_mult * b * sat[phase] * pv).value();
|
||||
}
|
||||
|
||||
V values(5);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
values[i] = fip[i].sum();
|
||||
|
||||
const int dims = *std::max_element(fipnum.begin(), fipnum.end());
|
||||
std::vector<V> values(dims, V::Zero(5));
|
||||
|
||||
for (int d = 0; d < dims; ++d) {
|
||||
for (int c = 0; c < nc; ++c) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (fipnum[c] == d) {
|
||||
values[d][i] += fip[c][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,8 +110,10 @@ namespace Opm {
|
||||
const PolymerBlackoilState& current ) const;
|
||||
|
||||
/// Compute fluid in place.
|
||||
V computeFluidInPlace(const PolymerBlackoilState& x,
|
||||
const WellStateFullyImplicitBlackoilPolymer& xw);
|
||||
std::vector<V>
|
||||
computeFluidInPlace(const PolymerBlackoilState& x,
|
||||
const WellStateFullyImplicitBlackoilPolymer& xw,
|
||||
const std::vector<int>& fipnum);
|
||||
|
||||
private:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user