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

Implement and finish MPAS dynamical core initialization #267

Merged

Conversation

kuanchihwang
Copy link
Collaborator

This PR implements the dyn_init subroutine, which is responsible for initializing MPAS dynamical core by one of the following methods:

  1. Setting analytic initial condition.
  2. Reading initial condition from a file.
  3. Restarting from a file.

This should be the last step of MPAS dynamical core initialization. After this PR, MPAS dynamical core is ready for time integration.

Implementation notes:

  • More elaborate error checking for the allocation of constituents.
  • Support for deferring the definition of constituents until run-time. There are no longer assumptions about the index order or position of constituents.
  • Accessor functions/subroutines for querying:
    • Local mesh dimensions.
    • Constituent names and indexes.
    • Mapping between constituent indexes and MPAS scalar indexes.
  • Enhancements that enable constructing an arbitrary list of variables to input/output data to/from MPAS dynamical core.
  • Enhancements and fixes for handling ordinary variables and variable arrays during input.
  • Finish MPAS dynamical core initialization.

Test steps:

"<path-to>/CAM-SIMA/cime/scripts/create_newcase" --case "<case-name>" --compset FKESSLER --project "<project-id>" --res mpasa480_mpasa480 --run-unsupported
cd "<case-name>"
./case.setup
./xmlchange CAM_LINKED_LIBS="-lmpas"
./xmlchange DEBUG="TRUE"
./xmlchange DOUT_S="FALSE"
# Add the following to `user_nl_cam`:
# * `config_block_decomp_file_prefix = '${DIN_LOC_ROOT}/atm/cam/inic/mpas/mpasa480.graph.info.part.'`.
# * `config_dt = 1800.0`.
./case.build
./case.submit

Observe log entries similar to the following in atm.log.<job-id>.<date>-<time>:

dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_define_scalar entered
dyn_mpas_debug_print (0): Constituent index 1
dyn_mpas_debug_print (0):     Constituent name: cloud_liquid_water_mixing_ratio_wrt_moist_air_and_condensed_water
dyn_mpas_debug_print (0):     Is water species: T
dyn_mpas_debug_print (0):     Index mapping from constituent to MPAS scalar: 1 -> 1
dyn_mpas_debug_print (0): Constituent index 2
dyn_mpas_debug_print (0):     Constituent name: rain_mixing_ratio_wrt_moist_air_and_condensed_water
dyn_mpas_debug_print (0):     Is water species: T
dyn_mpas_debug_print (0):     Index mapping from constituent to MPAS scalar: 2 -> 2
dyn_mpas_debug_print (0): Constituent index 3
dyn_mpas_debug_print (0):     Constituent name: water_vapor_mixing_ratio_wrt_moist_air_and_condensed_water
dyn_mpas_debug_print (0):     Is water species: T
dyn_mpas_debug_print (0):     Index mapping from constituent to MPAS scalar: 3 -> 3
dyn_mpas_debug_print (0): MPAS scalar index 1
dyn_mpas_debug_print (0):     MPAS scalar name: cloud_liquid_water_mixing_ratio_wrt_moist_air_and_condensed_water
dyn_mpas_debug_print (0):     Is water species: T
dyn_mpas_debug_print (0):     Index mapping from MPAS scalar to constituent: 1 -> 1
dyn_mpas_debug_print (0): MPAS scalar index 2
dyn_mpas_debug_print (0):     MPAS scalar name: rain_mixing_ratio_wrt_moist_air_and_condensed_water
dyn_mpas_debug_print (0):     Is water species: T
dyn_mpas_debug_print (0):     Index mapping from MPAS scalar to constituent: 2 -> 2
dyn_mpas_debug_print (0): MPAS scalar index 3
dyn_mpas_debug_print (0):     MPAS scalar name: water_vapor_mixing_ratio_wrt_moist_air_and_condensed_water
dyn_mpas_debug_print (0):     Is water species: T
dyn_mpas_debug_print (0):     Index mapping from MPAS scalar to constituent: 3 -> 3
dyn_mpas_debug_print (0): index_qv = 3
dyn_mpas_debug_print (0): moist_start = 1
dyn_mpas_debug_print (0): moist_end = 3
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_define_scalar completed
dyn_debug_print (0): Calling check_topography_data
dyn_debug_print (0): Topography file is not used
dyn_debug_print (0): Calling set_analytic_initial_condition
dyn_debug_print (0): Preparing to set analytic initial condition
dyn_debug_print (0): Setting MPAS state "u"
           U initialized by "BC_WAV_SET_IC"
           V initialized by "BC_WAV_SET_IC"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_compute_edge_wind entered
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "uReconstructZonal"
dyn_mpas_debug_print (0): Exchanging halo layers for "uReconstructZonal"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "uReconstructMeridional"
dyn_mpas_debug_print (0): Exchanging halo layers for "uReconstructMeridional"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "u"
dyn_mpas_debug_print (0): Exchanging halo layers for "u"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_compute_edge_wind completed
dyn_debug_print (0): Setting MPAS state "w"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "w"
dyn_mpas_debug_print (0): Exchanging halo layers for "w"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_debug_print (0): Setting MPAS state "scalars"
dyn_debug_print (0): Conversion is needed and applied for water vapor mixing ratio
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "scalars"
dyn_mpas_debug_print (0): Exchanging halo layers for "scalars"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_debug_print (0): Setting MPAS state "rho" and "theta"
 BC_WAV_SET_IC: Model top (in km) is at z=    41.426919000000005     
           PS initialized by "BC_WAV_SET_IC"
           T initialized by "BC_WAV_SET_IC"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "rho"
dyn_mpas_debug_print (0): Exchanging halo layers for "rho"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "theta"
dyn_mpas_debug_print (0): Exchanging halo layers for "theta"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_debug_print (0): Setting MPAS state "rho_base" and "theta_base"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "rho_base"
dyn_mpas_debug_print (0): Exchanging halo layers for "rho_base"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo entered
dyn_mpas_debug_print (0): Inquiring field information for "theta_base"
dyn_mpas_debug_print (0): Exchanging halo layers for "theta_base"
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_exchange_halo completed
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_init_phase4 entered
dyn_mpas_debug_print (0): Coupling time interval is   1800.000000 seconds
dyn_mpas_debug_print (0): Time step is   1800.000000 seconds
dyn_mpas_debug_print (0): Setting up OpenMP threading
dyn_mpas_debug_print (0): Setting up dimensions
dyn_mpas_debug_print (0): Initializing time levels
dyn_mpas_debug_print (0): Initializing atmospheric variables
dyn_mpas_debug_print (0): Initializing dynamics
dyn_mpas_debug_print (0): dyn_mpas_subdriver::dyn_mpas_init_phase4 completed
dyn_mpas_debug_print (0): Successful initialization of MPAS dynamical core

Relative humidity (`relhum`) is a diagnostic variable.
It should not be included in MPAS input stream.
More elaborate error checking.
Also use a more descriptive name for number of constituents.
* Finish MPAS dynamical core initialization.
* Support for deferring the definition of constituents until run-time.
* Accessor functions/subroutines for querying:
  * Local mesh dimensions.
  * Constituent names and indexes.
  * Mapping between constituent indexes and MPAS scalar indexes.
It is now possible to construct an arbitrary list of variables
to input/output data to/from MPAS dynamical core. This functionality
may be overengineered, but it supports what CAM-SIMA needs.
There are two kinds of variables in MPAS: ordinary variables and
variable arrays. The old implementation would always skip the latter
entirely when encountering them during input.

The new implementation correctly distinguishes between the two, and
checks whether each variable is eligible to be input.
The instance of MPAS dynamical core resides in `dyn_comp`. `dyn_grid` depends on
`dyn_comp`, but not vice versa.
Copy link
Collaborator

@nusbaume nusbaume left a comment

Choose a reason for hiding this comment

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

Exciting to see that we can now fully initialize the MPAS dycore in CAM-SIMA, good work!

I do have some change requests though. Of course please let me know if you have any questions or concerns with any of my comments or suggestions. Thanks!

src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/driver/dyn_mpas_subdriver.F90 Outdated Show resolved Hide resolved
Maintain consistent style with others.
Copy link
Collaborator

@nusbaume nusbaume left a comment

Choose a reason for hiding this comment

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

Looks good to me now! I did have some final cleanup requests, but it doesn't need a re-review (from me at least). Thanks!

src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
Copy link
Collaborator

@mgduda mgduda left a comment

Choose a reason for hiding this comment

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

I haven't yet had a chance to try different types of ICs, so I'll likely make a second pass with some further comments.

src/dynamics/mpas/driver/dyn_mpas_subdriver.F90 Outdated Show resolved Hide resolved
type(file_desc_t), pointer, intent(in) :: pio_file

character(*), parameter :: subname = 'dyn_mpas_subdriver::dyn_mpas_init_phase3'
character(strkind) :: mesh_filename
integer :: mesh_format
integer, pointer :: num_scalars => null()
type(mpas_pool_type), pointer :: mpas_pool => null()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Rather than initialize these here (adding the implicit SAVE attribute), is there a reason to not just nullify these either at the beginning of this routine or just before they are (hopefully) set? Would doing this remove the need to explicitly nullify these at the end of the subroutine?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I pushed a731e97 to avoid explicit initialization of pointers.

Thanks for catching this. I don't know why I thought the rule doesn't apply to pointers.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's possible that I'm wrong, but `5.1 Type declaration statements" of the 2003 standard states:

33 If initialization is =>null-init, object-name shall be a pointer, and its initial association status is disas-
34 sociated.
35 The presence of initialization implies that object-name is saved, except for an object-name in a named
36 common block or an object-name with the PARAMETER attribute. The implied SAVE attribute may
37 be reaffirmed by explicit use of the SAVE attribute in the type declaration statement, by inclusion of
38 the object-name in a SAVE statement (5.2.12), or by the appearance of a SAVE statement without a
39 saved-entity -list in the same scoping unit.

src/dynamics/mpas/driver/dyn_mpas_subdriver.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/driver/dyn_mpas_subdriver.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/driver/dyn_mpas_subdriver.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
src/dynamics/mpas/dyn_comp.F90 Outdated Show resolved Hide resolved
According to "8.4 Initialization", it states "Explicit initialization of a
variable that is not in a common block implies the SAVE attribute". This
also applies to pointer variables like here.

Avoid the implied SAVE attribute by removing explicit initialization. Uphold
the principle of least astonishment.
Easier to pinpoint where error occurs.
Zero or negative values are not allowed. Others are just fine.
@kuanchihwang kuanchihwang requested a review from mgduda July 29, 2024 21:02
Copy link
Collaborator

@mgduda mgduda left a comment

Choose a reason for hiding this comment

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

Apologies for taking so long to complete this review! This all seems good to me.

@kuanchihwang kuanchihwang merged commit 8d71300 into ESCOMP:development Aug 1, 2024
6 checks passed
@kuanchihwang kuanchihwang deleted the staging/implement-dyn-init branch August 1, 2024 01:20
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.

3 participants