mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Work in progress on well flux equations.
This commit is contained in:
parent
74a5e10f7b
commit
765ce23c3e
@ -198,7 +198,7 @@ namespace Opm {
|
|||||||
, rq_ (fluid.numPhases())
|
, rq_ (fluid.numPhases())
|
||||||
, residual_ ( { std::vector<ADB>(fluid.numPhases(), ADB::null()),
|
, residual_ ( { std::vector<ADB>(fluid.numPhases(), ADB::null()),
|
||||||
ADB::null(),
|
ADB::null(),
|
||||||
std::vector<ADB>(fluid.numPhases(), ADB::null()),
|
ADB::null(),
|
||||||
ADB::null() } )
|
ADB::null() } )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -275,6 +275,7 @@ namespace Opm {
|
|||||||
: pressure ( ADB::null())
|
: pressure ( ADB::null())
|
||||||
, saturation(np, ADB::null())
|
, saturation(np, ADB::null())
|
||||||
, rs ( ADB::null())
|
, rs ( ADB::null())
|
||||||
|
, qs ( ADB::null())
|
||||||
, bhp ( ADB::null())
|
, bhp ( ADB::null())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -326,6 +327,7 @@ namespace Opm {
|
|||||||
// water saturation (if water present)
|
// water saturation (if water present)
|
||||||
// gas saturation (if gas present)
|
// gas saturation (if gas present)
|
||||||
// gas solution factor (if both gas and oil present)
|
// gas solution factor (if both gas and oil present)
|
||||||
|
// well rates per active phase and well
|
||||||
// well bottom-hole pressure
|
// well bottom-hole pressure
|
||||||
// Note that oil is assumed to always be present, but is never
|
// Note that oil is assumed to always be present, but is never
|
||||||
// a primary variable.
|
// a primary variable.
|
||||||
@ -335,6 +337,7 @@ namespace Opm {
|
|||||||
if (gasandoil) {
|
if (gasandoil) {
|
||||||
bpat.push_back(nc);
|
bpat.push_back(nc);
|
||||||
}
|
}
|
||||||
|
bpat.push_back(xw.bhp().size() * np);
|
||||||
bpat.push_back(xw.bhp().size());
|
bpat.push_back(xw.bhp().size());
|
||||||
|
|
||||||
SolutionState state(np);
|
SolutionState state(np);
|
||||||
@ -379,6 +382,11 @@ namespace Opm {
|
|||||||
state.rs = ADB::constant(Rs, bpat);
|
state.rs = ADB::constant(Rs, bpat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Well rates.
|
||||||
|
assert (not xw.wellRates().empty());
|
||||||
|
const V qs = Eigen::Map<const V>(& xw.wellRates()[0], xw.wellRates().size());
|
||||||
|
state.qs = ADB::constant(qs, bpat);
|
||||||
|
|
||||||
// Well bottom-hole pressure.
|
// Well bottom-hole pressure.
|
||||||
assert (not xw.bhp().empty());
|
assert (not xw.bhp().empty());
|
||||||
const V bhp = Eigen::Map<const V>(& xw.bhp()[0], xw.bhp().size());
|
const V bhp = Eigen::Map<const V>(& xw.bhp()[0], xw.bhp().size());
|
||||||
@ -427,6 +435,11 @@ namespace Opm {
|
|||||||
vars0.push_back(rs);
|
vars0.push_back(rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initial well rates.
|
||||||
|
assert (not xw.wellRates().empty());
|
||||||
|
const V qs = Eigen::Map<const V>(& xw.wellRates()[0], xw.wellRates().size());
|
||||||
|
vars0.push_back(qs);
|
||||||
|
|
||||||
// Initial well bottom-hole pressure.
|
// Initial well bottom-hole pressure.
|
||||||
assert (not xw.bhp().empty());
|
assert (not xw.bhp().empty());
|
||||||
const V bhp = Eigen::Map<const V>(& xw.bhp()[0], xw.bhp().size());
|
const V bhp = Eigen::Map<const V>(& xw.bhp()[0], xw.bhp().size());
|
||||||
@ -470,6 +483,9 @@ namespace Opm {
|
|||||||
state.rs = ADB::constant(V::Zero(nc), bpat);
|
state.rs = ADB::constant(V::Zero(nc), bpat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Qs.
|
||||||
|
state.qs = vars[ nextvar++ ];
|
||||||
|
|
||||||
// Bhp.
|
// Bhp.
|
||||||
state.bhp = vars[ nextvar++ ];
|
state.bhp = vars[ nextvar++ ];
|
||||||
|
|
||||||
@ -646,11 +662,7 @@ namespace Opm {
|
|||||||
const ADB nkgradp_well = transw * (p_perfcell - p_perfwell);
|
const ADB nkgradp_well = transw * (p_perfcell - p_perfwell);
|
||||||
// DUMP(nkgradp_well);
|
// DUMP(nkgradp_well);
|
||||||
const Selector<double> cell_to_well_selector(nkgradp_well.value());
|
const Selector<double> cell_to_well_selector(nkgradp_well.value());
|
||||||
ADB qs = ADB::constant(V::Zero(nw*np), state.bhp.blockPattern());
|
ADB well_rates_all = ADB::constant(V::Zero(nw*np), state.bhp.blockPattern());
|
||||||
// We can safely use a dummy rs here (for well calculations)
|
|
||||||
// as long as we do not inject oil.
|
|
||||||
const ADB rs_perfwell = ADB::constant(V::Zero(nperf), state.bhp.blockPattern());
|
|
||||||
const std::vector<ADB> well_kr = computeRelPermWells(state, well_s, well_cells);
|
|
||||||
ADB perf_total_mob = subset(rq_[0].mob, well_cells);
|
ADB perf_total_mob = subset(rq_[0].mob, well_cells);
|
||||||
for (int phase = 1; phase < np; ++phase) {
|
for (int phase = 1; phase < np; ++phase) {
|
||||||
perf_total_mob += subset(rq_[phase].mob, well_cells);
|
perf_total_mob += subset(rq_[phase].mob, well_cells);
|
||||||
@ -669,7 +681,7 @@ namespace Opm {
|
|||||||
const ADB perf_flux = perf_mob * (nkgradp_well); // No gravity term for perforations.
|
const ADB perf_flux = perf_mob * (nkgradp_well); // No gravity term for perforations.
|
||||||
well_perf_rates[phase] = (perf_flux*perf_b);
|
well_perf_rates[phase] = (perf_flux*perf_b);
|
||||||
const ADB well_rates = wops_.p2w * well_perf_rates[phase];
|
const ADB well_rates = wops_.p2w * well_perf_rates[phase];
|
||||||
qs += superset(well_rates, Span(nw, 1, phase*nw), nw*np);
|
well_rates_all += superset(well_rates, Span(nw, 1, phase*nw), nw*np);
|
||||||
|
|
||||||
// const ADB well_contrib = superset(perf_flux*perf_b, well_cells, nc);
|
// const ADB well_contrib = superset(perf_flux*perf_b, well_cells, nc);
|
||||||
well_contribs[phase] = superset(perf_flux*perf_b, well_cells, nc);
|
well_contribs[phase] = superset(perf_flux*perf_b, well_cells, nc);
|
||||||
@ -680,10 +692,14 @@ namespace Opm {
|
|||||||
const int oilpos = pu.phase_pos[Oil];
|
const int oilpos = pu.phase_pos[Oil];
|
||||||
const int gaspos = pu.phase_pos[Gas];
|
const int gaspos = pu.phase_pos[Gas];
|
||||||
const ADB rs_perf = subset(state.rs, well_cells);
|
const ADB rs_perf = subset(state.rs, well_cells);
|
||||||
qs += superset(well_perf_rates[oilpos]*rs_perf, Span(nw, 1, gaspos*nw), nw*np);
|
well_rates_all += superset(well_perf_rates[oilpos]*rs_perf, Span(nw, 1, gaspos*nw), nw*np);
|
||||||
// DUMP(well_contribs[gaspos] + well_contribs[oilpos]*state.rs);
|
// DUMP(well_contribs[gaspos] + well_contribs[oilpos]*state.rs);
|
||||||
residual_.mass_balance[gaspos] += well_contribs[oilpos]*state.rs;
|
residual_.mass_balance[gaspos] += well_contribs[oilpos]*state.rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the well flux equation
|
||||||
|
residual_.well_flux_eq = state.qs - well_rates_all;
|
||||||
|
|
||||||
// Handling BHP and SURFACE_RATE wells.
|
// Handling BHP and SURFACE_RATE wells.
|
||||||
V bhp_targets(nw);
|
V bhp_targets(nw);
|
||||||
V rate_targets(nw);
|
V rate_targets(nw);
|
||||||
@ -704,7 +720,7 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const ADB bhp_residual = bhp - bhp_targets;
|
const ADB bhp_residual = bhp - bhp_targets;
|
||||||
const ADB rate_residual = rate_distr * qs - rate_targets;
|
const ADB rate_residual = rate_distr * state.qs - rate_targets;
|
||||||
// Choose bhp residual for positive bhp targets.
|
// Choose bhp residual for positive bhp targets.
|
||||||
Selector<double> bhp_selector(bhp_targets);
|
Selector<double> bhp_selector(bhp_targets);
|
||||||
residual_.well_eq = bhp_selector.select(bhp_residual, rate_residual);
|
residual_.well_eq = bhp_selector.select(bhp_residual, rate_residual);
|
||||||
@ -987,13 +1003,7 @@ namespace Opm {
|
|||||||
if (active_[Oil] && active_[Gas]) {
|
if (active_[Oil] && active_[Gas]) {
|
||||||
r = std::max(r, residual_.rs_or_sg_eq.value().matrix().norm());
|
r = std::max(r, residual_.rs_or_sg_eq.value().matrix().norm());
|
||||||
}
|
}
|
||||||
for (std::vector<ADB>::const_iterator
|
r = std::max(r, residual_.well_flux_eq.value().matrix().norm());
|
||||||
b = residual_.well_flux_eq.begin(),
|
|
||||||
e = residual_.well_flux_eq.end();
|
|
||||||
b != e; ++b)
|
|
||||||
{
|
|
||||||
r = std::max(r, (*b).value().matrix().norm());
|
|
||||||
}
|
|
||||||
r = std::max(r, residual_.well_eq.value().matrix().norm());
|
r = std::max(r, residual_.well_eq.value().matrix().norm());
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
@ -80,6 +80,7 @@ namespace Opm {
|
|||||||
ADB pressure;
|
ADB pressure;
|
||||||
std::vector<ADB> saturation;
|
std::vector<ADB> saturation;
|
||||||
ADB rs;
|
ADB rs;
|
||||||
|
ADB qs;
|
||||||
ADB bhp;
|
ADB bhp;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -116,7 +117,7 @@ namespace Opm {
|
|||||||
struct {
|
struct {
|
||||||
std::vector<ADB> mass_balance;
|
std::vector<ADB> mass_balance;
|
||||||
ADB rs_or_sg_eq; // Only used if both gas and oil present
|
ADB rs_or_sg_eq; // Only used if both gas and oil present
|
||||||
std::vector<ADB> well_flux_eq;
|
ADB well_flux_eq;
|
||||||
ADB well_eq;
|
ADB well_eq;
|
||||||
} residual_;
|
} residual_;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user