ccpp-framework icon indicating copy to clipboard operation
ccpp-framework copied to clipboard

DRAFT TO DISCUSS - add CCPP register phase

Open peverwhee opened this issue 1 year ago • 0 comments

Overview

This PR adds a new phase, register, that can be called by a host model and used by schemes to perform any set up that needs to happen BEFORE the grid is established.

NOTE: this PR also removes the old dynamic_constituent_routine metadata implementation for runtime constituents.

Description

I have implemented it as an "optional" phase, by which I mean that it is not required that a host model call this phase (though I'm happy to be overruled!). As a result, the register phase does not change the CCPP "state" (but will produce an error if it is called after the init phase).

More:

Dynamic/run-time constituent handling:

  • If a scheme has run-time constituents, those shall be allocated, instantiated, and returned from the scheme's register phase. This metadata is required (the framework determines that there are runtime constituents from a scheme if there is a ccpp_constituent_properties_t variable required):
[ <unique dynamic constituent local name> ]
  standard_name = <some unique standard name>
  dimensions = (:)
  type = ccpp_constituent_properties_t
  intent = out
  allocatable = true
  • The standard name doesn't really matter but MUST be different from other runtime constituent standard names in the scheme; it may be easiest to standardize this to something like dynamic_constituents_for_<scheme>
  • The framework will then compile all scheme constituents into module-level variables in the host cap called <suite>_dynamic_constituents, which are then used to pack and initialize the module level constituents object <host>_constituents_obj.
  • If there are no dynamic constituents registered by any schemes within a suite, that suite's dynamic constituents array is allocated to 0.

Generated host cap code examples

  1. Multiple schemes have dynamic constituents:
subroutine test_host_ccpp_physics_register(suite_name, errmsg, errflg)

      use ccpp_cld_suite_cap, only: cld_suite_register

      character(len=*)                         :: suite_name
      character(len=512)                       :: errmsg
      integer                                  :: errflg
      type(ccpp_constituent_properties_t),allocatable          :: dyn_const(:)
      type(ccpp_constituent_properties_t),allocatable          :: dyn_const_ice(:)
      integer                                  :: num_dyn_consts
      integer                                  :: const_index

      errflg = 0
      errmsg = ""
      if (trim(suite_name) == 'cld_suite') then
         call cld_suite_register(errflg=errflg, errmsg=errmsg, dyn_const=dyn_const,               &
              dyn_const_ice=dyn_const_ice)
         allocate(cld_suite_dynamic_constituents(0+size(dyn_const)+size(dyn_const_ice)))
         ! Pack the suite-level dynamic, run-time constituents array
         num_dyn_consts = 0
         do const_index = 1, size(dyn_const)
            cld_suite_dynamic_constituents(num_dyn_consts + const_index) = dyn_const(const_index)
         end do
         num_dyn_consts = num_dyn_consts + size(dyn_const)
         deallocate(dyn_const)
         do const_index = 1, size(cld_suite_dynamic_constituents)
            call cld_suite_dynamic_constituents(const_index)%standard_name(stdname,               &
                 errcode=errflg, errmsg=errmsg)
         end do
         do const_index = 1, size(dyn_const_ice)
            cld_suite_dynamic_constituents(num_dyn_consts + const_index) =                        &
                 dyn_const_ice(const_index)
         end do
         num_dyn_consts = num_dyn_consts + size(dyn_const_ice)
         deallocate(dyn_const_ice)
      else
         write(errmsg, '(3a)')"No suite named ", trim(suite_name), "found"
         errflg = 1
      end if

   end subroutine test_host_ccpp_physics_register
  1. No schemes have dynamic constituents:
subroutine test_host_ccpp_physics_register(suite_name, errmsg, errflg)

      use ccpp_ddt_suite_cap,  only: ddt_suite_register
      use ccpp_temp_suite_cap, only: temp_suite_register

      character(len=*)                         :: suite_name
      character(len=512)                       :: errmsg
      integer                                  :: errflg

      errflg = 0
      errmsg = ""
      if (trim(suite_name) == 'ddt_suite') then
         call ddt_suite_register(errflg=errflg, errmsg=errmsg)
         ! Suite does not return dynamic constituents; allocate to zero
         allocate(ddt_suite_dynamic_constituents(0))
      else if (trim(suite_name) == 'temp_suite') then
         call temp_suite_register(errflg=errflg, errmsg=errmsg, config_var=config_var)
         ! Suite does not return dynamic constituents; allocate to zero
         allocate(temp_suite_dynamic_constituents(0))
      else
         write(errmsg, '(3a)')"No suite named ", trim(suite_name), "found"
         errflg = 1
      end if

   end subroutine test_host_ccpp_physics_register

Misc notes

Since this phase is called before the grid is initialized, variables are not allocated at this time (that still happens in init) and no variables with horizontal and vertical dimensions can be passed in.

UI Changes

User interface changes?: Yes, but they're optional If a host model wishes to utilize schemes' register phases, they must add a call to <host_model>_ccpp_physics_register(suite_name, errmsg, errflg)

Testing

test removed: removed unit tests for dyn_const_routines (old implementation of runtime constituent handling) unit tests: Removed old dynamic constituents testing system tests: Updated capgen and advection tests to include register phases (with and without dynamic constituents) manual testing:

This update needs some additional testing and error handling (will implement during/after discussion), such as:

  • Test/handle when a scheme tries to output runtime constituents from a non-register phase
  • Test/handle when two schemes have the same standard name for their dynamic constituents?
  • Test/handle when scheme tries to use the wrong constituents DDT?

Fixes: closes #572

peverwhee avatar Aug 05 '24 18:08 peverwhee