There might be wells without any perforations. It it happens
to be the last well will supscript over the bounds. In other
cases we actually return the correction for the next well.
Not sure whether returning 0 makes any sense, though.
Previously we initialized a variable for a global
(i.e. sum over all processes) value with the local
value first and the overwrote it with the computed
global. This meant the name did not reflect the value
during the first initialization.
With this commit we fix this by using an additional
variable for the local value that is used to compute
the global one.
If this option was set there were some branches in
the code that did depend on the local number of wells
but should depend on the number of wells in the reservoir
no matter on which process they are stored.
With this commit we introduce BlackOilModelBase::localWellsActive()
which only takes local wells into account. The function now
BlackOilModelBase::wellsActive() considers all active wells in the
reservoir.
assumes:
- solvent is immiscible in the oil phase
- gas pvt and relperms are used for the solvent
- no initial solvent in the model
Solvent is injected using the WSOLVENT keyword
TODO: Make it possible to change WSOLVENT
in assemble(...). This makes VFPINJ behave as expected, and
VFPPROD for the "trivial table". For the nontrivial table,
VFPPROD does not match expected behaviour.
1) NNC are added the grad, div and average operators
2) NNC are added the upwindSelector
3) NNC transmissibilities are added to the face transmissibilities
The simplifications are:
- Do not pass cell indices to fluidViscosity(), fluidReciprocFVF().
- Pass b (reciprocal f.v.f.) to fluidDensity() instead of pressure etc.
This saves one call to fluidReciprocFVF(), that is removed from
fluidDensity(). Instead the previously stored quantity is passed
to fluidDensity() as an argument.
The method has been split in three parts:
computeWellFlux(const SolutionState& state,
const std::vector<ADB>& mob_perfcells,
const std::vector<ADB>& b_perfcells,
V& aliveWells,
std::vector<ADB>& cq_s);
void
updatePerfPhaseRatesAndPressures(const std::vector<ADB>& cq_s,
const SolutionState& state,
WellState& xw);
void
addWellFluxEq(const std::vector<ADB>& cq_s,
const SolutionState& state);
This reduces the function length, although most of the content of addWellEq()
now is in computeWellFlux(), so that function is still quite long. It also
allows us to use smaller sets of function arguments, which makes methods easier
to understand.
Finally, it makes it easier to create derived models with custom behaviour.