Commit 96cf137 introduced support for Peaceman index calculation
that honoured general completion directions (X,Y,Z). This was
accomplished through a permutation index that reordered the
permeability and geometric extent components according to a local
coordinate system along the completion.
In a complete breakdown of logic, however, the d-component extent
vector was indexed as though it were a d-by-d matrix. This commit
restores sanity to the processing.
Pointy hat: @bska.
This commit extends the feature set of the WellsManager to support
horizontal ("X" and "Y") completions and include the net-to-gross
ratio in the Peaceman index ("Completion Transmissibility Factor,
CTF") of a well completion. The NTG factor is included if present
in the input deck represented by the "eclipseState".
There are two separate, though related, parts to this commit. The
first part splits the calculation of Peaceman's "effective radius"
out to a separate utility function, effectiveRadius(), and
generalises WellsManagerDetail::computeWellIndex() to account for
arbitrary directions and NTG factors. The second part uses
GridPropertyAccess::Compressed<> to extract the NTG vector from the
input if present while providing a fall-back value of 1.0 if no such
vector is available.
Note: We may wish to make the extraction policy configurable at some
point in the future.
This commit tightens the function header of method
WellsManager::createWellsFromSpecs()
to accept a reference-to-const 'cartesian_to_compressed' map. It
used to be a complete, copy-constructed object, so this is a slight
performance enhancement as we no longer need to copy a (somewhat)
large object on every call to the method.
This commit generalises the implementation of utility function
'getCubeDim' to support arbitrary number of space dimensions. In
actual practice there's no change in features as we only really use
a compile-time constant (= 3) to specify the number of space
dimensions.
This is a demonstration of using the
GridPropertyAccess::Compressed<>
class template. We save (some) memory by not creating the zero
fall-back vector in assignPermeability(), preferring instead to use
the fall-back/default mechanism of ArrayPolicy::ExtractFromDeck<>.
While here, adjust vector<PermComponent>::reserve() capacity to
reflect actual requirements.
Clients expect column-major (Fortran) ordering of the contiguous
"permeability_" array so that's what we create despite "tensor"
being row-major.
Suggested by: [at] atgeirr
This commit switches the assignment
diagonal = max(diagonal, minval)
to using a reference in the "diagonal" expression. This guarantees
that the indexing is done once which eases maintainability. While
here, replace the hard-coded dimension stride ('3') with the current
run-time dimension. This is mostly for symmetry because the overall
code is only really supported in three space dimension.
Calling code relies on permeability tensors being stored in column
major order (row index cycling the most rapidly). Honour that
requirement. The previous assignment implied row major ordering
(column index cycling the most rapidly). This, however, is a
pedantic rather than visible change because the surrounding code
enforces symmetric tensors whence both orderings produce the same
results when the array is viewed contiguously.
This commit removes several instances of EOL whitespace in function
'swatInitScaling()'. Aesthetic only. No functional changes.
Suggested by: [at] atgeirr
The constant 1.0e-8 was used as a threshold to distinguish "low"
from "high" capillary pressure values. Introduce acutual constant
"pc_low_threshold" to clarify that role.
Suggested by: [at] atgeirr
This commit renames the 'np' parameter used to allocate small arrays
for saturations and capillary pressures to 'max_np' to better
reflect its purpose.
Suggested by: [at] atgeirr
New function well_controls_clone(), implemented in terms of the
public API only, mirrors the objective of function clone_wells(),
only for well control sets. Add a basic test to demonstrate the
function too.
The 'cpty' field is for internal memory management purposes only.
No client can know of its existence, let alone inspect or directly
change the value, so it should not be used to adjudicate control set
equality. This was useful during the refactoring work to introduce
the opm-parser support, but its utility has since ceased.
Okay'ed by: [at] atgeirr and [at] joakim-hove
This was missing in commit 4c2120c and produced some build failures
that were hard to analyse. I'm not convinced that the underlying
problem is solved, but this does at least restore the build.
The class OwnerOverlapCopyCommunication is not defined unless MPI is
avilable. Therefore, we cannot reference the type unless we know
that MPI is available in the current translation unit.
The initial implementation of RK4IVP<>::operator() failed to take
into account the possibility that we might need to evaluate the
function outside the vertical span for which it was initially
defined. This situation occurs, for instance, in the not uncommon
cases of the GOC being above or the WOC being below the model.
This commit installs a crude Hermitian extrapolation procedure to
handle these cases. Refinements are likely.
This commit adds support for assigning the initial phase pressure
distribution to a subset of the total grid cells. This is needed in
order to fully support equilibration regions. The existing region
support (template parameter 'Region' in function 'phasePressures()')
was only used/needed to define PVT property (specifically, the fluid
phase density) calculator pertaining to a particular equilibration
region.
This commit adds a simple facility for calculating initial phase
pressures assuming stationary conditions, a known reference pressure
in the oil zone as well as the depth and capillary pressures at the
water-oil and gas-oil contacts.
Function 'Opm::equil::phasePressures()' uses a simple ODE/IVP-based
approach, solved using the traditional RK4 method with constant step
sizes, to derive the required pressure values. Specifically, we
solve the ODE
dp/dz = rho(z,p) * g
with 'z' represening depth, 'p' being a phase pressure and 'rho' the
associate phase density. Finally, 'g' is the acceleration of
gravity. We assume that we can calculate phase densities, e.g.,
from table look-up. This assumption holds in the case of an ECLIPSE
input deck.
Using RK4 with constant step sizes is a limitation of this
implementation. This, basically, assumes that the phase densities
varies only smoothly with depth and pressure (at reservoir
conditions).
This is intentionally black-oil specific because we presently do no
know how to handle other cases (e.g., more phases or number of phases
different from number of components).
The WellsManager class handles INJECTORS by assigning a phase
distribution (W->ctrls[i]->distr) that coincides with the injected
fluid for the corresponding well (e.g., {1,0,0} for WATER injectors in
a three-phase WATER/OIL/GAS simulation). This, however, meshes poorly
with the restriction that all phase components must be ONE in the case
of wells constrained by total reservoir volume flow targets (RESV)
that was introduced in commit b7d1634.
This change-set limits the restriction on phase distributions to
PRODUCERs only and is a tentative solution to GitHub PR #360.
The <have_boost_redef.hpp> header was introduced (commit 82369f9) as
a work-around for a particular interaction in the Autotools-based
setup of OPM-Core and the Dune core modules. Notably, Dune's
"Enable" trick for Boost failed on some older Autoconf systems. Now
that we're using CMake, however, that kluge is no longer needed
because we (OPM-Core) always
#define HAVE_BOOST 1
i.e., as an explict true/false value.
Therefore, we need no longer include <have_boost_redef.hpp> . The
header will be removed at a later time.
The numbers in the deck are more indicative of FIELD unit conventions
than METRIC unit conventions, so allow the input parser to interpret
the data in that manner.
The "maxit_" counter is an upper limit on the number of non-linear
iterations in a single cell. Declaring this as a "double" is counter
intuitive unless one expects the number to be *really* high.
Present since
- Commit 93d4bd8 (TransportModelTwophase.hpp)
- Commit e0d38cf (TransportModelTwophaseCompressible.hpp)
This commit corrects an error that has been present since the
introduction of function wellsToSrc() in commit a50bb8f but was never
detected. Although the conversion int->double->std::size_t is likely to
be loss-less, it is better to not introduce any more steps than are
actually needed.
This is a minor bugfix to account for the presence of shut wells
(characterised by "ctrls[w]->current < 0"). The existing code would
lead to indexing outside the "ctrls" array in the context of a shut
well.
We previously ignored effects of gravity in the calculation of the well
connection fluxes (i.e., perforation fluxes). This commit includes
those effects where appropriate.
Specifically, the tests
if (!wells->type[self_index] == INJECTOR)
if (!wells->type[self_index] == PRODUCER)
produced the expected results *only* because INJECTOR==0 and PRODUCER==1
in the WellType enumeration, thus (!INJECTOR == PRODUCER) and
(!PRODUCER == INJECTOR).
Installing the (much) more appropriate
if (wells->type[self_index] != INJECTOR)
if (wells->type[self_index] != PRODUCER)
is not only more readable, it is also future-proof and scales better if
we ever introduce new WellTypes (e.g., a MONITOR).
This installs a measure of safety on the part of the interface in that
the caller is free to dispose of the wells object upon returning from
the WellsManager constructor.