Skip to content

Commit

Permalink
Capgen in SCM: Multiple instances of local_name in Group Cap (#631)
Browse files Browse the repository at this point in the history
Description:
Allow for multiple instances of the same local_name being used in the
Group cap for two situations:
a) with different standard_names
b) in different DDTs .

User interface changes?: No

Fixes: #629 

Testing:
Added to var_compatibility_test to exercise feature.

This PR contains changes included in #630

---------

Co-authored-by: Dom Heinzeller <dom.heinzeller@icloud.com>
  • Loading branch information
dustinswales and climbfuji authored Feb 12, 2025
1 parent aed2471 commit 6c494b2
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 7 deletions.
25 changes: 25 additions & 0 deletions scripts/metavar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1677,12 +1677,37 @@ def add_variable(self, newvar, run_env, exists_ok=False, gen_unique=False,
context=newvar.context)
# end if
# end if
# Check if local_name exists in Group. If applicable, Create new
# variable with unique name. There are two instances when new names are
# created:
# - Same <local_name> used in different DDTs.
# - Different <standard_name> using the same <local_name> in a Group.
# During the Group analyze phase, <gen_unique> is True.
lname = newvar.get_prop_value('local_name')
lvar = self.find_local_name(lname)
if lvar is not None:
# Check if <lvar> is part of a different DDT than <newvar>.
# The API uses the full variable references when calling the Group Caps,
# <lvar.call_string(self))> and <newvar.call_string(self)>.
# Within the context of a full reference, it is allowable for local_names
# to be the same in different data containers.
newvar_callstr = newvar.call_string(self)
lvar_callstr = lvar.call_string(self)
if newvar_callstr and lvar_callstr:
if newvar_callstr != lvar_callstr:
if not gen_unique:
exists_ok = True
# end if
# end if
# end if
if gen_unique:
new_lname = self.new_internal_variable_name(prefix=lname)
newvar = newvar.clone(new_lname)
# Local_name needs to be the local_name for the new
# internal variable, otherwise multiple instances of the same
# local_name in the Group cap will all be overwritten with the
# same local_name
lname = new_lname
elif not exists_ok:
errstr = 'Invalid local_name: {} already registered{}'
cstr = context_string(lvar.source.context, with_comma=True)
Expand Down
2 changes: 1 addition & 1 deletion scripts/suite_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -2273,7 +2273,7 @@ def manage_variable(self, newvar):
ParseSource(_API_SOURCE_NAME,
_API_LOCAL_VAR_NAME, newvar.context),
self.run_env)
self.add_variable(local_var, self.run_env, exists_ok=True)
self.add_variable(local_var, self.run_env, exists_ok=True, gen_unique=True)
# Finally, make sure all dimensions are accounted for
emsg = self.add_variable_dimensions(local_var, _API_LOCAL_VAR_TYPES,
adjust_intent=True,
Expand Down
7 changes: 6 additions & 1 deletion test/var_compatibility_test/effr_diag.F90
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ end subroutine effr_diag_init
!> \section arg_table_effr_diag_run Argument Table
!! \htmlinclude arg_table_effr_diag_run.html
!!
subroutine effr_diag_run( effrr_in, errmsg, errflg)
subroutine effr_diag_run( effrr_in, scalar_var, errmsg, errflg)

real(kind_phys), intent(in) :: effrr_in(:,:)
integer, intent(in) :: scalar_var
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errflg
!----------------------------------------------------------------
Expand All @@ -49,6 +50,10 @@ subroutine effr_diag_run( effrr_in, errmsg, errflg)

call cmp_effr_diag(effrr_in, effrr_min, effrr_max)

if (scalar_var .ne. 380) then
errmsg = 'ERROR: effr_diag_run(): scalar_var should be 380'
errflg = 1
endif
end subroutine effr_diag_run

subroutine cmp_effr_diag(effr, effr_min, effr_max)
Expand Down
7 changes: 7 additions & 0 deletions test/var_compatibility_test/effr_diag.meta
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@
kind = kind_phys
intent = in
top_at_one = True
[ scalar_var ]
standard_name = scalar_variable_for_testing_c
long_name = unused scalar variable C
units = m
dimensions = ()
type = integer
intent = in
[ errmsg ]
standard_name = ccpp_error_message
long_name = Error message for error handling in CCPP
Expand Down
8 changes: 7 additions & 1 deletion test/var_compatibility_test/effr_post.F90
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ end subroutine effr_post_init
!> \section arg_table_effr_post_run Argument Table
!! \htmlinclude arg_table_effr_post_run.html
!!
subroutine effr_post_run( effrr_inout, errmsg, errflg)
subroutine effr_post_run( effrr_inout, scalar_var, errmsg, errflg)

real(kind_phys), intent(inout) :: effrr_inout(:,:)
real(kind_phys), intent(in) :: scalar_var
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errflg
!----------------------------------------------------------------
Expand All @@ -50,6 +51,11 @@ subroutine effr_post_run( effrr_inout, errmsg, errflg)
! Do some post-processing on effrr...
effrr_inout(:,:) = effrr_inout(:,:)*1._kind_phys

if (scalar_var .ne. 1013.0) then
errmsg = 'ERROR: effr_post_run(): scalar_var should be 1013.0'
errflg = 1
endif

end subroutine effr_post_run

end module effr_post
8 changes: 8 additions & 0 deletions test/var_compatibility_test/effr_post.meta
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
type = real
kind = kind_phys
intent = inout
[ scalar_var ]
standard_name = scalar_variable_for_testing_b
long_name = unused scalar variable B
units = m
dimensions = ()
type = real
kind = kind_phys
intent = in
[ errmsg ]
standard_name = ccpp_error_message
long_name = Error message for error handling in CCPP
Expand Down
8 changes: 7 additions & 1 deletion test/var_compatibility_test/effr_pre.F90
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ end subroutine effr_pre_init
!> \section arg_table_effr_pre_run Argument Table
!! \htmlinclude arg_table_effr_pre_run.html
!!
subroutine effr_pre_run( effrr_inout, errmsg, errflg)
subroutine effr_pre_run( effrr_inout, scalar_var, errmsg, errflg)

real(kind_phys), intent(inout) :: effrr_inout(:,:)
real(kind_phys), intent(in) :: scalar_var
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errflg
!----------------------------------------------------------------
Expand All @@ -49,6 +50,11 @@ subroutine effr_pre_run( effrr_inout, errmsg, errflg)
! Do some pre-processing on effrr...
effrr_inout(:,:) = effrr_inout(:,:)*1._kind_phys

if (scalar_var .ne. 273.15) then
errmsg = 'ERROR: effr_pre_run(): scalar_var should be 273.15'
errflg = 1
endif

end subroutine effr_pre_run

end module effr_pre
8 changes: 8 additions & 0 deletions test/var_compatibility_test/effr_pre.meta
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
type = real
kind = kind_phys
intent = inout
[ scalar_var ]
standard_name = scalar_variable_for_testing_a
long_name = unused scalar variable A
units = m
dimensions = ()
type = real
kind = kind_phys
intent = in
[ errmsg ]
standard_name = ccpp_error_message
long_name = Error message for error handling in CCPP
Expand Down
6 changes: 6 additions & 0 deletions test/var_compatibility_test/run_test
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_d
required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_loop_begin"
required_vars_var_compatibility="${required_vars_var_compatibility},horizontal_loop_end"
required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing"
required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing_a"
required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing_b"
required_vars_var_compatibility="${required_vars_var_compatibility},scalar_variable_for_testing_c"
required_vars_var_compatibility="${required_vars_var_compatibility},scheme_order_in_suite"
required_vars_var_compatibility="${required_vars_var_compatibility},vertical_layer_dimension"
input_vars_var_compatibility="cloud_graupel_number_concentration"
Expand All @@ -158,6 +161,9 @@ input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_dimensi
input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_loop_begin"
input_vars_var_compatibility="${input_vars_var_compatibility},horizontal_loop_end"
input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing"
input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing_a"
input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing_b"
input_vars_var_compatibility="${input_vars_var_compatibility},scalar_variable_for_testing_c"
input_vars_var_compatibility="${input_vars_var_compatibility},scheme_order_in_suite"
input_vars_var_compatibility="${input_vars_var_compatibility},vertical_layer_dimension"
output_vars_var_compatibility="ccpp_error_code,ccpp_error_message"
Expand Down
10 changes: 8 additions & 2 deletions test/var_compatibility_test/test_host.F90
Original file line number Diff line number Diff line change
Expand Up @@ -351,13 +351,16 @@ program test

character(len=cs), target :: test_parts1(1) = (/ 'radiation ' /)

character(len=cm), target :: test_invars1(9) = (/ &
character(len=cm), target :: test_invars1(12) = (/ &
'effective_radius_of_stratiform_cloud_rain_particle ', &
'effective_radius_of_stratiform_cloud_liquid_water_particle', &
'effective_radius_of_stratiform_cloud_snow_particle ', &
'effective_radius_of_stratiform_cloud_graupel ', &
'cloud_graupel_number_concentration ', &
'scalar_variable_for_testing ', &
'scalar_variable_for_testing_a ', &
'scalar_variable_for_testing_b ', &
'scalar_variable_for_testing_c ', &
'scheme_order_in_suite ', &
'flag_indicating_cloud_microphysics_has_graupel ', &
'flag_indicating_cloud_microphysics_has_ice '/)
Expand All @@ -374,7 +377,7 @@ program test
'scheme_order_in_suite '/)


character(len=cm), target :: test_reqvars1(13) = (/ &
character(len=cm), target :: test_reqvars1(16) = (/ &
'ccpp_error_code ', &
'ccpp_error_message ', &
'effective_radius_of_stratiform_cloud_rain_particle ', &
Expand All @@ -385,6 +388,9 @@ program test
'cloud_graupel_number_concentration ', &
'cloud_ice_number_concentration ', &
'scalar_variable_for_testing ', &
'scalar_variable_for_testing_a ', &
'scalar_variable_for_testing_b ', &
'scalar_variable_for_testing_c ', &
'scheme_order_in_suite ', &
'flag_indicating_cloud_microphysics_has_graupel ', &
'flag_indicating_cloud_microphysics_has_ice '/)
Expand Down
4 changes: 4 additions & 0 deletions test/var_compatibility_test/test_host_data.F90
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ module test_host_data
ncg, & ! number concentration of cloud graupel
nci ! number concentration of cloud ice
real(kind_phys) :: scalar_var
real(kind_phys) :: scalar_varA
real(kind_phys) :: scalar_varB
integer :: scalar_varC
integer :: scheme_order

end type physics_state

public allocate_physics_state
Expand Down
20 changes: 20 additions & 0 deletions test/var_compatibility_test/test_host_data.meta
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@
dimensions = ()
type = real
kind = kind_phys
[scalar_varA]
standard_name = scalar_variable_for_testing_a
long_name = unused scalar variable A
units = m
dimensions = ()
type = real
kind = kind_phys
[scalar_varB]
standard_name = scalar_variable_for_testing_b
long_name = unused scalar variable B
units = m
dimensions = ()
type = real
kind = kind_phys
[scalar_varC]
standard_name = scalar_variable_for_testing_c
long_name = unused scalar variable C
units = m
dimensions = ()
type = integer
[scheme_order]
standard_name = scheme_order_in_suite
long_name = scheme order in suite definition file
Expand Down
5 changes: 4 additions & 1 deletion test/var_compatibility_test/test_host_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ subroutine init_data()
call allocate_physics_state(ncols, pver, phys_state, has_graupel, has_ice)
phys_state%effrr = 1.0E-3 ! 1000 microns, in meter
phys_state%effrl = 1.0E-4 ! 100 microns, in meter
phys_state%scalar_var = 1.0 ! in m
phys_state%scalar_var = 1.0 ! in m
phys_state%scalar_varA = 273.15 ! in K
phys_state%scalar_varB = 1013.0 ! in mb
phys_state%scalar_varC = 380 ! in ppmv
effrs = 5.0E-4 ! 500 microns, in meter
if (has_graupel) then
phys_state%effrg = 2.5E-4 ! 250 microns, in meter
Expand Down
3 changes: 3 additions & 0 deletions test/var_compatibility_test/test_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ def usage(errmsg=None):
"effective_radius_of_stratiform_cloud_graupel",
"cloud_graupel_number_concentration",
"scalar_variable_for_testing",
"scalar_variable_for_testing_a",
"scalar_variable_for_testing_b",
"scalar_variable_for_testing_c",
"scheme_order_in_suite",
"flag_indicating_cloud_microphysics_has_graupel",
"flag_indicating_cloud_microphysics_has_ice"]
Expand Down

0 comments on commit 6c494b2

Please sign in to comment.