diff --git a/scripts/constituents.py b/scripts/constituents.py index 4fdebee4..9a7489a5 100644 --- a/scripts/constituents.py +++ b/scripts/constituents.py @@ -28,7 +28,7 @@ class ConstituentVarDict(VarDictionary): allocation and support for these variables. """ - __const_prop_array_name = "ccpp_constituent_array" + __const_prop_array_name = "ccpp_constituents" __const_prop_init_name = "ccpp_constituents_initialized" __const_prop_init_consts = "ccpp_create_constituent_array" __constituent_type = "suite" diff --git a/scripts/host_cap.py b/scripts/host_cap.py index 4cebb517..35f7fae1 100644 --- a/scripts/host_cap.py +++ b/scripts/host_cap.py @@ -217,7 +217,7 @@ def add_constituent_vars(cap, host_model, suite_list, run_env): to create the dictionary. """ # First create a MetadataTable for the constituents DDT - stdname_layer = "ccpp_num_constituents" + stdname_layer = "number_of_ccpp_constituents" horiz_dim = "horizontal_dimension" vert_layer_dim = "vertical_layer_dimension" vert_interface_dim = "vertical_interface_dimension" @@ -232,7 +232,7 @@ def add_constituent_vars(cap, host_model, suite_list, run_env): f" standard_name = {stdname_layer}", " units = count", " dimensions = ()", " type = integer", f"[ {array_layer} ]", - " standard_name = ccpp_constituent_array", + " standard_name = ccpp_constituents", " units = none", f" dimensions = ({horiz_dim}, {vert_layer_dim}, {stdname_layer})", " type = real", " kind = kind_phys"] diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90 index df80ec0d..c9f5322b 100644 --- a/src/ccpp_constituent_prop_mod.F90 +++ b/src/ccpp_constituent_prop_mod.F90 @@ -35,6 +35,7 @@ module ccpp_constituent_prop_mod character(len=:), private, allocatable :: vert_dim integer, private :: const_ind = int_unassigned logical, private :: advected = .false. + logical, private :: thermo_active = .false. ! While the quantities below can be derived from the standard name, ! this implementation avoids string searching in parameterizations ! const_type distinguishes mass, volume, and number conc. mixing ratios @@ -61,6 +62,7 @@ module ccpp_constituent_prop_mod procedure :: vertical_dimension => ccp_get_vertical_dimension procedure :: const_index => ccp_const_index procedure :: is_advected => ccp_is_advected + procedure :: is_thermo_active => ccp_is_thermo_active procedure :: equivalent => ccp_is_equivalent procedure :: is_mass_mixing_ratio => ccp_is_mass_mixing_ratio procedure :: is_volume_mixing_ratio => ccp_is_volume_mixing_ratio @@ -76,9 +78,10 @@ module ccpp_constituent_prop_mod procedure :: copyConstituent generic :: assignment(=) => copyConstituent ! Methods that change state (XXgoldyXX: make private?) - procedure :: instantiate => ccp_instantiate - procedure :: deallocate => ccp_deallocate - procedure :: set_const_index => ccp_set_const_index + procedure :: instantiate => ccp_instantiate + procedure :: deallocate => ccp_deallocate + procedure :: set_const_index => ccp_set_const_index + procedure :: set_thermo_active => ccp_set_thermo_active end type ccpp_constituent_properties_t !! \section arg_table_ccpp_constituent_prop_ptr_t @@ -96,6 +99,7 @@ module ccpp_constituent_prop_mod procedure :: vertical_dimension => ccpt_get_vertical_dimension procedure :: const_index => ccpt_const_index procedure :: is_advected => ccpt_is_advected + procedure :: is_thermo_active => ccpt_is_thermo_active procedure :: is_mass_mixing_ratio => ccpt_is_mass_mixing_ratio procedure :: is_volume_mixing_ratio => ccpt_is_volume_mixing_ratio procedure :: is_number_concentration => ccpt_is_number_concentration @@ -109,8 +113,9 @@ module ccpp_constituent_prop_mod ! ccpt_set: Set the internal pointer procedure :: set => ccpt_set ! Methods that change state (XXgoldyXX: make private?) - procedure :: deallocate => ccpt_deallocate - procedure :: set_const_index => ccpt_set_const_index + procedure :: deallocate => ccpt_deallocate + procedure :: set_const_index => ccpt_set_const_index + procedure :: set_thermo_active => ccpt_set_thermo_active end type ccpp_constituent_prop_ptr_t !! \section arg_table_ccpp_model_constituents_t @@ -596,6 +601,45 @@ end subroutine ccp_set_const_index !####################################################################### + subroutine ccp_set_thermo_active(this, thermo_flag, errcode, errmsg) + ! Set whether this constituent is thermodynamically active, which + ! means that certain physics schemes will use this constitutent + ! when calculating thermodynamic quantities (e.g. enthalpy). + + ! Dummy arguments + class(ccpp_constituent_properties_t), intent(inout) :: this + logical, intent(in) :: thermo_flag + integer, optional, intent(out) :: errcode + character(len=*), optional, intent(out) :: errmsg + + !Set thermodynamically active flag for this constituent: + if (this%is_instantiated(errcode, errmsg)) then + this%thermo_active = thermo_flag + end if + + end subroutine ccp_set_thermo_active + + !####################################################################### + + subroutine ccp_is_thermo_active(this, val_out, errcode, errmsg) + + ! Dummy arguments + class(ccpp_constituent_properties_t), intent(in) :: this + logical, intent(out) :: val_out + integer, optional, intent(out) :: errcode + character(len=*), optional, intent(out) :: errmsg + + !If instantiated then check if constituent is + !thermodynamically active, otherwise return false: + if (this%is_instantiated(errcode, errmsg)) then + val_out = this%thermo_active + else + val_out = .false. + end if + end subroutine ccp_is_thermo_active + + !####################################################################### + subroutine ccp_is_advected(this, val_out, errcode, errmsg) ! Dummy arguments @@ -628,7 +672,8 @@ subroutine ccp_is_equivalent(this, oconst, equiv, errcode, errmsg) (trim(this%var_long_name) == trim(oconst%var_long_name)) .and. & (trim(this%vert_dim) == trim(oconst%vert_dim)) .and. & (this%advected .eqv. oconst%advected) .and. & - (this%const_default_value == oconst%const_default_value) + (this%const_default_value == oconst%const_default_value) .and. & + (this%thermo_active .eqv. oconst%thermo_active) else equiv = .false. end if @@ -1339,8 +1384,8 @@ end subroutine ccp_model_const_reset !######################################################################## - logical function ccp_model_const_is_match(this, index, advected) & - result(is_match) + logical function ccp_model_const_is_match(this, index, advected, & + thermo_active) result(is_match) ! Return .true. iff the constituent at matches a pattern ! Each (optional) property which is present represents something ! which is required as part of a match. @@ -1351,6 +1396,7 @@ logical function ccp_model_const_is_match(this, index, advected) & class(ccpp_model_constituents_t), intent(in) :: this integer, intent(in) :: index logical, optional, intent(in) :: advected + logical, optional, intent(in) :: thermo_active ! Local variable logical :: check @@ -1363,11 +1409,20 @@ logical function ccp_model_const_is_match(this, index, advected) & end if end if + if (present(thermo_active)) then + call this%const_metadata(index)%is_thermo_active(check) + if (thermo_active .neqv. check) then + is_match = .false. + end if + end if + + end function ccp_model_const_is_match !######################################################################## - subroutine ccp_model_const_num_match(this, nmatch, advected, errcode, errmsg) + subroutine ccp_model_const_num_match(this, nmatch, advected, thermo_active, & + errcode, errmsg) ! Query number of constituents matching pattern ! Each (optional) property which is present represents something ! which is required as part of a match. @@ -1377,6 +1432,7 @@ subroutine ccp_model_const_num_match(this, nmatch, advected, errcode, errmsg) class(ccpp_model_constituents_t), intent(in) :: this integer, intent(out) :: nmatch logical, optional, intent(in) :: advected + logical, optional, intent(in) :: thermo_active integer, optional, intent(out) :: errcode character(len=*), optional, intent(out) :: errmsg ! Local variables @@ -1386,7 +1442,7 @@ subroutine ccp_model_const_num_match(this, nmatch, advected, errcode, errmsg) nmatch = 0 if (this%const_props_locked(errcode=errcode, errmsg=errmsg, warn_func=subname)) then do index = 1, SIZE(this%const_metadata) - if (this%is_match(index, advected=advected)) then + if (this%is_match(index, advected=advected, thermo_active=thermo_active)) then nmatch = nmatch + 1 end if end do @@ -1452,7 +1508,7 @@ end subroutine ccp_model_const_metadata !######################################################################## subroutine ccp_model_const_copy_in_3d(this, const_array, advected, & - errcode, errmsg) + thermo_active, errcode, errmsg) ! Gather constituent fields matching pattern ! Each (optional) property which is present represents something ! which is required as part of a match. @@ -1462,6 +1518,7 @@ subroutine ccp_model_const_copy_in_3d(this, const_array, advected, & class(ccpp_model_constituents_t), intent(in) :: this real(kind_phys), intent(out) :: const_array(:,:,:) logical, optional, intent(in) :: advected + logical, optional, intent(in) :: thermo_active integer, optional, intent(out) :: errcode character(len=*), optional, intent(out) :: errmsg ! Local variables @@ -1478,7 +1535,8 @@ subroutine ccp_model_const_copy_in_3d(this, const_array, advected, & max_cind = SIZE(const_array, 3) num_levels = SIZE(const_array, 2) do index = 1, SIZE(this%const_metadata) - if (this%is_match(index, advected=advected)) then + if (this%is_match(index, advected=advected, & + thermo_active=thermo_active)) then ! See if we have room for another constituent cindex = cindex + 1 if (cindex > max_cind) then @@ -1527,7 +1585,7 @@ end subroutine ccp_model_const_copy_in_3d !######################################################################## subroutine ccp_model_const_copy_out_3d(this, const_array, advected, & - errcode, errmsg) + thermo_active, errcode, errmsg) ! Update constituent fields matching pattern ! Each (optional) property which is present represents something ! which is required as part of a match. @@ -1537,6 +1595,7 @@ subroutine ccp_model_const_copy_out_3d(this, const_array, advected, & class(ccpp_model_constituents_t), intent(inout) :: this real(kind_phys), intent(in) :: const_array(:,:,:) logical, optional, intent(in) :: advected + logical, optional, intent(in) :: thermo_active integer, optional, intent(out) :: errcode character(len=*), optional, intent(out) :: errmsg ! Local variables @@ -1553,7 +1612,8 @@ subroutine ccp_model_const_copy_out_3d(this, const_array, advected, & max_cind = SIZE(const_array, 3) num_levels = SIZE(const_array, 2) do index = 1, SIZE(this%const_metadata) - if (this%is_match(index, advected=advected)) then + if (this%is_match(index, advected=advected, & + thermo_active=thermo_active)) then ! See if we have room for another constituent cindex = cindex + 1 if (cindex > max_cind) then @@ -1828,6 +1888,28 @@ end subroutine ccpt_const_index !####################################################################### + subroutine ccpt_is_thermo_active(this, val_out, errcode, errmsg) + + ! Dummy arguments + class(ccpp_constituent_prop_ptr_t), intent(in) :: this + logical, intent(out) :: val_out + integer, optional, intent(out) :: errcode + character(len=*), optional, intent(out) :: errmsg + ! Local variable + character(len=*), parameter :: subname = 'ccpt_is_thermo_active' + + if (associated(this%prop)) then + call this%prop%is_thermo_active(val_out, errcode, errmsg) + else + val_out = .false. + call set_errvars(1, subname//": invalid constituent pointer", & + errcode=errcode, errmsg=errmsg) + end if + + end subroutine ccpt_is_thermo_active + + !####################################################################### + subroutine ccpt_is_advected(this, val_out, errcode, errmsg) ! Dummy arguments @@ -2123,9 +2205,9 @@ subroutine ccpt_set_const_index(this, index, errcode, errmsg) ! Dummy arguments class(ccpp_constituent_prop_ptr_t), intent(inout) :: this - integer, intent(in) :: index - integer, optional, intent(out) :: errcode - character(len=*), optional, intent(out) :: errmsg + integer, intent(in) :: index + integer, optional, intent(out) :: errcode + character(len=*), optional, intent(out) :: errmsg ! Local variable character(len=*), parameter :: subname = 'ccpt_set_const_index' @@ -2146,4 +2228,30 @@ subroutine ccpt_set_const_index(this, index, errcode, errmsg) end subroutine ccpt_set_const_index + !####################################################################### + + subroutine ccpt_set_thermo_active(this, thermo_flag, errcode, errmsg) + ! Set whether this constituent is thermodynamically active, which + ! means that certain physics schemes will use this constitutent + ! when calculating thermodynamic quantities (e.g. enthalpy). + + ! Dummy arguments + class(ccpp_constituent_prop_ptr_t), intent(inout) :: this + logical, intent(in) :: thermo_flag + integer, optional, intent(out) :: errcode + character(len=*), optional, intent(out) :: errmsg + ! Local variable + character(len=*), parameter :: subname = 'ccpt_set_thermo_active' + + if (associated(this%prop)) then + if (this%prop%is_instantiated(errcode, errmsg)) then + this%prop%thermo_active = thermo_flag + end if + else + call set_errvars(1, subname//": invalid constituent pointer", & + errcode=errcode, errmsg=errmsg) + end if + + end subroutine ccpt_set_thermo_active + end module ccpp_constituent_prop_mod diff --git a/src/ccpp_constituent_prop_mod.meta b/src/ccpp_constituent_prop_mod.meta index dd60eb13..99cf3145 100644 --- a/src/ccpp_constituent_prop_mod.meta +++ b/src/ccpp_constituent_prop_mod.meta @@ -16,32 +16,32 @@ name = ccpp_model_constituents_t type = ddt [ num_layer_vars ] - standard_name = ccpp_num_constituents + standard_name = number_of_ccpp_constituents long_name = Number of constituents managed by CCPP Framework units = count dimensions = () type = integer [ num_advected_vars ] - standard_name = ccpp_num_advected_constituents + standard_name = number_of_ccpp_advected_constituents long_name = Number of advected constituents managed by CCPP Framework units = count dimensions = () type = integer [ vars_layer ] - standard_name = ccpp_constituent_array + standard_name = ccpp_constituents long_name = Array of constituents managed by CCPP Framework units = none state_variable = true - dimensions = (horizontal_dimension, vertical_layer_dimension, ccpp_num_constituents) + dimensions = (horizontal_dimension, vertical_layer_dimension, number_of_ccpp_constituents) type = real | kind = kind_phys [ const_metadata ] - standard_name = ccpp_constituent_properties_array + standard_name = ccpp_constituent_properties units = None type = ccpp_constituent_prop_ptr_t - dimensions = (ccpp_num_constituents) + dimensions = (number_of_ccpp_constituents) [ vars_minvalue ] - standard_name = ccpp_constituent_array_minimum_values + standard_name = ccpp_constituent_minimum_values units = kg kg-1 type = real | kind = kind_phys - dimensions = (ccpp_num_constituents) + dimensions = (number_of_ccpp_constituents) protected = True diff --git a/test/advection_test/test_host.F90 b/test/advection_test/test_host.F90 index 86de7cd7..a1fb9147 100644 --- a/test/advection_test/test_host.F90 +++ b/test/advection_test/test_host.F90 @@ -33,15 +33,19 @@ module test_prog CONTAINS - subroutine check_errflg(subname, errflg, errmsg) + subroutine check_errflg(subname, errflg, errmsg, errflg_final) ! If errflg is not zero, print an error message - character(len=*), intent(in) :: subname - integer, intent(in) :: errflg - character(len=*), intent(in) :: errmsg + character(len=*), intent(in) :: subname + integer, intent(in) :: errflg + character(len=*), intent(in) :: errmsg + + integer, intent(out) :: errflg_final if (errflg /= 0) then write(6, '(a,i0,4a)') "Error ", errflg, " from ", trim(subname), & ':', trim(errmsg) + !Notify test script that a failure occurred: + errflg_final = -1 !Notify test script that a failure occured end if end subroutine check_errflg @@ -252,11 +256,16 @@ subroutine test_host(retval, test_suites) character(len=256) :: const_str character(len=512) :: errmsg integer :: errflg + integer :: errflg_final ! Used to notify testing script of test failure real(kind_phys), pointer :: const_ptr(:,:,:) real(kind_phys) :: default_value type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:) character(len=*), parameter :: subname = 'test_host' + ! Initialized "final" error flag used to report a failure to the larged + ! testing script: + errflg_final = 0 + ! Gather and test the inspection routines num_suites = size(test_suites) call ccpp_physics_suite_list(suite_names) @@ -310,143 +319,245 @@ subroutine test_host(retval, test_suites) long_name="Specific humidity", units="kg kg-1", & vertical_dim="vertical_layer_dimension", advected=.true., & errcode=errflg, errmsg=errmsg) - call check_errflg(subname//'.initialize', errflg, errmsg) + call check_errflg(subname//'.initialize', errflg, errmsg, errflg_final) if (errflg == 0) then call test_host_ccpp_register_constituents(suite_names(:), & host_constituents, errmsg=errmsg, errflg=errflg) end if if (errflg /= 0) then write(6, '(2a)') 'ERROR register_constituents: ', trim(errmsg) + retval = .false. + return end if ! Check number of advected constituents if (errflg == 0) then call test_host_ccpp_number_constituents(num_advected, errmsg=errmsg, & errflg=errflg) - call check_errflg(subname//".num_advected", errflg, errmsg) + call check_errflg(subname//".num_advected", errflg, errmsg, errflg_final) end if if (num_advected /= 3) then write(6, '(a,i0)') "ERROR: num advected constituents = ", num_advected - STOP 2 + retval = .false. + return end if ! Initialize constituent data call test_host_ccpp_initialize_constituents(ncols, pver, errflg, errmsg) - ! Initialize our 'data' - if (errflg == 0) then - const_ptr => test_host_constituents_array() - call test_host_const_get_index('specific_humidity', index, & - errflg, errmsg) - call check_errflg(subname//".index_specific_humidity", errflg, errmsg) - end if - if (errflg == 0) then - call test_host_const_get_index('cloud_liquid_dry_mixing_ratio', & - index_liq, errflg, errmsg) - call check_errflg(subname//".index_cld_liq", errflg, errmsg) + !Stop tests here if initialization failed (as all other tests will likely + !fail as well: + if (errflg /= 0) then + retval = .false. + return end if - if (errflg == 0) then - call test_host_const_get_index('cloud_ice_dry_mixing_ratio', & - index_ice, errflg, errmsg) - call check_errflg(subname//".index_cld_ice", errflg, errmsg) + + ! Initialize our 'data' + const_ptr => test_host_constituents_array() + + !Check if the specific humidity index can be found: + call test_host_const_get_index('specific_humidity', index, & + errflg, errmsg) + call check_errflg(subname//".index_specific_humidity", errflg, errmsg, & + errflg_final) + + !Check if the cloud liquid index can be found: + call test_host_const_get_index('cloud_liquid_dry_mixing_ratio', & + index_liq, errflg, errmsg) + call check_errflg(subname//".index_cld_liq", errflg, errmsg, & + errflg_final) + + !Check if the cloud ice index can be found: + call test_host_const_get_index('cloud_ice_dry_mixing_ratio', & + index_ice, errflg, errmsg) + call check_errflg(subname//".index_cld_ice", errflg, errmsg, & + errflg_final) + + !Stop tests here if the index checks failed, as all other tests will + !likely fail as well: + if (errflg_final /= 0) then + retval = .false. + return end if + call init_data(const_ptr, index, index_liq, index_ice) + ! Check some constituent properties - if (errflg == 0) then - const_props => test_host_model_const_properties() - call const_props(index)%standard_name(const_str, errflg, errmsg) - if (errflg /= 0) then - write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & - "to get standard_name for specific_humidity, index = ", & - index, trim(errmsg) - end if + !++++++++++++++++++++++++++++++++++ + + const_props => test_host_model_const_properties() + + !Standard name: + call const_props(index)%standard_name(const_str, errflg, errmsg) + if (errflg /= 0) then + write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & + "to get standard_name for specific_humidity, index = ", & + index, trim(errmsg) + errflg_final = -1 !Notify test script that a failure occured end if if (errflg == 0) then if (trim(const_str) /= 'specific_humidity') then write(6, *) "ERROR: standard name, '", trim(const_str), & "' should be 'specific_humidity'" - errflg = -1 + errflg_final = -1 !Notify test script that a failure occured end if + else + !Reset error flag to continue testing other properties: + errflg = 0 end if - if (errflg == 0) then - call const_props(index_liq)%long_name(const_str, errflg, errmsg) - if (errflg /= 0) then - write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & - "to get long_name for cld_liq index = ", & - index_liq, trim(errmsg) - end if + + !Long name: + call const_props(index_liq)%long_name(const_str, errflg, errmsg) + if (errflg /= 0) then + write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & + "to get long_name for cld_liq index = ", & + index_liq, trim(errmsg) + errflg_final = -1 !Notify test script that a failure occured end if if (errflg == 0) then if (trim(const_str) /= 'Cloud liquid dry mixing ratio') then write(6, *) "ERROR: long name, '", trim(const_str), & "' should be 'Cloud liquid dry mixing ratio'" - errflg = -1 + errflg_final = -1 !Notify test script that a failure occured end if + else + !Reset error flag to continue testing other properties: + errflg = 0 end if - if (errflg == 0) then - call const_props(index_ice)%is_mass_mixing_ratio(const_log, & - errflg, errmsg) - if (errflg /= 0) then - write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & - "to get mass mixing ratio prop for cld_ice index = ", & - index_ice, trim(errmsg) - end if + + !Mass mixing ratio: + call const_props(index_ice)%is_mass_mixing_ratio(const_log, errflg, & + errmsg) + if (errflg /= 0) then + write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & + "to get mass mixing ratio prop for cld_ice index = ", & + index_ice, trim(errmsg) + errflg_final = -1 !Notify test script that a failure occured end if if (errflg == 0) then if (.not. const_log) then write(6, *) "ERROR: cloud ice is not a mass mixing_ratio" - errflg = -1 + errflg_final = -1 !Notify test script that a failure occured end if + else + !Reset error flag to continue testing other properties: + errflg = 0 end if - if (errflg == 0) then - call const_props(index_ice)%is_dry(const_log, errflg, errmsg) - if (errflg /= 0) then - write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & - "to get dry prop for cld_ice index = ", index_ice, trim(errmsg) - end if + + !Dry mixing ratio: + call const_props(index_ice)%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 cld_ice index = ", index_ice, 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: cloud ice mass_mixing_ratio is not dry" - errflg = -1 + errflg_final = -1 end if + else + !Reset error flag to continue testing other properties: + errflg = 0 end if + !Check that being thermodynamically active defaults to False: + call const_props(index_ice)%is_thermo_active(check, errflg, errmsg) + if (errflg /= 0) then + write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & + "to get thermo_active prop for cld_ice index = ", index_ice, & + trim(errmsg) + errflg_final = -1 !Notify test script that a failure occurred + end if if (errflg == 0) then - call const_props(index_liq)%has_default(has_default, errflg, errmsg) + if (check) then !Should be False + write(6, *) "ERROR: 'is_thermo_active' should default to False ", & + "for all constituents unless set by host model." + errflg_final = -1 !Notify test script that a failure occured + end if + else + !Reset error flag to continue testing other properties: + errflg = 0 + end if + + !Check that setting a constituent to be thermodynamically active works + !as expected: + call const_props(index_ice)%set_thermo_active(.true., errflg, errmsg) + if (errflg /= 0) then + write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & + "to set thermo_active prop for cld_ice index = ", index_ice, & + trim(errmsg) + errflg_final = -1 !Notify test script that a failure occurred + end if + if (errflg == 0) then + call const_props(index_ice)%is_thermo_active(check, errflg, errmsg) if (errflg /= 0) then - write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & - "to check for default for cld_liq index = ", index_liq, trim(errmsg) + write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, & + " tryingto get thermo_active prop for cld_ice index = ", & + index_ice, trim(errmsg) + errflg_final = -1 !Notify test script that a failure occurred end if end if if (errflg == 0) then - if (has_default) then - write(6, *) "ERROR: cloud liquid mass_mixing_ratio should not have default but does" + if (.not.check) then !Should now be True + write(6, *) "ERROR: 'set_thermo_active' did not set", & + " thermo_active 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 + call const_props(index_liq)%has_default(has_default, errflg, errmsg) + if (errflg /= 0) then + write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & + "to check for default for cld_liq index = ", index_liq, trim(errmsg) + errflg_final = -1 !Notify test script that a failure occurred end if if (errflg == 0) then - call const_props(index_ice)%has_default(has_default, errflg, errmsg) - if (errflg /= 0) then - write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & - "to check for default for cld_ice index = ", index_ice, trim(errmsg) + if (has_default) then + write(6, *) "ERROR: cloud liquid mass_mixing_ratio should not have default but does" + 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_ice)%has_default(has_default, errflg, errmsg) + if (errflg /= 0) then + write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & + "to check for default for cld_ice index = ", index_ice, trim(errmsg) + errflg_final = -1 !Notify test script that a failure occurred end if if (errflg == 0) then if (.not. has_default) then write(6, *) "ERROR: cloud ice mass_mixing_ratio should have default but doesn't" end if + else + !Reset error flag to continue testing other properties: + errflg = 0 end if - if (errflg == 0) then - call const_props(index_ice)%default_value(default_value, errflg, errmsg) - if (errflg /= 0) then - write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & - "to grab default for cld_ice index = ", index_ice, trim(errmsg) - end if + call const_props(index_ice)%default_value(default_value, errflg, errmsg) + if (errflg /= 0) then + write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", & + "to grab default for cld_ice index = ", index_ice, trim(errmsg) + errflg_final = -1 !Notify test script that a failure occurred end if if (errflg == 0) then if (default_value /= 0.0_kind_phys) then write(6, *) "ERROR: cloud ice mass_mixing_ratio default is ", default_value, & " but should be 0.0" end if + else + !Reset error flag to continue testing other properties: + errflg = 0 end if + !++++++++++++++++++++++++++++++++++ + + !Set error flag to the "final" value, because any error + !above will likely result in a large number of failures + !below: + errflg = errflg_final ! Use the suite information to setup the run do sind = 1, num_suites @@ -460,6 +571,7 @@ subroutine test_host(retval, test_suites) end if end if end do + ! Loop over time steps do time_step = 1, num_time_steps ! Initialize the timestep @@ -541,7 +653,13 @@ subroutine test_host(retval, test_suites) end if end if - retval = errflg == 0 + !Make sure "final" flag is non-zero if "errflg" is: + if (errflg /= 0) then + errflg_final = -1 !Notify test script that a failure occured + end if + + !Set return value to False if any errors were found: + retval = errflg_final == 0 end subroutine test_host diff --git a/test/run_fortran_tests.sh b/test/run_fortran_tests.sh index 3b3512c2..8b0f5bcb 100755 --- a/test/run_fortran_tests.sh +++ b/test/run_fortran_tests.sh @@ -50,6 +50,11 @@ echo "Skipping var_action_test/run_test until feature is fully implemented" if [ $errcnt -eq 0 ]; then echo "All tests PASSed!" else - echo "${errcnt} tests FAILed" + if [ $errcnt -eq 1 ]; then + echo "${errcnt} test FAILed" + else + echo "${errcnt} tests FAILed" + fi + #Exit with non-zero exit code exit 1 fi diff --git a/test/unit_tests/sample_host_files/ddt1.meta b/test/unit_tests/sample_host_files/ddt1.meta index 3b1b15ba..e1a0f1ac 100644 --- a/test/unit_tests/sample_host_files/ddt1.meta +++ b/test/unit_tests/sample_host_files/ddt1.meta @@ -16,5 +16,5 @@ standard_name = vars_array long_name = Array of vars managed by ddt1 units = none - dimensions = (horizontal_dimension, vertical_layer_dimension, ccpp_num_constituents) + dimensions = (horizontal_dimension, vertical_layer_dimension, number_of_ccpp_constituents) type = real | kind = kind_phys diff --git a/test/unit_tests/sample_host_files/ddt1_plus.meta b/test/unit_tests/sample_host_files/ddt1_plus.meta index 78031b2a..ca3a92ab 100644 --- a/test/unit_tests/sample_host_files/ddt1_plus.meta +++ b/test/unit_tests/sample_host_files/ddt1_plus.meta @@ -16,5 +16,5 @@ standard_name = vars_array long_name = Array of vars managed by ddt2 units = none - dimensions = (horizontal_dimension, vertical_layer_dimension, ccpp_num_constituents) + dimensions = (horizontal_dimension, vertical_layer_dimension, number_of_ccpp_constituents) type = real | kind = kind_phys diff --git a/test/unit_tests/sample_host_files/ddt2.meta b/test/unit_tests/sample_host_files/ddt2.meta index 7412daf3..159f08b0 100644 --- a/test/unit_tests/sample_host_files/ddt2.meta +++ b/test/unit_tests/sample_host_files/ddt2.meta @@ -25,5 +25,5 @@ standard_name = vars_array long_name = Array of vars managed by ddt2 units = none - dimensions = (horizontal_dimension, vertical_layer_dimension, ccpp_num_constituents) + dimensions = (horizontal_dimension, vertical_layer_dimension, number_of_ccpp_constituents) type = real | kind = kind_phys diff --git a/test/unit_tests/sample_host_files/ddt2_extra_var.meta b/test/unit_tests/sample_host_files/ddt2_extra_var.meta index 49256b2e..867720e5 100644 --- a/test/unit_tests/sample_host_files/ddt2_extra_var.meta +++ b/test/unit_tests/sample_host_files/ddt2_extra_var.meta @@ -25,7 +25,7 @@ standard_name = vars_array long_name = Array of vars managed by ddt2 units = none - dimensions = (horizontal_dimension, vertical_layer_dimension, ccpp_num_constituents) + dimensions = (horizontal_dimension, vertical_layer_dimension, number_of_ccpp_constituents) type = real | kind = kind_phys [ bogus ] standard_name = misplaced_variable diff --git a/test/unit_tests/sample_host_files/ddt_data1_mod.meta b/test/unit_tests/sample_host_files/ddt_data1_mod.meta index c3b14874..e149c07b 100644 --- a/test/unit_tests/sample_host_files/ddt_data1_mod.meta +++ b/test/unit_tests/sample_host_files/ddt_data1_mod.meta @@ -25,7 +25,7 @@ standard_name = vars_array long_name = Array of vars managed by ddt2 units = none - dimensions = (horizontal_dimension, vertical_layer_dimension, ccpp_num_constituents) + dimensions = (horizontal_dimension, vertical_layer_dimension, number_of_ccpp_constituents) type = real | kind = kind_phys ########################################################################