From b7068d482d05430940a5fd6febd9be0e4953f13c Mon Sep 17 00:00:00 2001 From: Ramzi Kutteh Date: Tue, 16 Jul 2024 18:20:55 +1000 Subject: [PATCH 1/5] consistency_ice_veg_soil --- src/offline/cable_input.F90 | 9 +- src/offline/cable_parameters.F90 | 190 +++++++++++++++++++++++++++++- src/params/grid_constants_cbl.F90 | 2 + 3 files changed, 197 insertions(+), 4 deletions(-) diff --git a/src/offline/cable_input.F90 b/src/offline/cable_input.F90 index 6fe79b6d9..ee0c8cb88 100644 --- a/src/offline/cable_input.F90 +++ b/src/offline/cable_input.F90 @@ -2818,15 +2818,18 @@ SUBROUTINE load_parameters(met,air,ssnow,veg,climate,bgc,soil,canopy,rough,rad, END IF WRITE(logn,*) - !| 9. Construct derived parameters and zero initialisations for the + !> 9. Ensure the consistency of ice points between soil and vegetation + CALL consistency_ice_veg_soil(soil, veg) + + !| 10. Construct derived parameters and zero initialisations for the ! groundwater routine, regardless of where parameters and other ! initialisations have loaded from CALL derived_parameters(soil,sum_flux,bal,ssnow,veg,rough) - !> 10. Check for basic inconsistencies in parameter values + !> 11. Check for basic inconsistencies in parameter values CALL check_parameter_values(soil,veg,ssnow) - !> 11. Write per-site parameter values to log file if requested + !> 12. Write per-site parameter values to log file if requested CALL report_parameters(logn,soil,veg,bgc,rough,ssnow,canopy, & casamet,casapool,casaflux,phen,vegparmnew,verbose) diff --git a/src/offline/cable_parameters.F90 b/src/offline/cable_parameters.F90 index 534f73d43..29d20fdfb 100644 --- a/src/offline/cable_parameters.F90 +++ b/src/offline/cable_parameters.F90 @@ -67,7 +67,7 @@ MODULE cable_param_module PRIVATE PUBLIC get_default_params, write_default_params, derived_parameters, & check_parameter_values, report_parameters, parID_type, & - write_cnp_params + write_cnp_params, consistency_ice_veg_soil INTEGER :: patches_in_parfile=4 ! # patches in default global parameter ! file @@ -2064,7 +2064,195 @@ SUBROUTINE check_parameter_values(soil, veg, ssnow) END WHERE END SUBROUTINE check_parameter_values + + !=============================================================================== + + SUBROUTINE consistency_ice_veg_soil(soil, veg) + ! Ensure that when an active patch has a veg type of ice then its soil type is also ice and vice versa + ! Any change effected to enforce this consistency includes correcting the appropriate paramter values + + USE grid_constants_mod_cbl, ONLY : ICE_SoilType, ICE_VegType + USE cable_phys_constants_mod, ONLY : csice, density_ice + + TYPE (soil_parameter_type), INTENT(INOUT) :: soil ! soil parameter data + TYPE (veg_parameter_type), INTENT(INOUT) :: veg ! vegetation parameter + + INTEGER :: i, j, k, kIVP + LOGICAL :: LIceVegPatch + + + LIceVegPatch = .FALSE. + + look_for_ice_veg_patch: DO i = 1, mland ! loop over all gridcells + DO j = 1, landpt(i)%nap ! loop over all active patches in every gridcell + + k = landpt(i)%cstart + j - 1 ! absolute position of active veg patch + + IF(veg%iveg(k) == ICE_VegType) THEN ! check to see if there is at least one ice veg patch already + LIceVegPatch = .TRUE. + kIVP = k ! remember which patch it is + EXIT look_for_ice_veg_patch ! exit as we only need to find one ice veg patch + END IF + + END DO + END DO look_for_ice_veg_patch + + + DO i = 1, mland ! loop over all gridcells + DO j = 1, landpt(i)%nap ! loop over all active patches in every gridcell + + k = landpt(i)%cstart + j - 1 ! absolute position of active patch + + IF(soil%isoilm(k) == ICE_SoilType) THEN ! check to see if ice soil patch + + WRITE(*,*) 'SUBROUTINE load_parameters:' + WRITE(*,*) 'At land point number ', i + WRITE(*,*) 'And patch number ', k + WRITE(*,*) 'isoilm is ICE_SoilType' + WRITE(*,*) 'Set rhosoil = density_ice from CABLE physical constants' + WRITE(*,*) 'Set css = csice from CABLE physical constants' + + soil%rhosoil(k) = density_ice + soil%css(k) = csice + + END IF + + END DO + END DO + + + DO i = 1, mland ! loop over all gridcells + DO j = 1, landpt(i)%nap ! loop over all active patches in every gridcell + + k = landpt(i)%cstart + j - 1 ! absolute position of active patch + + IF((veg%iveg(k) == ICE_VegType) .AND. (soil%isoilm(k) /= ICE_SoilType)) THEN + + + WRITE(*,*) 'SUBROUTINE load_parameters:' + WRITE(*,*) 'At land point number ', i + WRITE(*,*) 'And patch number ', k + WRITE(*,*) 'iveg is ICE_VegType but isoilm is not ICE_SoilType' + WRITE(*,*) 'Changed isoilm to ICE_SoilType with appropriate parameter corrections' + + soil%isoilm(k) = ICE_SoilType + + ! correct appropriately parameters and derived parameters + + soil%rhosoil(k) = density_ice + soil%css(k) = csice + + + ELSE IF ((veg%iveg(k) /= ICE_VegType) .AND. (soil%isoilm(k) == ICE_SoilType)) THEN + + WRITE(*,*) 'SUBROUTINE load_parameters:' + WRITE(*,*) 'At land point number ', i + WRITE(*,*) 'And patch number ', k + WRITE(*,*) 'iveg is not ICE_VegType but isoilm is ICE_SoilType' + WRITE(*,*) 'Changed iveg to ICE_VegType with appropriate parameter corrections' + + + veg%iveg(k) = ICE_VegType + + ! correct appropriately parameters and derived parameters + + IF (LIceVegPatch) THEN ! if there is at least one ice veg patch already + ! use the parameter values from this ice veg patch for the new ice veg patch + + veg%frac4(k) = veg%frac4(kIVP) + veg%taul(k,1) = veg%taul(kIVP,1) + veg%taul(k,2) = veg%taul(kIVP,2) + veg%refl(k,1) = veg%refl(kIVP,1) + veg%refl(k,2) = veg%refl(kIVP,2) + veg%canst1(k) = veg%canst1(kIVP) + veg%dleaf(k) = veg%dleaf(kIVP) + veg%vcmax(k) = veg%vcmax(kIVP) + veg%ejmax(k) = veg%ejmax(kIVP) + veg%hc(k) = veg%hc(kIVP) + veg%xfang(k) = veg%xfang(kIVP) + veg%vbeta(k) = veg%vbeta(kIVP) + veg%xalbnir(k) = veg%xalbnir(kIVP) + veg%rp20(k) = veg%rp20(kIVP) + veg%rpcoef(k) = veg%rpcoef(kIVP) + veg%rs20(k) = veg%rs20(kIVP) + veg%shelrb(k) = veg%shelrb(kIVP) + veg%wai(k) = veg%wai(kIVP) + veg%a1gs(k) = veg%a1gs(kIVP) + veg%d0gs(k) = veg%d0gs(kIVP) + veg%vegcf(k) = veg%vegcf(kIVP) + veg%extkn(k) = veg%extkn(kIVP) + veg%tminvj(k) = veg%tminvj(kIVP) + veg%tmaxvj(k) = veg%tmaxvj(kIVP) + veg%g0(k) = veg%g0(kIVP) + veg%g1(k) = veg%g1(kIVP) + veg%a1gs(k) = veg%a1gs(kIVP) + veg%d0gs(k) = veg%d0gs(kIVP) + veg%alpha(k) = veg%alpha(kIVP) + veg%convex(k) = veg%convex(kIVP) + veg%cfrd(k) = veg%cfrd(kIVP) + veg%gswmin(k) = veg%gswmin(kIVP) + veg%conkc0(k) = veg%conkc0(kIVP) + veg%conko0(k) = veg%conko0(kIVP) + veg%ekc(k) = veg%ekc(kIVP) + veg%eko(k) = veg%eko(kIVP) + veg%rootbeta(k) = veg%rootbeta(kIVP) + veg%zr(k) = veg%zr(kIVP) + veg%clitt(k) = veg%clitt(kIVP) + + ELSE ! otherwise use default parameter values for ice + + veg%frac4(k) = vegin%frac4(ICE_VegType) + veg%taul(k,1) = vegin%taul1(ICE_VegType) + veg%taul(k,2) = vegin%taul2(ICE_VegType) + veg%refl(k,1) = vegin%refl1(ICE_VegType) + veg%refl(k,2) = vegin%refl2(ICE_VegType) + veg%canst1(k) = vegin%canst1(ICE_VegType) + veg%dleaf(k) = vegin%dleaf(ICE_VegType) + veg%vcmax(k) = vegin%vcmax(ICE_VegType) + veg%ejmax(k) = vegin%ejmax(ICE_VegType) + veg%hc(k) = vegin%hc(ICE_VegType) + veg%xfang(k) = vegin%xfang(ICE_VegType) + veg%vbeta(k) = vegin%vbeta(ICE_VegType) + veg%xalbnir(k) = vegin%xalbnir(ICE_VegType) + veg%rp20(k) = vegin%rp20(ICE_VegType) + veg%rpcoef(k) = vegin%rpcoef(ICE_VegType) + veg%rs20(k) = vegin%rs20(ICE_VegType) + veg%shelrb(k) = vegin%shelrb(ICE_VegType) + veg%wai(k) = vegin%wai(ICE_VegType) + veg%a1gs(k) = vegin%a1gs(ICE_VegType) + veg%d0gs(k) = vegin%d0gs(ICE_VegType) + veg%vegcf(k) = vegin%vegcf(ICE_VegType) + veg%extkn(k) = vegin%extkn(ICE_VegType) + veg%tminvj(k) = vegin%tminvj(ICE_VegType) + veg%tmaxvj(k) = vegin%tmaxvj(ICE_VegType) + veg%g0(k) = vegin%g0(ICE_VegType) + veg%g1(k) = vegin%g1(ICE_VegType) + veg%a1gs(k) = vegin%a1gs(ICE_VegType) + veg%d0gs(k) = vegin%d0gs(ICE_VegType) + veg%alpha(k) = vegin%alpha(ICE_VegType) + veg%convex(k) = vegin%convex(ICE_VegType) + veg%cfrd(k) = vegin%cfrd(ICE_VegType) + veg%gswmin(k) = vegin%gswmin(ICE_VegType) + veg%conkc0(k) = vegin%conkc0(ICE_VegType) + veg%conko0(k) = vegin%conko0(ICE_VegType) + veg%ekc(k) = vegin%ekc(ICE_VegType) + veg%eko(k) = vegin%eko(ICE_VegType) + veg%rootbeta(k) = vegin%rootbeta(ICE_VegType) + veg%zr(k) = vegin%zr(ICE_VegType) + veg%clitt(k) = vegin%clitt(ICE_VegType) + + END IF + + END IF + + END DO + END DO + + + END SUBROUTINE consistency_ice_veg_soil + !=============================================================================== + SUBROUTINE report_parameters(logn, soil, veg, bgc, rough, & ssnow, canopy, casamet, casapool, casaflux, & phen, vegparmnew, verbose ) diff --git a/src/params/grid_constants_cbl.F90 b/src/params/grid_constants_cbl.F90 index 2ae2aa6eb..8d2ec313a 100644 --- a/src/params/grid_constants_cbl.F90 +++ b/src/params/grid_constants_cbl.F90 @@ -47,6 +47,8 @@ MODULE grid_constants_mod_cbl INTEGER, PARAMETER :: ICE_SoilType = 9 ! SoilType Index (soilparm_cable.nml JAC) INTEGER, PARAMETER :: lakes_cable = 16! SoilType Index (soilparm_cable.nml JAC) +INTEGER, PARAMETER :: ICE_VegType = 17 ! permanent ice index for veg + INTEGER, PARAMETER :: mf = 2 ! # leaves (sunlit, shaded) INTEGER, PARAMETER :: niter = 4 ! number of iterations for za/L From d395e01412b7f748474884a3984945eecc23ce1e Mon Sep 17 00:00:00 2001 From: Ramzi Kutteh <98803952+rkutteh@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:08:08 +1000 Subject: [PATCH 2/5] Update cable_parameters.F90 changed write statements inside consistency_ice_veg_soil subroutine to output to logn instead of standard output --- src/offline/cable_parameters.F90 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/offline/cable_parameters.F90 b/src/offline/cable_parameters.F90 index 29d20fdfb..8dc6d28ac 100644 --- a/src/offline/cable_parameters.F90 +++ b/src/offline/cable_parameters.F90 @@ -2105,12 +2105,12 @@ SUBROUTINE consistency_ice_veg_soil(soil, veg) IF(soil%isoilm(k) == ICE_SoilType) THEN ! check to see if ice soil patch - WRITE(*,*) 'SUBROUTINE load_parameters:' - WRITE(*,*) 'At land point number ', i - WRITE(*,*) 'And patch number ', k - WRITE(*,*) 'isoilm is ICE_SoilType' - WRITE(*,*) 'Set rhosoil = density_ice from CABLE physical constants' - WRITE(*,*) 'Set css = csice from CABLE physical constants' + WRITE(logn,*) 'SUBROUTINE load_parameters:' + WRITE(logn,*) 'At land point number ', i + WRITE(logn,*) 'And patch number ', k + WRITE(logn,*) 'isoilm is ICE_SoilType' + WRITE(logn,*) 'Set rhosoil = density_ice from CABLE physical constants' + WRITE(logn,*) 'Set css = csice from CABLE physical constants' soil%rhosoil(k) = density_ice soil%css(k) = csice @@ -2129,11 +2129,11 @@ SUBROUTINE consistency_ice_veg_soil(soil, veg) IF((veg%iveg(k) == ICE_VegType) .AND. (soil%isoilm(k) /= ICE_SoilType)) THEN - WRITE(*,*) 'SUBROUTINE load_parameters:' - WRITE(*,*) 'At land point number ', i - WRITE(*,*) 'And patch number ', k - WRITE(*,*) 'iveg is ICE_VegType but isoilm is not ICE_SoilType' - WRITE(*,*) 'Changed isoilm to ICE_SoilType with appropriate parameter corrections' + WRITE(logn,*) 'SUBROUTINE load_parameters:' + WRITE(logn,*) 'At land point number ', i + WRITE(logn,*) 'And patch number ', k + WRITE(logn,*) 'iveg is ICE_VegType but isoilm is not ICE_SoilType' + WRITE(logn,*) 'Changed isoilm to ICE_SoilType with appropriate parameter corrections' soil%isoilm(k) = ICE_SoilType @@ -2145,11 +2145,11 @@ SUBROUTINE consistency_ice_veg_soil(soil, veg) ELSE IF ((veg%iveg(k) /= ICE_VegType) .AND. (soil%isoilm(k) == ICE_SoilType)) THEN - WRITE(*,*) 'SUBROUTINE load_parameters:' - WRITE(*,*) 'At land point number ', i - WRITE(*,*) 'And patch number ', k - WRITE(*,*) 'iveg is not ICE_VegType but isoilm is ICE_SoilType' - WRITE(*,*) 'Changed iveg to ICE_VegType with appropriate parameter corrections' + WRITE(logn,*) 'SUBROUTINE load_parameters:' + WRITE(logn,*) 'At land point number ', i + WRITE(logn,*) 'And patch number ', k + WRITE(logn,*) 'iveg is not ICE_VegType but isoilm is ICE_SoilType' + WRITE(logn,*) 'Changed iveg to ICE_VegType with appropriate parameter corrections' veg%iveg(k) = ICE_VegType From 4db04690a075673e4aabaf2677ed08a2f52c90b1 Mon Sep 17 00:00:00 2001 From: "C. Carouge" Date: Thu, 15 Aug 2024 15:36:11 +1000 Subject: [PATCH 3/5] (#338) - Add namelist option for ice consistency. --- documentation/docs/user_guide/inputs/cable_nml.md | 2 +- src/offline/cable_input.F90 | 4 +++- src/util/cable_runtime_opts_mod.F90 | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/documentation/docs/user_guide/inputs/cable_nml.md b/documentation/docs/user_guide/inputs/cable_nml.md index b7d2de2f3..14ed9e70c 100644 --- a/documentation/docs/user_guide/inputs/cable_nml.md +++ b/documentation/docs/user_guide/inputs/cable_nml.md @@ -134,7 +134,7 @@ applications. The following are annotated examples of cable.nml: | cable_user%access13roots | logical | .TRUE. .FALSE. | .FALSE. | Switch to use ACCESS1.3 %froot. | | cable_user%l_limit_labile | logical | .TRUE. .FALSE. | .FALSE. | Limit labile in spinup. | | cable_user%NtilesThruMetFile | logical | .TRUE. .FALSE. | .FALSE. | Specify Ntiles through met file. | - +| cable_user%l_ice_consistency | logical | .TRUE. .FALSE. | .FALSE. | If true, ensures consistency between soil and vegetation tiles with permanent ice. All tiles with permanent ice for soil will have ice for vegetation and vice-versa. All the parameters for these tiles are updated to the ice parameters. | ## For offline applications ## diff --git a/src/offline/cable_input.F90 b/src/offline/cable_input.F90 index ee0c8cb88..9c30208f7 100644 --- a/src/offline/cable_input.F90 +++ b/src/offline/cable_input.F90 @@ -2819,7 +2819,9 @@ SUBROUTINE load_parameters(met,air,ssnow,veg,climate,bgc,soil,canopy,rough,rad, WRITE(logn,*) !> 9. Ensure the consistency of ice points between soil and vegetation - CALL consistency_ice_veg_soil(soil, veg) + IF (cable_user%l_ice_consistency) THEN + CALL consistency_ice_veg_soil(soil, veg) + END IF !| 10. Construct derived parameters and zero initialisations for the ! groundwater routine, regardless of where parameters and other diff --git a/src/util/cable_runtime_opts_mod.F90 b/src/util/cable_runtime_opts_mod.F90 index 46b2da7b3..628f97a48 100644 --- a/src/util/cable_runtime_opts_mod.F90 +++ b/src/util/cable_runtime_opts_mod.F90 @@ -113,7 +113,9 @@ MODULE cable_runtime_opts_mod LOGICAL :: access13roots = .FALSE. !switch to use ACCESS1.3 %froot LOGICAL :: l_limit_labile = .FALSE. ! #237: limit Labile in spinup - LOGICAL :: NtilesThruMetFile = .FALSE. ! #199: Specify Ntiles thru met file + LOGICAL :: NtilesThruMetFile = .FALSE. ! #199: Specify Ntiles thru met file + ! #338 https://github.com/CABLE-LSM/CABLE/issues/338 + LOGICAL :: l_ice_consistency = .FALSE. END TYPE kbl_user_switches From 6ed2afc8315ff8ddb4862442854a40e62fa4710d Mon Sep 17 00:00:00 2001 From: "C. Carouge" Date: Thu, 15 Aug 2024 15:52:58 +1000 Subject: [PATCH 4/5] (#338) - Update doc --- documentation/docs/user_guide/inputs/cable_nml.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/user_guide/inputs/cable_nml.md b/documentation/docs/user_guide/inputs/cable_nml.md index 14ed9e70c..1ac59f001 100644 --- a/documentation/docs/user_guide/inputs/cable_nml.md +++ b/documentation/docs/user_guide/inputs/cable_nml.md @@ -134,7 +134,7 @@ applications. The following are annotated examples of cable.nml: | cable_user%access13roots | logical | .TRUE. .FALSE. | .FALSE. | Switch to use ACCESS1.3 %froot. | | cable_user%l_limit_labile | logical | .TRUE. .FALSE. | .FALSE. | Limit labile in spinup. | | cable_user%NtilesThruMetFile | logical | .TRUE. .FALSE. | .FALSE. | Specify Ntiles through met file. | -| cable_user%l_ice_consistency | logical | .TRUE. .FALSE. | .FALSE. | If true, ensures consistency between soil and vegetation tiles with permanent ice. All tiles with permanent ice for soil will have ice for vegetation and vice-versa. All the parameters for these tiles are updated to the ice parameters. | +| cable_user%l_ice_consistency | logical | .TRUE. .FALSE. | .FALSE. | If true, ensures consistency between soil and vegetation tiles with permanent ice. All tiles with permanent ice for soil will have ice for vegetation and vice-versa. All the parameters for these new ice tiles are updated to the ice parameters. | ## For offline applications ## From 57a343d6027da1e50fc4735bd7a28496b7da9485 Mon Sep 17 00:00:00 2001 From: "C. Carouge" Date: Wed, 21 Aug 2024 16:00:13 +1000 Subject: [PATCH 5/5] (#338) - Add new namelist option to cable.nml --- src/offline/cable.nml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/offline/cable.nml b/src/offline/cable.nml index 537222fcd..e8c104bb5 100644 --- a/src/offline/cable.nml +++ b/src/offline/cable.nml @@ -68,4 +68,5 @@ cable_user%CASA_DUMP_READ = .FALSE. ! TRUE reads CASA forcing from netcdf format cable_user%CASA_DUMP_WRITE = .FALSE. ! TRUE outputs CASA forcing in netcdf format cable_user%SSNOW_POTEV= 'HDM' ! Humidity Deficit Method + cable_user%l_ice_consistency = .FALSE. ! TRUE add QA step for ice tiles input. &end