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

Generalized subroutine to read the state variables from the namelist (get_state_variables) #783

Open
wants to merge 33 commits into
base: main
Choose a base branch
from

Conversation

mjs2369
Copy link
Contributor

@mjs2369 mjs2369 commented Dec 18, 2024

Description:

There are many variations of the subroutine to read the state variables from the namelist in various model_mods. Previously, a new variation of this subroutine would need to be written every time a new model is added to DART.

This PR creates an interface that allows for the use of one of the two generalized subroutines that can read the state variables from a namelist:
get_state_variables_no_clamp reads netcdf variable name, dart qty, and update values from the nml
get_state_variables_clamp reads netcdf variable name, dart qty, clamp_values, and update values from the nml

Alternate versions for this subroutine were replaced with get_state_variables in the models MOM6, noah, wrf_hydro, MITgcm_ocean, aether_lat-lon, cam-fv, cam-se, POP, and cice

New dev test test_get_state_variables added

Fixes issue

Fixes #448

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

Documentation changes needed?

  • My change requires a change to the documentation.
    • I have updated the documentation accordingly.

Tests

Compiled all models with updated model_mods
Build_everything runs as expected with all compilers
Bitwise tested with CAM-FV
New dev test runs successfully and reports pass/fails correctly

Checklist for merging

  • Updated changelog entry
  • Documentation updated
  • Update conf.py

Checklist for release

  • Merge into main
  • Create release from the main branch with appropriate tag
  • Delete feature-branch

Testing Datasets

  • Dataset needed for testing available upon request
  • Dataset download instructions included
  • No dataset needed

…nto a table and verify its contents; putting it in the default_model_mod
Updating the generic routine by including the type state_vars_type and
storing the contents of the nml entry here

Including a conditional use_clamping that tells whether or not the
model's nml entry includes clamping values; executing a separate do
loop over the rows if true to allow for reading in these values
its functionality.

Adding checks against known values with fortran-test-anything
…del_mod

This model is the perfect example of how we can have separate calls to
get_state_variables for each file domain instead of having the domain
included in the state_variables nml item.
@hkershaw-brown
Copy link
Member

@mjs2369 Do you have restart files so you can test the changed model_mods?

Copy link
Member

@hkershaw-brown hkershaw-brown left a comment

Choose a reason for hiding this comment

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

Hi Marlee,

Good work finding all the model_mods routines that can be switched out by this.

I've put some comments in. The thing to sort out first, is the get_state_variables routine.

  1. Does the overloading and having to set clamping = .true. make. sense? '
  2. Can you keep state_vars type private, so the model_mod does not access the internals (see the comments on add_domain)?

The 3d template model_mod needs updating to use the new routines, since this is what is used when the 'new_model.sh' script is run.

Documentation for routine also needs adding, maybe 'adding a new model' is the best place for this, I'm not sure.

I think the tests should comprehensively test the whole table read - if we are running the test, should test all the values.

developer_tests/namelist/test_get_state_variables.f90 Outdated Show resolved Hide resolved
developer_tests/namelist/test_get_state_variables.f90 Outdated Show resolved Hide resolved
developer_tests/namelist/test_get_state_variables.f90 Outdated Show resolved Hide resolved
models/MITgcm_ocean/model_mod.f90 Outdated Show resolved Hide resolved
models/utilities/default_model_mod.f90 Outdated Show resolved Hide resolved
models/utilities/default_model_mod.f90 Outdated Show resolved Hide resolved
models/wrf_hydro/model_mod.f90 Outdated Show resolved Hide resolved
models/wrf_hydro/model_mod.f90 Outdated Show resolved Hide resolved
models/utilities/default_model_mod.f90 Outdated Show resolved Hide resolved
models/MOM6/model_mod.f90 Outdated Show resolved Hide resolved
@mjs2369
Copy link
Contributor Author

mjs2369 commented Dec 18, 2024

@mjs2369 Do you have restart files so you can test the changed model_mods?

Only for cam-fv and pop - do you want me to test that all models are bitwise?

@hkershaw-brown
Copy link
Member

@mjs2369 Do you have restart files so you can test the changed model_mods?

Only for cam-fv and pop - do you want me to test that all models are bitwise?

If you're changing the model_mod then yes, check that the new code does the expected.
Bitwise model_mod_check, or pmo, or filter if you have test cases set up - with clamping.
Or compare the domain info.

- Make the name of the function parse_variables
- Remove interface to create two distinct functions: parse_variables and parse_variables_clamp
- Remove use_clamping and max_state_vars arguments
- Update the calls to the function in all edited model_mods
@hkershaw-brown
Copy link
Member

this is cool Marlee.

@mjs2369 mjs2369 requested a review from hkershaw-brown January 9, 2025 20:29
@hkershaw-brown
Copy link
Member

Hi Marlee, it will be next week before I look at this, I'm not super worried about it, but it is a lot of model_mod changes to drop on a Friday! Have a good weekend

@hkershaw-brown
Copy link
Member

as in release on a Friday 'drop it like its hot'

call ok(state_vars%qtys(3) == QTY_U_CURRENT_COMPONENT)
call ok(state_vars%updates(1) .eqv. .true.)
call ok(state_vars%updates(2) .eqv. .true.)
call ok(state_vars%updates(3) .eqv. .true.)
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to test that state_vars%clamp_values is not allocated, since that is what your add_domain call is using to set clamping or not.


domain_id = add_domain(model_shape_file, nvars, &
var_names, quantity_list, clamp_vals, update_list )
domain_id = add_domain(model_shape_file, parse_variables_clamp(mitgcm_variables))
Copy link
Member

Choose a reason for hiding this comment

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

I don't think you can replace the routine for MITgcm_ocean because the original code adjusts the clamping values if you are doing a log transform for BGC variables:

! Adjust clamping in case of log-transform
if (quantity_list(i) == QTY_NITRATE_CONCENTRATION ) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_PHOSPHATE_CONCENTRATION ) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_DISSOLVED_OXYGEN ) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_PHYTOPLANKTON_BIOMASS ) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_ALKALINITY ) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_DISSOLVED_INORGANIC_CARBON) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_DISSOLVED_ORGANIC_P ) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_DISSOLVED_ORGANIC_NITROGEN) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_DISSOLVED_INORGANIC_IRON ) call adjust_clamp(clamp_vals(i, 1))
if (quantity_list(i) == QTY_SURFACE_CHLOROPHYLL ) call adjust_clamp(clamp_vals(i, 1))

update_list = update_var_list(1:nfields))
! parse_variables converts the character table that was read in from
! model_nml:model_state_variables and returns a state_var_type that
! can be passed to add_domain
Copy link
Member

Choose a reason for hiding this comment

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

This model_mod is missing the logic to use the default state variables if no model_state_variables = ' '
before calling add_domain

DART/models/POP/model_mod.f90

Lines 2774 to 2778 in f2deaa2

if ( state_variables(1) == ' ' ) then ! no model_state_variables namelist provided
call use_default_state_variables( state_variables )
string1 = 'model_nml:model_state_variables not specified using default variables'
call error_handler(E_MSG,'verify_state_variables',string1,source,revision,revdate)
endif

if model_state_variables = ' '
  call use_default_state_variables( state_variables )
  'blah blah using default state variables'
endif 
domain_id = add_domain('pop.r.nc', parse_variables(model_state_variables))

! parse_variables converts the character table that was read in from
! model_nml:model_state_variables and returns a state_var_type that can be
! passed to add_domain
domain_id = add_domain('cice.r.nc', parse_variables(model_state_variables))
Copy link
Member

Choose a reason for hiding this comment

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

Missing the logic for model_state_variables = ' '

DART/models/cice/model_mod.f90

Lines 2618 to 2622 in f2deaa2

if ( state_variables(1) == ' ' ) then ! no model_state_variables namelist provided
call use_default_state_variables( state_variables )
string1 = 'model_nml:model_state_variables not specified using default variables'
call error_handler(E_MSG,'verify_state_variables',string1,source,revision,revdate)
endif

@@ -2684,7 +2530,7 @@ subroutine use_default_state_variables( state_variables )
character(len=*), intent(inout) :: state_variables(:)

! strings must all be the same length for the gnu compiler
state_variables( 1:5*num_state_table_columns ) = &
state_variables( 1:5*3 ) = &
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
state_variables( 1:5*3 ) = &
state_variables( 1:15 ) = &

Copy link
Member

@hkershaw-brown hkershaw-brown left a comment

Choose a reason for hiding this comment

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

Hi Marlee, looks good.

I checked the template/threed_model_mod.f90 & threed_input.nml with new_model.sh

There are 3 model_mods that do need changing:
POP, CICE to have default state variable tables if none is specified in the namelist
MITgcm I don't think you can replace because the clamping values depend on whether a log transform is applied to BGC variables

Cheers,
Helen

@hkershaw-brown hkershaw-brown added the release+1 bundle with release after next label Jan 13, 2025
@mjs2369
Copy link
Contributor Author

mjs2369 commented Jan 13, 2025

I checked the template/threed_model_mod.f90 & threed_input.nml with new_model.sh

There are 3 model_mods that do need changing: POP, CICE to have default state variable tables if none is specified in the namelist MITgcm I don't think you can replace because the clamping values depend on whether a log transform is applied to BGC variables

Cheers, Helen

Thanks for all this Helen. I'll make these changes and let you know when it's ready for merging

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release+1 bundle with release after next
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: routine to read a table of state variables from namelist
3 participants