Plume refactor for wind at height field computation by Plume#23
Plume refactor for wind at height field computation by Plume#23
Conversation
with update strategies (WindAtHeight) + tests
handle derived parameters
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #23 +/- ##
===========================================
+ Coverage 69.16% 72.53% +3.37%
===========================================
Files 78 88 +10
Lines 3162 3587 +425
Branches 273 313 +40
===========================================
+ Hits 2187 2602 +415
- Misses 975 985 +10 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
d79c935 to
c4dc104
Compare
c4dc104 to
23c124a
Compare
| ASSERT(target); | ||
|
|
||
| const auto& field3d = target->get(); | ||
| // @question: Should we make this a 3D field with nlevels = 1 to keep consistency with ifs Plume field provider ? |
There was a problem hiding this comment.
Hi reviewers, please take a moment to look at this question because this has a strong impact on how the plugins will access the underlying data (see here).
I am under the impression that in the Plume module in IFS the 2D fields are built with a level key, so the atlas array has two dimensions and the second one is sized 1 for 2D fields, e.g. lnsp. Therefore, plugins using 2D fields will still use the same interface as 3D fields but hardcode the level to 0: lnspArr(index, 0) instead of lnspArr(index).
Should the strategies reproduce this structure ? Is it in fact necessary for the partitioning to happen correctly ? Or is it more idiomatic to create truly 1d atlas arrays like is currently done here ?
There was a problem hiding this comment.
Partitioning is independent of the levels. Only the horizontal dimension is partitioned.
It is possible to follow this pattern to treat horizontal-only (2d) field as a field with also a single vertical level:
template <typename T>
atlas::array::View<const T, 2> make_3d_view(const atlas::Field& field) {
using namespace atlas::array;
if (field.levels()) {
return make_view<const T, 2>(field);
}
else {
return make_view<const T, 1>(field).slice(Range::all(), Range::dummy());
}
}The use is then:
auto const_view1_3d = make_3d_view<double>( field1_2d );
auto const_view2_3d = make_3d_view<double>( field2_3d );
Description
This PR equips Plume with the ability to control its own share of the data, via an observer/publisher pattern and update strategies.
This need comes from the GRIB2 migration which impacts the height levels computed by IFS. Instead of deferring the wind at height computation to the plugin, Plume can manage this diagnostic field and serve it to the plugins as it would for any model field.
The strategy mechanism implemented is generic and allows extension to other data types beyond fields (see README in
plume/data/for steps to add new strategies). The only concrete strategy implemented computes the wind at a given height from a wind field and the geopotential, compare tovdfvintsubroutine for scientific correctness.To apply the strategies, Plume model data and parameter representations have been refactored to allow model variables to be observed by Plume-owned variables, such that updates trigger a recomputation of the observing parameters. A templated approach was followed to allow seamless extension to more data types and dependency types.
This PR is separated in two main commits, the first one introduces the model data and parameter refactor with the new patterns, and the second one focuses on the Plume Manager, and handling the change from the client side (requesting derived fields, negotiating them, and creating them).
Contributor Declaration
By opening this pull request, I affirm the following: