This commit enables updating individual well properties for one or
more wells using the WELSPECS keyword. In particular, this revised
logic enables changing the controlling group without affecting any
other well property such as the location of the well head or the
well reference depth.
Defaulted properties do not affect change in Well::update*(). This,
in turn, begets a change to the logic of how we update the reference
depths. Previously, we always interpreted a defaulted reference
depth item as
Compute the reference depth from the location of the well's
reservoir connections
We now alter this interpretation slightly to mean
Don't recompute the reference depth if the input has already
assigned a numerical value for this property
If the input has never assigned an explicit numerical value for the
reference depth, then we continue using the original interpretation
of a defaulted reference depth item--e.g., to update the reference
depth as a result of new reservoir connections.
The simulation can request the original interpretation even after
having assigned a numeric reference depth, by entering a new
WELSPECS keyword specifying a negative value for the the reference
depth item.
To this end, introduce a new data member in the Well class,
bool Well::derive_refdepth_from_conns_
which tracks whether or not the reference depth has been assigned an
explicit numeric value.
As an example, this new WELSPECS behaviour enables using something
like
ACTIONX
A 1 /
WOPR 'P*' < 123.4 /
/
WELSPECS
'?' 'LOWPRESS' /
/
ENDACTIO
as a way to move all wells matching the pattern 'P*', and with a low
oil production rate, to the group 'LOWPRESS'. This could, in turn,
apply a different set of group-level production controls to those
wells.
This commit adds a new member function,
bool Well::hasRefDepth() const
that allows the caller to query whether or not a particular well has
an active value for the well BHP reference depth. The most common
cause of this value being missing is that the depth item of WELSPECS
is defaulted while the well is not connected to any active cells.
This predicate allows client code, e.g., the restart output module,
to safely access reference depth values in the case of potentially
missing reference depths.
Changed (BASE_SIM.DATA, BASE_SIM_THPRES.DATA, RESTART_SIM.DATA), testblackoilstate3.DATA and testrft.DATA since they affect the tests in test_Restart.cpp, test_restartwellinfo.cpp and test_RFT.cpp respectively.
When replaying the Schedule keywords due to ACTIONX only the actual ACTIONX
keywords should be involved with the runtime flag set to true. The rest of the
deck should be evaluated in the normal way.
- Add member KeywordLocation to vfp tables
- Improve error messages
- Remove array_type typedef - use std::vector<double>
- Use class based enums
- Replace assert(x) -> if (!x) throw
Heed advice from [at]joakim-hove to keep client code as close to
strictly SI as possible. We must nevertheless continue to store the
raw (input/output units) requested PI value internally as this is
the only way to ensure that both the client and implementation has
consistent view of the well's preferred phase. This means pushing
the unit conversion into Well::getWellPIScalingFactor().
Thanks to [at]joakim-hove for pointing out that the Well already
maintains an internal UnitSystem data member which makes the process
of converting the PI units trivial.
There and back again. We don't actually need the preferred phase at
the time of encountering the WELPI request. [at]joakim-hove was
right, the preferred phase of an injector must reflect the state at
the same report step as the WELPI keyword. In other words, if the
injected phase is reset at the same report step as a WELPI keyword,
then the new preferred phase must be that of the new injected phase.
This reverts commit 3eef45e87d.
1. The well reference depth should *not* be updated when new connections are
added with COMPDAT.
2. The well reference depth should be recalculated when the well is updated with
the WELSPECS keyword.
This commit adds a new in/out parameter, scalingApplicable, to the
applyWellProdIndexScaling functions. This parameter carries time
(history) information on whether or not a particular connection is
eligible for WELPI-based CTF scaling. Entries are marked ineligible
(false) and left untouched on subsequent calls if the corresponding
connection is ineligible at any point--e.g., as a result of new
COMPDAT entries.
This ability enables implementing WELPI CTF scaling at the Schedule
level which is the only level that has sufficient time information
to identify all the unique Well/WellConnections object combinations.
This commit adds a new special purpose predicate member function
bool Well::hasSameConnectionsPointers
which checks if the internal WellConnections pointers of two Well
objects (*this and the input argument) point to the same object.
This, in turn, enables identifying when to apply dynamic WELPI CTF
scaling across the time direction the internalized connection
information.
First part, implemented in a new member function
Well::getWellPIScalingFactor
calculates a CTF scaling factor from stored WELPI information and a
dynamically calculated well-level PI value. The second part, using
the original name applyWellProdIndexScaling, applies an externally
calculate CTF scaling factor to all eligble connections.
This is needed to enable applying multiple scalings across the time
direction. Update unit tests accordingly.
This is to handle the case of an injector changing its injected (and
therefore preferred) phase (e.g., in WCONINJE or WCONINJH) at the
same report step as a WELPI CTF rescaling, but logically after the
WELPI action is applied.
For instance, this happens in the following setup:
WCONINJH
INJ2 WATER OPEN 5500 /
/
DATES
1 'JAN' 2020 /
/
WELPI
'INJ2' 0.1E5 /
/
WCONINJH
INJ2 GAS OPEN 701627 /
/
DATES
1 'FEB' 2020 /
/
In this case, the WELPI for 'INJ2' is supposed to be interpreted as
the water-phase PI (preferred phase is 'WATER' when we read WELPI),
but since the injecting phase is reset to 'GAS' at the same report
step we risk misinterpreting the PI as pertaining to the 'GAS' phase
when calculating the well's effective/dynamic PI in the simulator if
we just use Well::getPreferredPhase().
Switch the the well's input PI from an optional<double> to an
optional<struct> that captures both the input PI value (SI units)
and the preferred phase when processing the WELPI data. Provide a
way to query that information from the simulator and update unit
tests accordingly.
This commit adds logic implementing the static parts of the WELPI
keyword. We internalize the keyword data, record appropriate events
and provide hooks for dynamically adjusting the per-connection
transmissibility factor (Connection::CF()) when those events occur.
We implement support at three levels
- WellConnections:
Add new public member functions prepareWellPIScaling and
applyWellPIScaling which, respectively, creates bookkeeping
data to track those connections which are subject to CF scaling
and actually applies that CF scaling.
- Well:
Add new data member 'productivity_index' which holds the 'WELPI'
data value from the input keyword (converted to SI) and new
member functions updateWellProductivityIndex and
applyWellProdIndexScaling. The first follows the 'update*'
protocol (return 'true' if state change) and assigns new values
to 'productivity_index' while the second uses the stored PI
value and a dynamically calculated effective PI value to rescale
the pertinent connections' CF value.
- Schedule:
Add new member function handleWELPI which internalizes the WELPI
keyword and its data and records WELPI events for subsequent
playback in the simulator layer.
Also add a set of unit tests to exercise the new features at all
levels.
In particular, include standard library headers as needed, fix
function declarations (operator<<() for Well::WellProductionProperties),
and make a few helper functions 'static' to avoid warnings of the
form "no previous declaration for".
For the Schedule's keyword handlers, also switch to storing member
function pointers directly instead of std::function objects. This
saves space and does not incur function pointer conversions. Use
std::invoke to call those handlers to avoid having to spell out the
'->*' operator.
With this commit the IWEL[ActWCtrl] is assigned a value independently of the
wells OPEN / SHUT status.
With this PR the index enum value Status is used instead of the previously used
item11. Also numerical constants are introduced for eclipse status values for
Shut, Stop, Open and Auto.
1. If the well is MSW the connections in the WellConnection class is sorted in
output order in the ::order() method, and retained that way.
2. Add method WellConnection::output() which return a vector of connection
pointers sorted in output order.