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

Refactor of vertical reconstruction adding six new schemes #741

Open
wants to merge 3 commits into
base: dev/gfdl
Choose a base branch
from

Conversation

adcroft
Copy link
Member

@adcroft adcroft commented Oct 23, 2024

This refactor is motivated by i) adding a set of new reconstructions schemes
that are ready-to-use-now for remapping, but ii) will be an essential part of a
new grid generator that will use some of the new member methods available only
as a result of the refactor. The "refactor" actually duplicates many existing
schemes, leaving the original code in place to provide a period of transition
just in case there's some major reason to revert to the old style of code.

What changed

  • removed remapping_attic.F90
  • added 16 modules name Recon1d_*.F90, which extend a base Recon1d_type.F90
  • MOM_remapping.F90
    • rewrote remapping_unit_tests to be tidier
    • added tests for
      1. invariance when remapping to/from the same grid;
      2. preservation of a uniform value (many of the old schemes fail);
      3. internal consistency such as monotonic ordering of values at
        edges, no internal extrema, etc., but only for the new Recon1d_* schemes.
  • added more schemes to config_src/drivesr/timing_tests/time_MOM_remapping.F90
  • added documentation via _Vertical_Reconstruction.dox with references

Six new schemes are added: C_PLM_CW, C_PLM_CWK, C_MPLM_CWK, C_EMPLM_CWK,
C_PPM_CWK, and C_EPPM_CWK.

Ten existing schemes were ported to the new class, along with their
non-monotonic behaviors or ill-formed expressions. Others can be ported later
if needed, although one result of the refactor was the discovery that none of
the existing schemes worked as desired.

The new form uses a class (Recon1d) to define a uniform API for all the
reconstruction schemes. The methods of the class include:

  • init() that creates work arrays and stores parameters such as h_neglect
  • reconstruct() that causes the reconstruction parameters to be calculated
  • average() that returns the average between two points in a reconstruction
    (used in the remap_src_to_sub_grid() functions)
  • unit_tests() method
  • check_reconstruction() checks that a reconstruction has the
    properties that it should (e.g. reconstruction values are monotonic)
    Theses properties are defined by each scheme, although many are shared
    between schemes.
  • f() that evaluates the reconstruction at a point (this will be used in the
    new grid-generator).
  • dfdx() that evaluates the derivative of the reconstruction at a point (this
    will be used in the new grid-generator)

Testing

New tests have been added that check uniform states are preserved, states are
preserved under unchanging grid, and that the reconstructions are internally
consistent according to their own definition. This last is only available for
the new class-based schemes via the check_reconstruction() method which can be
customized to each reconstruction, which allows us to document which properties
(e.g. monotonicity) are satisfied and which are not. These new tests use
seeded random numbers which has proven useful for debugging/development, but
are not necessarily useful in the CI. Nevertheless, I've made it part of
remapping_unit_tests() so there is a template for debugging/testing new schemes
when we add them. The same sequence of random numbers is used for each scheme,
but the numbers are compiler dependent so the documented "fails" record the
compiler version in comments.

The base Recon1d class also provides a second type to make testing convenient.
In time, this could (should) be moved out to a stand-alone module, so long as
it does not become cumbersome. Currently this type is hidden to avoid expanding
the network of dependencies, particularly using anything in the framework/
directory which is not needed by the class.

Performance

  • the new class-based schemes are all faster than their counterparts in the
    original code style;
  • example numbers can be found in the build-test-perfmon job of this commit
    (expand the "Display timing results" at https://github.com/adcroft/MOM6/actions/runs/11481161473/job/31951185232);
  • e.g. timings for PPM_HYBGEN and C_PPM_HYBGEN show a marginal (~10%) speed
    up due to code style, and C_PPM_CWK has a more substantial speed up (~20%)
    due to a lighter algorithm;
  • I imagine we will see further speed ups if we worked on arrays rather than
    columns, which is an extension that could be implemented later.

Documentation

Minor (unrelated)

  • removed -j for nested make in .testing/Makefile

@Hallberg-NOAA Hallberg-NOAA added enhancement New feature or request refactor Code cleanup with no changes in functionality or results documentation Improvements or additions to documentation labels Nov 4, 2024
@adcroft
Copy link
Member Author

adcroft commented Nov 4, 2024

Some slides from the the MOM6 dev call
Refactor of Reconstruction.pdf

@adcroft
Copy link
Member Author

adcroft commented Nov 5, 2024

Given the new conflicts introduced since submission, I'll take the opportunity to split out the easy stuff (removing of remapping_attic, etc.). In the meantime, let's move forward on the subsequent PRs...

@adcroft adcroft force-pushed the remap-pr branch 2 times, most recently from ecd87dd to 1830afd Compare November 5, 2024 14:03
This module contained very old concepts of unit tests for the
MOM_remapping functions, but have all been superseded by better
tests.
The helper type that shortens the testing lines will be needed
by both the upcoming Recon1d type and MOM_remapping, so it makes
sense to break the type out into a module. I've put this in framework/
but it is specifically a stand-alone module, not dependent on any
infrastructure code.
This refactor is motivated by i) adding a set of new reconstructions schemes
that are ready-to-use-now for remapping, but ii) will be an essential part of a
new grid generator that will use some of the new member methods available only
as a result of the refactor. The "refactor" actually duplicates many existing
schemes, leaving the original code in place to provide a period of transition
just in case there's some major reason to revert to the old style of code.

What changed
============
- added 16 modules name Recon1d_*.F90, which extend a base Recon1d_type.F90
- MOM_remapping.F90
  - rewrote remapping_unit_tests to be tidier
  - added tests for
    1) invariance when remapping to/from the same grid;
    2) preservation of a uniform value (many of the old schemes fail);
    3) internal consistency such as monotonic ordering of values at
       edges, no internal extrema, etc., but only for the new Recon1d_* schemes.
- added more schemes to config_src/drivesr/timing_tests/time_MOM_remapping.F90
- added documentation via _Vertical_Reconstruction.dox with references

Six new schemes are added: C_PLM_CW, C_PLM_CWK, C_MPLM_CWK, C_EMPLM_CWK,
C_PPM_CWK, and C_EPPM_CWK.

Ten existing schemes were ported to the new class, along with their
non-monotonic behaviors or ill-formed expressions.  Others can be ported later
if needed, although one result of the refactor was the discovery that none of
the existing schemes worked as desired.

The new form uses a class (Recon1d) to define a uniform API for all the
reconstruction schemes. The methods of the class include:
- init() that creates work arrays and stores parameters such as `h_neglect`
- reconstruct() that causes the reconstruction parameters to be calculated
- average() that returns the average between two points in a reconstruction
  (used in the remap_src_to_sub_grid() functions)
- unit_tests() method
- check_reconstruction() checks that a reconstruction has the
  properties that it should (e.g. reconstruction values are monotonic)
  Theses properties are defined by each scheme, although many are shared
  between schemes.
- f() that evaluates the reconstruction at a point (this will be used in the
  new grid-generator).
- dfdx() that evaluates the derivative of the reconstruction at a point (this
  will be used in the new grid-generator)

Testing
=======

New tests have been added that check uniform states are preserved, states are
preserved under unchanging grid, and that the reconstructions are internally
consistent according to their own definition. This last is only available for
the new class-based schemes via the check_reconstruction() method which can be
customized to each reconstruction, which allows us to document which properties
(e.g. monotonicity) are satisfied and which are not.  These new tests use
seeded random numbers which has proven useful for debugging/development, but
are not necessarily useful in the CI. Nevertheless, I've made it part of
remapping_unit_tests() so there is a template for debugging/testing new schemes
when we add them. The same sequence of random numbers is used for each scheme,
but the numbers are compiler dependent so the documented "fails" record the
compiler version in comments.

The helper type was previously broken out of MOM_remapping to make testing convenient.

Performance
===========
- the new class-based schemes are all faster than their counterparts in the
  original code style;
- example numbers can be found in the build-test-perfmon job  of this commit
  (expand the "Display timing results");
- e.g. timings for PPM_HYBGEN and C_PPM_HYBGEN show a marginal (~10%) speed
  up due to code style, and C_PPM_CWK has a more substantial speed up (~20%)
  due to a lighter algorithm;
- I imagine we will see further speed ups if we worked on arrays rather than
  columns, which is an extension that could be implemented later.

Documentation
=============
- the new module APIs are documented;
- a new page, `_Vertical_Reconstruction.dox`, details the vertical
  reconstruction schemes, tabulates the values of `REMPAPPING_SCHEME`,
  and summarize some properties.

Minor (unrelated)
=================
- removed `-j` for nested make in `.testing/Makefile`
@adcroft
Copy link
Member Author

adcroft commented Nov 6, 2024

Unrelated, but this PR was a test for an issue. Although we have "fixed" the codecov upload process, the patch information did not show up properly. I've managed to make it show up (click on the green check of a commit and then look at codecov/patch) but to make it work I pushed each commit of this PR to a new branch on NOAA-GFDL/MOM6, waiting for the codecov patch info to show up each time. The patch info is now available, e.g. https://app.codecov.io/gh/NOAA-GFDL/MOM6/commit/b8594428cae3d73ebefcd92ea51574d20e3921c4 . Ideally we want this to be available for any PR but obviously we don't want new branch on NOAA-GFDL for PRs. I'm not sure what the issue is; I had these commits uploaded and showing from my own fork, that apparently is not sufficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request refactor Code cleanup with no changes in functionality or results
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants