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

Constituent bugfixes #608

Merged
merged 10 commits into from
Nov 5, 2024
3 changes: 3 additions & 0 deletions scripts/host_cap.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,9 @@ def write_host_cap(host_model, api, module_name, output_dir, run_env):
call_str = suite_part_call_list(host_model, const_dict, spart, False,
dyn_const=True)
cap.write(f"call {suite.name}_{stage}({call_str})", 3)
cap.write("if (errflg /= 0) then", 3)
cap.write("return", 4)
cap.write("end if", 3)
# Allocate the suite's dynamic constituents array
size_string = "0+"
for var in host_local_vars.variable_list():
Expand Down
41 changes: 33 additions & 8 deletions src/ccpp_constituent_prop_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ subroutine copyConstituent(outConst, inConst)
outConst%molar_mass_val = inConst%molar_mass_val
outConst%thermo_active = inConst%thermo_active
outConst%water_species = inConst%water_species
outConst%var_units = inConst%var_units
outConst%const_water = inConst%const_water
end subroutine copyConstituent

!#######################################################################
Expand Down Expand Up @@ -371,7 +373,8 @@ end function ccp_is_instantiated
!#######################################################################

subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, &
advected, default_value, min_value, molar_mass, errcode, errmsg)
advected, default_value, min_value, molar_mass, water_species, &
mixing_ratio_type, errcode, errmsg)
! Initialize all fields in <this>

! Dummy arguments
Expand All @@ -384,6 +387,8 @@ subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, &
real(kind_phys), optional, intent(in) :: default_value
real(kind_phys), optional, intent(in) :: min_value
real(kind_phys), optional, intent(in) :: molar_mass
logical, optional, intent(in) :: water_species
character(len=*), optional, intent(in) :: mixing_ratio_type
integer, intent(out) :: errcode
character(len=*), intent(out) :: errmsg

Expand Down Expand Up @@ -414,6 +419,9 @@ subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, &
if (present(molar_mass)) then
this%molar_mass_val = molar_mass
end if
if (present(water_species)) then
this%water_species = water_species
end if
end if
if (errcode == 0) then
if (index(this%var_std_name, "volume_mixing_ratio") > 0) then
Expand All @@ -426,14 +434,29 @@ subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, &
end if
if (errcode == 0) then
! Determine if this mixing ratio is dry, moist, or "wet".
if (index(this%var_std_name, "wrt_moist_air") > 0) then
this%const_water = moist_mixing_ratio
else if (this%var_std_name == "specific_humidity") then
this%const_water = moist_mixing_ratio
else if (this%var_std_name == "wrt_total_mass") then
this%const_water = wet_mixing_ratio
! If a type was provided, use that (if it's valid)
if (present(mixing_ratio_type)) then
if (trim(mixing_ratio_type) == 'wet') then
this%const_water = wet_mixing_ratio
else if (trim(mixing_ratio_type) == 'moist') then
this%const_water = moist_mixing_ratio
else if (trim(mixing_ratio_type) == 'dry') then
this%const_water = dry_mixing_ratio
else
errcode = 1
write(errmsg, *) 'ccp_instantiate: invalid mixing ratio type. ', &
'Must be one of: "wet", "moist", or "dry". Got: "', &
trim(mixing_ratio_type), '"'
end if
else
this%const_water = dry_mixing_ratio
! Otherwise, parse it from the standard name
if (index(this%var_std_name, "wrt_moist_air_and_condensed_water") > 0) then
this%const_water = wet_mixing_ratio
else if (index(this%var_std_name, "wrt_moist_air") > 0) then
this%const_water = moist_mixing_ratio
else
this%const_water = dry_mixing_ratio
end if
end if
end if
if (errcode /= 0) then
Expand Down Expand Up @@ -740,11 +763,13 @@ subroutine ccp_is_equivalent(this, oconst, equiv, errcode, errmsg)
equiv = (trim(this%var_std_name) == trim(oconst%var_std_name)) .and. &
(trim(this%var_long_name) == trim(oconst%var_long_name)) .and. &
(trim(this%vert_dim) == trim(oconst%vert_dim)) .and. &
(trim(this%var_units) == trim(oconst%var_units)) .and. &
(this%advected .eqv. oconst%advected) .and. &
(this%const_default_value == oconst%const_default_value) .and. &
(this%min_val == oconst%min_val) .and. &
(this%molar_mass_val == oconst%molar_mass_val) .and. &
(this%thermo_active .eqv. oconst%thermo_active) .and. &
(this%const_water == oconst%const_water) .and. &
(this%water_species .eqv. oconst%water_species)
else
equiv = .false.
Expand Down
5 changes: 3 additions & 2 deletions test/advection_test/cld_ice.F90
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ subroutine cld_ice_register(dyn_const_ice, errmsg, errcode)
call dyn_const_ice(1)%instantiate(std_name='dyn_const1', long_name='dyn const1', &
units='kg kg-1', default_value=0._kind_phys, &
vertical_dim='vertical_layer_dimension', advected=.true., &
min_value=1000._kind_phys, errcode=errcode, errmsg=errmsg)
min_value=1000._kind_phys, water_species=.true., mixing_ratio_type='wet', &
errcode=errcode, errmsg=errmsg)
call dyn_const_ice(2)%instantiate(std_name='dyn_const2_wrt_moist_air', long_name='dyn const2', &
units='kg kg-1', default_value=0._kind_phys, &
vertical_dim='vertical_layer_dimension', advected=.true., &
errcode=errcode, errmsg=errmsg)
water_species=.false., errcode=errcode, errmsg=errmsg)

end subroutine cld_ice_register

Expand Down
6 changes: 2 additions & 4 deletions test/advection_test/cld_liq.F90
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,18 @@ subroutine cld_liq_register(dyn_const, errmsg, errflg)
character(len=512), intent(out) :: errmsg
integer, intent(out) :: errflg

character(len=256) :: stdname

errmsg = ''
errflg = 0
allocate(dyn_const(1), stat=errflg)
if (errflg /= 0) then
errmsg = 'Error allocating dyn_const in cld_liq_register'
return
end if
call dyn_const(1)%instantiate(std_name="dyn_const3", long_name='dyn const3', &
call dyn_const(1)%instantiate(std_name="dyn_const3_wrt_moist_air_and_condensed_water", long_name='dyn const3', &
units='kg kg-1', default_value=1._kind_phys, &
vertical_dim='vertical_layer_dimension', advected=.true., &
water_species=.true., mixing_ratio_type='dry', &
errcode=errflg, errmsg=errmsg)
call dyn_const(1)%standard_name(stdname, errcode=errflg, errmsg=errmsg)

end subroutine cld_liq_register

Expand Down
86 changes: 84 additions & 2 deletions test/advection_test/test_host.F90
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ subroutine test_host(retval, test_suites)
call test_host_const_get_index('dyn_const2_wrt_moist_air', index_dyn2, errflg, errmsg)
call check_errflg(subname//".index_dyn_const2", errflg, errmsg, &
errflg_final)
call test_host_const_get_index('dyn_const3', index_dyn3, errflg, errmsg)
call test_host_const_get_index('dyn_const3_wrt_moist_air_and_condensed_water', index_dyn3, errflg, errmsg)
call check_errflg(subname//".index_dyn_const3", errflg, errmsg, &
errflg_final)

Expand Down Expand Up @@ -602,7 +602,38 @@ subroutine test_host(retval, test_suites)
! Reset error flag to continue testing other properties:
errflg = 0
end if
! Check moist mixing ratio for a dynamic constituent
! Check wet mixing ratio for dynamic constituent 1
call const_props(index_dyn1)%is_dry(const_log, errflg, errmsg)
if (errflg /= 0) then
write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", &
"to get dry prop for dyn_const1 index = ", index_dyn1, trim(errmsg)
errflg_final = -1 ! Notify test script that a failure occurred
end if
if (errflg == 0) then
if (const_log) then
write(6, *) "ERROR: dyn_const1 is dry and should be wet"
errflg_final = -1
end if
else
! Reset error flag to continue testing other properties:
errflg = 0
end if
call const_props(index_dyn1)%is_wet(const_log, errflg, errmsg)
if (errflg /= 0) then
write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", &
"to get wet prop for dyn_const1 index = ", index_dyn1, trim(errmsg)
errflg_final = -1 ! Notify test script that a failure occurred
end if
if (errflg == 0) then
if (.not. const_log) then
write(6, *) "ERROR: dyn_const1 is not wet but should be"
errflg_final = -1
end if
else
! Reset error flag to continue testing other properties:
errflg = 0
end if
! Check moist mixing ratio for dynamic constituent 2
call const_props(index_dyn2)%is_dry(const_log, errflg, errmsg)
if (errflg /= 0) then
write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", &
Expand Down Expand Up @@ -633,6 +664,22 @@ subroutine test_host(retval, test_suites)
! Reset error flag to continue testing other properties:
errflg = 0
end if
! Check dry mixing ratio for dynamic constituent 3
call const_props(index_dyn3)%is_dry(const_log, errflg, errmsg)
if (errflg /= 0) then
write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", &
"to get dry prop for dyn_const3 index = ", index_dyn3, trim(errmsg)
errflg_final = -1 ! Notify test script that a failure occurred
end if
if (errflg == 0) then
if (.not. const_log) then
write(6, *) "ERROR: dyn_const3 is not dry and should be"
errflg_final = -1
end if
else
! Reset error flag to continue testing other properties:
errflg = 0
end if

! -------------------

Expand Down Expand Up @@ -866,6 +913,41 @@ subroutine test_host(retval, test_suites)
! Reset error flag to continue testing other properties:
errflg = 0
end if

! Check that setting a constituent to be a water species via the
! instantiate call works as expected
call const_props(index_dyn1)%is_water_species(check, errflg, errmsg)
if (errflg /= 0) then
write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, &
"trying to get water_species prop for dyn_const1 index = ", &
index_dyn1, trim(errmsg)
end if
if (errflg == 0) then
if (.not. check) then ! Should now be True
write(6,*) "ERROR: 'water_species=.true. did not set", &
" water_species constituent property correctly"
errflg_final = -1 ! Notify test script that a failure occurred
end if
else
! Reset error flag to continue testing other properties:
errflg = 0
end if
call const_props(index_dyn2)%is_water_species(check, errflg, errmsg)
if (errflg /= 0) then
write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, &
"trying to get water_species prop for dyn_const2 index = ", &
index_dyn2, trim(errmsg)
end if
if (errflg == 0) then
if (check) then ! Should now be False
write(6,*) "ERROR: 'water_species=.false. did not set", &
" water_species constituent property correctly"
errflg_final = -1 ! Notify test script that a failure occurred
end if
else
! Reset error flag to continue testing other properties:
errflg = 0
end if
! -------------------

! Check that setting a constituent's default value works as expected
Expand Down
1 change: 1 addition & 0 deletions test/advection_test/test_host_data.F90
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ subroutine allocate_physics_state(cols, levels, constituents, state)
deallocate(state%ps)
end if
allocate(state%ps(cols))
state%ps = 0.0_kind_phys
if (allocated(state%temp)) then
deallocate(state%temp)
end if
Expand Down
Loading