From 59994498fa895908aac2de9307f3e0e337b23f62 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Fri, 27 Sep 2024 22:56:11 -0600 Subject: [PATCH 1/9] add missing var_units check and copied field --- src/ccpp_constituent_prop_mod.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90 index 3370bff4..e4c4e002 100644 --- a/src/ccpp_constituent_prop_mod.F90 +++ b/src/ccpp_constituent_prop_mod.F90 @@ -225,6 +225,7 @@ 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 end subroutine copyConstituent !####################################################################### @@ -737,6 +738,7 @@ 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. & From bb58f977af39f096d153d5fc86425611b170b41d Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Mon, 30 Sep 2024 14:07:37 -0600 Subject: [PATCH 2/9] add optional water species variable to instantiate --- src/ccpp_constituent_prop_mod.F90 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90 index e4c4e002..d436370f 100644 --- a/src/ccpp_constituent_prop_mod.F90 +++ b/src/ccpp_constituent_prop_mod.F90 @@ -369,7 +369,7 @@ 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, errcode, errmsg) ! Initialize all fields in ! Dummy arguments @@ -382,6 +382,7 @@ 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 integer, intent(out) :: errcode character(len=*), intent(out) :: errmsg @@ -412,6 +413,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 From 7dd84c8f4dd212e4d3a6b52e6aa8688be542fa14 Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Mon, 30 Sep 2024 16:23:06 -0600 Subject: [PATCH 3/9] include mixing_ratio_type argument to instantiate --- src/ccpp_constituent_prop_mod.F90 | 33 +++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90 index d436370f..bb14ad66 100644 --- a/src/ccpp_constituent_prop_mod.F90 +++ b/src/ccpp_constituent_prop_mod.F90 @@ -369,7 +369,8 @@ end function ccp_is_instantiated !####################################################################### subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, & - advected, default_value, min_value, molar_mass, water_species, errcode, errmsg) + advected, default_value, min_value, molar_mass, water_species, & + mixing_ratio_type, errcode, errmsg) ! Initialize all fields in ! Dummy arguments @@ -383,6 +384,7 @@ subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, & 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 @@ -428,14 +430,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 From f3fc5a0272abf103c459d4002c364e57e59596f6 Mon Sep 17 00:00:00 2001 From: peverwhee Date: Mon, 4 Nov 2024 09:54:47 -0700 Subject: [PATCH 4/9] add tests for new instantiate fields; return from register on error before allocating --- scripts/host_cap.py | 3 ++ test/advection_test/cld_ice.F90 | 5 +- test/advection_test/cld_liq.F90 | 6 +-- test/advection_test/test_host.F90 | 86 ++++++++++++++++++++++++++++++- 4 files changed, 92 insertions(+), 8 deletions(-) diff --git a/scripts/host_cap.py b/scripts/host_cap.py index 3412e2cd..2c772d4b 100644 --- a/scripts/host_cap.py +++ b/scripts/host_cap.py @@ -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(): diff --git a/test/advection_test/cld_ice.F90 b/test/advection_test/cld_ice.F90 index ee53529d..759bcab1 100644 --- a/test/advection_test/cld_ice.F90 +++ b/test/advection_test/cld_ice.F90 @@ -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 diff --git a/test/advection_test/cld_liq.F90 b/test/advection_test/cld_liq.F90 index ec19cb17..ab40820f 100644 --- a/test/advection_test/cld_liq.F90 +++ b/test/advection_test/cld_liq.F90 @@ -23,8 +23,6 @@ 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) @@ -32,11 +30,11 @@ subroutine cld_liq_register(dyn_const, errmsg, errflg) 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 diff --git a/test/advection_test/test_host.F90 b/test/advection_test/test_host.F90 index 5146097b..74a9af90 100644 --- a/test/advection_test/test_host.F90 +++ b/test/advection_test/test_host.F90 @@ -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) @@ -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 ", & @@ -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 ! ------------------- @@ -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 From edab426cc63d8115ca2ba9cefd6557be4d939742 Mon Sep 17 00:00:00 2001 From: peverwhee Date: Mon, 4 Nov 2024 10:01:28 -0700 Subject: [PATCH 5/9] add const_water to equivalency check --- src/ccpp_constituent_prop_mod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90 index 6bdc2e6f..a81f4cac 100644 --- a/src/ccpp_constituent_prop_mod.F90 +++ b/src/ccpp_constituent_prop_mod.F90 @@ -229,6 +229,7 @@ subroutine copyConstituent(outConst, inConst) 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 !####################################################################### From 80338b5043492467a86516878e795b1965e4f88a Mon Sep 17 00:00:00 2001 From: peverwhee Date: Mon, 4 Nov 2024 10:50:10 -0700 Subject: [PATCH 6/9] add const_water property to equivalence check --- src/ccpp_constituent_prop_mod.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90 index a81f4cac..01107c2c 100644 --- a/src/ccpp_constituent_prop_mod.F90 +++ b/src/ccpp_constituent_prop_mod.F90 @@ -769,6 +769,7 @@ subroutine ccp_is_equivalent(this, oconst, equiv, errcode, errmsg) (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 .eqv. oconst%const_water) .and. & (this%water_species .eqv. oconst%water_species) else equiv = .false. From b95be3a3cd1c26e08b0dd6daa8c2c3473e7ac7f3 Mon Sep 17 00:00:00 2001 From: peverwhee Date: Mon, 4 Nov 2024 10:54:16 -0700 Subject: [PATCH 7/9] fix equals error --- src/ccpp_constituent_prop_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90 index 01107c2c..dc10a89d 100644 --- a/src/ccpp_constituent_prop_mod.F90 +++ b/src/ccpp_constituent_prop_mod.F90 @@ -769,7 +769,7 @@ subroutine ccp_is_equivalent(this, oconst, equiv, errcode, errmsg) (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 .eqv. oconst%const_water) .and. & + (this%const_water == oconst%const_water) .and. & (this%water_species .eqv. oconst%water_species) else equiv = .false. From 2ad470d8811df819b288997bda503d8468f73d48 Mon Sep 17 00:00:00 2001 From: peverwhee Date: Mon, 4 Nov 2024 13:48:55 -0700 Subject: [PATCH 8/9] initialize surface pressure array to appease gnu compiler --- test/advection_test/test_host_data.F90 | 1 + 1 file changed, 1 insertion(+) diff --git a/test/advection_test/test_host_data.F90 b/test/advection_test/test_host_data.F90 index c2d99798..ee33b66a 100644 --- a/test/advection_test/test_host_data.F90 +++ b/test/advection_test/test_host_data.F90 @@ -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 From 4448b182af943d57423550387d49890965a1361b Mon Sep 17 00:00:00 2001 From: Courtney Peverley Date: Tue, 5 Nov 2024 11:05:48 -0700 Subject: [PATCH 9/9] fix whitespace --- src/ccpp_constituent_prop_mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90 index dc10a89d..fde83d08 100644 --- a/src/ccpp_constituent_prop_mod.F90 +++ b/src/ccpp_constituent_prop_mod.F90 @@ -769,7 +769,7 @@ subroutine ccp_is_equivalent(this, oconst, equiv, errcode, errmsg) (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%const_water == oconst%const_water) .and. & (this%water_species .eqv. oconst%water_species) else equiv = .false.