Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalise Restart Representation of UDQs #4225

Merged
merged 3 commits into from
Oct 17, 2024

Conversation

bska
Copy link
Member

@bska bska commented Sep 23, 2024

This PR reimplements the RestartIO::RstUDQ type with a view towards introducing support for restarting simulation runs containing user defined quantities (UDQs) associated to the segments of multi-segmented wells. In particular, we replace the current value container with a back-end based on the CSRGraphFromCoordinates helper class. This, in turn, enables supporting UDQ values at the sub-entity level of a top-level entity such as the segments of a multi-segmented well.

We more clearly distinguish the producing side–i.e., the layer which loads information from a restart file–from the consuming side–i.e., the client code which forms UDQConfig and UDQState objects based on the restart file information, and require the producing side to signal when the restart information has been fully loaded. To this end, the producing side is expected to

  1. Call member function prepareValues() to signal that new values are being loaded
  2. Call member function addValue(), typically in a loop, to include new UDQ values from the restart file
  3. Call member function commitValues() to signal that all values have been loaded.

As an alternative to step 2, the producing side may call member function addScalarValue() if the quantity in question is scalar–typically a field level UDQ.

The producing side should also include any relevant entity names, usually well or group names, by calling the addEntityName() member function.

The consuming side is expected to interact with the information through operator[]() which returns a specialised ValueRange type that supports forward iteration, for instance in a range-for() loop.

This new interface begets a significant update to the UDQAssign class. In particular, we no longer need the rst_selector and instead add new constructor and add_record interfaces which take a RestartIO::RstUDQ object and a report step index. The previous interface based on the rst_selector implicitly assumed that all assignment statements applied a constant value to a collection of wells or groups, but this assumption does not generally hold when we load information from a restart file. The
new interface removes this assumption. While here, also make the AssignRecord into a private data type since client code does not generally need to know how we represent the assignment information.

Finally, add Doxygen-style documentation to the types

  • RestartIO::RstUDQ
  • UDQAssign
  • UDQConfig

While not much, this may help future maintainers understand the relationships between these types a little better.

@bska
Copy link
Member Author

bska commented Sep 23, 2024

I am creating this PR in draft mode because it depends on, and contains, the earlier PR #4224. I will keep the PR in a draft state until such time as it is ready for review and merging. That may be after we've created the release branches for the 2024.10 OPM release, since it's not clear to me that this is ready to go into a release version quite yet.

@bska bska force-pushed the generalise-rst-udq-info branch 9 times, most recently from 7c4148b to 345b7f3 Compare October 1, 2024 07:24
@bska bska force-pushed the generalise-rst-udq-info branch 5 times, most recently from 20f60b5 to 69d4b66 Compare October 2, 2024 13:08
@bska
Copy link
Member Author

bska commented Oct 2, 2024

jenkins build this please

@bska bska force-pushed the generalise-rst-udq-info branch 9 times, most recently from fa14a5d to 381cbd6 Compare October 9, 2024 11:55
@bska bska force-pushed the generalise-rst-udq-info branch 4 times, most recently from 3bca92f to 6f8d375 Compare October 16, 2024 10:50
@bska
Copy link
Member Author

bska commented Oct 17, 2024

jenkins build this please

This commit ensures that all known UDQ variable types (e.g, field,
group, well, segment) are accounted for in the INTEHEAD restart
vector.  We switch to having an appropriately sized std::array as a
member in InteHEAD::UdqParam represent the counts instead of having
individual members for each variable type.  This is more extensible
as well if we add more categories in the future.  We generate the
category counts to class UDQConfig, since this class already knows
the category counts internally (from UDQConfig::add_node()).  To
this end, add a new member function 'UDQConfig::exportTypeCount()'.

While here, make slight whitespace adjustments to the IUAP and IUAD
counting routines to simplify future maintenance.
This commit reimplements the RestartIO::RstUDQ type with a view
towards introducing support for restarting simulation runs
containing user defined quantities (UDQs) associated to the segments
of multi-segmented wells.  In particular, we replace the current
value container with a back-end based on the CSRGraphFromCoordinates
helper class.  This, in turn, enables supporting UDQ values at the
sub-entity level of a top-level entity such as the segments of a
multi-segmented well.

We more clearly distinguish the producing side--i.e., the layer
which loads information from a restart file--from the consuming
side--i.e., the client code which forms UDQConfig and UDQState
objects based on the restart file information, and require the
producing side to signal when the restart information has been fully
loaded.  To this end, the producing side is expected to

  1. Call member function prepareValues() to signal that new values
     are being loaded
  2. Call member function addValue(), typically in a loop, to
     include new UDQ values from the restart file
  3. Call member function commitValues() to signal that all values
     have been loaded.

As an alternative to step 2, the producing side may call member
function addScalarValue() if the quantity in question is
scalar--typically a field level UDQ.

The producing should also include any relevant entity names, usually
well or group names, by calling the addEntityName() member function.

The consuming side is expected to interact with the information
through operator[]() which returns a specialised ValueRange type
that supports forward iteration, for instance in a range-for() loop.

This new interface begets a significant update to the UDQAssign
class.  In particular, we no longer need the 'rst_selector' and
instead add new constructor and add_record interfaces which take a
RestartIO::RstUDQ object and a report step index.  The previous
interface based on the 'rst_selector' implicitly assumed that all
assignment statements applied a constant value to a collection of
wells or groups, but this assumption does not generally hold when we
load information from a restart file.  The new interface removes
this assumption.  While here, also make the AssignRecord into a
private data type since client code does not generally need to know
how we represent the assignment information.

Finally, add Doxygen-style documentation to the types

  * RestartIO::RstUDQ
  * UDQAssign
  * UDQConfig

While not much, this may help future maintainers understand the
relationships between these types a little better.
@bska
Copy link
Member Author

bska commented Oct 17, 2024

The release branches have been created and this work has been tested through the downstream PR #4226. I'm marking the PR as "ready for review", fully cognizant of the fact that it's large both in terms of number of changed files and in terms of number of changed lines.

@bska bska marked this pull request as ready for review October 17, 2024 11:32
@bska
Copy link
Member Author

bska commented Oct 17, 2024

jenkins build this please

Copy link
Member

@akva2 akva2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some typos and observations. This PR is quite big and it's hard to get a proper idea without spending a lot of time. But it looks good to me, and I trust your judgement if you think this is ready.

UDQAction UDQConfig::action_type(const std::string& udq_key) const
{
auto action_iter = this->input_index.find(udq_key);
return action_iter->second.action;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unchecked deref?

/// \param[in] create_segment_matcher Factory function for
/// constructing segment set matchers.
///
/// \param[in,out] st Summary vectors. For output and evaulating
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

evaluating

/// \param[in] create_region_matcher Factory function for
/// constructing region set matchers.
///
/// \param[in,out] st Summary vectors. For output and evaulating
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

evaluating

/// \param[in] key Unqualified UDQ name such as FUNNY, GUITAR,
/// WURST, or SUSHI.
///
/// \return Pending assingment object for \p key. Throws an
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assignment


// The following data structures are constrained by compatibility
// requirements in our simulation restart files. In particuar we
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

particular


/// Ordered set of DEFINE statements.
///
/// Mostly unused and should probably be removed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO:

const auto dudg = udqs.currentGroupUDQValue();

const auto subEntity = 0;
auto entity = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may be declared in the for to clarify scope (and not agitate static analyzers)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may be declared in the for to clarify scope

Not really. I appreciate that it's obscured by type deduction, but the iGrp induction variable has type vector<T>::size_type (typically std::size_t) while entity has type int. If we write

for (auto iGrp = 0*nGrp, entity = 0; ...)

then entity will have the same type as iGrp and that will cause an unconditional type conversion in the call to RstUDQ::addValue(). If we write it as

for (auto entity = 0, iGrp = 0*nGrp; ...)

then iGrp will have type int which will (typically) cause a "signed vs. unsigned comparison" warning in iGrp < nGrp.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, i missed the type difference. it's fine.

const auto dudw = udqs.currentWellUDQValue();

const auto subEntity = 0;
auto entity = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may be declared in the for to clarify scope (and not agitate static analyzers)


namespace detail {
template <typename... Ts>
struct Overloaded : public Ts... { using Ts::operator()...; };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could use VisitorOverloadSet (from Visitor.hpp)


/// UDQ's category, i.e., which level this UDQ applies to.
///
/// Exmples include, the FIELD (FU*), group (GU*), well (WU*), or well
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Examples

  - Use existing type Opm::VisitorOverloadSet instead of rolling our
    own implementation of the same algorithm in udq.cpp
  - Remove unused private member function UDQConfig::action_type()
  - Multiple spelling fixes
@bska
Copy link
Member Author

bska commented Oct 17, 2024

Thank you for looking at this. I've pushed an update to address the PR review comments.

@bska
Copy link
Member Author

bska commented Oct 17, 2024

jenkins build this please

@bska
Copy link
Member Author

bska commented Oct 17, 2024

PR approved and build check is green. I'll merge into master.

@bska bska merged commit c37f4ed into OPM:master Oct 17, 2024
1 check passed
@bska bska deleted the generalise-rst-udq-info branch October 17, 2024 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants