From 4d767241539b2dee1582c47a77dfbb072da791d6 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:27:11 -0500 Subject: [PATCH 01/89] [dev.01] define q_building Define, initialize, create history field, and create restart variable for `q_building`, internal building air specific humidity. Add argument "is_prog_buildtemp" to various subroutines to only initialize/create restart file for `q_building` if using prognostic temperature method. --- src/biogeophys/WaterDiagnosticType.F90 | 63 +++++++++++++++++++++++--- src/biogeophys/WaterType.F90 | 8 +++- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticType.F90 b/src/biogeophys/WaterDiagnosticType.F90 index 57be0e62af..8b05aadbb5 100644 --- a/src/biogeophys/WaterDiagnosticType.F90 +++ b/src/biogeophys/WaterDiagnosticType.F90 @@ -49,6 +49,8 @@ module WaterDiagnosticType real(r8), pointer :: qg_h2osfc_col (:) ! col ground specific humidity [kg/kg] real(r8), pointer :: qg_col (:) ! col ground specific humidity [kg/kg] real(r8), pointer :: qaf_lun (:) ! lun urban canopy air specific humidity (kg/kg) + ! [Cathy] dev.01 + real(r8), pointer :: q_building_lun (:) ! lun internal building air specific humidity (kg/kg) contains @@ -69,12 +71,14 @@ module WaterDiagnosticType contains !------------------------------------------------------------------------ - subroutine Init(this, bounds, info, tracer_vars) + subroutine Init(this, bounds, info, tracer_vars, is_prog_buildtemp) class(waterdiagnostic_type), intent(inout) :: this type(bounds_type) , intent(in) :: bounds class(water_info_base_type), intent(in), target :: info type(water_tracer_container_type), intent(inout) :: tracer_vars + ! Cathy [dev.01] + logical, intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used this%info => info @@ -82,7 +86,7 @@ subroutine Init(this, bounds, info, tracer_vars) call this%InitHistory(bounds) - call this%InitCold(bounds) + call this%InitCold(bounds, is_prog_buildtemp) end subroutine Init @@ -138,11 +142,15 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar1d(var = this%q_ref2m_patch, name = 'q_ref2m_patch', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_patch) + ! Cathy [dev.01] + call AllocateVar1d(var = this%q_building_lun, name = 'q_building_lun', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_landunit) end subroutine InitAllocate !------------------------------------------------------------------------ - subroutine InitHistory(this, bounds) + subroutine InitHistory(this, bounds, is_prog_buildtemp) ! ! !DESCRIPTION: ! Initialize module data structure @@ -153,6 +161,8 @@ subroutine InitHistory(this, bounds) ! !ARGUMENTS: class(waterdiagnostic_type), intent(in) :: this type(bounds_type), intent(in) :: bounds + ! Cathy [dev.01] + logical, intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: integer :: begp, endp @@ -162,6 +172,8 @@ subroutine InitHistory(this, bounds) begp = bounds%begp; endp= bounds%endp begc = bounds%begc; endc= bounds%endc + ! Cathy [dev.01] + begl = bounds%begl; endl= bounds%endl begg = bounds%begg; endg= bounds%endg @@ -241,12 +253,21 @@ subroutine InitHistory(this, bounds) long_name=this%info%lname('snow ice (ice landunits only)'), & ptr_col=this%snowice_col, c2l_scale_type='urbanf', l2g_scale_type='ice', & default='inactive') - + + ! Cathy [dev.01] + if ( is_prog_buildtemp ) then + this%q_building_lun(begl:endl) = spval + call hist_addfld1d ( & + fname=this%info%fname('QBUILD'), & + units='kg/kg', & + avgflag='A', & + long_name=this%info%lname('internal urban building air specific humidity'), & + ptr_lunit=this%q_building_lun, l2g_scale_type='unity', set_nourb=spval) end subroutine InitHistory !----------------------------------------------------------------------- - subroutine InitCold(this, bounds) + subroutine InitCold(this, bounds, is_prog_buildtemp) ! ! !DESCRIPTION: ! Initialize time constant variables and cold start conditions @@ -257,6 +278,8 @@ subroutine InitCold(this, bounds) ! !ARGUMENTS: class(waterdiagnostic_type), intent(in) :: this type(bounds_type) , intent(in) :: bounds + ! Cathy [dev.01] + logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: integer :: l @@ -286,10 +309,20 @@ subroutine InitCold(this, bounds) end if end do + ! Cathy [dev.01] + ! Initialize internal building specific humidity (following example above and t_building_max in TemperatureType.F90) + if ( is_prog_buildtemp ) then + do l = bounds%begl, bounds%endl + if (lun%urbpoi(l)) then + this%q_building_lun(l) = this%qaf_lun(l) ! set to urban canopy specific humidity + end if + end do + end if + end subroutine InitCold !------------------------------------------------------------------------ - subroutine Restart(this, bounds, ncid, flag) + subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. @@ -305,6 +338,8 @@ subroutine Restart(this, bounds, ncid, flag) type(bounds_type), intent(in) :: bounds type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' + ! Cathy [dev.01] + logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: integer :: c,l,j @@ -340,6 +375,22 @@ subroutine Restart(this, bounds, ncid, flag) interpinic_flag='interp', readvar=readvar, data=this%total_plant_stored_h2o_col) end if + ! Cathy [dev.01] + if ( is_prog_buildtemp ) then + ! landunit type physical state variable - q_building + call restartvar(ncid=ncid, flag=flag, & + varname=this%info%fname('q_building'), & + xtype=ncd_double, dim1name='landunit', & + long_name=this%info%lname('internal building air specific humidity)', & + units='kg/kg', & + interpinic_flag='interp', readvar=readvar, data=this%q_building_lun) + if (flag=='read' .and. .not. readvar) then + if (masterproc) write(iulog,*) "can't find q_building in initial file..." + if (masterproc) write(iulog,*) "Initialize q_building to qaf" + this%q_building_lun(bounds%begl:bounds%endl) = this%qaf_lun(bounds%begl:bounds%endl) + end if + end if + end subroutine Restart !----------------------------------------------------------------------- diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index bc257f27ad..da0ed395ba 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -78,6 +78,8 @@ module WaterType use Wateratm2lndBulkType , only : wateratm2lndbulk_type use WaterTracerContainerType , only : water_tracer_container_type use WaterTracerUtils , only : CompareBulkToTracer, SetTracerToBulkTimesRatio + ! Cathy [dev.01] + use UrbanParamsType , only : IsProgBuildTemp implicit none private @@ -385,7 +387,8 @@ subroutine DoInit(this, bounds, & call this%bulk_and_tracers(i)%waterdiagnostic_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & - this%bulk_and_tracers(i)%vars) + this%bulk_and_tracers(i)%vars, & + IsProgBuildTemp()) ! Cathy [dev.01] call this%bulk_and_tracers(i)%waterbalance_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & @@ -767,7 +770,8 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & t_soisno_col=t_soisno_col(bounds%begc:, -nlevsno+1:), & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) - call this%bulk_and_tracers(i)%waterdiagnostic_inst%Restart(bounds, ncid, flag=flag) + call this%bulk_and_tracers(i)%waterdiagnostic_inst%Restart(bounds, ncid, flag=flag, & + IsProgBuildTemp()) ! Cathy [dev.04] end do From c66517609bc53a4ff756a08a46d766e9ba6f4a43 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 1 May 2024 16:28:31 -0500 Subject: [PATCH 02/89] [dev.02] Modify ventilation & building flux 1. define `q_building_max` as a constant in clm_varcon.F90 2. add latent heat component to `eflx_ventilation` and `eflx_building` --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 33 +++++++++++++++++--- src/main/clm_varcon.F90 | 2 ++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index c680b13306..c8abf616b3 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -16,6 +16,8 @@ module UrbBuildTempOleson2015Mod use UrbanTimeVarType , only : urbantv_type use EnergyFluxType , only : energyflux_type use TemperatureType , only : temperature_type + ! Cathy [dev.02] + use WaterDiagnosticType, only : waterdiagnostic_type use LandunitType , only : lun use ColumnType , only : col ! @@ -42,7 +44,7 @@ module UrbBuildTempOleson2015Mod ! !INTERFACE: subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, & filter_nolakec, tk, urbanparams_inst, temperature_inst, & - energyflux_inst, urbantv_inst) + energyflux_inst, waterdiagnostic_inst, urbantv_inst) ! Cathy [dev.02] ! ! !DESCRIPTION: ! Solve for t_building, inner surface temperatures of roof, sunw, shdw, and floor temperature @@ -205,7 +207,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, use clm_varcon , only : rair, pstd, cpair, sb, hcv_roof, hcv_roof_enhanced, & hcv_floor, hcv_floor_enhanced, hcv_sunw, hcv_shdw, & em_roof_int, em_floor_int, em_sunw_int, em_shdw_int, & - dz_floor, dens_floor, cp_floor, vent_ach + dz_floor, dens_floor, cp_floor, vent_ach, & + ! Cathy [dev.02] + q_building_max, hvap use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall use clm_varctl , only : iulog use abortutils , only : endrun @@ -223,6 +227,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(urbanparams_type), intent(in) :: urbanparams_inst ! urban parameters type(temperature_type), intent(inout) :: temperature_inst ! temperature variables type(energyflux_type) , intent(inout) :: energyflux_inst ! energy flux variables + ! Cathy [dev.02] + type(waterdiagnostic_type), intent(inout) :: waterdiagnostic_inst ! water diagnostic variables type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables ! ! !LOCAL VARIABLES: @@ -236,6 +242,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: t_floor_bef(bounds%begl:bounds%endl) ! floor temperature at previous time step (K) real(r8) :: t_building_bef(bounds%begl:bounds%endl) ! internal building air temperature at previous time step [K] real(r8) :: t_building_bef_hac(bounds%begl:bounds%endl)! internal building air temperature before applying HAC [K] + ! Cathy [dev.02] + real(r8) :: q_building_bef(bounds%begl:bounds%endl) ! internal building air specific humidity at previous time step (kg/kg) + real(r8) :: q_building_bef_hac(bounds%begl:bounds%endl)! internal building air specific humidity before applying HAC (kg/kg) real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) ! urban air conditioning flux under AC adoption saturation (W/m**2) real(r8) :: hcv_roofi(bounds%begl:bounds%endl) ! roof convective heat transfer coefficient (W m-2 K-1) real(r8) :: hcv_sunwi(bounds%begl:bounds%endl) ! sunwall convective heat transfer coefficient (W m-2 K-1) @@ -329,6 +338,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, t_building_max => urbantv_inst%t_building_max , & ! Input: [real(r8) (:)] maximum internal building air temperature (K) t_building_min => urbanparams_inst%t_building_min , & ! Input: [real(r8) (:)] minimum internal building air temperature (K) + ! Cathy [dev.02] + qaf => waterdiagnostic_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) + q_building => waterdiagnostic_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) + eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (W/m**2) eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) eflx_urban_heat => energyflux_inst%eflx_urban_heat_lun,& ! Output: [real(r8) (:)] urban heating flux (W/m**2) @@ -903,13 +916,18 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if + ! Cathy [dev.02] ! Sensible heat flux from ventilation. It is added as a flux to the canyon floor in SoilTemperatureMod. ! Note that we multiply it here by wtlunit_roof which converts it from W/m2 of building area to W/m2 ! of urban area. eflx_urban_ac and eflx_urban_heat are treated similarly below. This flux is balanced ! by an equal and opposite flux into/out of the building and so has a net effect of zero on the energy balance ! of the urban landunit. - eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & - * rho_dair(l) * cpair * (taf(l) - t_building(l)) ) + ! eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & + ! * rho_dair(l) * cpair * (taf(l) - t_building(l)) ) + eflx_ventilation(l) = wtlunit_roof(l) * ( & + - ht_roof(l) * (ven_ach/3600._r8) * rho_dair(l) * cpair * (taf(l) - t_building(l)) & + - ht_roof(l) * (ven_ach/3600._r8) * rho_dair(l) * hvap * (qaf(l) - q_building(l)) & + ) end if end do @@ -950,7 +968,12 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if - eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) + ! Cathy [dev.02] + ! eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) + eflx_building(l) = wtlunit_roof(l) * ( & + (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) & + + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & + ) end if end do diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index e45f5c440e..4d825403f8 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -187,6 +187,8 @@ module clm_varcon real(r8), public, parameter :: sh_floor = 880._r8 ! specific heat of floor - concrete (Salmanca et al. 2010, TAC) (J kg-1 K-1) real(r8), public :: cp_floor = dens_floor*sh_floor ! volumetric heat capacity of floor - concrete (Salmanca et al. 2010, TAC) (J m-3 K-1) real(r8), public :: vent_ach = 0.3_r8 ! ventilation rate (air exchanges per hour) + ! Cathy [dev.02] + real(r8), public :: q_building_max = 0.013._r8 ! maximum internal building air specific humidity (kg/kg) real(r8), public :: wasteheat_limit = 100._r8 ! limit on wasteheat (W/m2) From 593dc8bb2e3821e24d18c98efac16446cd8295f1 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 1 May 2024 18:09:20 -0500 Subject: [PATCH 03/89] [dev.03] update q_building & dehumidify 1. update `q_building` for the current time step assuming perfect mixing; 2. implement dehumidification process under explicit-AC-adoption scheme: introduce local variable `eflx_urban_ac_sat_lat` to represent latent heat load being removed. Dehumidification under original scheme is not implemented. Humidification for heating is also not implemented. 3. reset `q_building` based on `eflx_urban_ac_sat_lat`. --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 40 +++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index c8abf616b3..57be5592f1 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -245,7 +245,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.02] real(r8) :: q_building_bef(bounds%begl:bounds%endl) ! internal building air specific humidity at previous time step (kg/kg) real(r8) :: q_building_bef_hac(bounds%begl:bounds%endl)! internal building air specific humidity before applying HAC (kg/kg) - real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) ! urban air conditioning flux under AC adoption saturation (W/m**2) + real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) ! urban air conditioning heat flux under AC adoption saturation (W/m**2) ! Cathy [dev.03] + ! Cathy [dev.03] + real(r8) :: eflx_urban_ac_sat_lat(bounds%begl:bounds%endl) ! urban air conditioning latent heat flux under AC adoption saturation (W/m**2) real(r8) :: hcv_roofi(bounds%begl:bounds%endl) ! roof convective heat transfer coefficient (W m-2 K-1) real(r8) :: hcv_sunwi(bounds%begl:bounds%endl) ! sunwall convective heat transfer coefficient (W m-2 K-1) real(r8) :: hcv_shdwi(bounds%begl:bounds%endl) ! shadewall convective heat transfer coefficient (W m-2 K-1) @@ -367,6 +369,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, t_shdw_inner_bef(l) = t_shdw_inner(l) t_floor_bef(l) = t_floor(l) t_building_bef(l) = t_building(l) + ! Cathy [dev.03] + q_building_bef(l) = q_building(l) if (t_roof_inner_bef(l) .le. t_building_bef(l)) then hcv_roofi(l) = hcv_roof_enhanced else @@ -931,6 +935,15 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do + ! Cathy [dev.03] + ! Update internal building air specific humidity + do fl = 1,num_urbanl + l = filter_urbanl(fl) + if (urbpoi(l)) then + q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) + q_building_bef(l) * (1 - vent_ach/3600._r8 * dtime) + end if + end do + ! Restrict internal building air temperature to between min and max ! Calculate heating or air conditioning flux from energy required to change ! internal building air temperature to t_building_min or t_building_max. @@ -940,8 +953,11 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, if (urbpoi(l)) then if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then t_building_bef_hac(l) = t_building(l) + ! Cathy [dev.03] + q_building_bef_hac(l) = q_building(l) ! rho_dair(l) = pstd / (rair*t_building(l)) - + + ! Sensible heat if (t_building_bef_hac(l) > t_building_max(l)) then if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: ! Here, t_building_max is the AC saturation setpoint @@ -964,6 +980,26 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if + + ! Cathy [dev.03] + ! Latent heat + ! Dehumidification process modifies eflx_urban_ac, and is only implemented for urban_explicit_ac = .true.; + ! the latent heat removed from internal building air is released to urban canyon as sensible heat. + ! Humidification process for urban heating is not implemented. + if (q_building_bef_hac(l) > q_building_max(l)) then + if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: + ! Here, q_building_max is the AC saturation humidity setpoint + eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & + (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max(l) & + - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & + ) + eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) + q_building(l) = q_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & + * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) + eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) + end if + end if + else eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 From caeba351b4a9bd4ad5bf8bd229eb350231bcc305 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 1 May 2024 18:19:27 -0500 Subject: [PATCH 04/89] [dev.03] update q_building & dehumidify (cont'd) add one line to account for when there is no sensible heat load and only latent heat load. --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 57be5592f1..1db66594ca 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -977,6 +977,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) ) else + ! Cathy [dev.03]: need this because dehumidification below may reference it + eflx_urban_ac_sat(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if From 600cf4cd8375e60ac3fcd293fefe2059f3fc3edb Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 2 May 2024 13:45:36 -0500 Subject: [PATCH 05/89] [dev.04] bug fix --- src/main/clm_varcon.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index 4d825403f8..62597b544d 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -188,7 +188,7 @@ module clm_varcon real(r8), public :: cp_floor = dens_floor*sh_floor ! volumetric heat capacity of floor - concrete (Salmanca et al. 2010, TAC) (J m-3 K-1) real(r8), public :: vent_ach = 0.3_r8 ! ventilation rate (air exchanges per hour) ! Cathy [dev.02] - real(r8), public :: q_building_max = 0.013._r8 ! maximum internal building air specific humidity (kg/kg) + real(r8), public :: q_building_max = 0.013_r8 ! maximum internal building air specific humidity (kg/kg) real(r8), public :: wasteheat_limit = 100._r8 ! limit on wasteheat (W/m2) From 485662cc4241e85ec0e8a5ae48893772ea0098f4 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Mon, 6 May 2024 15:58:14 -0500 Subject: [PATCH 06/89] [dev.04] bug fix (cont'd) --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 6 +++--- src/biogeophys/WaterDiagnosticType.F90 | 11 ++++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 1db66594ca..5bba75b838 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -988,15 +988,15 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Dehumidification process modifies eflx_urban_ac, and is only implemented for urban_explicit_ac = .true.; ! the latent heat removed from internal building air is released to urban canyon as sensible heat. ! Humidification process for urban heating is not implemented. - if (q_building_bef_hac(l) > q_building_max(l)) then + if (q_building_bef_hac(l) > q_building_max) then if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: ! Here, q_building_max is the AC saturation humidity setpoint eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max(l) & + (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & ) eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) - q_building(l) = q_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & + q_building(l) = q_building_max + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) end if diff --git a/src/biogeophys/WaterDiagnosticType.F90 b/src/biogeophys/WaterDiagnosticType.F90 index 8b05aadbb5..2deab32e74 100644 --- a/src/biogeophys/WaterDiagnosticType.F90 +++ b/src/biogeophys/WaterDiagnosticType.F90 @@ -84,7 +84,7 @@ subroutine Init(this, bounds, info, tracer_vars, is_prog_buildtemp) call this%InitAllocate(bounds, tracer_vars) - call this%InitHistory(bounds) + call this%InitHistory(bounds, is_prog_buildtemp) call this%InitCold(bounds, is_prog_buildtemp) @@ -167,6 +167,8 @@ subroutine InitHistory(this, bounds, is_prog_buildtemp) ! !LOCAL VARIABLES: integer :: begp, endp integer :: begc, endc + ! Cathy [dev.04] + integer :: begl, endl integer :: begg, endg !------------------------------------------------------------------------ @@ -263,6 +265,7 @@ subroutine InitHistory(this, bounds, is_prog_buildtemp) avgflag='A', & long_name=this%info%lname('internal urban building air specific humidity'), & ptr_lunit=this%q_building_lun, l2g_scale_type='unity', set_nourb=spval) + end if end subroutine InitHistory @@ -330,8 +333,10 @@ subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) ! !USES: use clm_varcon , only : nameg, namec use ncdio_pio , only : file_desc_t, ncd_double - use clm_varctl , only : use_fates_planthydro + use clm_varctl , only : use_fates_planthydro, iulog ! Cathy [dev.04] use restUtilMod + ! Cathy [dev.04] + use spmdMod , only : masterproc ! ! !ARGUMENTS: class(waterdiagnostic_type), intent(in) :: this @@ -381,7 +386,7 @@ subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) call restartvar(ncid=ncid, flag=flag, & varname=this%info%fname('q_building'), & xtype=ncd_double, dim1name='landunit', & - long_name=this%info%lname('internal building air specific humidity)', & + long_name=this%info%lname('internal building air specific humidity'), & units='kg/kg', & interpinic_flag='interp', readvar=readvar, data=this%q_building_lun) if (flag=='read' .and. .not. readvar) then From e2792d4849eca524b21befc626f46deb3662a09d Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Mon, 6 May 2024 16:15:24 -0500 Subject: [PATCH 07/89] [dev.04] bug fix (cont'd) --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 4 ++-- src/biogeophys/WaterDiagnosticBulkType.F90 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 5bba75b838..aaa5198b11 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -929,8 +929,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & ! * rho_dair(l) * cpair * (taf(l) - t_building(l)) ) eflx_ventilation(l) = wtlunit_roof(l) * ( & - - ht_roof(l) * (ven_ach/3600._r8) * rho_dair(l) * cpair * (taf(l) - t_building(l)) & - - ht_roof(l) * (ven_ach/3600._r8) * rho_dair(l) * hvap * (qaf(l) - q_building(l)) & + - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * cpair * (taf(l) - t_building(l)) & + - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * hvap * (qaf(l) - q_building(l)) & ) end if end do diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index dd556a2df6..0e3400d3bd 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -154,7 +154,7 @@ subroutine InitBulk(this, bounds, info, vars, & real(r8) , intent(in) :: h2osno_input_col(bounds%begc:) ! Initial total snow water (mm H2O) - call this%Init(bounds, info, vars) + call this%Init(bounds, info, vars, is_prog_buildtemp) call this%InitBulkAllocate(bounds) @@ -813,7 +813,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil !------------------------------------------------------------------------ - call this%Restart(bounds, ncid, flag=flag) + call this%Restart(bounds, ncid, flag=flag, is_prog_buildtemp) if(use_luna)then call restartvar(ncid=ncid, flag=flag, & From 33a79dbad059194555ad96a4670f127510e49c8d Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Mon, 6 May 2024 16:32:50 -0500 Subject: [PATCH 08/89] [dev.04] bug fix (cont'd) --- src/biogeophys/WaterDiagnosticBulkType.F90 | 10 +++++++--- src/biogeophys/WaterType.F90 | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 0e3400d3bd..5e3b7a4a8c 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -28,6 +28,8 @@ module WaterDiagnosticBulkType use WaterStateType, only : waterstate_type use WaterStateBulkType, only : waterstatebulk_type use WaterFluxType, only : waterflux_type + ! Cathy [dev.04] + use UrbanParamsType, only : IsProgBuildTemp ! implicit none save @@ -154,7 +156,7 @@ subroutine InitBulk(this, bounds, info, vars, & real(r8) , intent(in) :: h2osno_input_col(bounds%begc:) ! Initial total snow water (mm H2O) - call this%Init(bounds, info, vars, is_prog_buildtemp) + call this%Init(bounds, info, vars, IsProgBuildTemp()) call this%InitBulkAllocate(bounds) @@ -785,7 +787,7 @@ subroutine InitBulkCold(this, bounds, & end subroutine InitBulkCold !------------------------------------------------------------------------ - subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_file, waterstatebulk_inst) + subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_file, waterstatebulk_inst, is_prog_buildtemp) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. @@ -806,6 +808,8 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil character(len=*) , intent(in) :: flag ! 'read' or 'write' logical, intent(in) :: writing_finidat_interp_dest_file ! true if we are writing a finidat_interp_dest file (ignored for flag=='read') type(waterstatebulk_type), intent(in) :: waterstatebulk_inst + ! Cathy [dev.04] + logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: logical :: readvar @@ -813,7 +817,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil !------------------------------------------------------------------------ - call this%Restart(bounds, ncid, flag=flag, is_prog_buildtemp) + call this%Restart(bounds, ncid, flag=flag, is_prog_buildtemp=IsProgBuildTemp()) if(use_luna)then call restartvar(ncid=ncid, flag=flag, & diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index da0ed395ba..4bd54ec8d9 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -727,7 +727,7 @@ end subroutine UpdateAccVars !----------------------------------------------------------------------- subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & - watsat_col, t_soisno_col, altmax_lastyear_indx) + watsat_col, t_soisno_col, altmax_lastyear_indx, is_prog_buildtemp) ! Cathy [dev.04] ! ! !DESCRIPTION: ! Read/write information to/from restart file for all water variables @@ -741,6 +741,8 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year + ! Cathy [dev.04] + logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: integer :: i @@ -750,7 +752,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & SHR_ASSERT_ALL_FL((ubound(watsat_col, 1) == bounds%endc), sourcefile, __LINE__) - call this%waterfluxbulk_inst%restartBulk (bounds, ncid, flag=flag) + call this%waterfluxbulk_inst%restartBulk (bounds, ncid, flag=flag, is_prog_buildtemp=IsProgBuildTemp()) call this%waterstatebulk_inst%restartBulk (bounds, ncid, flag=flag, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & @@ -759,7 +761,9 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & call this%waterdiagnosticbulk_inst%restartBulk (bounds, ncid, flag=flag, & writing_finidat_interp_dest_file=writing_finidat_interp_dest_file, & - waterstatebulk_inst = this%waterstatebulk_inst) + waterstatebulk_inst = this%waterstatebulk_inst, & + ! Cathy [dev.04] + is_prog_buildtemp = IsProgBuildTemp()) do i = this%tracers_beg, this%tracers_end @@ -771,7 +775,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) call this%bulk_and_tracers(i)%waterdiagnostic_inst%Restart(bounds, ncid, flag=flag, & - IsProgBuildTemp()) ! Cathy [dev.04] + is_prog_buildtemp=IsProgBuildTemp()) ! Cathy [dev.04] end do From 7612c857ecc62d34034c3131eab4698538feb551 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Mon, 6 May 2024 16:50:08 -0500 Subject: [PATCH 09/89] [dev.04] bug fix (cont'd) --- src/biogeophys/SoilTemperatureMod.F90 | 5 ++++- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 4 ++-- src/biogeophys/WaterType.F90 | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 0dc8876d24..7583b0d034 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -541,7 +541,10 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter if ( IsProgBuildTemp() )then call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & - temperature_inst, energyflux_inst, urbantv_inst) + temperature_inst, energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst) + ! Cathy [dev.04]: using waterdiagnosticbulk_inst instead of waterdiagnostic_inst + ! because it seems vars in WaterDiagnosticType can be accessed through the bulk + ! type, and it has already been defined in this subroutine. end if do fc = 1,num_nolakec diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index aaa5198b11..5e140e8e4a 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -44,7 +44,7 @@ module UrbBuildTempOleson2015Mod ! !INTERFACE: subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, & filter_nolakec, tk, urbanparams_inst, temperature_inst, & - energyflux_inst, waterdiagnostic_inst, urbantv_inst) ! Cathy [dev.02] + energyflux_inst, urbantv_inst, waterdiagnostic_inst) ! Cathy [dev.02] ! ! !DESCRIPTION: ! Solve for t_building, inner surface temperatures of roof, sunw, shdw, and floor temperature @@ -227,9 +227,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(urbanparams_type), intent(in) :: urbanparams_inst ! urban parameters type(temperature_type), intent(inout) :: temperature_inst ! temperature variables type(energyflux_type) , intent(inout) :: energyflux_inst ! energy flux variables + type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables ! Cathy [dev.02] type(waterdiagnostic_type), intent(inout) :: waterdiagnostic_inst ! water diagnostic variables - type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables ! ! !LOCAL VARIABLES: integer, parameter :: neq = 5 ! number of equation/unknowns diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index 4bd54ec8d9..79d6917978 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -752,7 +752,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & SHR_ASSERT_ALL_FL((ubound(watsat_col, 1) == bounds%endc), sourcefile, __LINE__) - call this%waterfluxbulk_inst%restartBulk (bounds, ncid, flag=flag, is_prog_buildtemp=IsProgBuildTemp()) + call this%waterfluxbulk_inst%restartBulk (bounds, ncid, flag=flag) call this%waterstatebulk_inst%restartBulk (bounds, ncid, flag=flag, & watsat_col=watsat_col(bounds%begc:bounds%endc,:), & From 7b6d20cd7da7a0612271fff75f5a7327814b5e34 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Mon, 6 May 2024 17:11:31 -0500 Subject: [PATCH 10/89] [dev.04] bug fix (cont'd) --- src/biogeophys/SoilTemperatureMod.F90 | 11 ++++++----- src/main/clm_driver.F90 | 4 +++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 7583b0d034..fe4f39ce5a 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -20,6 +20,8 @@ module SoilTemperatureMod use WaterFluxBulkType , only : waterfluxbulk_type use WaterStateBulkType , only : waterstatebulk_type use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type + ! Cathy [dev.04] + use WaterDiagnosticType , only : waterdiagnostic_type use SolarAbsorbedType , only : solarabs_type use SoilStateType , only : soilstate_type use EnergyFluxType , only : energyflux_type @@ -91,7 +93,7 @@ module SoilTemperatureMod subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter_urbanc, & num_nolakep, filter_nolakep, num_nolakec, filter_nolakec, & atm2lnd_inst, urbanparams_inst, canopystate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst,& - solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst) + solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst, waterdiagnostic_inst) ! Cathy [dev.04] ! ! !DESCRIPTION: ! Snow and soil temperatures including phase change @@ -144,6 +146,8 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter type(solarabs_type) , intent(inout) :: solarabs_inst type(energyflux_type) , intent(inout) :: energyflux_inst type(temperature_type) , intent(inout) :: temperature_inst + ! Cathy [dev.04] + type(waterdiagnostic_type) , intent(inout) :: waterdiagnostic_inst ! water diagnostic variables ! ! !LOCAL VARIABLES: integer :: j,c,l,g ! indices @@ -541,10 +545,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter if ( IsProgBuildTemp() )then call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & - temperature_inst, energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst) - ! Cathy [dev.04]: using waterdiagnosticbulk_inst instead of waterdiagnostic_inst - ! because it seems vars in WaterDiagnosticType can be accessed through the bulk - ! type, and it has already been defined in this subroutine. + temperature_inst, energyflux_inst, urbantv_inst, waterdiagnostic_inst) ! Cathy [dev.04] end if do fc = 1,num_nolakec diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90 index 00a98e61b4..2d3c841eaf 100644 --- a/src/main/clm_driver.F90 +++ b/src/main/clm_driver.F90 @@ -849,7 +849,9 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro filter(nc)%num_nolakec , filter(nc)%nolakec, & atm2lnd_inst, urbanparams_inst, canopystate_inst, water_inst%waterstatebulk_inst, & water_inst%waterdiagnosticbulk_inst, water_inst%waterfluxbulk_inst, & - solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst) + solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst, & + ! Cathy [dev.04] + water_inst%waterdiagnostic_inst) ! The following is called immediately after SoilTemperature so that melted ice is ! converted back to solid ice as soon as possible From d0151196e37dece671c0d9f28a75f61b884b8647 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Mon, 6 May 2024 17:29:04 -0500 Subject: [PATCH 11/89] [dev.04] bug fix (cont'd) Revoke some changes from before b/c they may not be necessary. --- src/biogeophys/WaterDiagnosticBulkType.F90 | 4 +--- src/biogeophys/WaterType.F90 | 4 +--- src/main/clm_instMod.F90 | 4 +++- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 5e3b7a4a8c..42ba8b33c3 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -787,7 +787,7 @@ subroutine InitBulkCold(this, bounds, & end subroutine InitBulkCold !------------------------------------------------------------------------ - subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_file, waterstatebulk_inst, is_prog_buildtemp) + subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_file, waterstatebulk_inst) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. @@ -808,8 +808,6 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil character(len=*) , intent(in) :: flag ! 'read' or 'write' logical, intent(in) :: writing_finidat_interp_dest_file ! true if we are writing a finidat_interp_dest file (ignored for flag=='read') type(waterstatebulk_type), intent(in) :: waterstatebulk_inst - ! Cathy [dev.04] - logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: logical :: readvar diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index 79d6917978..0dc74aee41 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -761,9 +761,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & call this%waterdiagnosticbulk_inst%restartBulk (bounds, ncid, flag=flag, & writing_finidat_interp_dest_file=writing_finidat_interp_dest_file, & - waterstatebulk_inst = this%waterstatebulk_inst, & - ! Cathy [dev.04] - is_prog_buildtemp = IsProgBuildTemp()) + waterstatebulk_inst = this%waterstatebulk_inst) do i = this%tracers_beg, this%tracers_end diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index b9d74c418a..b6697e8c43 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -546,7 +546,9 @@ subroutine clm_instRest(bounds, ncid, flag, writing_finidat_interp_dest_file) writing_finidat_interp_dest_file = writing_finidat_interp_dest_file, & watsat_col = soilstate_inst%watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=temperature_inst%t_soisno_col(bounds%begc:bounds%endc, -nlevsno+1:), & - altmax_lastyear_indx=active_layer_inst%altmax_lastyear_indx_col(bounds%begc:bounds%endc)) + altmax_lastyear_indx=active_layer_inst%altmax_lastyear_indx_col(bounds%begc:bounds%endc), & + ! Cathy [dev.04] + is_prog_buildtemp = IsProgBuildTemp()) call irrigation_inst%restart (bounds, ncid, flag=flag) From d1e4dad4db29de362fe5491445d0202c4cb76c27 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 9 May 2024 15:11:38 -0500 Subject: [PATCH 12/89] [dev.04] bug fix (cont'd) Change all waterdiagnostic_type into waterdiagnosticbulk_type to try to fix the error of no "water_inst%waterdiagnostic_inst" defined when trying to call it in clm_driver.F90. --- src/biogeophys/SoilTemperatureMod.F90 | 10 +++++----- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 17 +++++++++-------- src/main/clm_driver.F90 | 4 +--- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index fe4f39ce5a..8c9e39e9ae 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -21,7 +21,7 @@ module SoilTemperatureMod use WaterStateBulkType , only : waterstatebulk_type use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type ! Cathy [dev.04] - use WaterDiagnosticType , only : waterdiagnostic_type + ! use WaterDiagnosticType , only : waterdiagnostic_type use SolarAbsorbedType , only : solarabs_type use SoilStateType , only : soilstate_type use EnergyFluxType , only : energyflux_type @@ -93,7 +93,7 @@ module SoilTemperatureMod subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter_urbanc, & num_nolakep, filter_nolakep, num_nolakec, filter_nolakec, & atm2lnd_inst, urbanparams_inst, canopystate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst,& - solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst, waterdiagnostic_inst) ! Cathy [dev.04] + solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst) ! Cathy [dev.04] ! ! !DESCRIPTION: ! Snow and soil temperatures including phase change @@ -146,8 +146,8 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter type(solarabs_type) , intent(inout) :: solarabs_inst type(energyflux_type) , intent(inout) :: energyflux_inst type(temperature_type) , intent(inout) :: temperature_inst - ! Cathy [dev.04] - type(waterdiagnostic_type) , intent(inout) :: waterdiagnostic_inst ! water diagnostic variables + ! Cathy [dev.04] + ! type(waterdiagnostic_type) , intent(inout) :: waterdiagnostic_inst ! water diagnostic variables ! ! !LOCAL VARIABLES: integer :: j,c,l,g ! indices @@ -545,7 +545,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter if ( IsProgBuildTemp() )then call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & - temperature_inst, energyflux_inst, urbantv_inst, waterdiagnostic_inst) ! Cathy [dev.04] + temperature_inst, energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst) ! Cathy [dev.04] end if do fc = 1,num_nolakec diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 5e140e8e4a..42a81efbde 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -16,8 +16,8 @@ module UrbBuildTempOleson2015Mod use UrbanTimeVarType , only : urbantv_type use EnergyFluxType , only : energyflux_type use TemperatureType , only : temperature_type - ! Cathy [dev.02] - use WaterDiagnosticType, only : waterdiagnostic_type + ! Cathy [dev.02] [dev.04] + use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type use LandunitType , only : lun use ColumnType , only : col ! @@ -44,7 +44,7 @@ module UrbBuildTempOleson2015Mod ! !INTERFACE: subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, & filter_nolakec, tk, urbanparams_inst, temperature_inst, & - energyflux_inst, urbantv_inst, waterdiagnostic_inst) ! Cathy [dev.02] + energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst) ! Cathy [dev.02] [dev.04] ! ! !DESCRIPTION: ! Solve for t_building, inner surface temperatures of roof, sunw, shdw, and floor temperature @@ -228,8 +228,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(temperature_type), intent(inout) :: temperature_inst ! temperature variables type(energyflux_type) , intent(inout) :: energyflux_inst ! energy flux variables type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables - ! Cathy [dev.02] - type(waterdiagnostic_type), intent(inout) :: waterdiagnostic_inst ! water diagnostic variables + ! Cathy [dev.02] [dev.04] + type(waterdiagnosticbulk_type), intent(inout) :: waterdiagnosticbulk_inst ! water diagnostic variables ! ! !LOCAL VARIABLES: integer, parameter :: neq = 5 ! number of equation/unknowns @@ -340,9 +340,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, t_building_max => urbantv_inst%t_building_max , & ! Input: [real(r8) (:)] maximum internal building air temperature (K) t_building_min => urbanparams_inst%t_building_min , & ! Input: [real(r8) (:)] minimum internal building air temperature (K) - ! Cathy [dev.02] - qaf => waterdiagnostic_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) - q_building => waterdiagnostic_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) + ! Cathy [dev.02] [dev.04] + ! trying to change to waterdiagnosticbulk_inst following how qaf was used in UrbanFluxesMod.F90 + qaf => waterdiagnosticbulk_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) + q_building => waterdiagnosticbulk_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (W/m**2) eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) diff --git a/src/main/clm_driver.F90 b/src/main/clm_driver.F90 index 2d3c841eaf..00a98e61b4 100644 --- a/src/main/clm_driver.F90 +++ b/src/main/clm_driver.F90 @@ -849,9 +849,7 @@ subroutine clm_drv(doalb, nextsw_cday, declinp1, declin, rstwr, nlend, rdate, ro filter(nc)%num_nolakec , filter(nc)%nolakec, & atm2lnd_inst, urbanparams_inst, canopystate_inst, water_inst%waterstatebulk_inst, & water_inst%waterdiagnosticbulk_inst, water_inst%waterfluxbulk_inst, & - solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst, & - ! Cathy [dev.04] - water_inst%waterdiagnostic_inst) + solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst) ! The following is called immediately after SoilTemperature so that melted ice is ! converted back to solid ice as soon as possible From b40cf24089d58e040390c0c643f9ab7011015cd8 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Fri, 17 May 2024 14:48:21 -0500 Subject: [PATCH 13/89] [dev.06] shift to RH setpoint 1. Define RH_building, add hist field 2. Convert RH_building_max (RH setpoint) to q_building_max (spec hum setpoint) 3. Calculate RH_building from q_building --- src/biogeophys/HumanIndexMod.F90 | 2 +- src/biogeophys/SoilTemperatureMod.F90 | 3 +- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 36 +++++++++++++++++--- src/biogeophys/WaterDiagnosticBulkType.F90 | 12 +++++++ src/main/clm_varcon.F90 | 4 ++- 5 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/biogeophys/HumanIndexMod.F90 b/src/biogeophys/HumanIndexMod.F90 index 17a1ef968e..597ad989e6 100644 --- a/src/biogeophys/HumanIndexMod.F90 +++ b/src/biogeophys/HumanIndexMod.F90 @@ -1350,7 +1350,7 @@ subroutine QSat_2 (T_k, p_t, es_mb, de_mbdT, dlnes_mbdT, rs, rsdT, foftk, fdT) ! Clausius-Clapeyron p_tmb = p_t*0.01_r8 tcfbdiff = T_k - Cf + beta - es_mb = es_C*exp(alpha*(T_k - Cf)/(tcfbdiff)) + es_mb = es_C*exp(alpha*(T_k - Cf)/(tcfbdiff)) ! Cathy [dev.06] notes: this calculates sat. vapor pressure dlnes_mbdT = alpha*beta/((tcfbdiff)*(tcfbdiff)) pminuse = p_tmb - es_mb de_mbdT = es_mb*dlnes_mbdT diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 8c9e39e9ae..f8a6c2d10b 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -545,7 +545,8 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter if ( IsProgBuildTemp() )then call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & - temperature_inst, energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst) ! Cathy [dev.04] + temperature_inst, energyflux_inst, urbantv_inst, & + waterdiagnosticbulk_inst, atm2lnd_inst) ! Cathy [dev.04] [dev.06] end if do fc = 1,num_nolakec diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 42a81efbde..c6e204edba 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -19,7 +19,9 @@ module UrbBuildTempOleson2015Mod ! Cathy [dev.02] [dev.04] use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type use LandunitType , only : lun - use ColumnType , only : col + use ColumnType , only : col + ! Cathy [dev.06] + use atm2lndType , only : atm2lnd_type ! ! !PUBLIC TYPES: implicit none @@ -44,7 +46,8 @@ module UrbBuildTempOleson2015Mod ! !INTERFACE: subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, & filter_nolakec, tk, urbanparams_inst, temperature_inst, & - energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst) ! Cathy [dev.02] [dev.04] + energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst, & + atm2lnd_inst) ! Cathy [dev.02] [dev.04] [dev.06] ! ! !DESCRIPTION: ! Solve for t_building, inner surface temperatures of roof, sunw, shdw, and floor temperature @@ -209,12 +212,16 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, em_roof_int, em_floor_int, em_sunw_int, em_shdw_int, & dz_floor, dens_floor, cp_floor, vent_ach, & ! Cathy [dev.02] - q_building_max, hvap + ! q_building_max, hvap + ! Cathy [dev.06] + rh_building_max, hvap use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall use clm_varctl , only : iulog use abortutils , only : endrun use clm_varpar , only : nlevurb, nlevsno, nlevmaxurbgrnd use UrbanParamsType , only : urban_hac, urban_hac_off, urban_hac_on, urban_wasteheat_on, urban_explicit_ac + ! Cathy [dev.06] + use QSatMod , only : QSat ! ! !ARGUMENTS: implicit none @@ -230,6 +237,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables ! Cathy [dev.02] [dev.04] type(waterdiagnosticbulk_type), intent(inout) :: waterdiagnosticbulk_inst ! water diagnostic variables + ! Cathy [dev.06] + type(atm2lnd_type) , intent(in) :: atm2lnd_inst ! ! !LOCAL VARIABLES: integer, parameter :: neq = 5 ! number of equation/unknowns @@ -310,6 +319,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! on exit, if info = 0, the n-by-nrhs solution matrix x integer :: info ! exit information for LAPACK routine dgesv integer :: ipiv(neq) ! the pivot indices that define the permutation matrix P + ! Cathy [dev.06] + real(r8) :: q_building_max ! maximum internal building air specific humidity determined from rh_building_max (kg/kg) + real(r8) :: qsat_building_max ! maximum internal building air saturated specific humidity/mixing ratio used to determing q_building_max from rh_building_max (kg/kg) + real(r8) :: qsat_building ! internal building air saturated specific humidity/mixing ratio used to calculate rh_building (kg/kg) !EOP !----------------------------------------------------------------------- @@ -344,6 +357,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! trying to change to waterdiagnosticbulk_inst following how qaf was used in UrbanFluxesMod.F90 qaf => waterdiagnosticbulk_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) q_building => waterdiagnosticbulk_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) + ! Cathy [dev.06] + rh_building => waterdiagnosticbulk_inst%rh_building_lun,& ! InOut: [real(r8) (:)] internal building air relative humidity (%) + forc_pbot => atm2lnd_inst%forc_pbot_not_downscaled_grc,& ! Input:[real(r8) (:)] atmospheric pressure (Pa) eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (W/m**2) eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) @@ -951,13 +967,19 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) + ! Cathy [dev.06] + g = lun%gridcell(l) if (urbpoi(l)) then if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then t_building_bef_hac(l) = t_building(l) ! Cathy [dev.03] q_building_bef_hac(l) = q_building(l) ! rho_dair(l) = pstd / (rair*t_building(l)) - + ! Cathy [dev.06] + ! Calculate q setpoint from RH setpoint + call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) + q_building_max = rh_building_max*qsat_building_max + ! Sensible heat if (t_building_bef_hac(l) > t_building_max(l)) then if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: @@ -991,7 +1013,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Humidification process for urban heating is not implemented. if (q_building_bef_hac(l) > q_building_max) then if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: - ! Here, q_building_max is the AC saturation humidity setpoint + ! Here, q_building_max is the AC humidity setpoint under saturated adoption eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & @@ -1013,6 +1035,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & ) + ! Cathy [dev.06] + ! Calculate relative humidity based on specific humidity + call QSat(t_building(l), forc_pbot(g), qsat_building) + rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) end if end do diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 42ba8b33c3..32a02612b0 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -65,6 +65,8 @@ module WaterDiagnosticBulkType real(r8), pointer :: rh_ref2m_patch (:) ! patch 2 m height surface relative humidity (%) real(r8), pointer :: rh_ref2m_r_patch (:) ! patch 2 m height surface relative humidity - rural (%) real(r8), pointer :: rh_ref2m_u_patch (:) ! patch 2 m height surface relative humidity - urban (%) + ! Cathy [dev.06] + real(r8), pointer :: rh_building_lun (:) ! lun internal building air relative humidity (%) real(r8), pointer :: rh_af_patch (:) ! patch fractional humidity of canopy air (dimensionless) ! private real(r8), pointer :: rh10_af_patch (:) ! 10-day mean patch fractional humidity of canopy air (dimensionless) real(r8), pointer :: dqgdT_col (:) ! col d(qg)/dT @@ -221,6 +223,8 @@ subroutine InitBulkAllocate(this, bounds) allocate(this%rh_ref2m_patch (begp:endp)) ; this%rh_ref2m_patch (:) = nan allocate(this%rh_ref2m_u_patch (begp:endp)) ; this%rh_ref2m_u_patch (:) = nan allocate(this%rh_ref2m_r_patch (begp:endp)) ; this%rh_ref2m_r_patch (:) = nan + ! Cathy [dev.06] + allocate(this%rh_building_lun (begl:endl)) ; this%rh_building_lun (:) = nan allocate(this%rh_af_patch (begp:endp)) ; this%rh_af_patch (:) = nan allocate(this%rh10_af_patch (begp:endp)) ; this%rh10_af_patch (:) = spval @@ -359,6 +363,14 @@ subroutine InitBulkHistory(this, bounds) long_name=this%info%lname('Urban 2m relative humidity'), & ptr_patch=this%rh_ref2m_u_patch, set_nourb=spval, default='inactive') + this%rh_building_lun(begl:endl) = spval + call hist_addfld1d ( & + fname=this%info%fname('RHBUILD'), & + units='%', & + avgflag='A', & + long_name=this%info%lname('Internal urban building air relative humidity'), & + ptr_lunit=this%rh_building_lun, set_nourb=spval, default='inactive') + this%rh_af_patch(begp:endp) = spval call hist_addfld1d ( & fname=this%info%fname('RHAF'), & diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index 62597b544d..cb0a228805 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -188,7 +188,9 @@ module clm_varcon real(r8), public :: cp_floor = dens_floor*sh_floor ! volumetric heat capacity of floor - concrete (Salmanca et al. 2010, TAC) (J m-3 K-1) real(r8), public :: vent_ach = 0.3_r8 ! ventilation rate (air exchanges per hour) ! Cathy [dev.02] - real(r8), public :: q_building_max = 0.013_r8 ! maximum internal building air specific humidity (kg/kg) + ! real(r8), public :: q_building_max = 0.013_r8 ! maximum internal building air specific humidity (kg/kg) + ! Cathy [dev.06] + real(r8), public :: rh_building_max = 60._r8 ! maximum internal building air relative humidity (%) real(r8), public :: wasteheat_limit = 100._r8 ! limit on wasteheat (W/m2) From 62970a71822ee8f00ea74121d084639b260dcabd Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Sun, 19 May 2024 16:54:19 -0500 Subject: [PATCH 14/89] [dev.07] debug --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index c6e204edba..da10ef2ae8 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -242,7 +242,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! ! !LOCAL VARIABLES: integer, parameter :: neq = 5 ! number of equation/unknowns - integer :: fc,fl,c,l ! indices + ! Cathy [dev.07] + ! integer :: fc,fl,c,l ! indices + integer :: fc,fl,c,l,g ! indices real(r8) :: dtime ! land model time step (s) real(r8) :: building_hwr(bounds%begl:bounds%endl) ! building height to building width ratio (-) real(r8) :: t_roof_inner_bef(bounds%begl:bounds%endl) ! roof inside surface temperature at previous time step (K) From 5c720ce7f432829bc012ee8db8a71a9d0580ff00 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Sun, 19 May 2024 19:34:00 -0500 Subject: [PATCH 15/89] [dev.07] debug cont'd --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index da10ef2ae8..66b7ac623c 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -977,10 +977,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.03] q_building_bef_hac(l) = q_building(l) ! rho_dair(l) = pstd / (rair*t_building(l)) - ! Cathy [dev.06] + ! Cathy [dev.06] [dev.07] ! Calculate q setpoint from RH setpoint call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) - q_building_max = rh_building_max*qsat_building_max + q_building_max = rh_building_max / 100._r8 * qsat_building_max ! Sensible heat if (t_building_bef_hac(l) > t_building_max(l)) then From fc0c0ee54161c9d3b52e1da30aeafaa5be7098ab Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 22 May 2024 12:29:54 -0500 Subject: [PATCH 16/89] [dev.09] put RH control inside temp control --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 48 ++++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 66b7ac623c..45bae39cfe 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -982,14 +982,32 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) q_building_max = rh_building_max / 100._r8 * qsat_building_max - ! Sensible heat if (t_building_bef_hac(l) > t_building_max(l)) then if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: + + ! Sensible heat ! Here, t_building_max is the AC saturation setpoint eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_max(l) & - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) ) t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) & * dtime / (ht_roof(l) * rho_dair(l) * cpair * wtlunit_roof(l)) + ! eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) + + ! Cathy [dev.09] + ! Latent heat + if (q_building_bef_hac(l) > q_building_max) then + ! the latent heat removed from internal building air is released to urban canyon as sensible heat. + ! Humidification process for urban heating is not implemented. + ! Here, q_building_max is the AC humidity setpoint under saturated adoption + eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & + (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & + - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & + ) + eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) + q_building(l) = q_building_max + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & + * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) + + end if eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) else t_building(l) = t_building_max(l) @@ -1003,7 +1021,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) ) else ! Cathy [dev.03]: need this because dehumidification below may reference it - eflx_urban_ac_sat(l) = 0._r8 + ! eflx_urban_ac_sat(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if @@ -1013,19 +1031,19 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Dehumidification process modifies eflx_urban_ac, and is only implemented for urban_explicit_ac = .true.; ! the latent heat removed from internal building air is released to urban canyon as sensible heat. ! Humidification process for urban heating is not implemented. - if (q_building_bef_hac(l) > q_building_max) then - if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: - ! Here, q_building_max is the AC humidity setpoint under saturated adoption - eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & - - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & - ) - eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) - q_building(l) = q_building_max + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & - * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) - eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) - end if - end if + ! if (q_building_bef_hac(l) > q_building_max) then + ! if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: + ! ! Here, q_building_max is the AC humidity setpoint under saturated adoption + ! eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & + ! (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & + ! - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & + ! ) + ! eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) + ! q_building(l) = q_building_max + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & + ! * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) + ! eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) + ! end if + ! end if else eflx_urban_ac(l) = 0._r8 From 3b749292f1822948790e3d160966d646304224cf Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 28 May 2024 16:03:51 -0500 Subject: [PATCH 17/89] [dev.11] rho, cp of humid air Change density and specific heat capacity from dry air to humid air. NOT DONE IN THIS COMMIT but may need to change pressure from forc_pbot to pstd in some QSat() calls to maintain consistency with original code. --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 50 +++++++++++++------- src/main/clm_varcon.F90 | 6 ++- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 45bae39cfe..8ef736d63b 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -213,8 +213,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, dz_floor, dens_floor, cp_floor, vent_ach, & ! Cathy [dev.02] ! q_building_max, hvap - ! Cathy [dev.06] - rh_building_max, hvap + ! Cathy [dev.06] [dev.11] + rh_building_max, hvap, rwat, cpwvap use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall use clm_varctl , only : iulog use abortutils , only : endrun @@ -270,7 +270,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: dz_floori(bounds%begl:bounds%endl) ! concrete floor thickness (m) real(r8) :: cp_floori(bounds%begl:bounds%endl) ! concrete floor volumetric heat capacity (J m-3 K-1) real(r8) :: cv_floori(bounds%begl:bounds%endl) ! intermediate calculation for concrete floor (W m-2 K-1) + ! Cathy [dev.11] rho_dair below will be temporarily used as density of HUMID air; the var name and description will be changed later real(r8) :: rho_dair(bounds%begl:bounds%endl) ! density of dry air at standard pressure and t_building (kg m-3) + real(r8) :: cp_hair(bounds%begl:bounds%endl) ! specific heat capacity of indoor humid air (J kg-1 K-1) real(r8) :: vf_rf(bounds%begl:bounds%endl) ! view factor of roof for floor (-) real(r8) :: vf_fr(bounds%begl:bounds%endl) ! view factor of floor for roof (-) real(r8) :: vf_wf(bounds%begl:bounds%endl) ! view factor of wall for floor (-) @@ -325,6 +327,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: q_building_max ! maximum internal building air specific humidity determined from rh_building_max (kg/kg) real(r8) :: qsat_building_max ! maximum internal building air saturated specific humidity/mixing ratio used to determing q_building_max from rh_building_max (kg/kg) real(r8) :: qsat_building ! internal building air saturated specific humidity/mixing ratio used to calculate rh_building (kg/kg) + ! Cathy [dev.11] + real(r8) :: esat_building ! internal building air saturated vapor pressure used to calculate p_vapor (Pa) + real(r8) :: p_vapor ! internal building air partial pressure of water vapor (Pa) !EOP !----------------------------------------------------------------------- @@ -412,8 +417,17 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, cp_floori(l) = cp_floor ! Intermediate calculation for concrete floor (W m-2 K-1) cv_floori(l) = (dz_floori(l) * cp_floori(l)) / dtime + ! Cathy [dev.11] ! Density of dry air at standard pressure and t_building (kg m-3) - rho_dair(l) = pstd / (rair*t_building_bef(l)) + ! rho_dair(l) = pstd / (rair*t_building_bef(l)) + ! Saturated vapor pressure at t_building (Pa) + call QSat(t_building_bef(l), pstd, qsat_building, es = esat_building) + ! Partial pressure of water vapor (Pa) + p_vapor = min(1._r8, q_building_bef(l) / qsat_building ) * esat_building + ! Density of HUMID air at standard pressure and t_building (kg m-3) + rho_dair(l) = ( pstd - p_vapor ) / ( rair * t_building_bef(l) ) + p_vapor / ( rwat * t_building_bef(l)) + ! Specific heat capacity of HUMID air (J/kg/K) + cp_hair(l) = cpair + cpwvap * q_building_bef(l) ! Building height to building width ratio building_hwr(l) = canyon_hwr(l)*(1._r8-wtlunit_roof(l))/wtlunit_roof(l) end if @@ -677,15 +691,15 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, a(5,4) = - 0.5_r8*hcv_floori(l) - a(5,5) = ((ht_roof(l)*rho_dair(l)*cpair)/dtime) + & - ((ht_roof(l)*vent_ach)/3600._r8)*rho_dair(l)*cpair + & + a(5,5) = ((ht_roof(l)*rho_dair(l)*cp_hair(l))/dtime) + & + ((ht_roof(l)*vent_ach)/3600._r8)*rho_dair(l)*cp_hair(l) + & 0.5_r8*hcv_roofi(l) + & 0.5_r8*hcv_sunwi(l)*building_hwr(l) + & 0.5_r8*hcv_shdwi(l)*building_hwr(l) + & 0.5_r8*hcv_floori(l) - result(5) = (ht_roof(l)*rho_dair(l)*cpair/dtime)*t_building_bef(l) & - + ((ht_roof(l)*vent_ach)/3600._r8)*rho_dair(l)*cpair*taf(l) & + result(5) = (ht_roof(l)*rho_dair(l)*cp_hair(l)/dtime)*t_building_bef(l) & + + ((ht_roof(l)*vent_ach)/3600._r8)*rho_dair(l)*cp_hair(l)*taf(l) & + 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & + 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & + 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & @@ -923,8 +937,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if - enrgy_bal_buildair(l) = (ht_roof(l)*rho_dair(l)*cpair/dtime)*(t_building(l) - t_building_bef(l)) & - - ht_roof(l)*(vent_ach/3600._r8)*rho_dair(l)*cpair*(taf(l) - t_building(l)) & + enrgy_bal_buildair(l) = (ht_roof(l)*rho_dair(l)*cp_hair(l)/dtime)*(t_building(l) - t_building_bef(l)) & + - ht_roof(l)*(vent_ach/3600._r8)*rho_dair(l)*cp_hair(l)*(taf(l) - t_building(l)) & - 0.5_r8*hcv_roofi(l)*(t_roof_inner(l) - t_building(l)) & - 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner(l) - t_building(l))*building_hwr(l) & @@ -948,7 +962,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & ! * rho_dair(l) * cpair * (taf(l) - t_building(l)) ) eflx_ventilation(l) = wtlunit_roof(l) * ( & - - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * cpair * (taf(l) - t_building(l)) & + - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * cp_hair(l) * (taf(l) - t_building(l)) & - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * hvap * (qaf(l) - q_building(l)) & ) end if @@ -987,10 +1001,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Sensible heat ! Here, t_building_max is the AC saturation setpoint - eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_max(l) & - - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) ) + eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_max(l) & + - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) & - * dtime / (ht_roof(l) * rho_dair(l) * cpair * wtlunit_roof(l)) + * dtime / (ht_roof(l) * rho_dair(l) * cp_hair(l) * wtlunit_roof(l)) ! eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) ! Cathy [dev.09] @@ -1011,14 +1025,14 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) else t_building(l) = t_building_max(l) - eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) & - - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) ) + eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) end if else if (t_building_bef_hac(l) < t_building_min(l)) then t_building(l) = t_building_min(l) - eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building(l) & - - (ht_roof(l) * rho_dair(l) * cpair / dtime) * t_building_bef_hac(l) ) + eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) else ! Cathy [dev.03]: need this because dehumidification below may reference it ! eflx_urban_ac_sat(l) = 0._r8 @@ -1052,7 +1066,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.02] ! eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) eflx_building(l) = wtlunit_roof(l) * ( & - (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_dair(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & ) ! Cathy [dev.06] diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index cb0a228805..6a0672004f 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -13,7 +13,9 @@ module clm_varcon SHR_CONST_RHOICE,SHR_CONST_TKFRZ,SHR_CONST_REARTH, & SHR_CONST_PDB, SHR_CONST_PI, SHR_CONST_CDAY, & SHR_CONST_RGAS, SHR_CONST_PSTD, & - SHR_CONST_MWDAIR, SHR_CONST_MWWV, SHR_CONST_CPFW + SHR_CONST_MWDAIR, SHR_CONST_MWWV, SHR_CONST_CPFW & + ! Cathy [dev.11] + SHR_CONST_CPWV use clm_varpar , only: numrad, nlevgrnd, nlevlak, nlevdecomp_full use clm_varpar , only: ngases use clm_varpar , only: nlayer @@ -56,6 +58,8 @@ module clm_varcon real(r8), public :: cpliq = SHR_CONST_CPFW ! Specific heat of water [J/kg-K] real(r8), public :: cpice = SHR_CONST_CPICE ! Specific heat of ice [J/kg-K] real(r8), public :: cpair = SHR_CONST_CPDAIR ! specific heat of dry air [J/kg/K] + ! Cathy [dev.11] + real(r8), public :: cpwvap = SHR_CONST_CPWV ! specific heat of water vapor [J/kg/K] real(r8), public :: hvap = SHR_CONST_LATVAP ! Latent heat of evap for water [J/kg] real(r8), public :: hsub = SHR_CONST_LATSUB ! Latent heat of sublimation [J/kg] real(r8), public :: hfus = SHR_CONST_LATICE ! Latent heat of fusion for ice [J/kg] From 3afe52b19189d92a3de70fae12587a9c15aac290 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 28 May 2024 16:20:06 -0500 Subject: [PATCH 18/89] [dev.11] fix bug --- src/main/clm_varcon.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index 6a0672004f..3413169a70 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -13,7 +13,7 @@ module clm_varcon SHR_CONST_RHOICE,SHR_CONST_TKFRZ,SHR_CONST_REARTH, & SHR_CONST_PDB, SHR_CONST_PI, SHR_CONST_CDAY, & SHR_CONST_RGAS, SHR_CONST_PSTD, & - SHR_CONST_MWDAIR, SHR_CONST_MWWV, SHR_CONST_CPFW & + SHR_CONST_MWDAIR, SHR_CONST_MWWV, SHR_CONST_CPFW, & ! Cathy [dev.11] SHR_CONST_CPWV use clm_varpar , only: numrad, nlevgrnd, nlevlak, nlevdecomp_full From 5f39e2069a7db917e0bb4a35079c624786ce40bb Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 28 May 2024 17:22:00 -0500 Subject: [PATCH 19/89] [dev.12] change pressure to pstd change all pressure in QSat() calls to pstd for consistency with original code (i.e., in calculation of rho_dair). --- src/biogeophys/SoilTemperatureMod.F90 | 2 +- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 35 ++++++++++---------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index f8a6c2d10b..04be4e1dfa 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -546,7 +546,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & temperature_inst, energyflux_inst, urbantv_inst, & - waterdiagnosticbulk_inst, atm2lnd_inst) ! Cathy [dev.04] [dev.06] + waterdiagnosticbulk_inst) ! Cathy [dev.12], atm2lnd_inst) ! Cathy [dev.04] [dev.06] end if do fc = 1,num_nolakec diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 8ef736d63b..844513b672 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -20,8 +20,8 @@ module UrbBuildTempOleson2015Mod use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type use LandunitType , only : lun use ColumnType , only : col - ! Cathy [dev.06] - use atm2lndType , only : atm2lnd_type + ! Cathy [dev.06] [dev.12] + ! use atm2lndType , only : atm2lnd_type ! ! !PUBLIC TYPES: implicit none @@ -46,8 +46,7 @@ module UrbBuildTempOleson2015Mod ! !INTERFACE: subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, & filter_nolakec, tk, urbanparams_inst, temperature_inst, & - energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst, & - atm2lnd_inst) ! Cathy [dev.02] [dev.04] [dev.06] + energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst) ! Cathy [dev.12], & atm2lnd_inst) ! Cathy [dev.02] [dev.04] [dev.06] ! ! !DESCRIPTION: ! Solve for t_building, inner surface temperatures of roof, sunw, shdw, and floor temperature @@ -237,14 +236,14 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables ! Cathy [dev.02] [dev.04] type(waterdiagnosticbulk_type), intent(inout) :: waterdiagnosticbulk_inst ! water diagnostic variables - ! Cathy [dev.06] - type(atm2lnd_type) , intent(in) :: atm2lnd_inst + ! Cathy [dev.06] [dev.12] + ! type(atm2lnd_type) , intent(in) :: atm2lnd_inst ! ! !LOCAL VARIABLES: integer, parameter :: neq = 5 ! number of equation/unknowns - ! Cathy [dev.07] - ! integer :: fc,fl,c,l ! indices - integer :: fc,fl,c,l,g ! indices + ! Cathy [dev.07] [dev.12]--return to original + integer :: fc,fl,c,l ! indices + ! integer :: fc,fl,c,l,g ! indices real(r8) :: dtime ! land model time step (s) real(r8) :: building_hwr(bounds%begl:bounds%endl) ! building height to building width ratio (-) real(r8) :: t_roof_inner_bef(bounds%begl:bounds%endl) ! roof inside surface temperature at previous time step (K) @@ -364,9 +363,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! trying to change to waterdiagnosticbulk_inst following how qaf was used in UrbanFluxesMod.F90 qaf => waterdiagnosticbulk_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) q_building => waterdiagnosticbulk_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) - ! Cathy [dev.06] + ! Cathy [dev.06] [dev.12] rh_building => waterdiagnosticbulk_inst%rh_building_lun,& ! InOut: [real(r8) (:)] internal building air relative humidity (%) - forc_pbot => atm2lnd_inst%forc_pbot_not_downscaled_grc,& ! Input:[real(r8) (:)] atmospheric pressure (Pa) + ! forc_pbot => atm2lnd_inst%forc_pbot_not_downscaled_grc,& ! Input:[real(r8) (:)] atmospheric pressure (Pa) eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (W/m**2) eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) @@ -983,17 +982,18 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) - ! Cathy [dev.06] - g = lun%gridcell(l) + ! Cathy [dev.06] [dev.12] + ! g = lun%gridcell(l) if (urbpoi(l)) then if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then t_building_bef_hac(l) = t_building(l) ! Cathy [dev.03] q_building_bef_hac(l) = q_building(l) ! rho_dair(l) = pstd / (rair*t_building(l)) - ! Cathy [dev.06] [dev.07] + ! Cathy [dev.06] [dev.07] [dev.12] ! Calculate q setpoint from RH setpoint - call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) + ! call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) + call QSat(t_building_bef_hac(l), pstd, qsat_building_max) q_building_max = rh_building_max / 100._r8 * qsat_building_max if (t_building_bef_hac(l) > t_building_max(l)) then @@ -1069,9 +1069,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, (ht_roof(l) * rho_dair(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & ) - ! Cathy [dev.06] + ! Cathy [dev.06] [dev.12] ! Calculate relative humidity based on specific humidity - call QSat(t_building(l), forc_pbot(g), qsat_building) + ! call QSat(t_building(l), forc_pbot(g), qsat_building) + call QSat(t_building(l), pstd, qsat_building) rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) end if end do From 3732413f9f05444b07ce0dc91ad20d22a9e5ec04 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Thu, 18 Jul 2024 12:36:05 -0600 Subject: [PATCH 20/89] Revert "[dev.12] change pressure to pstd" This reverts commit 5f39e2069a7db917e0bb4a35079c624786ce40bb. Changing back to using bottom layer of atmos. pressure to calculate rh_building, based on email discussion with Keith. Need another commit to update the use of pressure in density of humid air calculation. --- src/biogeophys/SoilTemperatureMod.F90 | 2 +- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 35 ++++++++++---------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 04be4e1dfa..f8a6c2d10b 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -546,7 +546,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & temperature_inst, energyflux_inst, urbantv_inst, & - waterdiagnosticbulk_inst) ! Cathy [dev.12], atm2lnd_inst) ! Cathy [dev.04] [dev.06] + waterdiagnosticbulk_inst, atm2lnd_inst) ! Cathy [dev.04] [dev.06] end if do fc = 1,num_nolakec diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 844513b672..8ef736d63b 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -20,8 +20,8 @@ module UrbBuildTempOleson2015Mod use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type use LandunitType , only : lun use ColumnType , only : col - ! Cathy [dev.06] [dev.12] - ! use atm2lndType , only : atm2lnd_type + ! Cathy [dev.06] + use atm2lndType , only : atm2lnd_type ! ! !PUBLIC TYPES: implicit none @@ -46,7 +46,8 @@ module UrbBuildTempOleson2015Mod ! !INTERFACE: subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, & filter_nolakec, tk, urbanparams_inst, temperature_inst, & - energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst) ! Cathy [dev.12], & atm2lnd_inst) ! Cathy [dev.02] [dev.04] [dev.06] + energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst, & + atm2lnd_inst) ! Cathy [dev.02] [dev.04] [dev.06] ! ! !DESCRIPTION: ! Solve for t_building, inner surface temperatures of roof, sunw, shdw, and floor temperature @@ -236,14 +237,14 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables ! Cathy [dev.02] [dev.04] type(waterdiagnosticbulk_type), intent(inout) :: waterdiagnosticbulk_inst ! water diagnostic variables - ! Cathy [dev.06] [dev.12] - ! type(atm2lnd_type) , intent(in) :: atm2lnd_inst + ! Cathy [dev.06] + type(atm2lnd_type) , intent(in) :: atm2lnd_inst ! ! !LOCAL VARIABLES: integer, parameter :: neq = 5 ! number of equation/unknowns - ! Cathy [dev.07] [dev.12]--return to original - integer :: fc,fl,c,l ! indices - ! integer :: fc,fl,c,l,g ! indices + ! Cathy [dev.07] + ! integer :: fc,fl,c,l ! indices + integer :: fc,fl,c,l,g ! indices real(r8) :: dtime ! land model time step (s) real(r8) :: building_hwr(bounds%begl:bounds%endl) ! building height to building width ratio (-) real(r8) :: t_roof_inner_bef(bounds%begl:bounds%endl) ! roof inside surface temperature at previous time step (K) @@ -363,9 +364,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! trying to change to waterdiagnosticbulk_inst following how qaf was used in UrbanFluxesMod.F90 qaf => waterdiagnosticbulk_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) q_building => waterdiagnosticbulk_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) - ! Cathy [dev.06] [dev.12] + ! Cathy [dev.06] rh_building => waterdiagnosticbulk_inst%rh_building_lun,& ! InOut: [real(r8) (:)] internal building air relative humidity (%) - ! forc_pbot => atm2lnd_inst%forc_pbot_not_downscaled_grc,& ! Input:[real(r8) (:)] atmospheric pressure (Pa) + forc_pbot => atm2lnd_inst%forc_pbot_not_downscaled_grc,& ! Input:[real(r8) (:)] atmospheric pressure (Pa) eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (W/m**2) eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) @@ -982,18 +983,17 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) - ! Cathy [dev.06] [dev.12] - ! g = lun%gridcell(l) + ! Cathy [dev.06] + g = lun%gridcell(l) if (urbpoi(l)) then if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then t_building_bef_hac(l) = t_building(l) ! Cathy [dev.03] q_building_bef_hac(l) = q_building(l) ! rho_dair(l) = pstd / (rair*t_building(l)) - ! Cathy [dev.06] [dev.07] [dev.12] + ! Cathy [dev.06] [dev.07] ! Calculate q setpoint from RH setpoint - ! call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) - call QSat(t_building_bef_hac(l), pstd, qsat_building_max) + call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) q_building_max = rh_building_max / 100._r8 * qsat_building_max if (t_building_bef_hac(l) > t_building_max(l)) then @@ -1069,10 +1069,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, (ht_roof(l) * rho_dair(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & ) - ! Cathy [dev.06] [dev.12] + ! Cathy [dev.06] ! Calculate relative humidity based on specific humidity - ! call QSat(t_building(l), forc_pbot(g), qsat_building) - call QSat(t_building(l), pstd, qsat_building) + call QSat(t_building(l), forc_pbot(g), qsat_building) rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) end if end do From 7bfcb5a6ccd526e45f3df495b8e8ce111832ea82 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 18 Jul 2024 14:19:51 -0500 Subject: [PATCH 21/89] [dev.13] update pressure Change all pressure from pstd (standard pressure) to forc_pbot (bottom layer atmos. forcing pressure). --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 8ef736d63b..e35b134d65 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -387,6 +387,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! 5. Calculate building height to building width ratio do fl = 1,num_urbanl l = filter_urbanl(fl) + ! Cathy [dev.13] + g = lun%gridcell(l) if (urbpoi(l)) then t_roof_inner_bef(l) = t_roof_inner(l) t_sunw_inner_bef(l) = t_sunw_inner(l) @@ -420,12 +422,13 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.11] ! Density of dry air at standard pressure and t_building (kg m-3) ! rho_dair(l) = pstd / (rair*t_building_bef(l)) + ! Cathy [dev.13] update all pressure to forc_pbot below ! Saturated vapor pressure at t_building (Pa) - call QSat(t_building_bef(l), pstd, qsat_building, es = esat_building) + call QSat(t_building_bef(l), forc_pbot(g), qsat_building, es = esat_building) ! Partial pressure of water vapor (Pa) p_vapor = min(1._r8, q_building_bef(l) / qsat_building ) * esat_building - ! Density of HUMID air at standard pressure and t_building (kg m-3) - rho_dair(l) = ( pstd - p_vapor ) / ( rair * t_building_bef(l) ) + p_vapor / ( rwat * t_building_bef(l)) + ! Density of HUMID air at bottom layer atmos. forcing pressure and t_building (kg m-3) + rho_dair(l) = ( forc_pbot(g) - p_vapor ) / ( rair * t_building_bef(l) ) + p_vapor / ( rwat * t_building_bef(l)) ! Specific heat capacity of HUMID air (J/kg/K) cp_hair(l) = cpair + cpwvap * q_building_bef(l) ! Building height to building width ratio From 5a2cf11e1de0a84e61943cccc41d5c87b25438f9 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 26 Sep 2024 22:33:14 -0500 Subject: [PATCH 22/89] [dev.14] Add output for sensible AC flux 1. Add variable 'eflx_urban_ac_sen_lun` and hist field `URBAN_AC_SEN` 2. Output `URBAN_AC_SEN` before latent heat is calculated --- src/biogeophys/EnergyFluxType.F90 | 14 ++++++++++++++ src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/biogeophys/EnergyFluxType.F90 b/src/biogeophys/EnergyFluxType.F90 index 2e709596a1..252725aacf 100644 --- a/src/biogeophys/EnergyFluxType.F90 +++ b/src/biogeophys/EnergyFluxType.F90 @@ -71,6 +71,8 @@ module EnergyFluxType real(r8), pointer :: eflx_heat_from_ac_lun (:) ! lun sensible heat flux to be put back into canyon due to removal by AC (W/m**2) real(r8), pointer :: eflx_building_lun (:) ! lun building heat flux from change in interior building air temperature (W/m**2) real(r8), pointer :: eflx_urban_ac_lun (:) ! lun urban air conditioning flux (W/m**2) + ! Cathy [dev.14] + real(r8), pointer :: eflx_urban_ac_sen_lun (:) ! lun sensible heat component of air conditioning flux (W/m**2) real(r8), pointer :: eflx_urban_heat_lun (:) ! lun urban heating flux (W/m**2) ! Derivatives of energy fluxes @@ -234,6 +236,8 @@ subroutine InitAllocate(this, bounds) allocate( this%eflx_heat_from_ac_lun (begl:endl)) ; this%eflx_heat_from_ac_lun (:) = nan allocate( this%eflx_building_lun (begl:endl)) ; this%eflx_building_lun (:) = nan allocate( this%eflx_urban_ac_lun (begl:endl)) ; this%eflx_urban_ac_lun (:) = nan + ! Cathy [dev.14] + allocate( this%eflx_urban_ac_sen_lun (begl:endl)) ; this%eflx_urban_ac_sen_lun (:) = nan allocate( this%eflx_urban_heat_lun (begl:endl)) ; this%eflx_urban_heat_lun (:) = nan allocate( this%eflx_traffic_lun (begl:endl)) ; this%eflx_traffic_lun (:) = nan allocate( this%eflx_wasteheat_lun (begl:endl)) ; this%eflx_wasteheat_lun (:) = nan @@ -589,6 +593,12 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp) avgflag='A', long_name='urban air conditioning flux', & ptr_lunit=this%eflx_urban_ac_lun, set_nourb=0._r8, l2g_scale_type='unity') + ! Cathy [dev.14] + this%eflx_urban_ac_sen_lun(begl:endl) = spval + call hist_addfld1d (fname='URBAN_AC_SEN', units='W/m^2', & + avgflag='A', long_name='sensible heat component of urban air conditioning flux', & + ptr_lunit=this%eflx_urban_ac_sen_lun, set_nourb=0._r8, l2g_scale_type='unity') + this%eflx_urban_heat_lun(begl:endl) = spval call hist_addfld1d (fname='URBAN_HEAT', units='W/m^2', & avgflag='A', long_name='urban heating flux', & @@ -762,6 +772,8 @@ subroutine InitCold(this, bounds, t_grnd_col, is_simple_buildtemp, is_prog_build if ( is_prog_buildtemp )then this%eflx_building_lun(l) = 0._r8 this%eflx_urban_ac_lun(l) = 0._r8 + ! Cathy [dev.14] + this%eflx_urban_ac_sen_lun(l)= 0._r8 this%eflx_urban_heat_lun(l) = 0._r8 end if @@ -775,6 +787,8 @@ subroutine InitCold(this, bounds, t_grnd_col, is_simple_buildtemp, is_prog_build if ( is_prog_buildtemp )then this%eflx_building_lun(l) = 0._r8 this%eflx_urban_ac_lun(l) = 0._r8 + ! Cathy [dev.14] + this%eflx_urban_ac_sen_lun(l)= 0._r8 this%eflx_urban_heat_lun(l) = 0._r8 this%eflx_ventilation_lun(l)= 0._r8 end if diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index e35b134d65..2f9d16c84c 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -370,6 +370,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (W/m**2) eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) + eflx_urban_ac_sen => energyflux_inst%eflx_urban_ac_sen_lun,& ! Output: [real(r8) (:)] sensible heat component of urban air conditioning flux (W/m**2) eflx_urban_heat => energyflux_inst%eflx_urban_heat_lun,& ! Output: [real(r8) (:)] urban heating flux (W/m**2) eflx_ventilation => energyflux_inst%eflx_ventilation_lun & ! Output: [real(r8) (:)] sensible heat flux from building ventilation (W/m**2) ) @@ -1008,7 +1009,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) & * dtime / (ht_roof(l) * rho_dair(l) * cp_hair(l) * wtlunit_roof(l)) - ! eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) + ! Cathy [dev.14] + eflx_urban_ac_sen(l) = p_ac(l) * eflx_urban_ac_sat(l) ! Cathy [dev.09] ! Latent heat @@ -1039,6 +1041,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, else ! Cathy [dev.03]: need this because dehumidification below may reference it ! eflx_urban_ac_sat(l) = 0._r8 + ! Cathy [dev.14] + eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if @@ -1063,6 +1067,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! end if else + ! Cathy [dev.14] + eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if From 455d3b5454b9994c3f8d988427388582f5fe5101 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 15 Oct 2024 19:55:10 -0500 Subject: [PATCH 23/89] [dev.15] Calculate condensed water flux 1. Calculate total condensed water, and convert it to water flux per impervious surface area in UrbBuildTempOlesonMod.F90 (incl. a write statement); 2. Add new variable `qflx_condensate_from_ac_col` in WaterFluxType.F90; 3. Update BuildingTemperature() calls --- src/biogeophys/SoilTemperatureMod.F90 | 3 +- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 43 ++++++++++++++++++-- src/biogeophys/WaterFluxType.F90 | 6 +++ 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index f8a6c2d10b..ec2988c297 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -544,9 +544,10 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter if ( IsProgBuildTemp() )then call BuildingTemperature(bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, & + num_urbanc, filter_urbanc, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & temperature_inst, energyflux_inst, urbantv_inst, & - waterdiagnosticbulk_inst, atm2lnd_inst) ! Cathy [dev.04] [dev.06] + waterdiagnosticbulk_inst, atm2lnd_inst) ! Cathy [dev.04] [dev.06] [dev.15] end if do fc = 1,num_nolakec diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 2f9d16c84c..341759f187 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -18,6 +18,8 @@ module UrbBuildTempOleson2015Mod use TemperatureType , only : temperature_type ! Cathy [dev.02] [dev.04] use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type + ! Cathy [dev.15] + use WaterFluxBulkType , only : waterfluxbulk_type use LandunitType , only : lun use ColumnType , only : col ! Cathy [dev.06] @@ -45,9 +47,10 @@ module UrbBuildTempOleson2015Mod ! ! !INTERFACE: subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, & - filter_nolakec, tk, urbanparams_inst, temperature_inst, & + filter_nolakec, num_urbanc, filter_urbanc, & + tk, urbanparams_inst, temperature_inst, & energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst, & - atm2lnd_inst) ! Cathy [dev.02] [dev.04] [dev.06] + waterfluxbulk_inst, atm2lnd_inst) ! Cathy [dev.02] [dev.04] [dev.06] [dev.15] ! ! !DESCRIPTION: ! Solve for t_building, inner surface temperatures of roof, sunw, shdw, and floor temperature @@ -215,7 +218,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! q_building_max, hvap ! Cathy [dev.06] [dev.11] rh_building_max, hvap, rwat, cpwvap - use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall + use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_imperv ! Cathy [dev.15] use clm_varctl , only : iulog use abortutils , only : endrun use clm_varpar , only : nlevurb, nlevsno, nlevmaxurbgrnd @@ -228,6 +231,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(bounds_type), intent(in) :: bounds ! bounds integer , intent(in) :: num_nolakec ! number of column non-lake points in column filter integer , intent(in) :: filter_nolakec(:) ! column filter for non-lake points + ! Cathy [dev.15] + integer , intent(in) :: num_urbanc ! number of column urban points in column filter + integer , intent(in) :: filter_urbanc(:) ! column filter for urban points integer , intent(in) :: num_urbanl ! number of urban landunits in clump integer , intent(in) :: filter_urbanl(:) ! urban landunit filter real(r8), intent(in) :: tk(bounds%begc: , -nlevsno+1: ) ! thermal conductivity (W m-1 K-1) [col, j] @@ -237,6 +243,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables ! Cathy [dev.02] [dev.04] type(waterdiagnosticbulk_type), intent(inout) :: waterdiagnosticbulk_inst ! water diagnostic variables + ! Cathy [dev.15] + type(waterfluxbulk_type), intent(inout) :: waterfluxbulk_inst ! water flux variables ! Cathy [dev.06] type(atm2lnd_type) , intent(in) :: atm2lnd_inst ! @@ -330,6 +338,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.11] real(r8) :: esat_building ! internal building air saturated vapor pressure used to calculate p_vapor (Pa) real(r8) :: p_vapor ! internal building air partial pressure of water vapor (Pa) + ! Cathy [dev.15] + real(r8) :: qtot_condensate(bounds%begc:bounds%endc) ! total condensed water due to dehumidification per impervious road area (kg/m2) !EOP !----------------------------------------------------------------------- @@ -372,7 +382,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) eflx_urban_ac_sen => energyflux_inst%eflx_urban_ac_sen_lun,& ! Output: [real(r8) (:)] sensible heat component of urban air conditioning flux (W/m**2) eflx_urban_heat => energyflux_inst%eflx_urban_heat_lun,& ! Output: [real(r8) (:)] urban heating flux (W/m**2) - eflx_ventilation => energyflux_inst%eflx_ventilation_lun & ! Output: [real(r8) (:)] sensible heat flux from building ventilation (W/m**2) + eflx_ventilation => energyflux_inst%eflx_ventilation_lun, & ! Output: [real(r8) (:)] sensible heat flux from building ventilation (W/m**2) + + ! Cathy [dev.15] + qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for impervious road area (mm/s) ) ! Get step size @@ -1078,6 +1091,28 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, (ht_roof(l) * rho_dair(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & ) + + ! Cathy [dev.15] + + ! Calculate total water condensed by dehumidification, if any [kg/m2 impervious road area]. + ! Multiplying wtlunit_roof(l) / (1-wtlunit_roof(l)) converts building area to canyon floor area, + ! then multiplying 1/(1-wtroad_perv(l)) converts canyon floor area to impervious road area. + qtot_condensate(l) = ( wtlunit_roof(l) / (1._r8-wtlunit_roof(l)) ) & + * ( 1._r8/(1._r8-wtroad_perv(l)) ) & + * max(0, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) + + ! Calculate water flux due to dehumidification to be added to impervious road [mm/s]. + ! water flux to other urban columns are set to 0. + do fc = 1, num_urbanc + c = filter_urbanc(fc) + if (ctype(c) == icol_road_imperv) then + qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime + write(iulog,*) '############# Cathy [dev.15] calculated qflx_condensate_from_ac: ', qflx_condensate_from_ac(c), '#############' + else if (ctype(c) == icol_roof .or. ctype(c) == icol_sunwall .or. ctype(c) == icol_shadewall) then + qflx_condensate_from_ac(c) = 0._r8 + end if + end do + ! Cathy [dev.06] ! Calculate relative humidity based on specific humidity call QSat(t_building(l), forc_pbot(g), qsat_building) diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 23980a21c9..5615afa88b 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -50,6 +50,8 @@ module WaterFluxType real(r8), pointer :: qflx_evap_tot_col (:) ! col col_qflx_evap_soi + col_qflx_evap_veg + qflx_tran_veg real(r8), pointer :: qflx_liqevap_from_top_layer_patch(:) ! patch rate of liquid water evaporated from top soil or snow layer (mm H2O/s) [+] real(r8), pointer :: qflx_liqevap_from_top_layer_col(:) ! col rate of liquid water evaporated from top soil or snow layer (mm H2O/s) [+] + ! Cathy [dev.15] + real(r8), pointer :: qflx_condensate_from_ac_col(:) ! col condensate due to dehumidification from air-conditioning (mm H2O/S) [+] ! In the snow capping parametrization excess mass above h2osno_max is removed. A breakdown of mass into liquid ! and solid fluxes is done, these are represented by qflx_snwcp_liq_col and qflx_snwcp_ice_col. @@ -269,6 +271,10 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar1d(var = this%qflx_liqevap_from_top_layer_patch, name = 'qflx_liqevap_from_top_layer_patch', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_patch) + ! Cathy [dev.15] + call AllocateVar1d(var = this%qflx_condensate_from_ac_col, name = 'qflx_condensate_from_ac_col', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_column) call AllocateVar1d(var = this%qflx_infl_col, name = 'qflx_infl_col', & container = tracer_vars, & From 997182c502764a8488dc00ebaac6aeb4a445bcf1 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 15 Oct 2024 21:01:00 -0500 Subject: [PATCH 24/89] [dev.15] debug --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 341759f187..83aea05f2c 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -355,6 +355,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ht_roof => lun%ht_roof , & ! Input: [real(r8) (:)] height of urban roof (m) canyon_hwr => lun%canyon_hwr , & ! Input: [real(r8) (:)] ratio of building height to street hwidth (-) wtlunit_roof => lun%wtlunit_roof , & ! Input: [real(r8) (:)] weight of roof with respect to landunit + ! Cathy [dev.15] + wtroad_perv => lun%wtroad_perv , & ! Input: [real(r8) (:)] weight of pervious road column to total road (-) urbpoi => lun%urbpoi , & ! Input: [logical (:)] true => landunit is an urban point taf => temperature_inst%taf_lun , & ! Input: [real(r8) (:)] urban canopy air temperature (K) From 8fa2d874626f7016cbf6a3edf6eeca6280b08638 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:37:48 -0500 Subject: [PATCH 25/89] [dev.15] debug cont'd --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 83aea05f2c..c41aae747a 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1101,7 +1101,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! then multiplying 1/(1-wtroad_perv(l)) converts canyon floor area to impervious road area. qtot_condensate(l) = ( wtlunit_roof(l) / (1._r8-wtlunit_roof(l)) ) & * ( 1._r8/(1._r8-wtroad_perv(l)) ) & - * max(0, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) + * max(0._r8, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) ! Calculate water flux due to dehumidification to be added to impervious road [mm/s]. ! water flux to other urban columns are set to 0. From 1ab522e523439fd266be8266b2be60b556616440 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 15 Oct 2024 23:49:59 -0500 Subject: [PATCH 26/89] [dev.15] debug cont'd --- src/biogeophys/SoilTemperatureMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index ec2988c297..6b8499871d 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -547,7 +547,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter num_urbanc, filter_urbanc, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & temperature_inst, energyflux_inst, urbantv_inst, & - waterdiagnosticbulk_inst, atm2lnd_inst) ! Cathy [dev.04] [dev.06] [dev.15] + waterdiagnosticbulk_inst, waterfluxbulk_inst, atm2lnd_inst) ! Cathy [dev.04] [dev.06] [dev.15] end if do fc = 1,num_nolakec From 20478c50434b45be6139ea6db67fde983e575d01 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 17 Oct 2024 12:50:45 -0500 Subject: [PATCH 27/89] [dev.16] add condensate to surface runoff 1. calculate condensate flux w.r.t. urban land unit area in BuildingTemperature subroutine; 2. add condensate flux to surface runoff in TotalSurfaceRunoff subroutine. --- src/biogeophys/SoilHydrologyMod.F90 | 5 ++++- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 12 +++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/biogeophys/SoilHydrologyMod.F90 b/src/biogeophys/SoilHydrologyMod.F90 index 5a4aa50f6e..c8e2f5e675 100644 --- a/src/biogeophys/SoilHydrologyMod.F90 +++ b/src/biogeophys/SoilHydrologyMod.F90 @@ -555,6 +555,8 @@ subroutine TotalSurfaceRunoff(bounds, num_hydrologyc, filter_hydrologyc, & qflx_liqevap_from_top_layer => waterfluxbulk_inst%qflx_liqevap_from_top_layer_col, & ! Input: [real(r8) (:) ] rate of liquid water evaporated from top soil or snow layer (mm H2O/s) [+] qflx_floodc => waterfluxbulk_inst%qflx_floodc_col , & ! Input: [real(r8) (:) ] column flux of flood water from RTM qflx_sat_excess_surf => waterfluxbulk_inst%qflx_sat_excess_surf_col , & ! Input: [real(r8) (:) ] surface runoff due to saturated surface (mm H2O /s) + ! Cathy [dev.15] + qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col, & ! Input: [real(r8) (:) ] condensate from air-conditioning (mm H2O /s) xs_urban => soilhydrology_inst%xs_urban_col , & ! Output: [real(r8) (:) ] excess soil water above urban ponding limit @@ -597,7 +599,8 @@ subroutine TotalSurfaceRunoff(bounds, num_hydrologyc, filter_hydrologyc, & qflx_surf(c) = xs_urban(c) end if ! send flood water flux to runoff for all urban columns - qflx_surf(c) = qflx_surf(c) + qflx_floodc(c) + ! Cathy [dev.15] + qflx_surf(c) = qflx_surf(c) + qflx_floodc(c) + qflx_condensate_from_ac(c) else if (col%itype(c) == icol_sunwall .or. col%itype(c) == icol_shadewall) then qflx_surf(c) = 0._r8 end if diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index c41aae747a..1d53f66f83 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1096,14 +1096,12 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.15] - ! Calculate total water condensed by dehumidification, if any [kg/m2 impervious road area]. - ! Multiplying wtlunit_roof(l) / (1-wtlunit_roof(l)) converts building area to canyon floor area, - ! then multiplying 1/(1-wtroad_perv(l)) converts canyon floor area to impervious road area. - qtot_condensate(l) = ( wtlunit_roof(l) / (1._r8-wtlunit_roof(l)) ) & - * ( 1._r8/(1._r8-wtroad_perv(l)) ) & - * max(0._r8, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) + ! Calculate total water condensed by dehumidification, if any [kg/m2 urban land unit area]. + ! Although all condensed water flux get added to the impervious road column (that goes directly into surface runoff), + ! the area it is based on should be consistent with the other fluxes in the runoff term. + qtot_condensate(l) = wtlunit_roof(l) * max(0._r8, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) - ! Calculate water flux due to dehumidification to be added to impervious road [mm/s]. + ! Calculate and assign water flux due to dehumidification to impervious road column [mm/s]. ! water flux to other urban columns are set to 0. do fc = 1, num_urbanc c = filter_urbanc(fc) From 9a592d1ee4dca28b396990612e16829b8083a789 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:36:53 -0500 Subject: [PATCH 28/89] [dev.16] add condensate to water balance checks `qflx_condensate_from_ac_col` is added to column-level water balance check, and `qflx_condensate_from_ac_grc` is calculated & added to grid-cell-level water balance check. Note these two terms have not been added to the error messages. --- src/biogeophys/BalanceCheckMod.F90 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index b3efe6e525..adeb725a93 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -498,6 +498,8 @@ subroutine BalanceCheck( bounds, & real(r8) :: qflx_glcice_dyn_water_flux_grc(bounds%begg:bounds%endg) ! grid cell-level water flux needed for balance check due to glc_dyn_runoff_routing [mm H2O/s] (positive means addition of water to the system) real(r8) :: qflx_snwcp_discarded_liq_grc(bounds%begg:bounds%endg) ! grid cell-level excess liquid h2o due to snow capping, which we simply discard in order to reset the snow pack [mm H2O /s] real(r8) :: qflx_snwcp_discarded_ice_grc(bounds%begg:bounds%endg) ! grid cell-level excess solid h2o due to snow capping, which we simply discard in order to reset the snow pack [mm H2O /s] + ! Cathy [dev.16] + real(r8) :: qflx_condensate_from_ac_grc(bounds%begg:bounds%endg) ! grid cell-level condensate from air-conditioning [mm H2O /s] real(r8) :: errh2o_max_val ! Maximum value of error in water conservation error over all columns [mm H2O] real(r8) :: errh2osno_max_val ! Maximum value of error in h2osno conservation error over all columns [kg m-2] @@ -568,6 +570,8 @@ subroutine BalanceCheck( bounds, & qflx_sfc_irrig_col => waterflux_inst%qflx_sfc_irrig_col , & ! Input: [real(r8) (:) ] column level irrigation flux (mm H2O /s) qflx_sfc_irrig_grc => waterlnd2atm_inst%qirrig_grc , & ! Input: [real(r8) (:) ] grid cell-level irrigation flux (mm H20 /s) qflx_glcice_dyn_water_flux_col => waterflux_inst%qflx_glcice_dyn_water_flux_col, & ! Input: [real(r8) (:)] column level water flux needed for balance check due to glc_dyn_runoff_routing (mm H2O/s) (positive means addition of water to the system) + ! Cathy [dev.15] + qflx_condensate_from_ac_col => waterflux_inst%qflx_condensate_from_ac_col, & ! Input: [real(r8) (:)] column level condensate water flux from air-conditioning (mm H2O /s) dhsdt_canopy => energyflux_inst%dhsdt_canopy_patch , & ! Input: [real(r8) (:) ] change in heat content of canopy (W/m**2) [+ to atm] eflx_lwrad_out => energyflux_inst%eflx_lwrad_out_patch , & ! Input: [real(r8) (:) ] emitted infrared (longwave) radiation (W/m**2) @@ -642,6 +646,8 @@ subroutine BalanceCheck( bounds, & + qflx_flood_col(c) & + qflx_sfc_irrig_col(c) & + qflx_glcice_dyn_water_flux_col(c) & + ! Cathy [dev.16] + + qflx_condensate_from_ac_col(c) & - qflx_evap_tot_col(c) & - qflx_surf_col(c) & - qflx_qrgwl_col(c) & @@ -722,6 +728,11 @@ subroutine BalanceCheck( bounds, & qflx_snwcp_discarded_ice_col(bounds%begc:bounds%endc), & qflx_snwcp_discarded_ice_grc(bounds%begg:bounds%endg), & c2l_scale_type= 'urbanf', l2g_scale_type='unity' ) + ! Cathy [dev.16] + call c2g( bounds, & + qflx_condensate_from_ac_col(bounds%begc:bounds%endc), & + qflx_condensate_from_ac_grc(bounds%begg:bounds%endg), & + c2l_scale_type= 'urbanf', l2g_scale_type='unity' ) do g = bounds%begg, bounds%endg errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & @@ -730,6 +741,8 @@ subroutine BalanceCheck( bounds, & + forc_flood_grc(g) & + qflx_sfc_irrig_grc(g) & + qflx_glcice_dyn_water_flux_grc(g) & + ! Cathy [dev.16] + + qflx_condensate_from_ac_grc & - qflx_evap_tot_grc(g) & - qflx_surf_grc(g) & - qflx_qrgwl_grc(g) & From 12fabb9c1b9ace108eac338db60bd96af3cf6c8f Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:58:14 -0500 Subject: [PATCH 29/89] [dev.16] debug --- src/biogeophys/BalanceCheckMod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index adeb725a93..d02a491064 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -742,7 +742,7 @@ subroutine BalanceCheck( bounds, & + qflx_sfc_irrig_grc(g) & + qflx_glcice_dyn_water_flux_grc(g) & ! Cathy [dev.16] - + qflx_condensate_from_ac_grc & + + qflx_condensate_from_ac_grc(g) & - qflx_evap_tot_grc(g) & - qflx_surf_grc(g) & - qflx_qrgwl_grc(g) & From 1cb7864e26437b4aa0e4dbb9daeee110c945db2d Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 23 Oct 2024 00:25:28 -0500 Subject: [PATCH 30/89] [dev.16] change condensate flux base area --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 1d53f66f83..9734a44d0a 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -339,7 +339,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: esat_building ! internal building air saturated vapor pressure used to calculate p_vapor (Pa) real(r8) :: p_vapor ! internal building air partial pressure of water vapor (Pa) ! Cathy [dev.15] - real(r8) :: qtot_condensate(bounds%begc:bounds%endc) ! total condensed water due to dehumidification per impervious road area (kg/m2) + real(r8) :: qtot_condensate(bounds%begc:bounds%endc) ! total condensed water due to dehumidification per building area (kg/m2) !EOP !----------------------------------------------------------------------- @@ -1096,19 +1096,18 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.15] - ! Calculate total water condensed by dehumidification, if any [kg/m2 urban land unit area]. - ! Although all condensed water flux get added to the impervious road column (that goes directly into surface runoff), - ! the area it is based on should be consistent with the other fluxes in the runoff term. - qtot_condensate(l) = wtlunit_roof(l) * max(0._r8, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) + ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. + ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff). + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) - ! Calculate and assign water flux due to dehumidification to impervious road column [mm/s]. + ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. ! water flux to other urban columns are set to 0. do fc = 1, num_urbanc c = filter_urbanc(fc) - if (ctype(c) == icol_road_imperv) then + if (ctype(c) == icol_roof) then qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime write(iulog,*) '############# Cathy [dev.15] calculated qflx_condensate_from_ac: ', qflx_condensate_from_ac(c), '#############' - else if (ctype(c) == icol_roof .or. ctype(c) == icol_sunwall .or. ctype(c) == icol_shadewall) then + else ! if (ctype(c) == icol_road_imperv .or. ctype(c) == icol_sunwall .or. ctype(c) == icol_shadewall) then qflx_condensate_from_ac(c) = 0._r8 end if end do From 5b3ad0f2fc88f5ce382701dd1317f9b9a3e7e9fa Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 23 Oct 2024 18:49:13 -0500 Subject: [PATCH 31/89] [dev.16.1] manual error check --- src/biogeophys/BalanceCheckMod.F90 | 23 ++++++++++++++++++++ src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index d02a491064..22dfcc98bd 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -511,6 +511,10 @@ subroutine BalanceCheck( bounds, & real(r8), parameter :: h2o_warning_thresh = 1.e-9_r8 ! Warning threshhold for error in errh2o and errh2osnow real(r8), parameter :: energy_warning_thresh = 1.e-7_r8 ! Warning threshhold for error in errsol, errsol, errseb, errlonv real(r8), parameter :: error_thresh = 1.e-5_r8 ! Error threshhold for conservation error + ! ################################## Cathy [dev.16.1] local vars for error check begins ################################## + real(r8), :: tot_cond_from_col ! total condensate from AC mass flow rate calculated from column-level var [kg/s] + real(r8), :: tot_cond_from_grc ! total condensate from AC mass flow rate calculated from grid-cell-level var [kg/s] + ! ################################## Cathy [dev.16.1] local vars for error check ends ################################## !----------------------------------------------------------------------- @@ -762,6 +766,25 @@ subroutine BalanceCheck( bounds, & enddo endif + ! ################################## Cathy [dev.16.1]: error check for qflx_condensate_from_ac begins ################################## + ! Below, total condensate mass flow in kg/s will be calculated based on both the column-level var and the grid-cell var. + ! They should match if our code in assigning condensate flux to roof column was correct and the c2g aggregation + ! is done correctly. + do c = bounds%begc,bounds%endc + g = col%gridcell(c) + l = col%landunit(c) + + if (col%itype(c) == icol_roof) then + ! tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*col%wtgcell(c)) ! kg/s = kg/m2/s * m2 + tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*lun%wtgcell(l)*lun%wtlunit_roof(l)) ! grid area * lun frac * roof frac + tot_cond_from_grc = qflx_condensate_from_ac_grc(g) * (grc%area(g)*1.e6_r8) + if (tot_cond_from_col > 0._r8 .or. tot_cond_from_grc > 0._r8) then + write(iulog,*) 'Cathy [dev.16.1] at ', nstep, ' from column: ', tot_cond_from_col + write(iulog,*) 'Cathy [dev.16.1] at ', nstep, ' from gridcell: ', tot_cond_from_grc + end if + end do + ! ################################## Cathy [dev.16.1]: error check for qflx_condensate_from_ac ends ################################## + errh2o_max_val = maxval(abs(errh2o_grc(bounds%begg:bounds%endg))) ! BUG(rgk, 2021-04-13, ESCOMP/CTSM#1314) Temporarily bypassing gridcell-level check with use_fates_planthydro until issue 1314 is resolved diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 9734a44d0a..7692b66761 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1106,7 +1106,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, c = filter_urbanc(fc) if (ctype(c) == icol_roof) then qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime - write(iulog,*) '############# Cathy [dev.15] calculated qflx_condensate_from_ac: ', qflx_condensate_from_ac(c), '#############' + ! write(iulog,*) '############# Cathy [dev.15] calculated qflx_condensate_from_ac: ', qflx_condensate_from_ac(c), '#############' else ! if (ctype(c) == icol_road_imperv .or. ctype(c) == icol_sunwall .or. ctype(c) == icol_shadewall) then qflx_condensate_from_ac(c) = 0._r8 end if From d3d01bbe529086ea6e64872e14dad0f4f874d9e1 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 23 Oct 2024 19:10:23 -0500 Subject: [PATCH 32/89] [dev.16.1] debug --- src/biogeophys/BalanceCheckMod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index 22dfcc98bd..792bd5f0a8 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -512,8 +512,8 @@ subroutine BalanceCheck( bounds, & real(r8), parameter :: energy_warning_thresh = 1.e-7_r8 ! Warning threshhold for error in errsol, errsol, errseb, errlonv real(r8), parameter :: error_thresh = 1.e-5_r8 ! Error threshhold for conservation error ! ################################## Cathy [dev.16.1] local vars for error check begins ################################## - real(r8), :: tot_cond_from_col ! total condensate from AC mass flow rate calculated from column-level var [kg/s] - real(r8), :: tot_cond_from_grc ! total condensate from AC mass flow rate calculated from grid-cell-level var [kg/s] + real(r8) :: tot_cond_from_col ! total condensate from AC mass flow rate calculated from column-level var [kg/s] + real(r8) :: tot_cond_from_grc ! total condensate from AC mass flow rate calculated from grid-cell-level var [kg/s] ! ################################## Cathy [dev.16.1] local vars for error check ends ################################## !----------------------------------------------------------------------- @@ -770,6 +770,7 @@ subroutine BalanceCheck( bounds, & ! Below, total condensate mass flow in kg/s will be calculated based on both the column-level var and the grid-cell var. ! They should match if our code in assigning condensate flux to roof column was correct and the c2g aggregation ! is done correctly. + do c = bounds%begc,bounds%endc g = col%gridcell(c) l = col%landunit(c) @@ -781,6 +782,7 @@ subroutine BalanceCheck( bounds, & if (tot_cond_from_col > 0._r8 .or. tot_cond_from_grc > 0._r8) then write(iulog,*) 'Cathy [dev.16.1] at ', nstep, ' from column: ', tot_cond_from_col write(iulog,*) 'Cathy [dev.16.1] at ', nstep, ' from gridcell: ', tot_cond_from_grc + end if end if end do ! ################################## Cathy [dev.16.1]: error check for qflx_condensate_from_ac ends ################################## From 3a6715307bebbd0bdc20420c56297a47c9452cb4 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:31:45 -0500 Subject: [PATCH 33/89] [dev.16.1] debug cont'd 1. trying to fix the problem that condensate mass flowrate calculated from gridcell is nan. I suspect due to qflx_condensate_from_ac are nan at non-urban columns. 2. caught wrong dimension for qtot_condensate --- src/biogeophys/BalanceCheckMod.F90 | 5 +++-- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 2 +- src/biogeophys/WaterFluxType.F90 | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index 792bd5f0a8..f9a34b966e 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -780,8 +780,9 @@ subroutine BalanceCheck( bounds, & tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*lun%wtgcell(l)*lun%wtlunit_roof(l)) ! grid area * lun frac * roof frac tot_cond_from_grc = qflx_condensate_from_ac_grc(g) * (grc%area(g)*1.e6_r8) if (tot_cond_from_col > 0._r8 .or. tot_cond_from_grc > 0._r8) then - write(iulog,*) 'Cathy [dev.16.1] at ', nstep, ' from column: ', tot_cond_from_col - write(iulog,*) 'Cathy [dev.16.1] at ', nstep, ' from gridcell: ', tot_cond_from_grc + write(iulog,*) 'Cathy [dev.16.1] at grid = ',g, 'nstep = ',nstep, & + ' from col: ', tot_cond_from_col, & + ' from grc: ', tot_cond_from_grc end if end if end do diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 7692b66761..86aec0e46c 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -339,7 +339,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: esat_building ! internal building air saturated vapor pressure used to calculate p_vapor (Pa) real(r8) :: p_vapor ! internal building air partial pressure of water vapor (Pa) ! Cathy [dev.15] - real(r8) :: qtot_condensate(bounds%begc:bounds%endc) ! total condensed water due to dehumidification per building area (kg/m2) + real(r8) :: qtot_condensate(bounds%begl:bounds%endl) ! total condensed water due to dehumidification per building area (kg/m2) !EOP !----------------------------------------------------------------------- diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 5615afa88b..011cf4d92b 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -271,10 +271,10 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar1d(var = this%qflx_liqevap_from_top_layer_patch, name = 'qflx_liqevap_from_top_layer_patch', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_patch) - ! Cathy [dev.15] + ! Cathy [dev.15] [dev.16.1] call AllocateVar1d(var = this%qflx_condensate_from_ac_col, name = 'qflx_condensate_from_ac_col', & container = tracer_vars, & - bounds = bounds, subgrid_level = subgrid_level_column) + bounds = bounds, subgrid_level = subgrid_level_column, ival = 0.0_r8) call AllocateVar1d(var = this%qflx_infl_col, name = 'qflx_infl_col', & container = tracer_vars, & From 7a290f2f89e187de8f1982e19ed05651077a7f32 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:18:47 -0500 Subject: [PATCH 34/89] [dev.16.1] remove write statements --- src/biogeophys/BalanceCheckMod.F90 | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index f9a34b966e..0e8207cb97 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -512,8 +512,8 @@ subroutine BalanceCheck( bounds, & real(r8), parameter :: energy_warning_thresh = 1.e-7_r8 ! Warning threshhold for error in errsol, errsol, errseb, errlonv real(r8), parameter :: error_thresh = 1.e-5_r8 ! Error threshhold for conservation error ! ################################## Cathy [dev.16.1] local vars for error check begins ################################## - real(r8) :: tot_cond_from_col ! total condensate from AC mass flow rate calculated from column-level var [kg/s] - real(r8) :: tot_cond_from_grc ! total condensate from AC mass flow rate calculated from grid-cell-level var [kg/s] + ! real(r8) :: tot_cond_from_col ! total condensate from AC mass flow rate calculated from column-level var [kg/s] + ! real(r8) :: tot_cond_from_grc ! total condensate from AC mass flow rate calculated from grid-cell-level var [kg/s] ! ################################## Cathy [dev.16.1] local vars for error check ends ################################## !----------------------------------------------------------------------- @@ -771,21 +771,21 @@ subroutine BalanceCheck( bounds, & ! They should match if our code in assigning condensate flux to roof column was correct and the c2g aggregation ! is done correctly. - do c = bounds%begc,bounds%endc - g = col%gridcell(c) - l = col%landunit(c) - - if (col%itype(c) == icol_roof) then - ! tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*col%wtgcell(c)) ! kg/s = kg/m2/s * m2 - tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*lun%wtgcell(l)*lun%wtlunit_roof(l)) ! grid area * lun frac * roof frac - tot_cond_from_grc = qflx_condensate_from_ac_grc(g) * (grc%area(g)*1.e6_r8) - if (tot_cond_from_col > 0._r8 .or. tot_cond_from_grc > 0._r8) then - write(iulog,*) 'Cathy [dev.16.1] at grid = ',g, 'nstep = ',nstep, & - ' from col: ', tot_cond_from_col, & - ' from grc: ', tot_cond_from_grc - end if - end if - end do + ! do c = bounds%begc,bounds%endc + ! g = col%gridcell(c) + ! l = col%landunit(c) + ! + ! if (col%itype(c) == icol_roof) then + ! ! tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*col%wtgcell(c)) ! kg/s = kg/m2/s * m2 + ! tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*lun%wtgcell(l)*lun%wtlunit_roof(l)) ! grid area * lun frac * roof frac + ! tot_cond_from_grc = qflx_condensate_from_ac_grc(g) * (grc%area(g)*1.e6_r8) + ! if (tot_cond_from_col > 0._r8 .or. tot_cond_from_grc > 0._r8) then + ! write(iulog,*) 'Cathy [dev.16.1] at grid = ',g, 'nstep = ',nstep, & + ! ' from col: ', tot_cond_from_col, & + ! ' from grc: ', tot_cond_from_grc + ! end if + ! end if + ! end do ! ################################## Cathy [dev.16.1]: error check for qflx_condensate_from_ac ends ################################## errh2o_max_val = maxval(abs(errh2o_grc(bounds%begg:bounds%endg))) From ad41a8178e6b263cc07b5125579e9d258b0eebb8 Mon Sep 17 00:00:00 2001 From: cathyxinchangli <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:29:02 -0500 Subject: [PATCH 35/89] [dev.16.2] update RH setpoint to 65% --- src/main/clm_varcon.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index 3413169a70..2e07a5db26 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -194,7 +194,7 @@ module clm_varcon ! Cathy [dev.02] ! real(r8), public :: q_building_max = 0.013_r8 ! maximum internal building air specific humidity (kg/kg) ! Cathy [dev.06] - real(r8), public :: rh_building_max = 60._r8 ! maximum internal building air relative humidity (%) + real(r8), public :: rh_building_max = 65._r8 ! maximum internal building air relative humidity (%) real(r8), public :: wasteheat_limit = 100._r8 ! limit on wasteheat (W/m2) From de44b1909ce58cdc73b57be8a06684ae87b671c6 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 27 May 2025 18:11:46 -0700 Subject: [PATCH 36/89] [dev.17] output condensate flux --- src/biogeophys/WaterFluxType.F90 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 011cf4d92b..da9f1599be 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -594,6 +594,15 @@ subroutine InitHistory(this, bounds) long_name=this%info%lname('Rural total runoff'), & ptr_col=this%qflx_runoff_r_col, set_spec=spval, default='inactive') + ! Cathy [dev.17]: add condensate from AC to output + this%qflx_condensate_from_ac(begc:endc) = spval + call hist_addfld1d ( & + fname=this%info%fname('QCOND_FROM_AC'), & + units='mm/s', & + avgflag='A', & + long_name=this%info%lname('Condensed water flux from AC dehumidification'), & + ptr_col=this%qflx_condensate_from_ac, set_nourb=spval, c2l_scale_type='urbanf', default='inactive') + this%qflx_snomelt_col(begc:endc) = spval call hist_addfld1d ( & fname=this%info%fname('QSNOMELT'), & From 6dd803292ff7d4bc926b0666b560bf65c48916c7 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 27 May 2025 18:53:26 -0700 Subject: [PATCH 37/89] [dev.17] debug --- src/biogeophys/WaterFluxType.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index da9f1599be..61af52dbbd 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -595,13 +595,13 @@ subroutine InitHistory(this, bounds) ptr_col=this%qflx_runoff_r_col, set_spec=spval, default='inactive') ! Cathy [dev.17]: add condensate from AC to output - this%qflx_condensate_from_ac(begc:endc) = spval + this%qflx_condensate_from_ac_col(begc:endc) = spval call hist_addfld1d ( & fname=this%info%fname('QCOND_FROM_AC'), & units='mm/s', & avgflag='A', & long_name=this%info%lname('Condensed water flux from AC dehumidification'), & - ptr_col=this%qflx_condensate_from_ac, set_nourb=spval, c2l_scale_type='urbanf', default='inactive') + ptr_col=this%qflx_condensate_from_ac_col, set_nourb=spval, c2l_scale_type='urbanf', default='inactive') this%qflx_snomelt_col(begc:endc) = spval call hist_addfld1d ( & From c2ab31aa3fbb6341883a16aa07f475d20b292fe7 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 29 May 2025 14:28:51 -0700 Subject: [PATCH 38/89] [dev.17] debug Initialize QCOND_FROM_AC values in hist files to be 0 instead of spval (1e36) --- src/biogeophys/WaterFluxType.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 61af52dbbd..9655de4184 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -595,7 +595,7 @@ subroutine InitHistory(this, bounds) ptr_col=this%qflx_runoff_r_col, set_spec=spval, default='inactive') ! Cathy [dev.17]: add condensate from AC to output - this%qflx_condensate_from_ac_col(begc:endc) = spval + this%qflx_condensate_from_ac_col(begc:endc) = 0.0_r8 call hist_addfld1d ( & fname=this%info%fname('QCOND_FROM_AC'), & units='mm/s', & From 1b004457a1740fa9f453a5f40a0121d4855e5f1c Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Thu, 29 May 2025 19:20:06 -0700 Subject: [PATCH 39/89] [dev.17] debug Set values for non urban columns to be 0.0_r8 in hist field. --- src/biogeophys/BalanceCheckMod.F90 | 4 ++++ src/biogeophys/WaterFluxType.F90 | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index 0e8207cb97..f0cae0a442 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -695,6 +695,8 @@ subroutine BalanceCheck( bounds, & write(iulog,*)'qflx_surf = ',qflx_surf_col(indexc)*dtime write(iulog,*)'qflx_qrgwl = ',qflx_qrgwl_col(indexc)*dtime write(iulog,*)'qflx_drain = ',qflx_drain_col(indexc)*dtime + ! Cathy [dev.17] help debug the water imbalance + write(iulog,*)'qflx_condensate_from_ac = ',qflx_condensate_from_ac_col(indexc)*dtime write(iulog,*)'qflx_ice_runoff = ',qflx_ice_runoff_col(indexc)*dtime @@ -824,6 +826,8 @@ subroutine BalanceCheck( bounds, & write(iulog,*)'qflx_drain_perched = ',qflx_drain_perched_grc(indexg)*dtime write(iulog,*)'forc_flood = ',forc_flood_grc(indexg)*dtime write(iulog,*)'qflx_glcice_dyn_water_flux = ',qflx_glcice_dyn_water_flux_grc(indexg)*dtime + ! Cathy [dev.17] help debug the water imbalance + write(iulog,*)'qflx_condensate_from_ac = ',qflx_condensate_from_ac_grc(indexg)*dtime write(iulog,*)'CTSM is stopping' call endrun(subgrid_index=indexg, subgrid_level=subgrid_level_gridcell, msg=errmsg(sourcefile, __LINE__)) diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 9655de4184..4bbed80b5e 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -601,7 +601,7 @@ subroutine InitHistory(this, bounds) units='mm/s', & avgflag='A', & long_name=this%info%lname('Condensed water flux from AC dehumidification'), & - ptr_col=this%qflx_condensate_from_ac_col, set_nourb=spval, c2l_scale_type='urbanf', default='inactive') + ptr_col=this%qflx_condensate_from_ac_col, set_nourb=0.0_r8, c2l_scale_type='urbanf', default='inactive') this%qflx_snomelt_col(begc:endc) = spval call hist_addfld1d ( & From 0d1268ef91fcb70c4cf1e775d4e9b60dd10f0be1 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 11 Jun 2025 17:49:01 -0700 Subject: [PATCH 40/89] [dev.18] correct condensate flux calculation 1. Correct condensate flux calculation: should use before and after HAC values 2. Move it to right after dehumidification energy calculation 3. Added the necessary set to zero statements 4. Housekeeping (added comments, removed unused code) --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 58 ++++++++------------ 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 86aec0e46c..e1c5943863 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1005,7 +1005,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.06] g = lun%gridcell(l) if (urbpoi(l)) then - if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then + if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then ! Cathy: if use HAC scheme: t_building_bef_hac(l) = t_building(l) ! Cathy [dev.03] q_building_bef_hac(l) = q_building(l) @@ -1015,8 +1015,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) q_building_max = rh_building_max / 100._r8 * qsat_building_max - if (t_building_bef_hac(l) > t_building_max(l)) then - if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: + if (t_building_bef_hac(l) > t_building_max(l)) then ! Cathy: if AC is triggered: + if (urban_explicit_ac) then ! Cathy: use explicit ac adoption rate parameterization scheme: ! Sensible heat ! Here, t_building_max is the AC saturation setpoint @@ -1029,7 +1029,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.09] ! Latent heat - if (q_building_bef_hac(l) > q_building_max) then + if (q_building_bef_hac(l) > q_building_max) then ! Cathy: if dehumidification is needed: ! the latent heat removed from internal building air is released to urban canyon as sensible heat. ! Humidification process for urban heating is not implemented. ! Here, q_building_max is the AC humidity setpoint under saturated adoption @@ -1042,50 +1042,44 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) end if + eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) - else + ! Cathy [dev.15] + ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. + ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff). + ! Cathy [dev.18] + ! Debug condensate flux: total condensed water should be calculated from difference between before and + ! after AC, not before and after this time step. + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) + else ! Cathy: not using explicit AC scheme: t_building(l) = t_building_max(l) - eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & + ! Cathy [dev.18] + eflx_urban_ac_sen(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + eflx_urban_ac(l) = eflx_urban_ac_sen(l) + 0._r8 ! placeholder for eflx_urban_ac_lat(l) + qtot_condensate(l) = 0._r8 end if - else if (t_building_bef_hac(l) < t_building_min(l)) then + else if (t_building_bef_hac(l) < t_building_min(l)) then ! Cathy: if heating is triggered: t_building(l) = t_building_min(l) eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) - else + else ! Cathy: if no AC or heating is triggered: ! Cathy [dev.03]: need this because dehumidification below may reference it ! eflx_urban_ac_sat(l) = 0._r8 - ! Cathy [dev.14] + ! Cathy [dev.14] [dev.18] eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 + qtot_condensate(l) = 0._r8 end if - ! Cathy [dev.03] - ! Latent heat - ! Dehumidification process modifies eflx_urban_ac, and is only implemented for urban_explicit_ac = .true.; - ! the latent heat removed from internal building air is released to urban canyon as sensible heat. - ! Humidification process for urban heating is not implemented. - ! if (q_building_bef_hac(l) > q_building_max) then - ! if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: - ! ! Here, q_building_max is the AC humidity setpoint under saturated adoption - ! eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & - ! (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & - ! - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & - ! ) - ! eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) - ! q_building(l) = q_building_max + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & - ! * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) - ! eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) - ! end if - ! end if - else - ! Cathy [dev.14] + ! Cathy [dev.14] [dev.18] eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 + qtot_condensate(l) = 0._r8 end if ! Cathy [dev.02] ! eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) @@ -1094,12 +1088,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & ) - ! Cathy [dev.15] - - ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. - ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff). - qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) - ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. ! water flux to other urban columns are set to 0. do fc = 1, num_urbanc From d0af2bf47f5d2011578efa858186a1130889ae42 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 11 Jun 2025 23:08:19 -0700 Subject: [PATCH 41/89] [dev.18] continue attempting to debug --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index e1c5943863..3bef7760da 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -992,7 +992,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) if (urbpoi(l)) then - q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) + q_building_bef(l) * (1 - vent_ach/3600._r8 * dtime) + q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) + q_building_bef(l) * (1._r8 - vent_ach/3600._r8 * dtime) end if end do @@ -1050,7 +1050,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.18] ! Debug condensate flux: total condensed water should be calculated from difference between before and ! after AC, not before and after this time step. - qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) + ! qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) + qtot_condensate(l) = abs ( (ht_roof(l) * rho_dair(l)) * q_building(l) & + - (ht_roof(l) * rho_dair(l)) * q_building_bef_hac(l) ) else ! Cathy: not using explicit AC scheme: t_building(l) = t_building_max(l) ! Cathy [dev.18] From 2a4be858168169491c49f56965949576c48c98bd Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Fri, 13 Jun 2025 16:08:28 -0700 Subject: [PATCH 42/89] Revert "[dev.18] continue attempting to debug" This reverts commit d0af2bf47f5d2011578efa858186a1130889ae42. --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 3bef7760da..e1c5943863 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -992,7 +992,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) if (urbpoi(l)) then - q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) + q_building_bef(l) * (1._r8 - vent_ach/3600._r8 * dtime) + q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) + q_building_bef(l) * (1 - vent_ach/3600._r8 * dtime) end if end do @@ -1050,9 +1050,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.18] ! Debug condensate flux: total condensed water should be calculated from difference between before and ! after AC, not before and after this time step. - ! qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) - qtot_condensate(l) = abs ( (ht_roof(l) * rho_dair(l)) * q_building(l) & - - (ht_roof(l) * rho_dair(l)) * q_building_bef_hac(l) ) + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) else ! Cathy: not using explicit AC scheme: t_building(l) = t_building_max(l) ! Cathy [dev.18] From 0bf22dcb849d1026cead1f6d844a28c343b85ec1 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Fri, 13 Jun 2025 16:09:34 -0700 Subject: [PATCH 43/89] Revert "[dev.18] correct condensate flux calculation" This reverts commit 0d1268ef91fcb70c4cf1e775d4e9b60dd10f0be1. --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 58 ++++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index e1c5943863..86aec0e46c 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1005,7 +1005,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.06] g = lun%gridcell(l) if (urbpoi(l)) then - if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then ! Cathy: if use HAC scheme: + if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then t_building_bef_hac(l) = t_building(l) ! Cathy [dev.03] q_building_bef_hac(l) = q_building(l) @@ -1015,8 +1015,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) q_building_max = rh_building_max / 100._r8 * qsat_building_max - if (t_building_bef_hac(l) > t_building_max(l)) then ! Cathy: if AC is triggered: - if (urban_explicit_ac) then ! Cathy: use explicit ac adoption rate parameterization scheme: + if (t_building_bef_hac(l) > t_building_max(l)) then + if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: ! Sensible heat ! Here, t_building_max is the AC saturation setpoint @@ -1029,7 +1029,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.09] ! Latent heat - if (q_building_bef_hac(l) > q_building_max) then ! Cathy: if dehumidification is needed: + if (q_building_bef_hac(l) > q_building_max) then ! the latent heat removed from internal building air is released to urban canyon as sensible heat. ! Humidification process for urban heating is not implemented. ! Here, q_building_max is the AC humidity setpoint under saturated adoption @@ -1042,44 +1042,50 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) end if - eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) - ! Cathy [dev.15] - ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. - ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff). - ! Cathy [dev.18] - ! Debug condensate flux: total condensed water should be calculated from difference between before and - ! after AC, not before and after this time step. - qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) - else ! Cathy: not using explicit AC scheme: + else t_building(l) = t_building_max(l) - ! Cathy [dev.18] - eflx_urban_ac_sen(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & + eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) - eflx_urban_ac(l) = eflx_urban_ac_sen(l) + 0._r8 ! placeholder for eflx_urban_ac_lat(l) - qtot_condensate(l) = 0._r8 end if - else if (t_building_bef_hac(l) < t_building_min(l)) then ! Cathy: if heating is triggered: + else if (t_building_bef_hac(l) < t_building_min(l)) then t_building(l) = t_building_min(l) eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) - else ! Cathy: if no AC or heating is triggered: + else ! Cathy [dev.03]: need this because dehumidification below may reference it ! eflx_urban_ac_sat(l) = 0._r8 - ! Cathy [dev.14] [dev.18] + ! Cathy [dev.14] eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 - qtot_condensate(l) = 0._r8 end if + ! Cathy [dev.03] + ! Latent heat + ! Dehumidification process modifies eflx_urban_ac, and is only implemented for urban_explicit_ac = .true.; + ! the latent heat removed from internal building air is released to urban canyon as sensible heat. + ! Humidification process for urban heating is not implemented. + ! if (q_building_bef_hac(l) > q_building_max) then + ! if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: + ! ! Here, q_building_max is the AC humidity setpoint under saturated adoption + ! eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & + ! (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & + ! - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & + ! ) + ! eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) + ! q_building(l) = q_building_max + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & + ! * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) + ! eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) + ! end if + ! end if + else - ! Cathy [dev.14] [dev.18] + ! Cathy [dev.14] eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 - qtot_condensate(l) = 0._r8 end if ! Cathy [dev.02] ! eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) @@ -1088,6 +1094,12 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & ) + ! Cathy [dev.15] + + ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. + ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff). + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) + ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. ! water flux to other urban columns are set to 0. do fc = 1, num_urbanc From df6c4c2c2499589065582db756169e12128aa904 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Fri, 13 Jun 2025 16:11:50 -0700 Subject: [PATCH 44/89] [dev.18] Only correctly condensate flux calc --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 86aec0e46c..4361e08a8c 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1094,11 +1094,11 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & ) - ! Cathy [dev.15] + ! Cathy [dev.15] [dev.18] ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff). - qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef(l))) * ht_roof(l) * rho_dair(l) + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. ! water flux to other urban columns are set to 0. From cd7b25aef3e913ca5b7e1a55b82fcdfbe1eeb335 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Mon, 16 Jun 2025 16:10:35 -0700 Subject: [PATCH 45/89] [dev.18.01] change where q_buliding(l) is updated This probably doesn't solve the bug, but should make eflx_ventilation more correct --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 4361e08a8c..57ca249260 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -745,6 +745,15 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do + ! Cathy [dev.03] + ! Update internal building air specific humidity + do fl = 1,num_urbanl + l = filter_urbanl(fl) + if (urbpoi(l)) then + q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) + q_building_bef(l) * (1 - vent_ach/3600._r8 * dtime) + end if + end do + ! Energy balance checks do fl = 1,num_urbanl l = filter_urbanl(fl) @@ -987,15 +996,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do - ! Cathy [dev.03] - ! Update internal building air specific humidity - do fl = 1,num_urbanl - l = filter_urbanl(fl) - if (urbpoi(l)) then - q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) + q_building_bef(l) * (1 - vent_ach/3600._r8 * dtime) - end if - end do - ! Restrict internal building air temperature to between min and max ! Calculate heating or air conditioning flux from energy required to change ! internal building air temperature to t_building_min or t_building_max. From 1b1936a202b02fbb50da12637c896ec852b199ec Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Mon, 16 Jun 2025 23:31:22 -0700 Subject: [PATCH 46/89] [dev.18.02] debug: output lun level var --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 8 +++++++- src/biogeophys/WaterFluxType.F90 | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 57ca249260..9acd6f9188 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -389,6 +389,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.15] qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for impervious road area (mm/s) ) + qflx_condensate_from_ac_lu => waterfluxbulk_inst%qflx_condensate_from_ac_lun & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for urban area by land unit (mm/s) + ) ! Get step size @@ -1095,10 +1097,14 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ) ! Cathy [dev.15] [dev.18] - ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff). qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) + ! Cathy [dev.18.02] + ! qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * abs ( & + ! ( ht_roof(l) * rho_dair(l) / dtime ) * q_building(l) - & + ! ( ht_roof(l) * rho_dair(l) / dtime ) * q_building_bef_hac(l) ) + qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. ! water flux to other urban columns are set to 0. diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 4bbed80b5e..377d436579 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -52,7 +52,9 @@ module WaterFluxType real(r8), pointer :: qflx_liqevap_from_top_layer_col(:) ! col rate of liquid water evaporated from top soil or snow layer (mm H2O/s) [+] ! Cathy [dev.15] real(r8), pointer :: qflx_condensate_from_ac_col(:) ! col condensate due to dehumidification from air-conditioning (mm H2O/S) [+] - + ! Cathy [dev.18.02] + real(r8), pointer :: qflx_condensate_from_ac_lun(:) ! lun condensate due to dehumidification from air-conditioning (mm H2O/S) [+] + ! In the snow capping parametrization excess mass above h2osno_max is removed. A breakdown of mass into liquid ! and solid fluxes is done, these are represented by qflx_snwcp_liq_col and qflx_snwcp_ice_col. real(r8), pointer :: qflx_snwcp_liq_col (:) ! col excess liquid h2o due to snow capping (outgoing) (mm H2O /s) @@ -275,6 +277,10 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar1d(var = this%qflx_condensate_from_ac_col, name = 'qflx_condensate_from_ac_col', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, ival = 0.0_r8) + ! Cathy [dev.18.02] + call AllocateVar1d(var = this%qflx_condensate_from_ac_lun, name = 'qflx_condensate_from_ac_lun', & + container = tracer_vars, & + bounds = bounds, subgrid_level = subgrid_level_landunit, ival = 0.0_r8) call AllocateVar1d(var = this%qflx_infl_col, name = 'qflx_infl_col', & container = tracer_vars, & @@ -602,6 +608,14 @@ subroutine InitHistory(this, bounds) avgflag='A', & long_name=this%info%lname('Condensed water flux from AC dehumidification'), & ptr_col=this%qflx_condensate_from_ac_col, set_nourb=0.0_r8, c2l_scale_type='urbanf', default='inactive') + ! Cathy [dev.18.02] + this%qflx_condensate_from_ac_lun(begl:endl) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('QCOND_FROM_AC_LUN'), & + units='mm/s', & + avgflag='A', & + long_name=this%info%lname('Condensed water flux from AC dehumidification (lun var)'), & + ptr_lunit=this%qflx_condensate_from_ac_lun, set_nourb=0.0_r8, l2g_scale_type='unity') !, default='inactive') this%qflx_snomelt_col(begc:endc) = spval call hist_addfld1d ( & From b865561cdb529ade1d8d7a316c52ca09b927cc75 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 17 Jun 2025 01:20:46 -0700 Subject: [PATCH 47/89] [dev.18.02] cont'd --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 9acd6f9188..c227ff4fcd 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -388,7 +388,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.15] qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for impervious road area (mm/s) - ) qflx_condensate_from_ac_lu => waterfluxbulk_inst%qflx_condensate_from_ac_lun & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for urban area by land unit (mm/s) ) From c68321551ac7a704d9373e6cb9c7ad1bd28167a0 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 17 Jun 2025 01:24:23 -0700 Subject: [PATCH 48/89] [dev.18.02] cont'd 2 --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index c227ff4fcd..7a8c71bfd8 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -387,7 +387,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_ventilation => energyflux_inst%eflx_ventilation_lun, & ! Output: [real(r8) (:)] sensible heat flux from building ventilation (W/m**2) ! Cathy [dev.15] - qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for impervious road area (mm/s) + qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col, & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for impervious road area (mm/s) qflx_condensate_from_ac_lu => waterfluxbulk_inst%qflx_condensate_from_ac_lun & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for urban area by land unit (mm/s) ) From 34ceff6bccd7f19b854d7dc067042c33a068be86 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Tue, 17 Jun 2025 16:24:22 -0700 Subject: [PATCH 49/89] [dev.18.03] loop over columns separately --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 27 +++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 7a8c71bfd8..9b32f52ca2 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1104,18 +1104,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! ( ht_roof(l) * rho_dair(l) / dtime ) * q_building(l) - & ! ( ht_roof(l) * rho_dair(l) / dtime ) * q_building_bef_hac(l) ) qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime - - ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. - ! water flux to other urban columns are set to 0. - do fc = 1, num_urbanc - c = filter_urbanc(fc) - if (ctype(c) == icol_roof) then - qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime - ! write(iulog,*) '############# Cathy [dev.15] calculated qflx_condensate_from_ac: ', qflx_condensate_from_ac(c), '#############' - else ! if (ctype(c) == icol_road_imperv .or. ctype(c) == icol_sunwall .or. ctype(c) == icol_shadewall) then - qflx_condensate_from_ac(c) = 0._r8 - end if - end do ! Cathy [dev.06] ! Calculate relative humidity based on specific humidity @@ -1124,6 +1112,21 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do + ! Cathy [dev.18.03] Start a seperate loop for this: + ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. + ! water flux to other urban columns are set to 0. + do fc = 1,num_urbanc + c = filter_urbanc(fc) + l = clandunit(c) + if (urbpoi(l)) then + if (ctype(c) == icol_roof) then + qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime + else + qflx_condensate_from_ac(c) = 0._r8 + end if + end if + end do + end associate end subroutine BuildingTemperature From e6069b3be8258dd1ec526f917ed2494c297a5868 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 18 Jun 2025 17:15:55 -0700 Subject: [PATCH 50/89] [dev.19] add consistency check Add code block to check if the energy flux derived from the condensate output match the energy flux calculated directly (threshold = 1e-5 W m-2 urban area) --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 23 +++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 9b32f52ca2..00f7a681d2 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -339,7 +339,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: esat_building ! internal building air saturated vapor pressure used to calculate p_vapor (Pa) real(r8) :: p_vapor ! internal building air partial pressure of water vapor (Pa) ! Cathy [dev.15] - real(r8) :: qtot_condensate(bounds%begl:bounds%endl) ! total condensed water due to dehumidification per building area (kg/m2) + real(r8) :: qtot_condensate(bounds%begl:bounds%endl) ! total condensed water due to dehumidification per building area (kg m-2) + ! Cathy [dev.19] + real(r8) :: eflx_urban_ac_lat_derived(bounds%begl:bounds%endl) ! urban air conditioning latent heat flux derived from condensate output, for error check (W m-2) + real(r8) :: err_eflx_urban_ac_lat(bounds%begl:bounds%endl) ! Difference in urban air conditioning latent heat flux for error check (W m-2) !EOP !----------------------------------------------------------------------- @@ -1112,6 +1115,24 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do + ! Cathy [dev.19] Dehumidification scheme consistency check: + ! The following code block checks if the energy and water calculations from the dehumidification scheme match + do fl = 1,num_urbanl + l = filter_urbanl(fl) + if (urbpoi(l)) then + ! dehumidification energy flux calculated from condensate: + eflx_urban_ac_lat_derived(l) = qflx_condensate_from_ac_lu(l) * hvap + ! Difference in dehumidification energy flux: + err_eflx_urban_ac_lat(l) = eflx_urban_ac_lat_derived(l) - (eflx_urban_ac(l) - eflx_urban_ac_sen(l)) + if (abs(err_eflx_urban_ac_lat(l)) > 1.e-5_r8 ) then + write (iulog,*) 'urban dehumidification energy does not match condensate output,' + write (iulog,*) 'error in dehumidification energy flux [W/m2 urban]: ',err_eflx_urban_ac_lat(l) + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + end if + end if + end do + ! Cathy [dev.18.03] Start a seperate loop for this: ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. ! water flux to other urban columns are set to 0. From 87f91dc0f1837b567e8fe6a227fd435bf1f3ea54 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li <55264121+cathyxinchangli@users.noreply.github.com> Date: Wed, 18 Jun 2025 22:11:41 -0700 Subject: [PATCH 51/89] [dev.20] clean up 1. add sensible heat load assignment under non-explicit-AC-adoption case 2. clean up and consolidate some comments --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 31 ++++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 00f7a681d2..9e0a0567cf 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1049,8 +1049,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) else t_building(l) = t_building_max(l) - eflx_urban_ac(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & + eflx_urban_ac_sen(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + eflx_urban_ac(l) = eflx_urban_ac_sen(l) + 0._r8 ! 0._r8 is a placeholder for eflx_urban_ac_lat(l) end if else if (t_building_bef_hac(l) < t_building_min(l)) then @@ -1066,25 +1067,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_heat(l) = 0._r8 end if - ! Cathy [dev.03] - ! Latent heat - ! Dehumidification process modifies eflx_urban_ac, and is only implemented for urban_explicit_ac = .true.; - ! the latent heat removed from internal building air is released to urban canyon as sensible heat. - ! Humidification process for urban heating is not implemented. - ! if (q_building_bef_hac(l) > q_building_max) then - ! if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: - ! ! Here, q_building_max is the AC humidity setpoint under saturated adoption - ! eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & - ! (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & - ! - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & - ! ) - ! eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) - ! q_building(l) = q_building_max + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & - ! * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) - ! eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) - ! end if - ! end if - else ! Cathy [dev.14] eflx_urban_ac_sen(l) = 0._r8 @@ -1100,12 +1082,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Cathy [dev.15] [dev.18] ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. - ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff). qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) - ! Cathy [dev.18.02] - ! qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * abs ( & - ! ( ht_roof(l) * rho_dair(l) / dtime ) * q_building(l) - & - ! ( ht_roof(l) * rho_dair(l) / dtime ) * q_building_bef_hac(l) ) + ! Cathy [dev.18.02] condensate water flux [mm/s] w.r.t. urban land unit area qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime ! Cathy [dev.06] @@ -1134,7 +1112,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end do ! Cathy [dev.18.03] Start a seperate loop for this: - ! Calculate and assign water flux due to dehumidification to roof column [mm/s]. + ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff) + ! Calculate and assign water flux due to dehumidification to roof column [mm/s], ! water flux to other urban columns are set to 0. do fc = 1,num_urbanc c = filter_urbanc(fc) From 24e8ff949ad0205fe7895bb633877576057af9b0 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Tue, 4 Aug 2026 17:51:40 -0600 Subject: [PATCH 52/89] Add ac_dehumid master toggle --- bld/CLMBuildNamelist.pm | 14 ++ bld/namelist_files/namelist_defaults_ctsm.xml | 3 + .../namelist_definition_ctsm.xml | 6 + src/biogeophys/BalanceCheckMod.F90 | 85 ++++---- src/biogeophys/EnergyFluxType.F90 | 11 +- src/biogeophys/SoilHydrologyMod.F90 | 10 +- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 184 +++++++++--------- src/biogeophys/UrbanParamsType.F90 | 17 +- src/biogeophys/WaterDiagnosticBulkType.F90 | 22 ++- src/biogeophys/WaterFluxType.F90 | 32 +-- src/biogeophys/WaterType.F90 | 6 +- 11 files changed, 217 insertions(+), 173 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 1ebe720d65..4996a4f708 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2249,8 +2249,22 @@ sub setup_logic_urban { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'building_temp_method'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_hac'); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'ac_dehumid'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_explicit_ac'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_traffic'); + + if (value_is_true($nl->get_value('ac_dehumid'))) { + my $urban_hac = remove_leading_and_trailing_quotes($nl->get_value('urban_hac')); + if ($urban_hac ne 'ON' && $urban_hac ne 'ON_WASTEHEAT') { + $log->fatal_error("ac_dehumid requires urban_hac to be ON or ON_WASTEHEAT"); + } + if (! value_is_true($nl->get_value('urban_explicit_ac'))) { + $log->fatal_error("ac_dehumid requires urban_explicit_ac=.true."); + } + if ($nl->get_value('building_temp_method') != 1) { + $log->fatal_error("ac_dehumid requires building_temp_method=1"); + } + } } #------------------------------------------------------------------------------- diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index f1f21e27d4..af199e37c1 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -146,6 +146,9 @@ attributes from the config_cache.xml file (with keys converted to upper-case). FAST NONE + +.false. + .true. .true. diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 85a36a17b5..d4459d32ca 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1075,6 +1075,12 @@ Turn urban air conditioning/heating ON or OFF and add wasteheat: If TRUE, use explicit, time-varying AC adoption rate for air-conditioning flux and interior building temperature calculations. + +If TRUE, simulate indoor humidity, air-conditioning latent cooling, and condensate runoff. +Requires urban_hac to be ON or ON_WASTEHEAT, urban_explicit_ac to be TRUE, and the prognostic building-temperature method. + + If TRUE, urban traffic flux will be activated (Currently NOT implemented). diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index f0cae0a442..b512caf323 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -36,6 +36,7 @@ module BalanceCheckMod use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall use column_varcon , only : icol_road_perv, icol_road_imperv use clm_varctl , only : use_hillslope_routing + use UrbanParamsType , only : ac_dehumid ! ! !PUBLIC TYPES: implicit none @@ -644,22 +645,22 @@ subroutine BalanceCheck( bounds, & ! add qflx_drain_perched and qflx_flood if (col%active(c)) then - errh2o_col(c) = endwb_col(c) - begwb_col(c) & - - (forc_rain_col(c) & - + forc_snow_col(c) & - + qflx_flood_col(c) & - + qflx_sfc_irrig_col(c) & - + qflx_glcice_dyn_water_flux_col(c) & - ! Cathy [dev.16] - + qflx_condensate_from_ac_col(c) & - - qflx_evap_tot_col(c) & - - qflx_surf_col(c) & - - qflx_qrgwl_col(c) & - - qflx_drain_col(c) & - - qflx_drain_perched_col(c) & - - qflx_ice_runoff_col(c) & - - qflx_snwcp_discarded_liq_col(c) & - - qflx_snwcp_discarded_ice_col(c)) * dtime + if (ac_dehumid) then + errh2o_col(c) = endwb_col(c) - begwb_col(c) & + - (forc_rain_col(c) + forc_snow_col(c) + qflx_flood_col(c) & + + qflx_sfc_irrig_col(c) + qflx_glcice_dyn_water_flux_col(c) & + + qflx_condensate_from_ac_col(c) - qflx_evap_tot_col(c) & + - qflx_surf_col(c) - qflx_qrgwl_col(c) - qflx_drain_col(c) & + - qflx_drain_perched_col(c) - qflx_ice_runoff_col(c) & + - qflx_snwcp_discarded_liq_col(c) - qflx_snwcp_discarded_ice_col(c)) * dtime + else + errh2o_col(c) = endwb_col(c) - begwb_col(c) & + - (forc_rain_col(c) + forc_snow_col(c) + qflx_flood_col(c) & + + qflx_sfc_irrig_col(c) + qflx_glcice_dyn_water_flux_col(c) & + - qflx_evap_tot_col(c) - qflx_surf_col(c) - qflx_qrgwl_col(c) & + - qflx_drain_col(c) - qflx_drain_perched_col(c) - qflx_ice_runoff_col(c) & + - qflx_snwcp_discarded_liq_col(c) - qflx_snwcp_discarded_ice_col(c)) * dtime + end if else @@ -695,8 +696,9 @@ subroutine BalanceCheck( bounds, & write(iulog,*)'qflx_surf = ',qflx_surf_col(indexc)*dtime write(iulog,*)'qflx_qrgwl = ',qflx_qrgwl_col(indexc)*dtime write(iulog,*)'qflx_drain = ',qflx_drain_col(indexc)*dtime - ! Cathy [dev.17] help debug the water imbalance - write(iulog,*)'qflx_condensate_from_ac = ',qflx_condensate_from_ac_col(indexc)*dtime + if (ac_dehumid) then + write(iulog,*)'qflx_condensate_from_ac = ',qflx_condensate_from_ac_col(indexc)*dtime + end if write(iulog,*)'qflx_ice_runoff = ',qflx_ice_runoff_col(indexc)*dtime @@ -734,29 +736,30 @@ subroutine BalanceCheck( bounds, & qflx_snwcp_discarded_ice_col(bounds%begc:bounds%endc), & qflx_snwcp_discarded_ice_grc(bounds%begg:bounds%endg), & c2l_scale_type= 'urbanf', l2g_scale_type='unity' ) - ! Cathy [dev.16] - call c2g( bounds, & - qflx_condensate_from_ac_col(bounds%begc:bounds%endc), & - qflx_condensate_from_ac_grc(bounds%begg:bounds%endg), & - c2l_scale_type= 'urbanf', l2g_scale_type='unity' ) + if (ac_dehumid) then + call c2g( bounds, & + qflx_condensate_from_ac_col(bounds%begc:bounds%endc), & + qflx_condensate_from_ac_grc(bounds%begg:bounds%endg), & + c2l_scale_type= 'urbanf', l2g_scale_type='unity' ) + end if do g = bounds%begg, bounds%endg - errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & - - (forc_rain_grc(g) & - + forc_snow_grc(g) & - + forc_flood_grc(g) & - + qflx_sfc_irrig_grc(g) & - + qflx_glcice_dyn_water_flux_grc(g) & - ! Cathy [dev.16] - + qflx_condensate_from_ac_grc(g) & - - qflx_evap_tot_grc(g) & - - qflx_surf_grc(g) & - - qflx_qrgwl_grc(g) & - - qflx_drain_grc(g) & - - qflx_drain_perched_grc(g) & - - qflx_ice_runoff_grc(g) & - - qflx_snwcp_discarded_liq_grc(g) & - - qflx_snwcp_discarded_ice_grc(g)) * dtime + if (ac_dehumid) then + errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & + - (forc_rain_grc(g) + forc_snow_grc(g) + forc_flood_grc(g) & + + qflx_sfc_irrig_grc(g) + qflx_glcice_dyn_water_flux_grc(g) & + + qflx_condensate_from_ac_grc(g) - qflx_evap_tot_grc(g) & + - qflx_surf_grc(g) - qflx_qrgwl_grc(g) - qflx_drain_grc(g) & + - qflx_drain_perched_grc(g) - qflx_ice_runoff_grc(g) & + - qflx_snwcp_discarded_liq_grc(g) - qflx_snwcp_discarded_ice_grc(g)) * dtime + else + errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & + - (forc_rain_grc(g) + forc_snow_grc(g) + forc_flood_grc(g) & + + qflx_sfc_irrig_grc(g) + qflx_glcice_dyn_water_flux_grc(g) & + - qflx_evap_tot_grc(g) - qflx_surf_grc(g) - qflx_qrgwl_grc(g) & + - qflx_drain_grc(g) - qflx_drain_perched_grc(g) - qflx_ice_runoff_grc(g) & + - qflx_snwcp_discarded_liq_grc(g) - qflx_snwcp_discarded_ice_grc(g)) * dtime + end if end do ! add landunit level flux variable, convert from (m3/s) to (kg m-2 s-1) @@ -827,7 +830,9 @@ subroutine BalanceCheck( bounds, & write(iulog,*)'forc_flood = ',forc_flood_grc(indexg)*dtime write(iulog,*)'qflx_glcice_dyn_water_flux = ',qflx_glcice_dyn_water_flux_grc(indexg)*dtime ! Cathy [dev.17] help debug the water imbalance - write(iulog,*)'qflx_condensate_from_ac = ',qflx_condensate_from_ac_grc(indexg)*dtime + if (ac_dehumid) then + write(iulog,*)'qflx_condensate_from_ac = ',qflx_condensate_from_ac_grc(indexg)*dtime + end if write(iulog,*)'CTSM is stopping' call endrun(subgrid_index=indexg, subgrid_level=subgrid_level_gridcell, msg=errmsg(sourcefile, __LINE__)) diff --git a/src/biogeophys/EnergyFluxType.F90 b/src/biogeophys/EnergyFluxType.F90 index 252725aacf..0cb540253a 100644 --- a/src/biogeophys/EnergyFluxType.F90 +++ b/src/biogeophys/EnergyFluxType.F90 @@ -14,6 +14,7 @@ module EnergyFluxType use ColumnType , only : col use PatchType , only : patch use AnnualFluxDribbler, only : annual_flux_dribbler_type, annual_flux_dribbler_gridcell + use UrbanParamsType, only : ac_dehumid ! implicit none save @@ -594,10 +595,12 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp) ptr_lunit=this%eflx_urban_ac_lun, set_nourb=0._r8, l2g_scale_type='unity') ! Cathy [dev.14] - this%eflx_urban_ac_sen_lun(begl:endl) = spval - call hist_addfld1d (fname='URBAN_AC_SEN', units='W/m^2', & - avgflag='A', long_name='sensible heat component of urban air conditioning flux', & - ptr_lunit=this%eflx_urban_ac_sen_lun, set_nourb=0._r8, l2g_scale_type='unity') + if (ac_dehumid) then + this%eflx_urban_ac_sen_lun(begl:endl) = spval + call hist_addfld1d (fname='URBAN_AC_SEN', units='W/m^2', & + avgflag='A', long_name='sensible heat component of urban air conditioning flux', & + ptr_lunit=this%eflx_urban_ac_sen_lun, set_nourb=0._r8, l2g_scale_type='unity') + end if this%eflx_urban_heat_lun(begl:endl) = spval call hist_addfld1d (fname='URBAN_HEAT', units='W/m^2', & diff --git a/src/biogeophys/SoilHydrologyMod.F90 b/src/biogeophys/SoilHydrologyMod.F90 index c8e2f5e675..74a27fe1f4 100644 --- a/src/biogeophys/SoilHydrologyMod.F90 +++ b/src/biogeophys/SoilHydrologyMod.F90 @@ -33,6 +33,7 @@ module SoilHydrologyMod use LandunitType , only : lun use ColumnType , only : column_type, col use PatchType , only : patch + use UrbanParamsType , only : ac_dehumid ! ! !PUBLIC TYPES: @@ -598,9 +599,12 @@ subroutine TotalSurfaceRunoff(bounds, num_hydrologyc, filter_hydrologyc, & pondmx_urban/dtime) qflx_surf(c) = xs_urban(c) end if - ! send flood water flux to runoff for all urban columns - ! Cathy [dev.15] - qflx_surf(c) = qflx_surf(c) + qflx_floodc(c) + qflx_condensate_from_ac(c) + ! Send flood water flux to runoff for all urban columns. + if (ac_dehumid) then + qflx_surf(c) = qflx_surf(c) + qflx_floodc(c) + qflx_condensate_from_ac(c) + else + qflx_surf(c) = qflx_surf(c) + qflx_floodc(c) + end if else if (col%itype(c) == icol_sunwall .or. col%itype(c) == icol_shadewall) then qflx_surf(c) = 0._r8 end if diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 9e0a0567cf..96b34c4c2b 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -222,7 +222,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, use clm_varctl , only : iulog use abortutils , only : endrun use clm_varpar , only : nlevurb, nlevsno, nlevmaxurbgrnd - use UrbanParamsType , only : urban_hac, urban_hac_off, urban_hac_on, urban_wasteheat_on, urban_explicit_ac + use UrbanParamsType , only : urban_hac, urban_hac_off, urban_hac_on, urban_wasteheat_on, & + urban_explicit_ac, ac_dehumid ! Cathy [dev.06] use QSatMod , only : QSat ! @@ -415,8 +416,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, t_shdw_inner_bef(l) = t_shdw_inner(l) t_floor_bef(l) = t_floor(l) t_building_bef(l) = t_building(l) - ! Cathy [dev.03] - q_building_bef(l) = q_building(l) + if (ac_dehumid) then + q_building_bef(l) = q_building(l) + end if if (t_roof_inner_bef(l) .le. t_building_bef(l)) then hcv_roofi(l) = hcv_roof_enhanced else @@ -439,18 +441,16 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, cp_floori(l) = cp_floor ! Intermediate calculation for concrete floor (W m-2 K-1) cv_floori(l) = (dz_floori(l) * cp_floori(l)) / dtime - ! Cathy [dev.11] - ! Density of dry air at standard pressure and t_building (kg m-3) - ! rho_dair(l) = pstd / (rair*t_building_bef(l)) - ! Cathy [dev.13] update all pressure to forc_pbot below - ! Saturated vapor pressure at t_building (Pa) - call QSat(t_building_bef(l), forc_pbot(g), qsat_building, es = esat_building) - ! Partial pressure of water vapor (Pa) - p_vapor = min(1._r8, q_building_bef(l) / qsat_building ) * esat_building - ! Density of HUMID air at bottom layer atmos. forcing pressure and t_building (kg m-3) - rho_dair(l) = ( forc_pbot(g) - p_vapor ) / ( rair * t_building_bef(l) ) + p_vapor / ( rwat * t_building_bef(l)) - ! Specific heat capacity of HUMID air (J/kg/K) - cp_hair(l) = cpair + cpwvap * q_building_bef(l) + if (ac_dehumid) then + call QSat(t_building_bef(l), forc_pbot(g), qsat_building, es = esat_building) + p_vapor = min(1._r8, q_building_bef(l) / qsat_building) * esat_building + rho_dair(l) = (forc_pbot(g) - p_vapor) / (rair * t_building_bef(l)) & + + p_vapor / (rwat * t_building_bef(l)) + cp_hair(l) = cpair + cpwvap * q_building_bef(l) + else + rho_dair(l) = pstd / (rair*t_building_bef(l)) + cp_hair(l) = cpair + end if ! Building height to building width ratio building_hwr(l) = canyon_hwr(l)*(1._r8-wtlunit_roof(l))/wtlunit_roof(l) end if @@ -749,14 +749,15 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do - ! Cathy [dev.03] - ! Update internal building air specific humidity - do fl = 1,num_urbanl - l = filter_urbanl(fl) - if (urbpoi(l)) then - q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) + q_building_bef(l) * (1 - vent_ach/3600._r8 * dtime) - end if - end do + if (ac_dehumid) then + do fl = 1,num_urbanl + l = filter_urbanl(fl) + if (urbpoi(l)) then + q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) & + + q_building_bef(l) * (1 - vent_ach/3600._r8 * dtime) + end if + end do + end if ! Energy balance checks do fl = 1,num_urbanl @@ -985,18 +986,19 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if - ! Cathy [dev.02] ! Sensible heat flux from ventilation. It is added as a flux to the canyon floor in SoilTemperatureMod. ! Note that we multiply it here by wtlunit_roof which converts it from W/m2 of building area to W/m2 ! of urban area. eflx_urban_ac and eflx_urban_heat are treated similarly below. This flux is balanced ! by an equal and opposite flux into/out of the building and so has a net effect of zero on the energy balance ! of the urban landunit. - ! eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & - ! * rho_dair(l) * cpair * (taf(l) - t_building(l)) ) - eflx_ventilation(l) = wtlunit_roof(l) * ( & - - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * cp_hair(l) * (taf(l) - t_building(l)) & - - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * hvap * (qaf(l) - q_building(l)) & - ) + if (ac_dehumid) then + eflx_ventilation(l) = wtlunit_roof(l) * ( & + - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * cp_hair(l) * (taf(l) - t_building(l)) & + - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * hvap * (qaf(l) - q_building(l)) ) + else + eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & + * rho_dair(l) * cpair * (taf(l) - t_building(l)) ) + end if end if end do @@ -1011,13 +1013,12 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, if (urbpoi(l)) then if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then t_building_bef_hac(l) = t_building(l) - ! Cathy [dev.03] - q_building_bef_hac(l) = q_building(l) ! rho_dair(l) = pstd / (rair*t_building(l)) - ! Cathy [dev.06] [dev.07] - ! Calculate q setpoint from RH setpoint - call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) - q_building_max = rh_building_max / 100._r8 * qsat_building_max + if (ac_dehumid) then + q_building_bef_hac(l) = q_building(l) + call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) + q_building_max = rh_building_max / 100._r8 * qsat_building_max + end if if (t_building_bef_hac(l) > t_building_max(l)) then if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: @@ -1028,30 +1029,30 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) & * dtime / (ht_roof(l) * rho_dair(l) * cp_hair(l) * wtlunit_roof(l)) - ! Cathy [dev.14] - eflx_urban_ac_sen(l) = p_ac(l) * eflx_urban_ac_sat(l) - - ! Cathy [dev.09] - ! Latent heat - if (q_building_bef_hac(l) > q_building_max) then - ! the latent heat removed from internal building air is released to urban canyon as sensible heat. - ! Humidification process for urban heating is not implemented. - ! Here, q_building_max is the AC humidity setpoint under saturated adoption - eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & - - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) & - ) - eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) - q_building(l) = q_building_max + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat_lat(l) & - * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) + if (ac_dehumid) then + eflx_urban_ac_sen(l) = p_ac(l) * eflx_urban_ac_sat(l) + end if + if (ac_dehumid) then + if (q_building_bef_hac(l) > q_building_max) then + ! Humidification during urban heating is not implemented. + eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & + (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & + - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) ) + eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) + q_building(l) = q_building_max + (1._r8 - p_ac(l)) * eflx_urban_ac_sat_lat(l) & + * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) + end if end if eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) else t_building(l) = t_building_max(l) - eflx_urban_ac_sen(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) - eflx_urban_ac(l) = eflx_urban_ac_sen(l) + 0._r8 ! 0._r8 is a placeholder for eflx_urban_ac_lat(l) + eflx_urban_ac(l) = wtlunit_roof(l) * abs( & + (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + if (ac_dehumid) then + eflx_urban_ac_sen(l) = eflx_urban_ac(l) + end if end if else if (t_building_bef_hac(l) < t_building_min(l)) then @@ -1059,45 +1060,35 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) else - ! Cathy [dev.03]: need this because dehumidification below may reference it - ! eflx_urban_ac_sat(l) = 0._r8 - ! Cathy [dev.14] - eflx_urban_ac_sen(l) = 0._r8 + if (ac_dehumid) eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if else - ! Cathy [dev.14] - eflx_urban_ac_sen(l) = 0._r8 + if (ac_dehumid) eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if - ! Cathy [dev.02] - ! eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_dair(l)*cpair/dtime) * (t_building(l) - t_building_bef(l)) - eflx_building(l) = wtlunit_roof(l) * ( & - (ht_roof(l) * rho_dair(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & - + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) & - ) - - ! Cathy [dev.15] [dev.18] - ! Calculate total water condensed by dehumidification, if any [kg/m2 building area]. - qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) - ! Cathy [dev.18.02] condensate water flux [mm/s] w.r.t. urban land unit area - qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime - - ! Cathy [dev.06] - ! Calculate relative humidity based on specific humidity - call QSat(t_building(l), forc_pbot(g), qsat_building) - rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) + if (ac_dehumid) then + eflx_building(l) = wtlunit_roof(l) * ( & + (ht_roof(l) * rho_dair(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & + + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) ) + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) + qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime + call QSat(t_building(l), forc_pbot(g), qsat_building) + rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) + else + eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_dair(l)*cpair/dtime) & + * (t_building(l) - t_building_bef(l)) + end if end if end do - ! Cathy [dev.19] Dehumidification scheme consistency check: - ! The following code block checks if the energy and water calculations from the dehumidification scheme match - do fl = 1,num_urbanl - l = filter_urbanl(fl) - if (urbpoi(l)) then + if (ac_dehumid) then + do fl = 1,num_urbanl + l = filter_urbanl(fl) + if (urbpoi(l)) then ! dehumidification energy flux calculated from condensate: eflx_urban_ac_lat_derived(l) = qflx_condensate_from_ac_lu(l) * hvap ! Difference in dehumidification energy flux: @@ -1108,24 +1099,25 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, write (iulog,*) 'clm model is stopping' call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if - end if - end do + end if + end do ! Cathy [dev.18.03] Start a seperate loop for this: ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff) ! Calculate and assign water flux due to dehumidification to roof column [mm/s], ! water flux to other urban columns are set to 0. - do fc = 1,num_urbanc - c = filter_urbanc(fc) - l = clandunit(c) - if (urbpoi(l)) then - if (ctype(c) == icol_roof) then - qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime - else - qflx_condensate_from_ac(c) = 0._r8 - end if - end if - end do + do fc = 1,num_urbanc + c = filter_urbanc(fc) + l = clandunit(c) + if (urbpoi(l)) then + if (ctype(c) == icol_roof) then + qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime + else + qflx_condensate_from_ac(c) = 0._r8 + end if + end if + end do + end if end associate end subroutine BuildingTemperature diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90 index 4b7b80e4fe..ddb8d3d96c 100644 --- a/src/biogeophys/UrbanParamsType.F90 +++ b/src/biogeophys/UrbanParamsType.F90 @@ -101,6 +101,7 @@ module UrbanParamsType character(len= *), parameter, public :: urban_hac_on = 'ON' character(len= *), parameter, public :: urban_wasteheat_on = 'ON_WASTEHEAT' character(len= 16), public :: urban_hac = urban_hac_off + logical, public :: ac_dehumid = .false. ! whether to simulate AC dehumidification logical, public :: urban_explicit_ac = .true. ! whether to use explicit, time-varying AC adoption rate logical, public :: urban_traffic = .false. ! urban traffic fluxes @@ -848,7 +849,7 @@ subroutine UrbanReadNML ( NLFilename ) integer :: unitn ! unit for namelist file character(len=32) :: subname = 'UrbanReadNML' ! subroutine name - namelist / clmu_inparm / urban_hac, urban_explicit_ac, urban_traffic, building_temp_method + namelist / clmu_inparm / urban_hac, ac_dehumid, urban_explicit_ac, urban_traffic, building_temp_method !EOP !----------------------------------------------------------------------- @@ -876,6 +877,7 @@ subroutine UrbanReadNML ( NLFilename ) ! Broadcast namelist variables read in call shr_mpi_bcast(urban_hac, mpicom) + call shr_mpi_bcast(ac_dehumid, mpicom) call shr_mpi_bcast(urban_explicit_ac, mpicom) call shr_mpi_bcast(urban_traffic, mpicom) call shr_mpi_bcast(building_temp_method, mpicom) @@ -885,9 +887,21 @@ subroutine UrbanReadNML ( NLFilename ) write(iulog,*)'Urban traffic fluxes are not implemented currently' call endrun(msg=errMsg(sourcefile, __LINE__)) end if + if (ac_dehumid) then + if (trim(urban_hac) /= urban_hac_on .and. trim(urban_hac) /= urban_wasteheat_on) then + call endrun(msg='ac_dehumid requires urban_hac to be ON or ON_WASTEHEAT'//errmsg(sourcefile, __LINE__)) + end if + if (.not. urban_explicit_ac) then + call endrun(msg='ac_dehumid requires urban_explicit_ac=.true.'//errmsg(sourcefile, __LINE__)) + end if + if (building_temp_method /= BUILDING_TEMP_METHOD_PROG) then + call endrun(msg='ac_dehumid requires the prognostic building temperature method'//errmsg(sourcefile, __LINE__)) + end if + end if ! if ( masterproc )then write(iulog,*) ' urban air conditioning/heating and wasteheat = ', urban_hac + write(iulog,*) ' urban air-conditioning dehumidification = ', ac_dehumid write(iulog,*) ' urban explicit air-conditioning adoption rate = ', urban_explicit_ac write(iulog,*) ' urban traffic flux = ', urban_traffic end if @@ -958,4 +972,3 @@ end module UrbanParamsType - diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 32a02612b0..d67c3ce652 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -29,7 +29,7 @@ module WaterDiagnosticBulkType use WaterStateBulkType, only : waterstatebulk_type use WaterFluxType, only : waterflux_type ! Cathy [dev.04] - use UrbanParamsType, only : IsProgBuildTemp + use UrbanParamsType, only : IsProgBuildTemp, ac_dehumid ! implicit none save @@ -158,7 +158,7 @@ subroutine InitBulk(this, bounds, info, vars, & real(r8) , intent(in) :: h2osno_input_col(bounds%begc:) ! Initial total snow water (mm H2O) - call this%Init(bounds, info, vars, IsProgBuildTemp()) + call this%Init(bounds, info, vars, IsProgBuildTemp() .and. ac_dehumid) call this%InitBulkAllocate(bounds) @@ -363,13 +363,15 @@ subroutine InitBulkHistory(this, bounds) long_name=this%info%lname('Urban 2m relative humidity'), & ptr_patch=this%rh_ref2m_u_patch, set_nourb=spval, default='inactive') - this%rh_building_lun(begl:endl) = spval - call hist_addfld1d ( & - fname=this%info%fname('RHBUILD'), & - units='%', & - avgflag='A', & - long_name=this%info%lname('Internal urban building air relative humidity'), & - ptr_lunit=this%rh_building_lun, set_nourb=spval, default='inactive') + if (ac_dehumid) then + this%rh_building_lun(begl:endl) = spval + call hist_addfld1d ( & + fname=this%info%fname('RHBUILD'), & + units='%', & + avgflag='A', & + long_name=this%info%lname('Internal urban building air relative humidity'), & + ptr_lunit=this%rh_building_lun, set_nourb=spval, default='inactive') + end if this%rh_af_patch(begp:endp) = spval call hist_addfld1d ( & @@ -827,7 +829,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil !------------------------------------------------------------------------ - call this%Restart(bounds, ncid, flag=flag, is_prog_buildtemp=IsProgBuildTemp()) + call this%Restart(bounds, ncid, flag=flag, is_prog_buildtemp=IsProgBuildTemp() .and. ac_dehumid) if(use_luna)then call restartvar(ncid=ncid, flag=flag, & diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 377d436579..2e115311ab 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -17,6 +17,7 @@ module WaterFluxType use WaterInfoBaseType, only : water_info_base_type use WaterTracerContainerType, only : water_tracer_container_type use WaterTracerUtils, only : AllocateVar1d, AllocateVar2d + use UrbanParamsType, only : ac_dehumid ! implicit none private @@ -601,21 +602,22 @@ subroutine InitHistory(this, bounds) ptr_col=this%qflx_runoff_r_col, set_spec=spval, default='inactive') ! Cathy [dev.17]: add condensate from AC to output - this%qflx_condensate_from_ac_col(begc:endc) = 0.0_r8 - call hist_addfld1d ( & - fname=this%info%fname('QCOND_FROM_AC'), & - units='mm/s', & - avgflag='A', & - long_name=this%info%lname('Condensed water flux from AC dehumidification'), & - ptr_col=this%qflx_condensate_from_ac_col, set_nourb=0.0_r8, c2l_scale_type='urbanf', default='inactive') - ! Cathy [dev.18.02] - this%qflx_condensate_from_ac_lun(begl:endl) = 0.0_r8 - call hist_addfld1d ( & - fname=this%info%fname('QCOND_FROM_AC_LUN'), & - units='mm/s', & - avgflag='A', & - long_name=this%info%lname('Condensed water flux from AC dehumidification (lun var)'), & - ptr_lunit=this%qflx_condensate_from_ac_lun, set_nourb=0.0_r8, l2g_scale_type='unity') !, default='inactive') + if (ac_dehumid) then + this%qflx_condensate_from_ac_col(begc:endc) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('QCOND_FROM_AC'), & + units='mm/s', & + avgflag='A', & + long_name=this%info%lname('Condensed water flux from AC dehumidification'), & + ptr_col=this%qflx_condensate_from_ac_col, set_nourb=0.0_r8, c2l_scale_type='urbanf', default='inactive') + this%qflx_condensate_from_ac_lun(begl:endl) = 0.0_r8 + call hist_addfld1d ( & + fname=this%info%fname('QCOND_FROM_AC_LUN'), & + units='mm/s', & + avgflag='A', & + long_name=this%info%lname('Condensed water flux from AC dehumidification (lun var)'), & + ptr_lunit=this%qflx_condensate_from_ac_lun, set_nourb=0.0_r8, l2g_scale_type='unity') + end if this%qflx_snomelt_col(begc:endc) = spval call hist_addfld1d ( & diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index 0dc74aee41..8cf2177d5b 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -79,7 +79,7 @@ module WaterType use WaterTracerContainerType , only : water_tracer_container_type use WaterTracerUtils , only : CompareBulkToTracer, SetTracerToBulkTimesRatio ! Cathy [dev.01] - use UrbanParamsType , only : IsProgBuildTemp + use UrbanParamsType , only : IsProgBuildTemp, ac_dehumid implicit none private @@ -388,7 +388,7 @@ subroutine DoInit(this, bounds, & call this%bulk_and_tracers(i)%waterdiagnostic_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & this%bulk_and_tracers(i)%vars, & - IsProgBuildTemp()) ! Cathy [dev.01] + IsProgBuildTemp() .and. ac_dehumid) ! Cathy [dev.01] call this%bulk_and_tracers(i)%waterbalance_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & @@ -773,7 +773,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) call this%bulk_and_tracers(i)%waterdiagnostic_inst%Restart(bounds, ncid, flag=flag, & - is_prog_buildtemp=IsProgBuildTemp()) ! Cathy [dev.04] + is_prog_buildtemp=IsProgBuildTemp() .and. ac_dehumid) ! Cathy [dev.04] end do From 40511d46bb68830092416c36671e3ddb15c199d8 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Tue, 4 Aug 2026 18:08:57 -0600 Subject: [PATCH 53/89] clean up unnecessary comments --- src/biogeophys/BalanceCheckMod.F90 | 27 ----------------- src/biogeophys/EnergyFluxType.F90 | 5 ---- src/biogeophys/HumanIndexMod.F90 | 3 +- src/biogeophys/SoilHydrologyMod.F90 | 1 - src/biogeophys/SoilTemperatureMod.F90 | 6 ++-- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 31 ++------------------ src/biogeophys/WaterDiagnosticBulkType.F90 | 3 -- src/biogeophys/WaterDiagnosticType.F90 | 14 +-------- src/biogeophys/WaterFluxType.F90 | 5 ---- src/biogeophys/WaterType.F90 | 8 ++--- src/main/clm_instMod.F90 | 2 -- src/main/clm_varcon.F90 | 4 --- 12 files changed, 10 insertions(+), 99 deletions(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index b512caf323..8a0881cbe6 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -499,7 +499,6 @@ subroutine BalanceCheck( bounds, & real(r8) :: qflx_glcice_dyn_water_flux_grc(bounds%begg:bounds%endg) ! grid cell-level water flux needed for balance check due to glc_dyn_runoff_routing [mm H2O/s] (positive means addition of water to the system) real(r8) :: qflx_snwcp_discarded_liq_grc(bounds%begg:bounds%endg) ! grid cell-level excess liquid h2o due to snow capping, which we simply discard in order to reset the snow pack [mm H2O /s] real(r8) :: qflx_snwcp_discarded_ice_grc(bounds%begg:bounds%endg) ! grid cell-level excess solid h2o due to snow capping, which we simply discard in order to reset the snow pack [mm H2O /s] - ! Cathy [dev.16] real(r8) :: qflx_condensate_from_ac_grc(bounds%begg:bounds%endg) ! grid cell-level condensate from air-conditioning [mm H2O /s] real(r8) :: errh2o_max_val ! Maximum value of error in water conservation error over all columns [mm H2O] @@ -512,10 +511,8 @@ subroutine BalanceCheck( bounds, & real(r8), parameter :: h2o_warning_thresh = 1.e-9_r8 ! Warning threshhold for error in errh2o and errh2osnow real(r8), parameter :: energy_warning_thresh = 1.e-7_r8 ! Warning threshhold for error in errsol, errsol, errseb, errlonv real(r8), parameter :: error_thresh = 1.e-5_r8 ! Error threshhold for conservation error - ! ################################## Cathy [dev.16.1] local vars for error check begins ################################## ! real(r8) :: tot_cond_from_col ! total condensate from AC mass flow rate calculated from column-level var [kg/s] ! real(r8) :: tot_cond_from_grc ! total condensate from AC mass flow rate calculated from grid-cell-level var [kg/s] - ! ################################## Cathy [dev.16.1] local vars for error check ends ################################## !----------------------------------------------------------------------- @@ -575,7 +572,6 @@ subroutine BalanceCheck( bounds, & qflx_sfc_irrig_col => waterflux_inst%qflx_sfc_irrig_col , & ! Input: [real(r8) (:) ] column level irrigation flux (mm H2O /s) qflx_sfc_irrig_grc => waterlnd2atm_inst%qirrig_grc , & ! Input: [real(r8) (:) ] grid cell-level irrigation flux (mm H20 /s) qflx_glcice_dyn_water_flux_col => waterflux_inst%qflx_glcice_dyn_water_flux_col, & ! Input: [real(r8) (:)] column level water flux needed for balance check due to glc_dyn_runoff_routing (mm H2O/s) (positive means addition of water to the system) - ! Cathy [dev.15] qflx_condensate_from_ac_col => waterflux_inst%qflx_condensate_from_ac_col, & ! Input: [real(r8) (:)] column level condensate water flux from air-conditioning (mm H2O /s) dhsdt_canopy => energyflux_inst%dhsdt_canopy_patch , & ! Input: [real(r8) (:) ] change in heat content of canopy (W/m**2) [+ to atm] @@ -771,28 +767,6 @@ subroutine BalanceCheck( bounds, & enddo endif - ! ################################## Cathy [dev.16.1]: error check for qflx_condensate_from_ac begins ################################## - ! Below, total condensate mass flow in kg/s will be calculated based on both the column-level var and the grid-cell var. - ! They should match if our code in assigning condensate flux to roof column was correct and the c2g aggregation - ! is done correctly. - - ! do c = bounds%begc,bounds%endc - ! g = col%gridcell(c) - ! l = col%landunit(c) - ! - ! if (col%itype(c) == icol_roof) then - ! ! tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*col%wtgcell(c)) ! kg/s = kg/m2/s * m2 - ! tot_cond_from_col = qflx_condensate_from_ac_col(c) * (grc%area(g)*1.e6_r8*lun%wtgcell(l)*lun%wtlunit_roof(l)) ! grid area * lun frac * roof frac - ! tot_cond_from_grc = qflx_condensate_from_ac_grc(g) * (grc%area(g)*1.e6_r8) - ! if (tot_cond_from_col > 0._r8 .or. tot_cond_from_grc > 0._r8) then - ! write(iulog,*) 'Cathy [dev.16.1] at grid = ',g, 'nstep = ',nstep, & - ! ' from col: ', tot_cond_from_col, & - ! ' from grc: ', tot_cond_from_grc - ! end if - ! end if - ! end do - ! ################################## Cathy [dev.16.1]: error check for qflx_condensate_from_ac ends ################################## - errh2o_max_val = maxval(abs(errh2o_grc(bounds%begg:bounds%endg))) ! BUG(rgk, 2021-04-13, ESCOMP/CTSM#1314) Temporarily bypassing gridcell-level check with use_fates_planthydro until issue 1314 is resolved @@ -829,7 +803,6 @@ subroutine BalanceCheck( bounds, & write(iulog,*)'qflx_drain_perched = ',qflx_drain_perched_grc(indexg)*dtime write(iulog,*)'forc_flood = ',forc_flood_grc(indexg)*dtime write(iulog,*)'qflx_glcice_dyn_water_flux = ',qflx_glcice_dyn_water_flux_grc(indexg)*dtime - ! Cathy [dev.17] help debug the water imbalance if (ac_dehumid) then write(iulog,*)'qflx_condensate_from_ac = ',qflx_condensate_from_ac_grc(indexg)*dtime end if diff --git a/src/biogeophys/EnergyFluxType.F90 b/src/biogeophys/EnergyFluxType.F90 index 0cb540253a..9341dc7ac5 100644 --- a/src/biogeophys/EnergyFluxType.F90 +++ b/src/biogeophys/EnergyFluxType.F90 @@ -72,7 +72,6 @@ module EnergyFluxType real(r8), pointer :: eflx_heat_from_ac_lun (:) ! lun sensible heat flux to be put back into canyon due to removal by AC (W/m**2) real(r8), pointer :: eflx_building_lun (:) ! lun building heat flux from change in interior building air temperature (W/m**2) real(r8), pointer :: eflx_urban_ac_lun (:) ! lun urban air conditioning flux (W/m**2) - ! Cathy [dev.14] real(r8), pointer :: eflx_urban_ac_sen_lun (:) ! lun sensible heat component of air conditioning flux (W/m**2) real(r8), pointer :: eflx_urban_heat_lun (:) ! lun urban heating flux (W/m**2) @@ -237,7 +236,6 @@ subroutine InitAllocate(this, bounds) allocate( this%eflx_heat_from_ac_lun (begl:endl)) ; this%eflx_heat_from_ac_lun (:) = nan allocate( this%eflx_building_lun (begl:endl)) ; this%eflx_building_lun (:) = nan allocate( this%eflx_urban_ac_lun (begl:endl)) ; this%eflx_urban_ac_lun (:) = nan - ! Cathy [dev.14] allocate( this%eflx_urban_ac_sen_lun (begl:endl)) ; this%eflx_urban_ac_sen_lun (:) = nan allocate( this%eflx_urban_heat_lun (begl:endl)) ; this%eflx_urban_heat_lun (:) = nan allocate( this%eflx_traffic_lun (begl:endl)) ; this%eflx_traffic_lun (:) = nan @@ -594,7 +592,6 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp) avgflag='A', long_name='urban air conditioning flux', & ptr_lunit=this%eflx_urban_ac_lun, set_nourb=0._r8, l2g_scale_type='unity') - ! Cathy [dev.14] if (ac_dehumid) then this%eflx_urban_ac_sen_lun(begl:endl) = spval call hist_addfld1d (fname='URBAN_AC_SEN', units='W/m^2', & @@ -775,7 +772,6 @@ subroutine InitCold(this, bounds, t_grnd_col, is_simple_buildtemp, is_prog_build if ( is_prog_buildtemp )then this%eflx_building_lun(l) = 0._r8 this%eflx_urban_ac_lun(l) = 0._r8 - ! Cathy [dev.14] this%eflx_urban_ac_sen_lun(l)= 0._r8 this%eflx_urban_heat_lun(l) = 0._r8 end if @@ -790,7 +786,6 @@ subroutine InitCold(this, bounds, t_grnd_col, is_simple_buildtemp, is_prog_build if ( is_prog_buildtemp )then this%eflx_building_lun(l) = 0._r8 this%eflx_urban_ac_lun(l) = 0._r8 - ! Cathy [dev.14] this%eflx_urban_ac_sen_lun(l)= 0._r8 this%eflx_urban_heat_lun(l) = 0._r8 this%eflx_ventilation_lun(l)= 0._r8 diff --git a/src/biogeophys/HumanIndexMod.F90 b/src/biogeophys/HumanIndexMod.F90 index 597ad989e6..7357c332fc 100644 --- a/src/biogeophys/HumanIndexMod.F90 +++ b/src/biogeophys/HumanIndexMod.F90 @@ -1350,7 +1350,7 @@ subroutine QSat_2 (T_k, p_t, es_mb, de_mbdT, dlnes_mbdT, rs, rsdT, foftk, fdT) ! Clausius-Clapeyron p_tmb = p_t*0.01_r8 tcfbdiff = T_k - Cf + beta - es_mb = es_C*exp(alpha*(T_k - Cf)/(tcfbdiff)) ! Cathy [dev.06] notes: this calculates sat. vapor pressure + es_mb = es_C*exp(alpha*(T_k - Cf)/(tcfbdiff)) dlnes_mbdT = alpha*beta/((tcfbdiff)*(tcfbdiff)) pminuse = p_tmb - es_mb de_mbdT = es_mb*dlnes_mbdT @@ -1387,4 +1387,3 @@ end subroutine QSat_2 !----------------------------------------------------------------------- end module HumanIndexMod - diff --git a/src/biogeophys/SoilHydrologyMod.F90 b/src/biogeophys/SoilHydrologyMod.F90 index 74a27fe1f4..db11dc5766 100644 --- a/src/biogeophys/SoilHydrologyMod.F90 +++ b/src/biogeophys/SoilHydrologyMod.F90 @@ -556,7 +556,6 @@ subroutine TotalSurfaceRunoff(bounds, num_hydrologyc, filter_hydrologyc, & qflx_liqevap_from_top_layer => waterfluxbulk_inst%qflx_liqevap_from_top_layer_col, & ! Input: [real(r8) (:) ] rate of liquid water evaporated from top soil or snow layer (mm H2O/s) [+] qflx_floodc => waterfluxbulk_inst%qflx_floodc_col , & ! Input: [real(r8) (:) ] column flux of flood water from RTM qflx_sat_excess_surf => waterfluxbulk_inst%qflx_sat_excess_surf_col , & ! Input: [real(r8) (:) ] surface runoff due to saturated surface (mm H2O /s) - ! Cathy [dev.15] qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col, & ! Input: [real(r8) (:) ] condensate from air-conditioning (mm H2O /s) xs_urban => soilhydrology_inst%xs_urban_col , & ! Output: [real(r8) (:) ] excess soil water above urban ponding limit diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 6b8499871d..6a3fc301a7 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -20,7 +20,6 @@ module SoilTemperatureMod use WaterFluxBulkType , only : waterfluxbulk_type use WaterStateBulkType , only : waterstatebulk_type use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type - ! Cathy [dev.04] ! use WaterDiagnosticType , only : waterdiagnostic_type use SolarAbsorbedType , only : solarabs_type use SoilStateType , only : soilstate_type @@ -93,7 +92,7 @@ module SoilTemperatureMod subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter_urbanc, & num_nolakep, filter_nolakep, num_nolakec, filter_nolakec, & atm2lnd_inst, urbanparams_inst, canopystate_inst, waterstatebulk_inst, waterdiagnosticbulk_inst, waterfluxbulk_inst,& - solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst) ! Cathy [dev.04] + solarabs_inst, soilstate_inst, energyflux_inst, temperature_inst, urbantv_inst) ! ! !DESCRIPTION: ! Snow and soil temperatures including phase change @@ -146,7 +145,6 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter type(solarabs_type) , intent(inout) :: solarabs_inst type(energyflux_type) , intent(inout) :: energyflux_inst type(temperature_type) , intent(inout) :: temperature_inst - ! Cathy [dev.04] ! type(waterdiagnostic_type) , intent(inout) :: waterdiagnostic_inst ! water diagnostic variables ! ! !LOCAL VARIABLES: @@ -547,7 +545,7 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter num_urbanc, filter_urbanc, & tk(bounds%begc:bounds%endc, :), urbanparams_inst, & temperature_inst, energyflux_inst, urbantv_inst, & - waterdiagnosticbulk_inst, waterfluxbulk_inst, atm2lnd_inst) ! Cathy [dev.04] [dev.06] [dev.15] + waterdiagnosticbulk_inst, waterfluxbulk_inst, atm2lnd_inst) end if do fc = 1,num_nolakec diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 96b34c4c2b..378d51a1d8 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -16,13 +16,10 @@ module UrbBuildTempOleson2015Mod use UrbanTimeVarType , only : urbantv_type use EnergyFluxType , only : energyflux_type use TemperatureType , only : temperature_type - ! Cathy [dev.02] [dev.04] use WaterDiagnosticBulkType, only : waterdiagnosticbulk_type - ! Cathy [dev.15] use WaterFluxBulkType , only : waterfluxbulk_type use LandunitType , only : lun use ColumnType , only : col - ! Cathy [dev.06] use atm2lndType , only : atm2lnd_type ! ! !PUBLIC TYPES: @@ -50,7 +47,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, filter_nolakec, num_urbanc, filter_urbanc, & tk, urbanparams_inst, temperature_inst, & energyflux_inst, urbantv_inst, waterdiagnosticbulk_inst, & - waterfluxbulk_inst, atm2lnd_inst) ! Cathy [dev.02] [dev.04] [dev.06] [dev.15] + waterfluxbulk_inst, atm2lnd_inst) ! ! !DESCRIPTION: ! Solve for t_building, inner surface temperatures of roof, sunw, shdw, and floor temperature @@ -214,17 +211,14 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, hcv_floor, hcv_floor_enhanced, hcv_sunw, hcv_shdw, & em_roof_int, em_floor_int, em_sunw_int, em_shdw_int, & dz_floor, dens_floor, cp_floor, vent_ach, & - ! Cathy [dev.02] ! q_building_max, hvap - ! Cathy [dev.06] [dev.11] rh_building_max, hvap, rwat, cpwvap - use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_imperv ! Cathy [dev.15] + use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_imperv use clm_varctl , only : iulog use abortutils , only : endrun use clm_varpar , only : nlevurb, nlevsno, nlevmaxurbgrnd use UrbanParamsType , only : urban_hac, urban_hac_off, urban_hac_on, urban_wasteheat_on, & urban_explicit_ac, ac_dehumid - ! Cathy [dev.06] use QSatMod , only : QSat ! ! !ARGUMENTS: @@ -232,7 +226,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(bounds_type), intent(in) :: bounds ! bounds integer , intent(in) :: num_nolakec ! number of column non-lake points in column filter integer , intent(in) :: filter_nolakec(:) ! column filter for non-lake points - ! Cathy [dev.15] integer , intent(in) :: num_urbanc ! number of column urban points in column filter integer , intent(in) :: filter_urbanc(:) ! column filter for urban points integer , intent(in) :: num_urbanl ! number of urban landunits in clump @@ -242,16 +235,12 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, type(temperature_type), intent(inout) :: temperature_inst ! temperature variables type(energyflux_type) , intent(inout) :: energyflux_inst ! energy flux variables type(urbantv_type) , intent(in) :: urbantv_inst ! urban time varying variables - ! Cathy [dev.02] [dev.04] type(waterdiagnosticbulk_type), intent(inout) :: waterdiagnosticbulk_inst ! water diagnostic variables - ! Cathy [dev.15] type(waterfluxbulk_type), intent(inout) :: waterfluxbulk_inst ! water flux variables - ! Cathy [dev.06] type(atm2lnd_type) , intent(in) :: atm2lnd_inst ! ! !LOCAL VARIABLES: integer, parameter :: neq = 5 ! number of equation/unknowns - ! Cathy [dev.07] ! integer :: fc,fl,c,l ! indices integer :: fc,fl,c,l,g ! indices real(r8) :: dtime ! land model time step (s) @@ -262,11 +251,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: t_floor_bef(bounds%begl:bounds%endl) ! floor temperature at previous time step (K) real(r8) :: t_building_bef(bounds%begl:bounds%endl) ! internal building air temperature at previous time step [K] real(r8) :: t_building_bef_hac(bounds%begl:bounds%endl)! internal building air temperature before applying HAC [K] - ! Cathy [dev.02] real(r8) :: q_building_bef(bounds%begl:bounds%endl) ! internal building air specific humidity at previous time step (kg/kg) real(r8) :: q_building_bef_hac(bounds%begl:bounds%endl)! internal building air specific humidity before applying HAC (kg/kg) - real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) ! urban air conditioning heat flux under AC adoption saturation (W/m**2) ! Cathy [dev.03] - ! Cathy [dev.03] + real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) real(r8) :: eflx_urban_ac_sat_lat(bounds%begl:bounds%endl) ! urban air conditioning latent heat flux under AC adoption saturation (W/m**2) real(r8) :: hcv_roofi(bounds%begl:bounds%endl) ! roof convective heat transfer coefficient (W m-2 K-1) real(r8) :: hcv_sunwi(bounds%begl:bounds%endl) ! sunwall convective heat transfer coefficient (W m-2 K-1) @@ -279,7 +266,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: dz_floori(bounds%begl:bounds%endl) ! concrete floor thickness (m) real(r8) :: cp_floori(bounds%begl:bounds%endl) ! concrete floor volumetric heat capacity (J m-3 K-1) real(r8) :: cv_floori(bounds%begl:bounds%endl) ! intermediate calculation for concrete floor (W m-2 K-1) - ! Cathy [dev.11] rho_dair below will be temporarily used as density of HUMID air; the var name and description will be changed later real(r8) :: rho_dair(bounds%begl:bounds%endl) ! density of dry air at standard pressure and t_building (kg m-3) real(r8) :: cp_hair(bounds%begl:bounds%endl) ! specific heat capacity of indoor humid air (J kg-1 K-1) real(r8) :: vf_rf(bounds%begl:bounds%endl) ! view factor of roof for floor (-) @@ -332,16 +318,12 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! on exit, if info = 0, the n-by-nrhs solution matrix x integer :: info ! exit information for LAPACK routine dgesv integer :: ipiv(neq) ! the pivot indices that define the permutation matrix P - ! Cathy [dev.06] real(r8) :: q_building_max ! maximum internal building air specific humidity determined from rh_building_max (kg/kg) real(r8) :: qsat_building_max ! maximum internal building air saturated specific humidity/mixing ratio used to determing q_building_max from rh_building_max (kg/kg) real(r8) :: qsat_building ! internal building air saturated specific humidity/mixing ratio used to calculate rh_building (kg/kg) - ! Cathy [dev.11] real(r8) :: esat_building ! internal building air saturated vapor pressure used to calculate p_vapor (Pa) real(r8) :: p_vapor ! internal building air partial pressure of water vapor (Pa) - ! Cathy [dev.15] real(r8) :: qtot_condensate(bounds%begl:bounds%endl) ! total condensed water due to dehumidification per building area (kg m-2) - ! Cathy [dev.19] real(r8) :: eflx_urban_ac_lat_derived(bounds%begl:bounds%endl) ! urban air conditioning latent heat flux derived from condensate output, for error check (W m-2) real(r8) :: err_eflx_urban_ac_lat(bounds%begl:bounds%endl) ! Difference in urban air conditioning latent heat flux for error check (W m-2) !EOP @@ -359,7 +341,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ht_roof => lun%ht_roof , & ! Input: [real(r8) (:)] height of urban roof (m) canyon_hwr => lun%canyon_hwr , & ! Input: [real(r8) (:)] ratio of building height to street hwidth (-) wtlunit_roof => lun%wtlunit_roof , & ! Input: [real(r8) (:)] weight of roof with respect to landunit - ! Cathy [dev.15] wtroad_perv => lun%wtroad_perv , & ! Input: [real(r8) (:)] weight of pervious road column to total road (-) urbpoi => lun%urbpoi , & ! Input: [logical (:)] true => landunit is an urban point @@ -376,11 +357,9 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, t_building_max => urbantv_inst%t_building_max , & ! Input: [real(r8) (:)] maximum internal building air temperature (K) t_building_min => urbanparams_inst%t_building_min , & ! Input: [real(r8) (:)] minimum internal building air temperature (K) - ! Cathy [dev.02] [dev.04] ! trying to change to waterdiagnosticbulk_inst following how qaf was used in UrbanFluxesMod.F90 qaf => waterdiagnosticbulk_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) q_building => waterdiagnosticbulk_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) - ! Cathy [dev.06] rh_building => waterdiagnosticbulk_inst%rh_building_lun,& ! InOut: [real(r8) (:)] internal building air relative humidity (%) forc_pbot => atm2lnd_inst%forc_pbot_not_downscaled_grc,& ! Input:[real(r8) (:)] atmospheric pressure (Pa) @@ -390,7 +369,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_heat => energyflux_inst%eflx_urban_heat_lun,& ! Output: [real(r8) (:)] urban heating flux (W/m**2) eflx_ventilation => energyflux_inst%eflx_ventilation_lun, & ! Output: [real(r8) (:)] sensible heat flux from building ventilation (W/m**2) - ! Cathy [dev.15] qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col, & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for impervious road area (mm/s) qflx_condensate_from_ac_lu => waterfluxbulk_inst%qflx_condensate_from_ac_lun & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for urban area by land unit (mm/s) ) @@ -408,7 +386,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! 5. Calculate building height to building width ratio do fl = 1,num_urbanl l = filter_urbanl(fl) - ! Cathy [dev.13] g = lun%gridcell(l) if (urbpoi(l)) then t_roof_inner_bef(l) = t_roof_inner(l) @@ -1008,7 +985,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) - ! Cathy [dev.06] g = lun%gridcell(l) if (urbpoi(l)) then if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then @@ -1102,7 +1078,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do - ! Cathy [dev.18.03] Start a seperate loop for this: ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff) ! Calculate and assign water flux due to dehumidification to roof column [mm/s], ! water flux to other urban columns are set to 0. diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index d67c3ce652..dd7f868658 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -28,7 +28,6 @@ module WaterDiagnosticBulkType use WaterStateType, only : waterstate_type use WaterStateBulkType, only : waterstatebulk_type use WaterFluxType, only : waterflux_type - ! Cathy [dev.04] use UrbanParamsType, only : IsProgBuildTemp, ac_dehumid ! implicit none @@ -65,7 +64,6 @@ module WaterDiagnosticBulkType real(r8), pointer :: rh_ref2m_patch (:) ! patch 2 m height surface relative humidity (%) real(r8), pointer :: rh_ref2m_r_patch (:) ! patch 2 m height surface relative humidity - rural (%) real(r8), pointer :: rh_ref2m_u_patch (:) ! patch 2 m height surface relative humidity - urban (%) - ! Cathy [dev.06] real(r8), pointer :: rh_building_lun (:) ! lun internal building air relative humidity (%) real(r8), pointer :: rh_af_patch (:) ! patch fractional humidity of canopy air (dimensionless) ! private real(r8), pointer :: rh10_af_patch (:) ! 10-day mean patch fractional humidity of canopy air (dimensionless) @@ -223,7 +221,6 @@ subroutine InitBulkAllocate(this, bounds) allocate(this%rh_ref2m_patch (begp:endp)) ; this%rh_ref2m_patch (:) = nan allocate(this%rh_ref2m_u_patch (begp:endp)) ; this%rh_ref2m_u_patch (:) = nan allocate(this%rh_ref2m_r_patch (begp:endp)) ; this%rh_ref2m_r_patch (:) = nan - ! Cathy [dev.06] allocate(this%rh_building_lun (begl:endl)) ; this%rh_building_lun (:) = nan allocate(this%rh_af_patch (begp:endp)) ; this%rh_af_patch (:) = nan allocate(this%rh10_af_patch (begp:endp)) ; this%rh10_af_patch (:) = spval diff --git a/src/biogeophys/WaterDiagnosticType.F90 b/src/biogeophys/WaterDiagnosticType.F90 index 2deab32e74..17a83144e3 100644 --- a/src/biogeophys/WaterDiagnosticType.F90 +++ b/src/biogeophys/WaterDiagnosticType.F90 @@ -49,7 +49,6 @@ module WaterDiagnosticType real(r8), pointer :: qg_h2osfc_col (:) ! col ground specific humidity [kg/kg] real(r8), pointer :: qg_col (:) ! col ground specific humidity [kg/kg] real(r8), pointer :: qaf_lun (:) ! lun urban canopy air specific humidity (kg/kg) - ! [Cathy] dev.01 real(r8), pointer :: q_building_lun (:) ! lun internal building air specific humidity (kg/kg) contains @@ -77,7 +76,6 @@ subroutine Init(this, bounds, info, tracer_vars, is_prog_buildtemp) type(bounds_type) , intent(in) :: bounds class(water_info_base_type), intent(in), target :: info type(water_tracer_container_type), intent(inout) :: tracer_vars - ! Cathy [dev.01] logical, intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used this%info => info @@ -142,7 +140,6 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar1d(var = this%q_ref2m_patch, name = 'q_ref2m_patch', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_patch) - ! Cathy [dev.01] call AllocateVar1d(var = this%q_building_lun, name = 'q_building_lun', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_landunit) @@ -161,20 +158,17 @@ subroutine InitHistory(this, bounds, is_prog_buildtemp) ! !ARGUMENTS: class(waterdiagnostic_type), intent(in) :: this type(bounds_type), intent(in) :: bounds - ! Cathy [dev.01] logical, intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: integer :: begp, endp integer :: begc, endc - ! Cathy [dev.04] integer :: begl, endl integer :: begg, endg !------------------------------------------------------------------------ begp = bounds%begp; endp= bounds%endp begc = bounds%begc; endc= bounds%endc - ! Cathy [dev.01] begl = bounds%begl; endl= bounds%endl begg = bounds%begg; endg= bounds%endg @@ -256,7 +250,6 @@ subroutine InitHistory(this, bounds, is_prog_buildtemp) ptr_col=this%snowice_col, c2l_scale_type='urbanf', l2g_scale_type='ice', & default='inactive') - ! Cathy [dev.01] if ( is_prog_buildtemp ) then this%q_building_lun(begl:endl) = spval call hist_addfld1d ( & @@ -281,7 +274,6 @@ subroutine InitCold(this, bounds, is_prog_buildtemp) ! !ARGUMENTS: class(waterdiagnostic_type), intent(in) :: this type(bounds_type) , intent(in) :: bounds - ! Cathy [dev.01] logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: @@ -312,7 +304,6 @@ subroutine InitCold(this, bounds, is_prog_buildtemp) end if end do - ! Cathy [dev.01] ! Initialize internal building specific humidity (following example above and t_building_max in TemperatureType.F90) if ( is_prog_buildtemp ) then do l = bounds%begl, bounds%endl @@ -333,9 +324,8 @@ subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) ! !USES: use clm_varcon , only : nameg, namec use ncdio_pio , only : file_desc_t, ncd_double - use clm_varctl , only : use_fates_planthydro, iulog ! Cathy [dev.04] + use clm_varctl , only : use_fates_planthydro, iulog use restUtilMod - ! Cathy [dev.04] use spmdMod , only : masterproc ! ! !ARGUMENTS: @@ -343,7 +333,6 @@ subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) type(bounds_type), intent(in) :: bounds type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' - ! Cathy [dev.01] logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: @@ -380,7 +369,6 @@ subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) interpinic_flag='interp', readvar=readvar, data=this%total_plant_stored_h2o_col) end if - ! Cathy [dev.01] if ( is_prog_buildtemp ) then ! landunit type physical state variable - q_building call restartvar(ncid=ncid, flag=flag, & diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 2e115311ab..7a1fe6d36b 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -51,9 +51,7 @@ module WaterFluxType real(r8), pointer :: qflx_evap_tot_col (:) ! col col_qflx_evap_soi + col_qflx_evap_veg + qflx_tran_veg real(r8), pointer :: qflx_liqevap_from_top_layer_patch(:) ! patch rate of liquid water evaporated from top soil or snow layer (mm H2O/s) [+] real(r8), pointer :: qflx_liqevap_from_top_layer_col(:) ! col rate of liquid water evaporated from top soil or snow layer (mm H2O/s) [+] - ! Cathy [dev.15] real(r8), pointer :: qflx_condensate_from_ac_col(:) ! col condensate due to dehumidification from air-conditioning (mm H2O/S) [+] - ! Cathy [dev.18.02] real(r8), pointer :: qflx_condensate_from_ac_lun(:) ! lun condensate due to dehumidification from air-conditioning (mm H2O/S) [+] ! In the snow capping parametrization excess mass above h2osno_max is removed. A breakdown of mass into liquid @@ -274,11 +272,9 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar1d(var = this%qflx_liqevap_from_top_layer_patch, name = 'qflx_liqevap_from_top_layer_patch', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_patch) - ! Cathy [dev.15] [dev.16.1] call AllocateVar1d(var = this%qflx_condensate_from_ac_col, name = 'qflx_condensate_from_ac_col', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, ival = 0.0_r8) - ! Cathy [dev.18.02] call AllocateVar1d(var = this%qflx_condensate_from_ac_lun, name = 'qflx_condensate_from_ac_lun', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_landunit, ival = 0.0_r8) @@ -601,7 +597,6 @@ subroutine InitHistory(this, bounds) long_name=this%info%lname('Rural total runoff'), & ptr_col=this%qflx_runoff_r_col, set_spec=spval, default='inactive') - ! Cathy [dev.17]: add condensate from AC to output if (ac_dehumid) then this%qflx_condensate_from_ac_col(begc:endc) = 0.0_r8 call hist_addfld1d ( & diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index 8cf2177d5b..74ff319230 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -78,7 +78,6 @@ module WaterType use Wateratm2lndBulkType , only : wateratm2lndbulk_type use WaterTracerContainerType , only : water_tracer_container_type use WaterTracerUtils , only : CompareBulkToTracer, SetTracerToBulkTimesRatio - ! Cathy [dev.01] use UrbanParamsType , only : IsProgBuildTemp, ac_dehumid implicit none @@ -388,7 +387,7 @@ subroutine DoInit(this, bounds, & call this%bulk_and_tracers(i)%waterdiagnostic_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & this%bulk_and_tracers(i)%vars, & - IsProgBuildTemp() .and. ac_dehumid) ! Cathy [dev.01] + IsProgBuildTemp() .and. ac_dehumid) call this%bulk_and_tracers(i)%waterbalance_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & @@ -727,7 +726,7 @@ end subroutine UpdateAccVars !----------------------------------------------------------------------- subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & - watsat_col, t_soisno_col, altmax_lastyear_indx, is_prog_buildtemp) ! Cathy [dev.04] + watsat_col, t_soisno_col, altmax_lastyear_indx, is_prog_buildtemp) ! ! !DESCRIPTION: ! Read/write information to/from restart file for all water variables @@ -741,7 +740,6 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year - ! Cathy [dev.04] logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used ! ! !LOCAL VARIABLES: @@ -773,7 +771,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) call this%bulk_and_tracers(i)%waterdiagnostic_inst%Restart(bounds, ncid, flag=flag, & - is_prog_buildtemp=IsProgBuildTemp() .and. ac_dehumid) ! Cathy [dev.04] + is_prog_buildtemp=IsProgBuildTemp() .and. ac_dehumid) end do diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index b6697e8c43..57e2ce2efc 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -547,7 +547,6 @@ subroutine clm_instRest(bounds, ncid, flag, writing_finidat_interp_dest_file) watsat_col = soilstate_inst%watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=temperature_inst%t_soisno_col(bounds%begc:bounds%endc, -nlevsno+1:), & altmax_lastyear_indx=active_layer_inst%altmax_lastyear_indx_col(bounds%begc:bounds%endc), & - ! Cathy [dev.04] is_prog_buildtemp = IsProgBuildTemp()) call irrigation_inst%restart (bounds, ncid, flag=flag) @@ -612,4 +611,3 @@ subroutine clm_instRest(bounds, ncid, flag, writing_finidat_interp_dest_file) end subroutine clm_instRest end module clm_instMod - diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index 2e07a5db26..a1c779a55d 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -14,7 +14,6 @@ module clm_varcon SHR_CONST_PDB, SHR_CONST_PI, SHR_CONST_CDAY, & SHR_CONST_RGAS, SHR_CONST_PSTD, & SHR_CONST_MWDAIR, SHR_CONST_MWWV, SHR_CONST_CPFW, & - ! Cathy [dev.11] SHR_CONST_CPWV use clm_varpar , only: numrad, nlevgrnd, nlevlak, nlevdecomp_full use clm_varpar , only: ngases @@ -58,7 +57,6 @@ module clm_varcon real(r8), public :: cpliq = SHR_CONST_CPFW ! Specific heat of water [J/kg-K] real(r8), public :: cpice = SHR_CONST_CPICE ! Specific heat of ice [J/kg-K] real(r8), public :: cpair = SHR_CONST_CPDAIR ! specific heat of dry air [J/kg/K] - ! Cathy [dev.11] real(r8), public :: cpwvap = SHR_CONST_CPWV ! specific heat of water vapor [J/kg/K] real(r8), public :: hvap = SHR_CONST_LATVAP ! Latent heat of evap for water [J/kg] real(r8), public :: hsub = SHR_CONST_LATSUB ! Latent heat of sublimation [J/kg] @@ -191,9 +189,7 @@ module clm_varcon real(r8), public, parameter :: sh_floor = 880._r8 ! specific heat of floor - concrete (Salmanca et al. 2010, TAC) (J kg-1 K-1) real(r8), public :: cp_floor = dens_floor*sh_floor ! volumetric heat capacity of floor - concrete (Salmanca et al. 2010, TAC) (J m-3 K-1) real(r8), public :: vent_ach = 0.3_r8 ! ventilation rate (air exchanges per hour) - ! Cathy [dev.02] ! real(r8), public :: q_building_max = 0.013_r8 ! maximum internal building air specific humidity (kg/kg) - ! Cathy [dev.06] real(r8), public :: rh_building_max = 65._r8 ! maximum internal building air relative humidity (%) real(r8), public :: wasteheat_limit = 100._r8 ! limit on wasteheat (W/m2) From 3f870b04932ae395bc21d1ee68bde5e259377831 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Fri, 7 Aug 2026 18:08:24 -0600 Subject: [PATCH 54/89] Replace ac_dehumid with building humidity modes --- bld/CLMBuildNamelist.pm | 18 +++--- bld/namelist_files/namelist_defaults_ctsm.xml | 4 +- .../namelist_definition_ctsm.xml | 12 ++-- src/biogeophys/BalanceCheckMod.F90 | 12 ++-- src/biogeophys/EnergyFluxType.F90 | 4 +- src/biogeophys/SoilHydrologyMod.F90 | 4 +- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 33 ++++++----- src/biogeophys/UrbanParamsType.F90 | 59 +++++++++++++++---- src/biogeophys/WaterDiagnosticBulkType.F90 | 8 +-- src/biogeophys/WaterFluxType.F90 | 4 +- src/biogeophys/WaterType.F90 | 6 +- 11 files changed, 106 insertions(+), 58 deletions(-) diff --git a/bld/CLMBuildNamelist.pm b/bld/CLMBuildNamelist.pm index 4996a4f708..ceceb21ae4 100755 --- a/bld/CLMBuildNamelist.pm +++ b/bld/CLMBuildNamelist.pm @@ -2249,20 +2249,24 @@ sub setup_logic_urban { add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'building_temp_method'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_hac'); - add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'ac_dehumid'); + add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'building_humidity_mode'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_explicit_ac'); add_default($opts, $nl_flags->{'inputdata_rootdir'}, $definition, $defaults, $nl, 'urban_traffic'); - if (value_is_true($nl->get_value('ac_dehumid'))) { + my $building_humidity_mode = $nl->get_value('building_humidity_mode'); + if ($building_humidity_mode < 0 || $building_humidity_mode > 2) { + $log->fatal_error("building_humidity_mode must be 0, 1, or 2"); + } + if ($building_humidity_mode >= 1 && $nl->get_value('building_temp_method') != 1) { + $log->fatal_error("building_humidity_mode=1 or 2 requires building_temp_method=1"); + } + if ($building_humidity_mode == 2) { my $urban_hac = remove_leading_and_trailing_quotes($nl->get_value('urban_hac')); if ($urban_hac ne 'ON' && $urban_hac ne 'ON_WASTEHEAT') { - $log->fatal_error("ac_dehumid requires urban_hac to be ON or ON_WASTEHEAT"); + $log->fatal_error("building_humidity_mode=2 requires urban_hac to be ON or ON_WASTEHEAT"); } if (! value_is_true($nl->get_value('urban_explicit_ac'))) { - $log->fatal_error("ac_dehumid requires urban_explicit_ac=.true."); - } - if ($nl->get_value('building_temp_method') != 1) { - $log->fatal_error("ac_dehumid requires building_temp_method=1"); + $log->fatal_error("building_humidity_mode=2 requires urban_explicit_ac=.true."); } } } diff --git a/bld/namelist_files/namelist_defaults_ctsm.xml b/bld/namelist_files/namelist_defaults_ctsm.xml index af199e37c1..708076bda4 100644 --- a/bld/namelist_files/namelist_defaults_ctsm.xml +++ b/bld/namelist_files/namelist_defaults_ctsm.xml @@ -146,8 +146,8 @@ attributes from the config_cache.xml file (with keys converted to upper-case). FAST NONE - -.false. + +0 .true. diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index d4459d32ca..1ce054e481 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1075,10 +1075,14 @@ Turn urban air conditioning/heating ON or OFF and add wasteheat: If TRUE, use explicit, time-varying AC adoption rate for air-conditioning flux and interior building temperature calculations. - -If TRUE, simulate indoor humidity, air-conditioning latent cooling, and condensate runoff. -Requires urban_hac to be ON or ON_WASTEHEAT, urban_explicit_ac to be TRUE, and the prognostic building-temperature method. + +Select treatment of indoor building humidity: + 0 = Existing CLMU formulation without indoor humidity or air-conditioning dehumidification + 1 = Indoor humidity and latent heat exchange without air-conditioning dehumidification + 2 = Indoor humidity and latent heat exchange with air-conditioning dehumidification and condensate production +Modes 1 and 2 require the prognostic building-temperature method. Mode 2 also requires urban_hac to be ON or +ON_WASTEHEAT and urban_explicit_ac to be TRUE. q_building_max) then ! Humidification during urban heating is not implemented. eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & @@ -1026,7 +1027,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_ac(l) = wtlunit_roof(l) * abs( & (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) - if (ac_dehumid) then + if (IsACDehumidificationEnabled()) then eflx_urban_ac_sen(l) = eflx_urban_ac(l) end if end if @@ -1036,22 +1037,24 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) else - if (ac_dehumid) eflx_urban_ac_sen(l) = 0._r8 + if (IsACDehumidificationEnabled()) eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if else - if (ac_dehumid) eflx_urban_ac_sen(l) = 0._r8 + if (IsACDehumidificationEnabled()) eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 eflx_urban_heat(l) = 0._r8 end if - if (ac_dehumid) then + if (IsBuildingHumidityEnabled()) then eflx_building(l) = wtlunit_roof(l) * ( & (ht_roof(l) * rho_dair(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) ) - qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) - qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime + if (IsACDehumidificationEnabled()) then + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) + qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime + end if call QSat(t_building(l), forc_pbot(g), qsat_building) rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) else @@ -1061,7 +1064,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do - if (ac_dehumid) then + if (IsACDehumidificationEnabled()) then do fl = 1,num_urbanl l = filter_urbanl(fl) if (urbpoi(l)) then diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90 index ddb8d3d96c..bd20cfefd4 100644 --- a/src/biogeophys/UrbanParamsType.F90 +++ b/src/biogeophys/UrbanParamsType.F90 @@ -23,6 +23,8 @@ module UrbanParamsType public :: CheckUrban ! Check validity of urban points public :: IsSimpleBuildTemp ! If using the simple building temperature method public :: IsProgBuildTemp ! If using the prognostic building temperature method + public :: IsBuildingHumidityEnabled ! If indoor building humidity is simulated + public :: IsACDehumidificationEnabled ! If AC dehumidification is simulated ! ! !PRIVATE TYPE type urbinp_type @@ -101,7 +103,10 @@ module UrbanParamsType character(len= *), parameter, public :: urban_hac_on = 'ON' character(len= *), parameter, public :: urban_wasteheat_on = 'ON_WASTEHEAT' character(len= 16), public :: urban_hac = urban_hac_off - logical, public :: ac_dehumid = .false. ! whether to simulate AC dehumidification + integer, parameter, public :: BUILDING_HUMIDITY_MODE_OFF = 0 + integer, parameter, public :: BUILDING_HUMIDITY_MODE_ON = 1 + integer, parameter, public :: BUILDING_HUMIDITY_MODE_DEHUMIDIFY = 2 + integer, public :: building_humidity_mode = BUILDING_HUMIDITY_MODE_OFF logical, public :: urban_explicit_ac = .true. ! whether to use explicit, time-varying AC adoption rate logical, public :: urban_traffic = .false. ! urban traffic fluxes @@ -849,7 +854,7 @@ subroutine UrbanReadNML ( NLFilename ) integer :: unitn ! unit for namelist file character(len=32) :: subname = 'UrbanReadNML' ! subroutine name - namelist / clmu_inparm / urban_hac, ac_dehumid, urban_explicit_ac, urban_traffic, building_temp_method + namelist / clmu_inparm / urban_hac, building_humidity_mode, urban_explicit_ac, urban_traffic, building_temp_method !EOP !----------------------------------------------------------------------- @@ -877,7 +882,7 @@ subroutine UrbanReadNML ( NLFilename ) ! Broadcast namelist variables read in call shr_mpi_bcast(urban_hac, mpicom) - call shr_mpi_bcast(ac_dehumid, mpicom) + call shr_mpi_bcast(building_humidity_mode, mpicom) call shr_mpi_bcast(urban_explicit_ac, mpicom) call shr_mpi_bcast(urban_traffic, mpicom) call shr_mpi_bcast(building_temp_method, mpicom) @@ -887,21 +892,28 @@ subroutine UrbanReadNML ( NLFilename ) write(iulog,*)'Urban traffic fluxes are not implemented currently' call endrun(msg=errMsg(sourcefile, __LINE__)) end if - if (ac_dehumid) then + if (building_humidity_mode < BUILDING_HUMIDITY_MODE_OFF .or. & + building_humidity_mode > BUILDING_HUMIDITY_MODE_DEHUMIDIFY) then + call endrun(msg='building_humidity_mode must be 0, 1, or 2'//errmsg(sourcefile, __LINE__)) + end if + if (building_humidity_mode >= BUILDING_HUMIDITY_MODE_ON .and. & + building_temp_method /= BUILDING_TEMP_METHOD_PROG) then + call endrun(msg='building_humidity_mode=1 or 2 requires the prognostic building temperature method'// & + errmsg(sourcefile, __LINE__)) + end if + if (building_humidity_mode == BUILDING_HUMIDITY_MODE_DEHUMIDIFY) then if (trim(urban_hac) /= urban_hac_on .and. trim(urban_hac) /= urban_wasteheat_on) then - call endrun(msg='ac_dehumid requires urban_hac to be ON or ON_WASTEHEAT'//errmsg(sourcefile, __LINE__)) + call endrun(msg='building_humidity_mode=2 requires urban_hac to be ON or ON_WASTEHEAT'// & + errmsg(sourcefile, __LINE__)) end if if (.not. urban_explicit_ac) then - call endrun(msg='ac_dehumid requires urban_explicit_ac=.true.'//errmsg(sourcefile, __LINE__)) - end if - if (building_temp_method /= BUILDING_TEMP_METHOD_PROG) then - call endrun(msg='ac_dehumid requires the prognostic building temperature method'//errmsg(sourcefile, __LINE__)) + call endrun(msg='building_humidity_mode=2 requires urban_explicit_ac=.true.'//errmsg(sourcefile, __LINE__)) end if end if ! if ( masterproc )then write(iulog,*) ' urban air conditioning/heating and wasteheat = ', urban_hac - write(iulog,*) ' urban air-conditioning dehumidification = ', ac_dehumid + write(iulog,*) ' urban building humidity mode = ', building_humidity_mode write(iulog,*) ' urban explicit air-conditioning adoption rate = ', urban_explicit_ac write(iulog,*) ' urban traffic flux = ', urban_traffic end if @@ -968,7 +980,32 @@ end function IsProgBuildTemp !----------------------------------------------------------------------- -end module UrbanParamsType + logical function IsBuildingHumidityEnabled( ) + implicit none + + if ( .not. ReadNamelist )then + write(iulog,*)'Testing on building_humidity_mode before urban namelist was read in' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + IsBuildingHumidityEnabled = building_humidity_mode >= BUILDING_HUMIDITY_MODE_ON + + end function IsBuildingHumidityEnabled + + !----------------------------------------------------------------------- + + logical function IsACDehumidificationEnabled( ) + implicit none + if ( .not. ReadNamelist )then + write(iulog,*)'Testing on building_humidity_mode before urban namelist was read in' + call endrun(msg=errMsg(sourcefile, __LINE__)) + end if + IsACDehumidificationEnabled = building_humidity_mode == BUILDING_HUMIDITY_MODE_DEHUMIDIFY + + end function IsACDehumidificationEnabled + + !----------------------------------------------------------------------- + +end module UrbanParamsType diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index dd7f868658..5a3a9c7b06 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -28,7 +28,7 @@ module WaterDiagnosticBulkType use WaterStateType, only : waterstate_type use WaterStateBulkType, only : waterstatebulk_type use WaterFluxType, only : waterflux_type - use UrbanParamsType, only : IsProgBuildTemp, ac_dehumid + use UrbanParamsType, only : IsBuildingHumidityEnabled ! implicit none save @@ -156,7 +156,7 @@ subroutine InitBulk(this, bounds, info, vars, & real(r8) , intent(in) :: h2osno_input_col(bounds%begc:) ! Initial total snow water (mm H2O) - call this%Init(bounds, info, vars, IsProgBuildTemp() .and. ac_dehumid) + call this%Init(bounds, info, vars, IsBuildingHumidityEnabled()) call this%InitBulkAllocate(bounds) @@ -360,7 +360,7 @@ subroutine InitBulkHistory(this, bounds) long_name=this%info%lname('Urban 2m relative humidity'), & ptr_patch=this%rh_ref2m_u_patch, set_nourb=spval, default='inactive') - if (ac_dehumid) then + if (IsBuildingHumidityEnabled()) then this%rh_building_lun(begl:endl) = spval call hist_addfld1d ( & fname=this%info%fname('RHBUILD'), & @@ -826,7 +826,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil !------------------------------------------------------------------------ - call this%Restart(bounds, ncid, flag=flag, is_prog_buildtemp=IsProgBuildTemp() .and. ac_dehumid) + call this%Restart(bounds, ncid, flag=flag, is_prog_buildtemp=IsBuildingHumidityEnabled()) if(use_luna)then call restartvar(ncid=ncid, flag=flag, & diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 7a1fe6d36b..95d1784828 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -17,7 +17,7 @@ module WaterFluxType use WaterInfoBaseType, only : water_info_base_type use WaterTracerContainerType, only : water_tracer_container_type use WaterTracerUtils, only : AllocateVar1d, AllocateVar2d - use UrbanParamsType, only : ac_dehumid + use UrbanParamsType, only : IsACDehumidificationEnabled ! implicit none private @@ -597,7 +597,7 @@ subroutine InitHistory(this, bounds) long_name=this%info%lname('Rural total runoff'), & ptr_col=this%qflx_runoff_r_col, set_spec=spval, default='inactive') - if (ac_dehumid) then + if (IsACDehumidificationEnabled()) then this%qflx_condensate_from_ac_col(begc:endc) = 0.0_r8 call hist_addfld1d ( & fname=this%info%fname('QCOND_FROM_AC'), & diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index 74ff319230..4462f55356 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -78,7 +78,7 @@ module WaterType use Wateratm2lndBulkType , only : wateratm2lndbulk_type use WaterTracerContainerType , only : water_tracer_container_type use WaterTracerUtils , only : CompareBulkToTracer, SetTracerToBulkTimesRatio - use UrbanParamsType , only : IsProgBuildTemp, ac_dehumid + use UrbanParamsType , only : IsBuildingHumidityEnabled implicit none private @@ -387,7 +387,7 @@ subroutine DoInit(this, bounds, & call this%bulk_and_tracers(i)%waterdiagnostic_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & this%bulk_and_tracers(i)%vars, & - IsProgBuildTemp() .and. ac_dehumid) + IsBuildingHumidityEnabled()) call this%bulk_and_tracers(i)%waterbalance_inst%Init(bounds, & this%bulk_and_tracers(i)%info, & @@ -771,7 +771,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) call this%bulk_and_tracers(i)%waterdiagnostic_inst%Restart(bounds, ncid, flag=flag, & - is_prog_buildtemp=IsProgBuildTemp() .and. ac_dehumid) + is_prog_buildtemp=IsBuildingHumidityEnabled()) end do From 02ef8b4562185388cadcee0a8ca05801dcea0e3d Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Tue, 11 Aug 2026 16:02:30 -0600 Subject: [PATCH 55/89] Improve readability Remove/modify comments, update subroutine argument and local var names for improved readability --- src/biogeophys/BalanceCheckMod.F90 | 2 - src/biogeophys/SoilHydrologyMod.F90 | 2 +- src/biogeophys/SoilTemperatureMod.F90 | 2 - src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 70 ++++++++++---------- src/biogeophys/UrbanParamsType.F90 | 33 ++++++++- src/biogeophys/WaterDiagnosticBulkType.F90 | 2 +- src/biogeophys/WaterDiagnosticType.F90 | 26 ++++---- src/biogeophys/WaterType.F90 | 6 +- src/main/clm_instMod.F90 | 4 +- 9 files changed, 86 insertions(+), 61 deletions(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index f42b66325e..9e8ff28862 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -511,8 +511,6 @@ subroutine BalanceCheck( bounds, & real(r8), parameter :: h2o_warning_thresh = 1.e-9_r8 ! Warning threshhold for error in errh2o and errh2osnow real(r8), parameter :: energy_warning_thresh = 1.e-7_r8 ! Warning threshhold for error in errsol, errsol, errseb, errlonv real(r8), parameter :: error_thresh = 1.e-5_r8 ! Error threshhold for conservation error - ! real(r8) :: tot_cond_from_col ! total condensate from AC mass flow rate calculated from column-level var [kg/s] - ! real(r8) :: tot_cond_from_grc ! total condensate from AC mass flow rate calculated from grid-cell-level var [kg/s] !----------------------------------------------------------------------- diff --git a/src/biogeophys/SoilHydrologyMod.F90 b/src/biogeophys/SoilHydrologyMod.F90 index d98f16fa93..5094ef2853 100644 --- a/src/biogeophys/SoilHydrologyMod.F90 +++ b/src/biogeophys/SoilHydrologyMod.F90 @@ -598,7 +598,7 @@ subroutine TotalSurfaceRunoff(bounds, num_hydrologyc, filter_hydrologyc, & pondmx_urban/dtime) qflx_surf(c) = xs_urban(c) end if - ! Send flood water flux to runoff for all urban columns. + ! Send flood water flux and air-conditioning condensate to runoff for all urban columns. if (IsACDehumidificationEnabled()) then qflx_surf(c) = qflx_surf(c) + qflx_floodc(c) + qflx_condensate_from_ac(c) else diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 6a3fc301a7..25eecc7952 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -20,7 +20,6 @@ module SoilTemperatureMod use WaterFluxBulkType , only : waterfluxbulk_type use WaterStateBulkType , only : waterstatebulk_type use WaterDiagnosticBulkType , only : waterdiagnosticbulk_type - ! use WaterDiagnosticType , only : waterdiagnostic_type use SolarAbsorbedType , only : solarabs_type use SoilStateType , only : soilstate_type use EnergyFluxType , only : energyflux_type @@ -145,7 +144,6 @@ subroutine SoilTemperature(bounds, num_urbanl, filter_urbanl, num_urbanc, filter type(solarabs_type) , intent(inout) :: solarabs_inst type(energyflux_type) , intent(inout) :: energyflux_inst type(temperature_type) , intent(inout) :: temperature_inst - ! type(waterdiagnostic_type) , intent(inout) :: waterdiagnostic_inst ! water diagnostic variables ! ! !LOCAL VARIABLES: integer :: j,c,l,g ! indices diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 7576714cd8..4a52243615 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -58,11 +58,11 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! qrd_sunw + qcd_sunw + qcv_sunw = 0 ! qrd_shdw + qcd_shdw + qcv_shdw = 0 ! qrd_floor + qcd_floor + qcv_floor = 0 -! Vbld*rho_dair*cpair*(dt_building/dt) = sum(Asfc*hcv_sfc*(t_sfc - t_building) -! + Vvent*rho_dair*cpair*(taf - t_building) +! Vbld*rho_air*cp_hair*(dt_building/dt) = sum(Asfc*hcv_sfc*(t_sfc - t_building) +! + Vvent*rho_air*cp_hair*(taf - t_building) ! where Vlbd is volume of building air, -! rho_dair is density of dry air at t_building (kg m-3), -! cpair is specific heat of dry air (J kg-1 K-1), +! rho_air is density of air at t_building (kg m-3), +! cp_hair is specific heat of air (J kg-1 K-1), ! dt_building is change in interior building temperature (K), ! dt is timestep (s), ! Asfc is surface area of roof, sunw, shdw, floor (m2) @@ -211,7 +211,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, hcv_floor, hcv_floor_enhanced, hcv_sunw, hcv_shdw, & em_roof_int, em_floor_int, em_sunw_int, em_shdw_int, & dz_floor, dens_floor, cp_floor, vent_ach, & - ! q_building_max, hvap rh_building_max, hvap, rwat, cpwvap use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall, icol_road_imperv use clm_varctl , only : iulog @@ -242,7 +241,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! ! !LOCAL VARIABLES: integer, parameter :: neq = 5 ! number of equation/unknowns - ! integer :: fc,fl,c,l ! indices integer :: fc,fl,c,l,g ! indices real(r8) :: dtime ! land model time step (s) real(r8) :: building_hwr(bounds%begl:bounds%endl) ! building height to building width ratio (-) @@ -254,8 +252,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: t_building_bef_hac(bounds%begl:bounds%endl)! internal building air temperature before applying HAC [K] real(r8) :: q_building_bef(bounds%begl:bounds%endl) ! internal building air specific humidity at previous time step (kg/kg) real(r8) :: q_building_bef_hac(bounds%begl:bounds%endl)! internal building air specific humidity before applying HAC (kg/kg) - real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) - real(r8) :: eflx_urban_ac_sat_lat(bounds%begl:bounds%endl) ! urban air conditioning latent heat flux under AC adoption saturation (W/m**2) + real(r8) :: eflx_urban_ac_sat(bounds%begl:bounds%endl) ! urban air conditioning flux under AC adoption saturation (W/m**2) + real(r8) :: eflx_urban_ac_sat_lat(bounds%begl:bounds%endl) ! latent heat component of urban air conditioning flux under AC adoption saturation (W/m**2) real(r8) :: hcv_roofi(bounds%begl:bounds%endl) ! roof convective heat transfer coefficient (W m-2 K-1) real(r8) :: hcv_sunwi(bounds%begl:bounds%endl) ! sunwall convective heat transfer coefficient (W m-2 K-1) real(r8) :: hcv_shdwi(bounds%begl:bounds%endl) ! shadewall convective heat transfer coefficient (W m-2 K-1) @@ -267,7 +265,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: dz_floori(bounds%begl:bounds%endl) ! concrete floor thickness (m) real(r8) :: cp_floori(bounds%begl:bounds%endl) ! concrete floor volumetric heat capacity (J m-3 K-1) real(r8) :: cv_floori(bounds%begl:bounds%endl) ! intermediate calculation for concrete floor (W m-2 K-1) - real(r8) :: rho_dair(bounds%begl:bounds%endl) ! density of dry air at standard pressure and t_building (kg m-3) + real(r8) :: rho_air(bounds%begl:bounds%endl) ! density of indoor air at outdoor pressure and t_building (kg m-3) real(r8) :: cp_hair(bounds%begl:bounds%endl) ! specific heat capacity of indoor humid air (J kg-1 K-1) real(r8) :: vf_rf(bounds%begl:bounds%endl) ! view factor of roof for floor (-) real(r8) :: vf_fr(bounds%begl:bounds%endl) ! view factor of floor for roof (-) @@ -422,11 +420,11 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, if (IsBuildingHumidityEnabled()) then call QSat(t_building_bef(l), forc_pbot(g), qsat_building, es = esat_building) p_vapor = min(1._r8, q_building_bef(l) / qsat_building) * esat_building - rho_dair(l) = (forc_pbot(g) - p_vapor) / (rair * t_building_bef(l)) & + rho_air(l) = (forc_pbot(g) - p_vapor) / (rair * t_building_bef(l)) & + p_vapor / (rwat * t_building_bef(l)) cp_hair(l) = cpair + cpwvap * q_building_bef(l) else - rho_dair(l) = pstd / (rair*t_building_bef(l)) + rho_air(l) = pstd / (rair*t_building_bef(l)) cp_hair(l) = cpair end if ! Building height to building width ratio @@ -692,15 +690,15 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, a(5,4) = - 0.5_r8*hcv_floori(l) - a(5,5) = ((ht_roof(l)*rho_dair(l)*cp_hair(l))/dtime) + & - ((ht_roof(l)*vent_ach)/3600._r8)*rho_dair(l)*cp_hair(l) + & + a(5,5) = ((ht_roof(l)*rho_air(l)*cp_hair(l))/dtime) + & + ((ht_roof(l)*vent_ach)/3600._r8)*rho_air(l)*cp_hair(l) + & 0.5_r8*hcv_roofi(l) + & 0.5_r8*hcv_sunwi(l)*building_hwr(l) + & 0.5_r8*hcv_shdwi(l)*building_hwr(l) + & 0.5_r8*hcv_floori(l) - result(5) = (ht_roof(l)*rho_dair(l)*cp_hair(l)/dtime)*t_building_bef(l) & - + ((ht_roof(l)*vent_ach)/3600._r8)*rho_dair(l)*cp_hair(l)*taf(l) & + result(5) = (ht_roof(l)*rho_air(l)*cp_hair(l)/dtime)*t_building_bef(l) & + + ((ht_roof(l)*vent_ach)/3600._r8)*rho_air(l)*cp_hair(l)*taf(l) & + 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & + 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & + 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & @@ -948,8 +946,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if - enrgy_bal_buildair(l) = (ht_roof(l)*rho_dair(l)*cp_hair(l)/dtime)*(t_building(l) - t_building_bef(l)) & - - ht_roof(l)*(vent_ach/3600._r8)*rho_dair(l)*cp_hair(l)*(taf(l) - t_building(l)) & + enrgy_bal_buildair(l) = (ht_roof(l)*rho_air(l)*cp_hair(l)/dtime)*(t_building(l) - t_building_bef(l)) & + - ht_roof(l)*(vent_ach/3600._r8)*rho_air(l)*cp_hair(l)*(taf(l) - t_building(l)) & - 0.5_r8*hcv_roofi(l)*(t_roof_inner(l) - t_building(l)) & - 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner(l) - t_building(l))*building_hwr(l) & @@ -971,11 +969,11 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! of the urban landunit. if (IsBuildingHumidityEnabled()) then eflx_ventilation(l) = wtlunit_roof(l) * ( & - - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * cp_hair(l) * (taf(l) - t_building(l)) & - - ht_roof(l) * (vent_ach/3600._r8) * rho_dair(l) * hvap * (qaf(l) - q_building(l)) ) + - ht_roof(l) * (vent_ach/3600._r8) * rho_air(l) * cp_hair(l) * (taf(l) - t_building(l)) & + - ht_roof(l) * (vent_ach/3600._r8) * rho_air(l) * hvap * (qaf(l) - q_building(l)) ) else eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & - * rho_dair(l) * cpair * (taf(l) - t_building(l)) ) + * rho_air(l) * cpair * (taf(l) - t_building(l)) ) end if end if end do @@ -1000,33 +998,34 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, if (t_building_bef_hac(l) > t_building_max(l)) then if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: - ! Sensible heat + ! Sensible heat component of AC ! Here, t_building_max is the AC saturation setpoint - eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_max(l) & - - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_max(l) & + - (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) & - * dtime / (ht_roof(l) * rho_dair(l) * cp_hair(l) * wtlunit_roof(l)) + * dtime / (ht_roof(l) * rho_air(l) * cp_hair(l) * wtlunit_roof(l)) if (IsACDehumidificationEnabled()) then eflx_urban_ac_sen(l) = p_ac(l) * eflx_urban_ac_sat(l) end if + ! Latent heat component of AC if (IsACDehumidificationEnabled()) then if (q_building_bef_hac(l) > q_building_max) then ! Humidification during urban heating is not implemented. eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_max & - - (ht_roof(l) * rho_dair(l) * hvap / dtime) * q_building_bef_hac(l) ) + (ht_roof(l) * rho_air(l) * hvap / dtime) * q_building_max & + - (ht_roof(l) * rho_air(l) * hvap / dtime) * q_building_bef_hac(l) ) eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) q_building(l) = q_building_max + (1._r8 - p_ac(l)) * eflx_urban_ac_sat_lat(l) & - * dtime / (ht_roof(l) * rho_dair(l) * hvap * wtlunit_roof(l)) + * dtime / (ht_roof(l) * rho_air(l) * hvap * wtlunit_roof(l)) end if end if eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) else t_building(l) = t_building_max(l) eflx_urban_ac(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + (ht_roof(l) * rho_hair(l) * cp_hair(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) if (IsACDehumidificationEnabled()) then eflx_urban_ac_sen(l) = eflx_urban_ac(l) end if @@ -1034,8 +1033,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, else if (t_building_bef_hac(l) < t_building_min(l)) then t_building(l) = t_building_min(l) - eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building(l) & - - (ht_roof(l) * rho_dair(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) else if (IsACDehumidificationEnabled()) eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 @@ -1049,21 +1048,22 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if if (IsBuildingHumidityEnabled()) then eflx_building(l) = wtlunit_roof(l) * ( & - (ht_roof(l) * rho_dair(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & - + (ht_roof(l) * rho_dair(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) ) + (ht_roof(l) * rho_air(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & + + (ht_roof(l) * rho_air(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) ) if (IsACDehumidificationEnabled()) then - qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_dair(l) + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_air(l) qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime end if call QSat(t_building(l), forc_pbot(g), qsat_building) rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) else - eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_dair(l)*cpair/dtime) & + eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_air(l)*cpair/dtime) & * (t_building(l) - t_building_bef(l)) end if end if end do + ! AC dehumidification consistency check if (IsACDehumidificationEnabled()) then do fl = 1,num_urbanl l = filter_urbanl(fl) diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90 index bd20cfefd4..e5fe4b330b 100644 --- a/src/biogeophys/UrbanParamsType.F90 +++ b/src/biogeophys/UrbanParamsType.F90 @@ -913,7 +913,7 @@ subroutine UrbanReadNML ( NLFilename ) ! if ( masterproc )then write(iulog,*) ' urban air conditioning/heating and wasteheat = ', urban_hac - write(iulog,*) ' urban building humidity mode = ', building_humidity_mode + write(iulog,*) ' urban building humidity mode = ', building_humidity_mode write(iulog,*) ' urban explicit air-conditioning adoption rate = ', urban_explicit_ac write(iulog,*) ' urban traffic flux = ', urban_traffic end if @@ -980,8 +980,23 @@ end function IsProgBuildTemp !----------------------------------------------------------------------- + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: IsBuildingHumidityEnabled + ! + ! !INTERFACE: + ! logical function IsBuildingHumidityEnabled( ) + ! + ! !DESCRIPTION: + ! + ! If indoor building humidity is being simulated + ! + ! !USES: implicit none + !EOP + !----------------------------------------------------------------------- if ( .not. ReadNamelist )then write(iulog,*)'Testing on building_humidity_mode before urban namelist was read in' @@ -993,8 +1008,23 @@ end function IsBuildingHumidityEnabled !----------------------------------------------------------------------- + !----------------------------------------------------------------------- + !BOP + ! + ! !IROUTINE: IsACDehumidificationEnabled + ! + ! !INTERFACE: + ! logical function IsACDehumidificationEnabled( ) + ! + ! !DESCRIPTION: + ! + ! If air-conditioning dehumidification is enabled + ! + ! !USES: implicit none + !EOP + !----------------------------------------------------------------------- if ( .not. ReadNamelist )then write(iulog,*)'Testing on building_humidity_mode before urban namelist was read in' @@ -1008,4 +1038,3 @@ end function IsACDehumidificationEnabled end module UrbanParamsType - diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 5a3a9c7b06..1240ecb9e0 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -826,7 +826,7 @@ subroutine RestartBulk(this, bounds, ncid, flag, writing_finidat_interp_dest_fil !------------------------------------------------------------------------ - call this%Restart(bounds, ncid, flag=flag, is_prog_buildtemp=IsBuildingHumidityEnabled()) + call this%Restart(bounds, ncid, flag=flag, is_prog_buildhumidity=IsBuildingHumidityEnabled()) if(use_luna)then call restartvar(ncid=ncid, flag=flag, & diff --git a/src/biogeophys/WaterDiagnosticType.F90 b/src/biogeophys/WaterDiagnosticType.F90 index 17a83144e3..fc4b609a84 100644 --- a/src/biogeophys/WaterDiagnosticType.F90 +++ b/src/biogeophys/WaterDiagnosticType.F90 @@ -70,21 +70,21 @@ module WaterDiagnosticType contains !------------------------------------------------------------------------ - subroutine Init(this, bounds, info, tracer_vars, is_prog_buildtemp) + subroutine Init(this, bounds, info, tracer_vars, is_prog_buildhumidity) class(waterdiagnostic_type), intent(inout) :: this type(bounds_type) , intent(in) :: bounds class(water_info_base_type), intent(in), target :: info type(water_tracer_container_type), intent(inout) :: tracer_vars - logical, intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used + logical, intent(in) :: is_prog_buildhumidity ! Prognostic building humidity is being used this%info => info call this%InitAllocate(bounds, tracer_vars) - call this%InitHistory(bounds, is_prog_buildtemp) + call this%InitHistory(bounds, is_prog_buildhumidity) - call this%InitCold(bounds, is_prog_buildtemp) + call this%InitCold(bounds, is_prog_buildhumidity) end subroutine Init @@ -147,7 +147,7 @@ subroutine InitAllocate(this, bounds, tracer_vars) end subroutine InitAllocate !------------------------------------------------------------------------ - subroutine InitHistory(this, bounds, is_prog_buildtemp) + subroutine InitHistory(this, bounds, is_prog_buildhumidity) ! ! !DESCRIPTION: ! Initialize module data structure @@ -158,7 +158,7 @@ subroutine InitHistory(this, bounds, is_prog_buildtemp) ! !ARGUMENTS: class(waterdiagnostic_type), intent(in) :: this type(bounds_type), intent(in) :: bounds - logical, intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used + logical, intent(in) :: is_prog_buildhumidity ! Prognostic building humidity is being used ! ! !LOCAL VARIABLES: integer :: begp, endp @@ -250,7 +250,7 @@ subroutine InitHistory(this, bounds, is_prog_buildtemp) ptr_col=this%snowice_col, c2l_scale_type='urbanf', l2g_scale_type='ice', & default='inactive') - if ( is_prog_buildtemp ) then + if ( is_prog_buildhumidity ) then this%q_building_lun(begl:endl) = spval call hist_addfld1d ( & fname=this%info%fname('QBUILD'), & @@ -263,7 +263,7 @@ subroutine InitHistory(this, bounds, is_prog_buildtemp) end subroutine InitHistory !----------------------------------------------------------------------- - subroutine InitCold(this, bounds, is_prog_buildtemp) + subroutine InitCold(this, bounds, is_prog_buildhumidity) ! ! !DESCRIPTION: ! Initialize time constant variables and cold start conditions @@ -274,7 +274,7 @@ subroutine InitCold(this, bounds, is_prog_buildtemp) ! !ARGUMENTS: class(waterdiagnostic_type), intent(in) :: this type(bounds_type) , intent(in) :: bounds - logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used + logical , intent(in) :: is_prog_buildhumidity ! Prognostic building humidity is being used ! ! !LOCAL VARIABLES: integer :: l @@ -305,7 +305,7 @@ subroutine InitCold(this, bounds, is_prog_buildtemp) end do ! Initialize internal building specific humidity (following example above and t_building_max in TemperatureType.F90) - if ( is_prog_buildtemp ) then + if ( is_prog_buildhumidity ) then do l = bounds%begl, bounds%endl if (lun%urbpoi(l)) then this%q_building_lun(l) = this%qaf_lun(l) ! set to urban canopy specific humidity @@ -316,7 +316,7 @@ subroutine InitCold(this, bounds, is_prog_buildtemp) end subroutine InitCold !------------------------------------------------------------------------ - subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) + subroutine Restart(this, bounds, ncid, flag, is_prog_buildhumidity) ! ! !DESCRIPTION: ! Read/Write module information to/from restart file. @@ -333,7 +333,7 @@ subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) type(bounds_type), intent(in) :: bounds type(file_desc_t), intent(inout) :: ncid ! netcdf id character(len=*) , intent(in) :: flag ! 'read' or 'write' - logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used + logical , intent(in) :: is_prog_buildhumidity ! Prognostic building humidity is being used ! ! !LOCAL VARIABLES: integer :: c,l,j @@ -369,7 +369,7 @@ subroutine Restart(this, bounds, ncid, flag, is_prog_buildtemp) interpinic_flag='interp', readvar=readvar, data=this%total_plant_stored_h2o_col) end if - if ( is_prog_buildtemp ) then + if ( is_prog_buildhumidity ) then ! landunit type physical state variable - q_building call restartvar(ncid=ncid, flag=flag, & varname=this%info%fname('q_building'), & diff --git a/src/biogeophys/WaterType.F90 b/src/biogeophys/WaterType.F90 index 4462f55356..a8f8c015cb 100644 --- a/src/biogeophys/WaterType.F90 +++ b/src/biogeophys/WaterType.F90 @@ -726,7 +726,7 @@ end subroutine UpdateAccVars !----------------------------------------------------------------------- subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & - watsat_col, t_soisno_col, altmax_lastyear_indx, is_prog_buildtemp) + watsat_col, t_soisno_col, altmax_lastyear_indx, is_prog_buildhumidity) ! ! !DESCRIPTION: ! Read/write information to/from restart file for all water variables @@ -740,7 +740,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & real(r8) , intent(in) :: watsat_col (bounds%begc:, 1:) ! volumetric soil water at saturation (porosity) real(r8) , intent(in) :: t_soisno_col(bounds%begc:, -nlevsno+1:) ! col soil temperature (Kelvin) integer , intent(in) :: altmax_lastyear_indx(bounds%begc:) !col active layer index last year - logical , intent(in) :: is_prog_buildtemp ! Prognostic building temp is being used + logical , intent(in) :: is_prog_buildhumidity ! Prognostic building humidity is being used ! ! !LOCAL VARIABLES: integer :: i @@ -771,7 +771,7 @@ subroutine Restart(this, bounds, ncid, flag, writing_finidat_interp_dest_file, & altmax_lastyear_indx=altmax_lastyear_indx(bounds%begc:)) call this%bulk_and_tracers(i)%waterdiagnostic_inst%Restart(bounds, ncid, flag=flag, & - is_prog_buildtemp=IsBuildingHumidityEnabled()) + is_prog_buildhumidity=is_prog_buildhumidity) end do diff --git a/src/main/clm_instMod.F90 b/src/main/clm_instMod.F90 index 57e2ce2efc..883facd58f 100644 --- a/src/main/clm_instMod.F90 +++ b/src/main/clm_instMod.F90 @@ -495,7 +495,7 @@ subroutine clm_instRest(bounds, ncid, flag, writing_finidat_interp_dest_file) ! ! !USES: use ncdio_pio , only : file_desc_t - use UrbanParamsType , only : IsSimpleBuildTemp, IsProgBuildTemp + use UrbanParamsType , only : IsSimpleBuildTemp, IsProgBuildTemp, IsBuildingHumidityEnabled use decompMod , only : get_proc_bounds, get_proc_clumps, get_clump_bounds use clm_varpar , only : nlevsno @@ -547,7 +547,7 @@ subroutine clm_instRest(bounds, ncid, flag, writing_finidat_interp_dest_file) watsat_col = soilstate_inst%watsat_col(bounds%begc:bounds%endc,:), & t_soisno_col=temperature_inst%t_soisno_col(bounds%begc:bounds%endc, -nlevsno+1:), & altmax_lastyear_indx=active_layer_inst%altmax_lastyear_indx_col(bounds%begc:bounds%endc), & - is_prog_buildtemp = IsProgBuildTemp()) + is_prog_buildhumidity = IsBuildingHumidityEnabled()) call irrigation_inst%restart (bounds, ncid, flag=flag) From e5c8083ce6f8ba7b1014261457e3c35c95d2f0ca Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Tue, 11 Aug 2026 16:14:10 -0600 Subject: [PATCH 56/89] correct typo --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 4a52243615..4fddca090e 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -1024,7 +1024,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, else t_building(l) = t_building_max(l) eflx_urban_ac(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_hair(l) * cp_hair(l) / dtime) * t_building(l) & + (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building(l) & - (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) if (IsACDehumidificationEnabled()) then eflx_urban_ac_sen(l) = eflx_urban_ac(l) From 3bdd812630ac66380bd6413a00846a009ed899da Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Tue, 11 Aug 2026 22:54:52 -0600 Subject: [PATCH 57/89] update inline comments and var long_name --- src/biogeophys/BalanceCheckMod.F90 | 2 +- src/biogeophys/EnergyFluxType.F90 | 12 ++++++------ src/biogeophys/SoilFluxesMod.F90 | 2 +- src/biogeophys/SoilTemperatureMod.F90 | 4 ++-- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index 9e8ff28862..6adc343126 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -579,7 +579,7 @@ subroutine BalanceCheck( bounds, & eflx_lh_tot => energyflux_inst%eflx_lh_tot_patch , & ! Input: [real(r8) (:) ] total latent heat flux (W/m**2) [+ to atm] eflx_soil_grnd => energyflux_inst%eflx_soil_grnd_patch , & ! Input: [real(r8) (:) ] soil heat flux (W/m**2) [+ = into soil] eflx_wasteheat_patch => energyflux_inst%eflx_wasteheat_patch , & ! Input: [real(r8) (:) ] sensible heat flux from urban heating/cooling sources of waste heat (W/m**2) - eflx_ventilation_patch => energyflux_inst%eflx_ventilation_patch , & ! Input: [real(r8) (:) ] sensible heat flux from building ventilation (W/m**2) + eflx_ventilation_patch => energyflux_inst%eflx_ventilation_patch , & ! Input: [real(r8) (:) ] sensible and latent heat flux from building ventilation (W/m**2) eflx_heat_from_ac_patch => energyflux_inst%eflx_heat_from_ac_patch , & ! Input: [real(r8) (:) ] sensible heat flux put back into canyon due to removal by AC (W/m**2) eflx_traffic_patch => energyflux_inst%eflx_traffic_patch , & ! Input: [real(r8) (:) ] traffic sensible heat flux (W/m**2) eflx_dynbal => energyflux_inst%eflx_dynbal_grc , & ! Input: [real(r8) (:) ] energy conversion flux due to dynamic land cover change(W/m**2) [+ to atm] diff --git a/src/biogeophys/EnergyFluxType.F90 b/src/biogeophys/EnergyFluxType.F90 index 9e83fb971f..728b498349 100644 --- a/src/biogeophys/EnergyFluxType.F90 +++ b/src/biogeophys/EnergyFluxType.F90 @@ -64,13 +64,13 @@ module EnergyFluxType real(r8), pointer :: eflx_anthro_patch (:) ! patch total anthropogenic heat flux (W/m**2) real(r8), pointer :: eflx_traffic_patch (:) ! patch traffic sensible heat flux (W/m**2) real(r8), pointer :: eflx_wasteheat_patch (:) ! patch sensible heat flux from domestic heating/cooling sources of waste heat (W/m**2) - real(r8), pointer :: eflx_ventilation_patch (:) ! patch sensible heat flux from building ventilation (W/m**2) + real(r8), pointer :: eflx_ventilation_patch (:) ! patch sensible and latent heat flux from building ventilation (W/m**2) real(r8), pointer :: eflx_heat_from_ac_patch (:) ! patch sensible heat flux put back into canyon due to removal by AC (W/m**2) real(r8), pointer :: eflx_traffic_lun (:) ! lun traffic sensible heat flux (W/m**2) real(r8), pointer :: eflx_wasteheat_lun (:) ! lun sensible heat flux from domestic heating/cooling sources of waste heat (W/m**2) - real(r8), pointer :: eflx_ventilation_lun (:) ! lun sensible heat flux from building ventilation (W/m**2) + real(r8), pointer :: eflx_ventilation_lun (:) ! lun sensible and latent heat flux from building ventilation (W/m**2) real(r8), pointer :: eflx_heat_from_ac_lun (:) ! lun sensible heat flux to be put back into canyon due to removal by AC (W/m**2) - real(r8), pointer :: eflx_building_lun (:) ! lun building heat flux from change in interior building air temperature (W/m**2) + real(r8), pointer :: eflx_building_lun (:) ! lun building heat flux from change in interior building air temperature (and humidity, if prognosed indoor humidity) (W/m**2) real(r8), pointer :: eflx_urban_ac_lun (:) ! lun urban air conditioning flux (W/m**2) real(r8), pointer :: eflx_urban_ac_sen_lun (:) ! lun sensible heat component of air conditioning flux (W/m**2) real(r8), pointer :: eflx_urban_heat_lun (:) ! lun urban heating flux (W/m**2) @@ -584,7 +584,7 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp) else this%eflx_urban_ac_lun(begl:endl) = spval call hist_addfld1d (fname='EFLXBUILD', units='W/m^2', & - avgflag='A', long_name='building heat flux from change in interior building air temperature', & + avgflag='A', long_name='building heat flux from change in interior building air temperature (and humidity, if prognosed indoor humidity)', & ptr_lunit=this%eflx_building_lun, set_nourb=0._r8, l2g_scale_type='unity') this%eflx_urban_ac_lun(begl:endl) = spval @@ -635,7 +635,7 @@ subroutine InitHistory(this, bounds, is_simple_buildtemp, is_prog_buildtemp) if ( is_prog_buildtemp )then this%eflx_ventilation_patch(begp:endp) = spval call hist_addfld1d (fname='VENTILATION', units='W/m^2', & - avgflag='A', long_name='sensible heat flux from building ventilation', & + avgflag='A', long_name='sensible (and latent, if prognosed indoor humidity) heat flux from building ventilation', & ptr_patch=this%eflx_ventilation_patch, set_nourb=0._r8, c2l_scale_type='urbanf') end if @@ -885,7 +885,7 @@ subroutine Restart(this, bounds, ncid, flag, is_simple_buildtemp, is_prog_buildt end if call restartvar(ncid=ncid, flag=flag, varname='EFLX_VENTILATION', xtype=ncd_double, & dim1name='landunit', & - long_name='sensible heat flux from building ventilation', units='watt/m^2', & + long_name='sensible (and latent, if prognosed indoor humidity) heat flux from building ventilation', units='watt/m^2', & interpinic_flag='interp', readvar=readvar, data=this%eflx_ventilation_lun) if (flag=='read' .and. .not. readvar) then if (masterproc) write(iulog,*) "can't find EFLX_VENTILATION in initial file..." diff --git a/src/biogeophys/SoilFluxesMod.F90 b/src/biogeophys/SoilFluxesMod.F90 index 44e6d0e1cd..2e8b443596 100644 --- a/src/biogeophys/SoilFluxesMod.F90 +++ b/src/biogeophys/SoilFluxesMod.F90 @@ -115,7 +115,7 @@ subroutine SoilFluxes (bounds, num_urbanl, filter_urbanl, & htvp => energyflux_inst%htvp_col , & ! Input: [real(r8) (:) ] latent heat of vapor of water (or sublimation) [j/kg] eflx_building_heat_errsoi=> energyflux_inst%eflx_building_heat_errsoi_col , & ! Input: [real(r8) (:)] heat flux to interior surface of walls and roof for errsoi check (W m-2) eflx_wasteheat_patch => energyflux_inst%eflx_wasteheat_patch , & ! Input: [real(r8) (:) ] sensible heat flux from urban heating/cooling sources of waste heat (W/m**2) - eflx_ventilation_patch => energyflux_inst%eflx_ventilation_patch , & ! Input: [real(r8) (:) ] sensible heat flux from building ventilation (W/m**2) + eflx_ventilation_patch => energyflux_inst%eflx_ventilation_patch , & ! Input: [real(r8) (:) ] sensible and latent heat flux from building ventilation (W/m**2) eflx_heat_from_ac_patch => energyflux_inst%eflx_heat_from_ac_patch , & ! Input: [real(r8) (:) ] sensible heat flux put back into canyon due to removal by AC (W/m**2) eflx_traffic_patch => energyflux_inst%eflx_traffic_patch , & ! Input: [real(r8) (:) ] traffic sensible heat flux (W/m**2) dlrad => energyflux_inst%dlrad_patch , & ! Input: [real(r8) (:) ] downward longwave radiation below the canopy [W/m2] diff --git a/src/biogeophys/SoilTemperatureMod.F90 b/src/biogeophys/SoilTemperatureMod.F90 index 25eecc7952..8882903230 100644 --- a/src/biogeophys/SoilTemperatureMod.F90 +++ b/src/biogeophys/SoilTemperatureMod.F90 @@ -1615,7 +1615,7 @@ subroutine ComputeGroundHeatFluxAndDeriv(bounds, & dlrad => energyflux_inst%dlrad_patch , & ! Input: [real(r8) (:) ] downward longwave radiation blow the canopy [W/m2] eflx_traffic => energyflux_inst%eflx_traffic_lun , & ! Input: [real(r8) (:) ] traffic sensible heat flux (W/m**2) eflx_wasteheat => energyflux_inst%eflx_wasteheat_lun , & ! Input: [real(r8) (:) ] sensible heat flux from urban heating/cooling sources of waste heat (W/m**2) - eflx_ventilation => energyflux_inst%eflx_ventilation_lun , & ! Input: [real(r8) (:) ] sensible heat flux from building ventilation (W/m**2) + eflx_ventilation => energyflux_inst%eflx_ventilation_lun , & ! Input: [real(r8) (:) ] sensible and latent heat flux from building ventilation (W/m**2) eflx_heat_from_ac => energyflux_inst%eflx_heat_from_ac_lun , & ! Input: [real(r8) (:) ] sensible heat flux put back into canyon due to removal by AC (W/m**2) eflx_sh_snow => energyflux_inst%eflx_sh_snow_patch , & ! Input: [real(r8) (:) ] sensible heat flux from snow (W/m**2) [+ to atm] eflx_sh_soil => energyflux_inst%eflx_sh_soil_patch , & ! Input: [real(r8) (:) ] sensible heat flux from soil (W/m**2) [+ to atm] @@ -1623,7 +1623,7 @@ subroutine ComputeGroundHeatFluxAndDeriv(bounds, & eflx_sh_grnd => energyflux_inst%eflx_sh_grnd_patch , & ! Input: [real(r8) (:) ] sensible heat flux from ground (W/m**2) [+ to atm] eflx_lwrad_net => energyflux_inst%eflx_lwrad_net_patch , & ! Input: [real(r8) (:) ] net infrared (longwave) rad (W/m**2) [+ = to atm] eflx_wasteheat_patch => energyflux_inst%eflx_wasteheat_patch , & ! Input: [real(r8) (:) ] sensible heat flux from urban heating/cooling sources of waste heat (W/m**2) - eflx_ventilation_patch => energyflux_inst%eflx_ventilation_patch , & ! Input: [real(r8) (:) ] sensible heat flux from building ventilation (W/m**2) + eflx_ventilation_patch => energyflux_inst%eflx_ventilation_patch , & ! Input: [real(r8) (:) ] sensible and latent heat flux from building ventilation (W/m**2) eflx_heat_from_ac_patch => energyflux_inst%eflx_heat_from_ac_patch , & ! Input: [real(r8) (:) ] sensible heat flux put back into canyon due to removal by AC (W/m**2) eflx_traffic_patch => energyflux_inst%eflx_traffic_patch , & ! Input: [real(r8) (:) ] traffic sensible heat flux (W/m**2) eflx_anthro => energyflux_inst%eflx_anthro_patch , & ! Input: [real(r8) (:) ] total anthropogenic heat flux (W/m**2) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 4fddca090e..a4ed18516a 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -362,11 +362,11 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, rh_building => waterdiagnosticbulk_inst%rh_building_lun,& ! InOut: [real(r8) (:)] internal building air relative humidity (%) forc_pbot => atm2lnd_inst%forc_pbot_not_downscaled_grc,& ! Input:[real(r8) (:)] atmospheric pressure (Pa) - eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (W/m**2) + eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (and humidity, if prognosed indoor humidity) (W/m**2) eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) eflx_urban_ac_sen => energyflux_inst%eflx_urban_ac_sen_lun,& ! Output: [real(r8) (:)] sensible heat component of urban air conditioning flux (W/m**2) eflx_urban_heat => energyflux_inst%eflx_urban_heat_lun,& ! Output: [real(r8) (:)] urban heating flux (W/m**2) - eflx_ventilation => energyflux_inst%eflx_ventilation_lun, & ! Output: [real(r8) (:)] sensible heat flux from building ventilation (W/m**2) + eflx_ventilation => energyflux_inst%eflx_ventilation_lun, & ! Output: [real(r8) (:)] sensible and latent heat flux from building ventilation (W/m**2) qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col, & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for impervious road area (mm/s) qflx_condensate_from_ac_lu => waterfluxbulk_inst%qflx_condensate_from_ac_lun & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for urban area by land unit (mm/s) @@ -962,7 +962,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if - ! Sensible heat flux from ventilation. It is added as a flux to the canyon floor in SoilTemperatureMod. + ! Sensible and latent heat flux from ventilation. It is added as a flux to the canyon floor in SoilTemperatureMod. ! Note that we multiply it here by wtlunit_roof which converts it from W/m2 of building area to W/m2 ! of urban area. eflx_urban_ac and eflx_urban_heat are treated similarly below. This flux is balanced ! by an equal and opposite flux into/out of the building and so has a net effect of zero on the energy balance From f59b1f628dbc6fbb3cf10e2f964764b0bd025b3b Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Wed, 12 Aug 2026 09:31:15 -0600 Subject: [PATCH 58/89] Fix build errors --- src/biogeophys/BalanceCheckMod.F90 | 2 +- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index 381b45b8c9..8f4d18bfe8 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -561,7 +561,7 @@ subroutine BalanceCheck( bounds, & qflx_sfc_irrig_col => waterflux_inst%qflx_sfc_irrig_col , & ! Input: [real(r8) (:) ] column level irrigation flux (mm H2O /s) qflx_sfc_irrig_grc => waterlnd2atm_inst%qirrig_grc , & ! Input: [real(r8) (:) ] grid cell-level irrigation flux (mm H20 /s) qflx_glcice_dyn_water_flux_col => waterflux_inst%qflx_glcice_dyn_water_flux_col, & ! Input: [real(r8) (:)] column level water flux needed for balance check due to glc_dyn_runoff_routing (mm H2O/s) (positive means addition of water to the system) - qflx_condensate_from_ac_col => waterflux_inst%qflx_condensate_from_ac_col, & ! Input: [real(r8) (:)] column level condensate water flux from air-conditioning (mm H2O /s) + qflx_condensate_from_ac_col => waterflux_inst%qflx_condensate_from_ac_col & ! Input: [real(r8) (:)] column level condensate water flux from air-conditioning (mm H2O /s) ) ! Get step size and time step diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 62e8d9f6b7..7ba1f6df3d 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -361,7 +361,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, qaf => waterdiagnosticbulk_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) q_building => waterdiagnosticbulk_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) rh_building => waterdiagnosticbulk_inst%rh_building_lun,& ! InOut: [real(r8) (:)] internal building air relative humidity (%) - forc_pbot => atm2lnd_inst%forc_pbot_not_downscaled_grc,& ! Input:[real(r8) (:)] atmospheric pressure (Pa) eflx_building => energyflux_inst%eflx_building_lun , & ! Output: [real(r8) (:)] building heat flux from change in interior building air temperature (and humidity, if prognosed indoor humidity) (W/m**2) eflx_urban_ac => energyflux_inst%eflx_urban_ac_lun , & ! Output: [real(r8) (:)] urban air conditioning flux (W/m**2) From fff8bfc83a06d4ec455df04f86e4e61577b51f17 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Tue, 25 Aug 2026 23:27:06 -0600 Subject: [PATCH 59/89] address pr comments --- .../namelist_definition_ctsm.xml | 6 +- bld/unit_testers/build-namelist_test.pl | 32 +++++- src/biogeophys/BalanceCheckMod.F90 | 62 ++++++----- src/biogeophys/SoilHydrologyMod.F90 | 4 +- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 104 +++++++++++------- src/biogeophys/UrbanParamsType.F90 | 4 +- src/biogeophys/WaterDiagnosticBulkType.F90 | 2 +- src/biogeophys/WaterFluxType.F90 | 8 +- src/main/clm_varcon.F90 | 3 +- 9 files changed, 140 insertions(+), 85 deletions(-) diff --git a/bld/namelist_files/namelist_definition_ctsm.xml b/bld/namelist_files/namelist_definition_ctsm.xml index 8c37930a04..d70b464496 100644 --- a/bld/namelist_files/namelist_definition_ctsm.xml +++ b/bld/namelist_files/namelist_definition_ctsm.xml @@ -1247,6 +1247,7 @@ Turn urban air conditioning/heating ON or OFF and add wasteheat: If TRUE, use explicit, time-varying AC adoption rate for air-conditioning flux and interior building temperature calculations. +See Li et al. (2024), doi:10.1029/2023MS004107 { options=>"-envxml_dir .", + namelst=>"building_humidity_mode=-1", + phys=>"clm6_0", + }, + "building humidity mode above range" + =>{ options=>"-envxml_dir .", + namelst=>"building_humidity_mode=3", + phys=>"clm6_0", + }, + "humidity mode 1 with simple temperature" + =>{ options=>"-envxml_dir .", + namelst=>"building_humidity_mode=1,building_temp_method=0", + phys=>"clm6_0", + }, + "humidity mode 2 with simple temperature" + =>{ options=>"-envxml_dir .", + namelst=>"building_humidity_mode=2,building_temp_method=0,urban_hac='ON',urban_explicit_ac=.true.", + phys=>"clm6_0", + }, + "humidity mode 2 with AC off" + =>{ options=>"-envxml_dir .", + namelst=>"building_humidity_mode=2,building_temp_method=1,urban_hac='OFF',urban_explicit_ac=.true.", + phys=>"clm6_0", + }, + "humidity mode 2 without explicit AC" + =>{ options=>"-envxml_dir .", + namelst=>"building_humidity_mode=2,building_temp_method=1,urban_hac='ON',urban_explicit_ac=.false.", + phys=>"clm6_0", + }, "cmip7_w_issp" =>{ options=>"-envxml_dir . -use_case 1850-2100_SSP2-4.5_transient", namelst=>"", CLM_CMIP_ERA=>"cmip7", diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index 8f4d18bfe8..b223427057 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -500,7 +500,7 @@ subroutine BalanceCheck( bounds, & real(r8) :: qflx_glcice_dyn_water_flux_grc(bounds%begg:bounds%endg) ! grid cell-level water flux needed for balance check due to glc_dyn_runoff_routing [mm H2O/s] (positive means addition of water to the system) real(r8) :: qflx_snwcp_discarded_liq_grc(bounds%begg:bounds%endg) ! grid cell-level excess liquid h2o due to snow capping, which we simply discard in order to reset the snow pack [mm H2O /s] real(r8) :: qflx_snwcp_discarded_ice_grc(bounds%begg:bounds%endg) ! grid cell-level excess solid h2o due to snow capping, which we simply discard in order to reset the snow pack [mm H2O /s] - real(r8) :: qflx_condensate_from_ac_grc(bounds%begg:bounds%endg) ! grid cell-level condensate from air-conditioning [mm H2O /s] + real(r8) :: qflx_condensate_from_ac_grc(bounds%begg:bounds%endg) ! grid cell-level condensate water flux from air-conditioning [mm H2O /s] real(r8) :: errh2o_max_val ! Maximum value of error in water conservation error over all columns [mm H2O] real(r8) :: errh2osno_max_val ! Maximum value of error in h2osno conservation error over all columns [kg m-2] @@ -592,21 +592,23 @@ subroutine BalanceCheck( bounds, & ! add qflx_drain_perched and qflx_flood if (col%active(c)) then + errh2o_col(c) = endwb_col(c) - begwb_col(c) & + - (forc_rain_col(c) & + + forc_snow_col(c) & + + qflx_flood_col(c) & + + qflx_sfc_irrig_col(c) & + + qflx_glcice_dyn_water_flux_col(c) & + - qflx_evap_tot_col(c) & + - qflx_surf_col(c) & + - qflx_qrgwl_col(c) & + - qflx_drain_col(c) & + - qflx_drain_perched_col(c) & + - qflx_ice_runoff_col(c) & + - qflx_snwcp_discarded_liq_col(c) & + - qflx_snwcp_discarded_ice_col(c)) * dtime + if (IsACDehumidificationEnabled()) then - errh2o_col(c) = endwb_col(c) - begwb_col(c) & - - (forc_rain_col(c) + forc_snow_col(c) + qflx_flood_col(c) & - + qflx_sfc_irrig_col(c) + qflx_glcice_dyn_water_flux_col(c) & - + qflx_condensate_from_ac_col(c) - qflx_evap_tot_col(c) & - - qflx_surf_col(c) - qflx_qrgwl_col(c) - qflx_drain_col(c) & - - qflx_drain_perched_col(c) - qflx_ice_runoff_col(c) & - - qflx_snwcp_discarded_liq_col(c) - qflx_snwcp_discarded_ice_col(c)) * dtime - else - errh2o_col(c) = endwb_col(c) - begwb_col(c) & - - (forc_rain_col(c) + forc_snow_col(c) + qflx_flood_col(c) & - + qflx_sfc_irrig_col(c) + qflx_glcice_dyn_water_flux_col(c) & - - qflx_evap_tot_col(c) - qflx_surf_col(c) - qflx_qrgwl_col(c) & - - qflx_drain_col(c) - qflx_drain_perched_col(c) - qflx_ice_runoff_col(c) & - - qflx_snwcp_discarded_liq_col(c) - qflx_snwcp_discarded_ice_col(c)) * dtime + errh2o_col(c) = errh2o_col(c) - qflx_condensate_from_ac_col(c) * dtime end if else @@ -691,21 +693,23 @@ subroutine BalanceCheck( bounds, & end if do g = bounds%begg, bounds%endg + errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & + - (forc_rain_grc(g) & + + forc_snow_grc(g) & + + forc_flood_grc(g) & + + qflx_sfc_irrig_grc(g) & + + qflx_glcice_dyn_water_flux_grc(g) & + - qflx_evap_tot_grc(g) & + - qflx_surf_grc(g) & + - qflx_qrgwl_grc(g) & + - qflx_drain_grc(g) & + - qflx_drain_perched_grc(g) & + - qflx_ice_runoff_grc(g) & + - qflx_snwcp_discarded_liq_grc(g) & + - qflx_snwcp_discarded_ice_grc(g)) * dtime + if (IsACDehumidificationEnabled()) then - errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & - - (forc_rain_grc(g) + forc_snow_grc(g) + forc_flood_grc(g) & - + qflx_sfc_irrig_grc(g) + qflx_glcice_dyn_water_flux_grc(g) & - + qflx_condensate_from_ac_grc(g) - qflx_evap_tot_grc(g) & - - qflx_surf_grc(g) - qflx_qrgwl_grc(g) - qflx_drain_grc(g) & - - qflx_drain_perched_grc(g) - qflx_ice_runoff_grc(g) & - - qflx_snwcp_discarded_liq_grc(g) - qflx_snwcp_discarded_ice_grc(g)) * dtime - else - errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & - - (forc_rain_grc(g) + forc_snow_grc(g) + forc_flood_grc(g) & - + qflx_sfc_irrig_grc(g) + qflx_glcice_dyn_water_flux_grc(g) & - - qflx_evap_tot_grc(g) - qflx_surf_grc(g) - qflx_qrgwl_grc(g) & - - qflx_drain_grc(g) - qflx_drain_perched_grc(g) - qflx_ice_runoff_grc(g) & - - qflx_snwcp_discarded_liq_grc(g) - qflx_snwcp_discarded_ice_grc(g)) * dtime + errh2o_grc(g) = errh2o_grc(g) - qflx_condensate_from_ac_grc(g) * dtime end if end do diff --git a/src/biogeophys/SoilHydrologyMod.F90 b/src/biogeophys/SoilHydrologyMod.F90 index a40f67c34a..f1e38d92e2 100644 --- a/src/biogeophys/SoilHydrologyMod.F90 +++ b/src/biogeophys/SoilHydrologyMod.F90 @@ -540,7 +540,9 @@ subroutine TotalSurfaceRunoff(bounds, num_hydrologyc, filter_hydrologyc, & pondmx_urban/dtime) qflx_surf(c) = xs_urban(c) end if - ! Send flood water flux and air-conditioning condensate to runoff for all urban columns. + ! Send flood water flux and air-conditioning condensate (the latter exists only + ! when prognosed indoor humidity and AC dehumidification are enabled) + ! to runoff for all urban columns if (IsACDehumidificationEnabled()) then qflx_surf(c) = qflx_surf(c) + qflx_floodc(c) + qflx_condensate_from_ac(c) else diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 7ba1f6df3d..33aa181613 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -6,6 +6,10 @@ module UrbBuildTempOleson2015Mod ! !DESCRIPTION: ! Calculates internal building air temperature ! + ! Explicit air-conditioning adoption is described by Li et al. (2024), + ! doi:10.1029/2023MS004107. Indoor humidity and air-conditioning dehumidification + ! are described by Li et al. (2026), doi:10.1038/s44284-026-00474-4. + ! ! !USES: use shr_kind_mod , only : r8 => shr_kind_r8 use decompMod , only : bounds_type, subgrid_level_landunit @@ -58,11 +62,11 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! qrd_sunw + qcd_sunw + qcv_sunw = 0 ! qrd_shdw + qcd_shdw + qcv_shdw = 0 ! qrd_floor + qcd_floor + qcv_floor = 0 -! Vbld*rho_air*cp_hair*(dt_building/dt) = sum(Asfc*hcv_sfc*(t_sfc - t_building) -! + Vvent*rho_air*cp_hair*(taf - t_building) +! Vbld*rho_air*cp_air*(dt_building/dt) = sum(Asfc*hcv_sfc*(t_sfc - t_building) +! + Vvent*rho_air*cp_air*(taf - t_building) ! where Vlbd is volume of building air, -! rho_air is density of air at t_building (kg m-3), -! cp_hair is specific heat of air (J kg-1 K-1), +! rho_air is density of indoor air at outdoor pressure and t_building (kg m-3), +! cp_air is specific heat capacity of indoor air (J kg-1 K-1), ! dt_building is change in interior building temperature (K), ! dt is timestep (s), ! Asfc is surface area of roof, sunw, shdw, floor (m2) @@ -266,7 +270,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, real(r8) :: cp_floori(bounds%begl:bounds%endl) ! concrete floor volumetric heat capacity (J m-3 K-1) real(r8) :: cv_floori(bounds%begl:bounds%endl) ! intermediate calculation for concrete floor (W m-2 K-1) real(r8) :: rho_air(bounds%begl:bounds%endl) ! density of indoor air at outdoor pressure and t_building (kg m-3) - real(r8) :: cp_hair(bounds%begl:bounds%endl) ! specific heat capacity of indoor humid air (J kg-1 K-1) + real(r8) :: cp_air(bounds%begl:bounds%endl) ! specific heat capacity of indoor air (J kg-1 K-1) real(r8) :: vf_rf(bounds%begl:bounds%endl) ! view factor of roof for floor (-) real(r8) :: vf_fr(bounds%begl:bounds%endl) ! view factor of floor for roof (-) real(r8) :: vf_wf(bounds%begl:bounds%endl) ! view factor of wall for floor (-) @@ -318,13 +322,13 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, integer :: info ! exit information for LAPACK routine dgesv integer :: ipiv(neq) ! the pivot indices that define the permutation matrix P real(r8) :: q_building_max ! maximum internal building air specific humidity determined from rh_building_max (kg/kg) - real(r8) :: qsat_building_max ! maximum internal building air saturated specific humidity/mixing ratio used to determing q_building_max from rh_building_max (kg/kg) - real(r8) :: qsat_building ! internal building air saturated specific humidity/mixing ratio used to calculate rh_building (kg/kg) + real(r8) :: qsat_building_max ! maximum specific humidity/mixing ratio of saturated internal building air at indoor temperature before HAC, used to determine q_building_max from rh_building_max (kg/kg) + real(r8) :: qsat_building ! specific humidity/mixing ratio of saturated internal building air at indoor temperature, used to calculate rho_air, cp_air, and rh_building (kg/kg) real(r8) :: esat_building ! internal building air saturated vapor pressure used to calculate p_vapor (Pa) real(r8) :: p_vapor ! internal building air partial pressure of water vapor (Pa) real(r8) :: qtot_condensate(bounds%begl:bounds%endl) ! total condensed water due to dehumidification per building area (kg m-2) real(r8) :: eflx_urban_ac_lat_derived(bounds%begl:bounds%endl) ! urban air conditioning latent heat flux derived from condensate output, for error check (W m-2) - real(r8) :: err_eflx_urban_ac_lat(bounds%begl:bounds%endl) ! Difference in urban air conditioning latent heat flux for error check (W m-2) + real(r8) :: err_eflx_urban_ac_lat(bounds%begl:bounds%endl) ! Difference between the dehumidification energy flux calculated from condensate and the urban AC latent heat flux for error check (W m-2) !EOP !----------------------------------------------------------------------- @@ -357,7 +361,6 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, t_building_max => urbantv_inst%t_building_max , & ! Input: [real(r8) (:)] maximum internal building air temperature (K) t_building_min => urbanparams_inst%t_building_min , & ! Input: [real(r8) (:)] minimum internal building air temperature (K) - ! trying to change to waterdiagnosticbulk_inst following how qaf was used in UrbanFluxesMod.F90 qaf => waterdiagnosticbulk_inst%qaf_lun , & ! Input: [real(r8) (:)] urban canopy air specific humidity (kg/kg) q_building => waterdiagnosticbulk_inst%q_building_lun,& ! InOut: [real(r8) (:)] internal building air specific humidity (kg/kg) rh_building => waterdiagnosticbulk_inst%rh_building_lun,& ! InOut: [real(r8) (:)] internal building air relative humidity (%) @@ -368,8 +371,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_heat => energyflux_inst%eflx_urban_heat_lun,& ! Output: [real(r8) (:)] urban heating flux (W/m**2) eflx_ventilation => energyflux_inst%eflx_ventilation_lun, & ! Output: [real(r8) (:)] sensible and latent heat flux from building ventilation (W/m**2) - qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col, & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for impervious road area (mm/s) - qflx_condensate_from_ac_lu => waterfluxbulk_inst%qflx_condensate_from_ac_lun & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for urban area by land unit (mm/s) + qflx_condensate_from_ac => waterfluxbulk_inst%qflx_condensate_from_ac_col, & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for roof (building footprint) area (mm/s) + qflx_condensate_from_ac_lu => waterfluxbulk_inst%qflx_condensate_from_ac_lun & ! Output: [real(r8) (:)] condensed water flux due to dehumidification for urban area (mm/s) ) ! Get step size @@ -418,15 +421,19 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Intermediate calculation for concrete floor (W m-2 K-1) cv_floori(l) = (dz_floori(l) * cp_floori(l)) / dtime if (IsBuildingHumidityEnabled()) then + ! Specific humidity (kg/kg) and vapor pressure (Pa) at saturation at current temperature and pressure call QSat(t_building_bef(l), forc_pbot(g), qsat_building, es = esat_building) + ! Indoor vapor pressure (Pa) from saturation vapor pressure. The saturation ratio is capped at 1 (100% saturation) + ! so indoor vapor pressure does not exceed saturation vapor pressure p_vapor = min(1._r8, q_building_bef(l) / qsat_building) * esat_building + ! Desity (kg m-3) and specific heat capacity (J kg-1 K-1) of moist air at current temperature and pressure rho_air(l) = (forc_pbot(g) - p_vapor) / (rair * t_building_bef(l)) & + p_vapor / (rwat * t_building_bef(l)) - cp_hair(l) = cpair + cpwvap * q_building_bef(l) + cp_air(l) = cpair + cpwvap * q_building_bef(l) else - ! Density of dry air at surface pressure and t_building (kg m-3) + ! Density (kg m-3) and specific heat capacity (J kg-1 K-1) of dry air at current temperature and pressure rho_air(l) = forc_pbot(g) / (rair*t_building_bef(l)) - cp_hair(l) = cpair + cp_air(l) = cpair end if ! Building height to building width ratio building_hwr(l) = canyon_hwr(l)*(1._r8-wtlunit_roof(l))/wtlunit_roof(l) @@ -691,15 +698,15 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, a(5,4) = - 0.5_r8*hcv_floori(l) - a(5,5) = ((ht_roof(l)*rho_air(l)*cp_hair(l))/dtime) + & - ((ht_roof(l)*vent_ach)/3600._r8)*rho_air(l)*cp_hair(l) + & + a(5,5) = ((ht_roof(l)*rho_air(l)*cp_air(l))/dtime) + & + ((ht_roof(l)*vent_ach)/3600._r8)*rho_air(l)*cp_air(l) + & 0.5_r8*hcv_roofi(l) + & 0.5_r8*hcv_sunwi(l)*building_hwr(l) + & 0.5_r8*hcv_shdwi(l)*building_hwr(l) + & 0.5_r8*hcv_floori(l) - result(5) = (ht_roof(l)*rho_air(l)*cp_hair(l)/dtime)*t_building_bef(l) & - + ((ht_roof(l)*vent_ach)/3600._r8)*rho_air(l)*cp_hair(l)*taf(l) & + result(5) = (ht_roof(l)*rho_air(l)*cp_air(l)/dtime)*t_building_bef(l) & + + ((ht_roof(l)*vent_ach)/3600._r8)*rho_air(l)*cp_air(l)*taf(l) & + 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & + 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & + 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & @@ -726,6 +733,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end if end do + ! Update indoor specific humidity assuming well-mixed indoor air if (IsBuildingHumidityEnabled()) then do fl = 1,num_urbanl l = filter_urbanl(fl) @@ -947,8 +955,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if - enrgy_bal_buildair(l) = (ht_roof(l)*rho_air(l)*cp_hair(l)/dtime)*(t_building(l) - t_building_bef(l)) & - - ht_roof(l)*(vent_ach/3600._r8)*rho_air(l)*cp_hair(l)*(taf(l) - t_building(l)) & + enrgy_bal_buildair(l) = (ht_roof(l)*rho_air(l)*cp_air(l)/dtime)*(t_building(l) - t_building_bef(l)) & + - ht_roof(l)*(vent_ach/3600._r8)*rho_air(l)*cp_air(l)*(taf(l) - t_building(l)) & - 0.5_r8*hcv_roofi(l)*(t_roof_inner(l) - t_building(l)) & - 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner(l) - t_building(l))*building_hwr(l) & @@ -963,14 +971,14 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if - ! Sensible and latent heat flux from ventilation. It is added as a flux to the canyon floor in SoilTemperatureMod. + ! Sensible and latent heat flux (if indoor humidity is prognosed) from ventilation. It is added as a flux to the canyon floor in SoilTemperatureMod. ! Note that we multiply it here by wtlunit_roof which converts it from W/m2 of building area to W/m2 ! of urban area. eflx_urban_ac and eflx_urban_heat are treated similarly below. This flux is balanced ! by an equal and opposite flux into/out of the building and so has a net effect of zero on the energy balance ! of the urban landunit. if (IsBuildingHumidityEnabled()) then eflx_ventilation(l) = wtlunit_roof(l) * ( & - - ht_roof(l) * (vent_ach/3600._r8) * rho_air(l) * cp_hair(l) * (taf(l) - t_building(l)) & + - ht_roof(l) * (vent_ach/3600._r8) * rho_air(l) * cp_air(l) * (taf(l) - t_building(l)) & - ht_roof(l) * (vent_ach/3600._r8) * rho_air(l) * hvap * (qaf(l) - q_building(l)) ) else eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & @@ -980,8 +988,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end do ! Restrict internal building air temperature to between min and max + ! and restric internal building air specific humidity to below max, when AC dehumidification is enabled. ! Calculate heating or air conditioning flux from energy required to change - ! internal building air temperature to t_building_min or t_building_max. + ! internal building air temperature to t_building_min or t_building_max + ! and internal building specific humidity to below q_building_max, when AC dehumidification is enabled. do fl = 1,num_urbanl l = filter_urbanl(fl) @@ -992,6 +1002,8 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! rho_dair(l) = pstd / (rair*t_building(l)) if (IsACDehumidificationEnabled()) then q_building_bef_hac(l) = q_building(l) + ! Convert maximum indoor relative humidity to maximum specific humidity + ! at the current indoor temperature and pressure. call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) q_building_max = rh_building_max / 100._r8 * qsat_building_max end if @@ -1001,22 +1013,25 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Sensible heat component of AC ! Here, t_building_max is the AC saturation setpoint - eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_max(l) & - - (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_max(l) & + - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) & - * dtime / (ht_roof(l) * rho_air(l) * cp_hair(l) * wtlunit_roof(l)) + * dtime / (ht_roof(l) * rho_air(l) * cp_air(l) * wtlunit_roof(l)) if (IsACDehumidificationEnabled()) then + ! Apply the AC adoption rate and assign to the AC sensible heat flux in preparation for later calculations eflx_urban_ac_sen(l) = p_ac(l) * eflx_urban_ac_sat(l) end if ! Latent heat component of AC if (IsACDehumidificationEnabled()) then if (q_building_bef_hac(l) > q_building_max) then - ! Humidification during urban heating is not implemented. + ! Calculate latent heat flux needed to lower indoor specific humidity to q_building_max at saturated AC adoption eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & (ht_roof(l) * rho_air(l) * hvap / dtime) * q_building_max & - (ht_roof(l) * rho_air(l) * hvap / dtime) * q_building_bef_hac(l) ) + ! Add to the sensible heat component calculated previously eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) + ! Reset q_building based on actual moisture removed at the actual AC adoption rate q_building(l) = q_building_max + (1._r8 - p_ac(l)) * eflx_urban_ac_sat_lat(l) & * dtime / (ht_roof(l) * rho_air(l) * hvap * wtlunit_roof(l)) end if @@ -1025,17 +1040,18 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, else t_building(l) = t_building_max(l) eflx_urban_ac(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building(l) & - - (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) if (IsACDehumidificationEnabled()) then eflx_urban_ac_sen(l) = eflx_urban_ac(l) end if end if else if (t_building_bef_hac(l) < t_building_min(l)) then + ! Humidification during urban heating is not implemented. t_building(l) = t_building_min(l) - eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building(l) & - - (ht_roof(l) * rho_air(l) * cp_hair(l) / dtime) * t_building_bef_hac(l) ) + eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) else if (IsACDehumidificationEnabled()) eflx_urban_ac_sen(l) = 0._r8 eflx_urban_ac(l) = 0._r8 @@ -1048,13 +1064,16 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_heat(l) = 0._r8 end if if (IsBuildingHumidityEnabled()) then + ! Calculate sensible and latent heat flux from the change in indoor air state. eflx_building(l) = wtlunit_roof(l) * ( & - (ht_roof(l) * rho_air(l)*cp_hair(l)/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_air(l)*cp_air(l)/dtime) * (t_building(l) - t_building_bef(l)) & + (ht_roof(l) * rho_air(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) ) if (IsACDehumidificationEnabled()) then + ! Convert the decrease in indoor water vapor to condensate per building footprint area. qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_air(l) qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime end if + ! Diagnose indoor relative humidity from the updated temperature and humidity. call QSat(t_building(l), forc_pbot(g), qsat_building) rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) else @@ -1068,23 +1087,28 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, if (IsACDehumidificationEnabled()) then do fl = 1,num_urbanl l = filter_urbanl(fl) - if (urbpoi(l)) then - ! dehumidification energy flux calculated from condensate: + ! Dehumidification energy flux calculated from condensate eflx_urban_ac_lat_derived(l) = qflx_condensate_from_ac_lu(l) * hvap - ! Difference in dehumidification energy flux: + ! Error between the above and the Latent heat component of AC energy flux err_eflx_urban_ac_lat(l) = eflx_urban_ac_lat_derived(l) - (eflx_urban_ac(l) - eflx_urban_ac_sen(l)) if (abs(err_eflx_urban_ac_lat(l)) > 1.e-5_r8 ) then - write (iulog,*) 'urban dehumidification energy does not match condensate output,' + write (iulog,*) 'dehumidification energy flux dervied from condensate does not match condensate output' + write (iulog,*) 'dehumidification energy flux derived from condensate [W/m2 urban]: ',eflx_urban_ac_lat_derived(l) + write (iulog,*) 'total AC energy flux [W/m2 urban]: ',eflx_urban_ac(l) + write (iulog,*) 'sensible heat component of AC energy flux [W/m2 urban]: ',eflx_urban_ac_sen(l) + write (iulog,*) 'latent heat component of AC energy flux (total minus sensible) [W/m2 urban]: ', & + eflx_urban_ac(l) - eflx_urban_ac_sen(l) write (iulog,*) 'error in dehumidification energy flux [W/m2 urban]: ',err_eflx_urban_ac_lat(l) + write (iulog,*) 'error tolerance [W/m2 urban]: ',1.e-5_r8 write (iulog,*) 'clm model is stopping' call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if - end if end do - ! Assume all condensed water gets added to the roof column (that goes directly into surface runoff) - ! Calculate and assign water flux due to dehumidification to roof column [mm/s], - ! water flux to other urban columns are set to 0. + ! Assign condensate water flux to roof column, which then goes directly to surface runoff. + ! It is assigned to roof column rather than other columns as it is calculated per building footprint, + ! which is equivalent to roof area. + ! Set condensate water lux to zero for all other columns. do fc = 1,num_urbanc c = filter_urbanc(fc) l = clandunit(c) diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90 index 209121c2d5..d7169dfde4 100644 --- a/src/biogeophys/UrbanParamsType.F90 +++ b/src/biogeophys/UrbanParamsType.F90 @@ -23,8 +23,8 @@ module UrbanParamsType public :: CheckUrban ! Check validity of urban points public :: IsSimpleBuildTemp ! If using the simple building temperature method public :: IsProgBuildTemp ! If using the prognostic building temperature method - public :: IsBuildingHumidityEnabled ! If indoor building humidity is simulated - public :: IsACDehumidificationEnabled ! If AC dehumidification is simulated + public :: IsBuildingHumidityEnabled ! If indoor building humidity is prognosed + public :: IsACDehumidificationEnabled ! If air-conditioning dehumidification is enabled ! ! !PRIVATE TYPE type urbinp_type diff --git a/src/biogeophys/WaterDiagnosticBulkType.F90 b/src/biogeophys/WaterDiagnosticBulkType.F90 index 0aa9dd9835..429536a5cb 100644 --- a/src/biogeophys/WaterDiagnosticBulkType.F90 +++ b/src/biogeophys/WaterDiagnosticBulkType.F90 @@ -367,7 +367,7 @@ subroutine InitBulkHistory(this, bounds) units='%', & avgflag='A', & long_name=this%info%lname('Internal urban building air relative humidity'), & - ptr_lunit=this%rh_building_lun, set_nourb=spval, default='inactive') + ptr_lunit=this%rh_building_lun, set_nourb=spval) end if this%rh_af_patch(begp:endp) = spval diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index 5f2481edc1..ecbed09b19 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -604,14 +604,8 @@ subroutine InitHistory(this, bounds) units='mm/s', & avgflag='A', & long_name=this%info%lname('Condensed water flux from AC dehumidification'), & - ptr_col=this%qflx_condensate_from_ac_col, set_nourb=0.0_r8, c2l_scale_type='urbanf', default='inactive') + ptr_col=this%qflx_condensate_from_ac_col, set_nourb=0.0_r8, c2l_scale_type='urbanf') this%qflx_condensate_from_ac_lun(begl:endl) = 0.0_r8 - call hist_addfld1d ( & - fname=this%info%fname('QCOND_FROM_AC_LUN'), & - units='mm/s', & - avgflag='A', & - long_name=this%info%lname('Condensed water flux from AC dehumidification (lun var)'), & - ptr_lunit=this%qflx_condensate_from_ac_lun, set_nourb=0.0_r8, l2g_scale_type='unity') end if this%qflx_snomelt_col(begc:endc) = spval diff --git a/src/main/clm_varcon.F90 b/src/main/clm_varcon.F90 index 9c4506a50b..751145ce97 100644 --- a/src/main/clm_varcon.F90 +++ b/src/main/clm_varcon.F90 @@ -190,8 +190,7 @@ module clm_varcon real(r8), public, parameter :: sh_floor = 880._r8 ! specific heat of floor - concrete (Salmanca et al. 2010, TAC) (J kg-1 K-1) real(r8), public :: cp_floor = dens_floor*sh_floor ! volumetric heat capacity of floor - concrete (Salmanca et al. 2010, TAC) (J m-3 K-1) real(r8), public :: vent_ach = 0.3_r8 ! ventilation rate (air exchanges per hour) - ! real(r8), public :: q_building_max = 0.013_r8 ! maximum internal building air specific humidity (kg/kg) - real(r8), public :: rh_building_max = 65._r8 ! maximum internal building air relative humidity (%) + real(r8), public :: rh_building_max = 65._r8 ! maximum internal building air relative humidity (Li et al. 2026, Nat Cities, which follows ASHRAE Standards 62.1-2022 and 62.1-2013) (%) real(r8), public :: wasteheat_limit = 100._r8 ! limit on wasteheat (W/m2) From b552d64a5c250911ece6467cdecf18ac320b577f Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Tue, 25 Aug 2026 23:35:57 -0600 Subject: [PATCH 60/89] return white space in errh2o_grc --- src/biogeophys/BalanceCheckMod.F90 | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/biogeophys/BalanceCheckMod.F90 b/src/biogeophys/BalanceCheckMod.F90 index b223427057..95efd0e632 100644 --- a/src/biogeophys/BalanceCheckMod.F90 +++ b/src/biogeophys/BalanceCheckMod.F90 @@ -693,19 +693,19 @@ subroutine BalanceCheck( bounds, & end if do g = bounds%begg, bounds%endg - errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & - - (forc_rain_grc(g) & - + forc_snow_grc(g) & - + forc_flood_grc(g) & - + qflx_sfc_irrig_grc(g) & - + qflx_glcice_dyn_water_flux_grc(g) & - - qflx_evap_tot_grc(g) & - - qflx_surf_grc(g) & - - qflx_qrgwl_grc(g) & - - qflx_drain_grc(g) & - - qflx_drain_perched_grc(g) & - - qflx_ice_runoff_grc(g) & - - qflx_snwcp_discarded_liq_grc(g) & + errh2o_grc(g) = endwb_grc(g) - begwb_grc(g) & + - (forc_rain_grc(g) & + + forc_snow_grc(g) & + + forc_flood_grc(g) & + + qflx_sfc_irrig_grc(g) & + + qflx_glcice_dyn_water_flux_grc(g) & + - qflx_evap_tot_grc(g) & + - qflx_surf_grc(g) & + - qflx_qrgwl_grc(g) & + - qflx_drain_grc(g) & + - qflx_drain_perched_grc(g) & + - qflx_ice_runoff_grc(g) & + - qflx_snwcp_discarded_liq_grc(g) & - qflx_snwcp_discarded_ice_grc(g)) * dtime if (IsACDehumidificationEnabled()) then From 8f34aa796a8b1653c88d87552a68bf0ee33c7b84 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Wed, 26 Aug 2026 16:53:12 -0600 Subject: [PATCH 61/89] fix typos --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index 33aa181613..d9836e453d 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -426,7 +426,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Indoor vapor pressure (Pa) from saturation vapor pressure. The saturation ratio is capped at 1 (100% saturation) ! so indoor vapor pressure does not exceed saturation vapor pressure p_vapor = min(1._r8, q_building_bef(l) / qsat_building) * esat_building - ! Desity (kg m-3) and specific heat capacity (J kg-1 K-1) of moist air at current temperature and pressure + ! Density (kg m-3) and specific heat capacity (J kg-1 K-1) of moist air at current temperature and pressure rho_air(l) = (forc_pbot(g) - p_vapor) / (rair * t_building_bef(l)) & + p_vapor / (rwat * t_building_bef(l)) cp_air(l) = cpair + cpwvap * q_building_bef(l) @@ -988,7 +988,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, end do ! Restrict internal building air temperature to between min and max - ! and restric internal building air specific humidity to below max, when AC dehumidification is enabled. + ! and restrict internal building air specific humidity to below max, when AC dehumidification is enabled. ! Calculate heating or air conditioning flux from energy required to change ! internal building air temperature to t_building_min or t_building_max ! and internal building specific humidity to below q_building_max, when AC dehumidification is enabled. @@ -1092,7 +1092,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Error between the above and the Latent heat component of AC energy flux err_eflx_urban_ac_lat(l) = eflx_urban_ac_lat_derived(l) - (eflx_urban_ac(l) - eflx_urban_ac_sen(l)) if (abs(err_eflx_urban_ac_lat(l)) > 1.e-5_r8 ) then - write (iulog,*) 'dehumidification energy flux dervied from condensate does not match condensate output' + write (iulog,*) 'dehumidification energy flux derived from condensate does not match condensate output' write (iulog,*) 'dehumidification energy flux derived from condensate [W/m2 urban]: ',eflx_urban_ac_lat_derived(l) write (iulog,*) 'total AC energy flux [W/m2 urban]: ',eflx_urban_ac(l) write (iulog,*) 'sensible heat component of AC energy flux [W/m2 urban]: ',eflx_urban_ac_sen(l) @@ -1108,7 +1108,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Assign condensate water flux to roof column, which then goes directly to surface runoff. ! It is assigned to roof column rather than other columns as it is calculated per building footprint, ! which is equivalent to roof area. - ! Set condensate water lux to zero for all other columns. + ! Set condensate water flux to zero for all other columns. do fc = 1,num_urbanc c = filter_urbanc(fc) l = clandunit(c) From 6143a6d44b4f0650849e360c9759b0034eda0d9c Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Thu, 27 Aug 2026 08:31:27 -0600 Subject: [PATCH 62/89] Get five unit tests working --- src/biogeophys/UrbanParamsType.F90 | 29 +++++++++++++++++++ .../test/Irrigation_test/test_irrigation.pf | 8 +++++ .../test/WaterType_test/test_water_type.pf | 7 +++++ .../test_dyn_cons_biogeophys.pf | 6 +++- .../dynInitColumns_test/test_init_columns.pf | 6 ++++ src/unit_test_shr/unittestDustEmisInputs.F90 | 9 +++++- 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90 index d7169dfde4..060dccb8c2 100644 --- a/src/biogeophys/UrbanParamsType.F90 +++ b/src/biogeophys/UrbanParamsType.F90 @@ -95,6 +95,7 @@ module UrbanParamsType contains procedure, public :: Init + procedure, public :: InitForTesting end type urbanparams_type ! @@ -369,6 +370,34 @@ subroutine Init(this, bounds) end subroutine Init + !----------------------------------------------------------------------- + subroutine InitForTesting(this, bounds) + ! + ! !DESCRIPTION: + ! Version of Init routine just for unit tests + ! + ! This version sets building_humidity_mode and then calls Init + ! + ! !ARGUMENTS: + class(urbanparams_type) , intent(inout) :: this + type(bounds_type) , intent(in) :: bounds + ! + ! !LOCAL VARIABLES: + + character(len=*), parameter :: subname = 'InitForTesting' + !----------------------------------------------------------------------- + + ! Default setting (prognostic indoor humidity and dehumidification off) + building_humidity_mode = 0 + + ! We set this to .true. to enable the IsBuildingHumidityEnabled and + ! IsACDehumidificationEnabled functions to be used for unit testing + ReadNamelist = .true. + + call Init(this, bounds = bounds) + + end subroutine InitForTesting + !----------------------------------------------------------------------- subroutine UrbanInput(begg, endg, mode) ! diff --git a/src/biogeophys/test/Irrigation_test/test_irrigation.pf b/src/biogeophys/test/Irrigation_test/test_irrigation.pf index d83fc94329..8257180af2 100644 --- a/src/biogeophys/test/Irrigation_test/test_irrigation.pf +++ b/src/biogeophys/test/Irrigation_test/test_irrigation.pf @@ -22,6 +22,7 @@ module test_irrigation use ColumnType , only : col use GridcellType , only : grc use pftconMod , only : pftcon + use UrbanParamsType, only : urbanparams_type use unittestWaterTypeFactory, only : unittest_water_type_factory_type use unittestSimpleSubgridSetupsMod, only : setup_single_veg_patch, setup_n_veg_patches use unittestFilterBuilderMod, only : filter_from_range @@ -37,6 +38,7 @@ module test_irrigation type, extends(irrigation_type) :: irrigation_test_type real(r8) :: gw_frac_from_con ! Fraction of groundwater irrigation taken from confined aquifer (same for all columns) real(r8), allocatable :: gw_frac_from_uncon(:) ! Fraction of groundwater irrigation taken from unconfined aquifer in various layers (same for all columns) + type(urbanparams_type) :: urbanparams_inst contains procedure, public :: InitForTesting ! Call the main irrigation InitForTesting, and also initialize IrrigationTestType's test-specific data to reasonable values procedure, public :: SetGwFractions ! Set fraction of groundwater from various sources @@ -417,6 +419,8 @@ contains ! ! !ARGUMENTS: class(TestIrrigation), intent(in) :: this + type(urbanparams_type) :: urbanparams_inst + integer, intent(in) :: maxpft ! max pft type that needs to be supported ! Irrigation method (drip by default); just set for the module-level pft_type parameter @@ -437,6 +441,10 @@ contains allocate(pftcon%irrigated(0:maxpft), source=1.0_r8) + ! Reguired so that the IsBuildingHumidityEnabled and IsACDehumidificationEnabled + ! namelist functions can be used + call urbanparams_inst%InitForTesting(bounds) + ! In the production code, irrig_method goes cft_lb:cft_ub; but it's safe to allocate ! more space than we really need here. allocate(irrig_method(bounds%begg:bounds%endg, 0:maxpft)) diff --git a/src/biogeophys/test/WaterType_test/test_water_type.pf b/src/biogeophys/test/WaterType_test/test_water_type.pf index f3edc731a3..3367047bf2 100644 --- a/src/biogeophys/test/WaterType_test/test_water_type.pf +++ b/src/biogeophys/test/WaterType_test/test_water_type.pf @@ -5,6 +5,7 @@ module test_water_type use funit use WaterType use shr_kind_mod , only : r8 => shr_kind_r8 + use UrbanParamsType, only : urbanparams_type use unittestSubgridMod, only : bounds, unittest_subgrid_teardown use unittestSimpleSubgridSetupsMod, only : setup_single_veg_patch use unittestUtils, only : endrun_msg @@ -15,6 +16,7 @@ module test_water_type @TestCase type, extends(TestCase) :: TestWaterType type(water_type) :: water_inst + type(urbanparams_type) :: urbanparams_inst type(unittest_water_type_factory_type) :: factory contains procedure :: setUp @@ -49,6 +51,11 @@ contains class(TestWaterType), intent(inout) :: this call setup_single_veg_patch(pft_type=1) + + ! Reguired so that the IsBuildingHumidityEnabled and IsACDehumidificationEnabled + ! namelist functions can be used + call this%urbanparams_inst%InitForTesting(bounds) + call this%factory%setup_after_subgrid(snl = 0, dz = 1._r8) call this%factory%create_water_type(this%water_inst, & enable_consistency_checks = .true., & diff --git a/src/dyn_subgrid/test/dynConsBiogeophys_test/test_dyn_cons_biogeophys.pf b/src/dyn_subgrid/test/dynConsBiogeophys_test/test_dyn_cons_biogeophys.pf index d991f0cc54..f77780a424 100644 --- a/src/dyn_subgrid/test/dynConsBiogeophys_test/test_dyn_cons_biogeophys.pf +++ b/src/dyn_subgrid/test/dynConsBiogeophys_test/test_dyn_cons_biogeophys.pf @@ -30,9 +30,9 @@ module test_dyn_cons_biogeophys type(unittest_water_type_factory_type) :: water_type_factory type(soilstate_type) :: soilstate_inst type(temperature_type) :: temperature_inst - type(urbanparams_type) :: urbanparams_inst type(lakestate_type) :: lakestate_inst type(water_type) :: water_inst + type(urbanparams_type) :: urbanparams_inst contains procedure :: setUp procedure :: tearDown @@ -195,6 +195,10 @@ contains ! Arbitrary value, not important here this%urbanparams_inst%nlev_improad(bounds%begl:bounds%endl) = 3 + ! Reguired so that the IsBuildingHumidityEnabled and IsACDehumidificationEnabled + ! namelist functions can be used + call this%urbanparams_inst%InitForTesting(bounds) + ! Initialize water_inst ! (snl and dz are totally arbitrary here: these are unimportant for this test) call this%water_type_factory%setup_after_subgrid(snl = -2, dz = 0.05_r8) diff --git a/src/dyn_subgrid/test/dynInitColumns_test/test_init_columns.pf b/src/dyn_subgrid/test/dynInitColumns_test/test_init_columns.pf index 79ec506f90..6b474ed261 100644 --- a/src/dyn_subgrid/test/dynInitColumns_test/test_init_columns.pf +++ b/src/dyn_subgrid/test/dynInitColumns_test/test_init_columns.pf @@ -15,6 +15,7 @@ module test_init_columns use shr_kind_mod , only : r8 => shr_kind_r8 use TemperatureType , only : temperature_type use WaterType , only : water_type + use UrbanParamsType, only : urbanparams_type use unittestWaterTypeFactory, only : unittest_water_type_factory_type use WaterstateType , only : waterstate_type use dynColumnTemplateMod, only : TEMPLATE_NONE_FOUND @@ -29,6 +30,7 @@ module test_init_columns integer :: l2 ! index of the landunit with landunit type 2 type(temperature_type) :: temperature_inst type(water_type) :: water_inst + type(urbanparams_type) :: urbanparams_inst type(unittest_water_type_factory_type) :: water_factory contains procedure :: setUp @@ -87,6 +89,10 @@ contains call unittest_subgrid_setup_end() + ! Reguired so that the IsBuildingHumidityEnabled and IsACDehumidificationEnabled + ! namelist functions can be used + call this%urbanparams_inst%InitForTesting(bounds) + call this%water_factory%setup_after_subgrid(snl = 0, dz = 1._r8) call this%water_factory%create_water_type(this%water_inst, & enable_isotopes = .true.) diff --git a/src/unit_test_shr/unittestDustEmisInputs.F90 b/src/unit_test_shr/unittestDustEmisInputs.F90 index 771eb410f7..60d6504931 100644 --- a/src/unit_test_shr/unittestDustEmisInputs.F90 +++ b/src/unit_test_shr/unittestDustEmisInputs.F90 @@ -9,6 +9,7 @@ module unittestDustEmisInputs use shr_kind_mod , only : r8 => shr_kind_r8 use unittestFilterBuilderMod, only : filter_from_range use atm2lndType, only : atm2lnd_type, atm2lnd_params_type + use UrbanParamsType, only : urbanparams_type use SoilStateType, only : soilstate_type use CanopyStateType, only : canopystate_type use TemperatureType, only : temperature_type @@ -32,6 +33,7 @@ module unittestDustEmisInputs type(unittest_water_type_factory_type), private :: water_factory type(water_type) :: water_inst type(frictionvel_type) :: frictionvel_inst + type(urbanparams_type) :: urbanparams_inst contains procedure, public :: setUp procedure, public :: tearDown @@ -86,6 +88,11 @@ subroutine setUp(this) ) call this%atm2lnd_inst%InitForTesting(bounds, atm2lnd_params) + + ! Reguired so that the IsBuildingHumidityEnabled and IsACDehumidificationEnabled + ! namelist functions can be used + call this%urbanparams_inst%InitForTesting(bounds) + ! Water and soil state -- after the subgrid setup call this%water_factory%setup_after_subgrid(snl = snl) call this%setupSoilState( ) ! This needs to happen before the water_type object creation @@ -271,4 +278,4 @@ end subroutine print_values !----------------------------------------------------------------------- -end module unittestDustEmisInputs \ No newline at end of file +end module unittestDustEmisInputs From af042b65c57367ea7e52e795b67476915d3c33d4 Mon Sep 17 00:00:00 2001 From: Keith Oleson Date: Thu, 3 Sep 2026 15:45:28 -0600 Subject: [PATCH 63/89] Replace assignment with variable name --- src/biogeophys/UrbanParamsType.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90 index 060dccb8c2..1a7b87aaae 100644 --- a/src/biogeophys/UrbanParamsType.F90 +++ b/src/biogeophys/UrbanParamsType.F90 @@ -388,7 +388,7 @@ subroutine InitForTesting(this, bounds) !----------------------------------------------------------------------- ! Default setting (prognostic indoor humidity and dehumidification off) - building_humidity_mode = 0 + building_humidity_mode = BUILDING_HUMIDITY_MODE_OFF ! We set this to .true. to enable the IsBuildingHumidityEnabled and ! IsACDehumidificationEnabled functions to be used for unit testing From 752b2eabad2b7dc4b3a06d5082e360e440267ba1 Mon Sep 17 00:00:00 2001 From: Cathy Xinchang Li Date: Mon, 7 Sep 2026 14:17:25 -0600 Subject: [PATCH 64/89] address additional comments after paired review --- src/biogeophys/UrbBuildTempOleson2015Mod.F90 | 1181 +++++++++--------- src/biogeophys/UrbanParamsType.F90 | 4 +- src/biogeophys/WaterFluxType.F90 | 3 +- 3 files changed, 586 insertions(+), 602 deletions(-) diff --git a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 index d9836e453d..d33f4ec815 100644 --- a/src/biogeophys/UrbBuildTempOleson2015Mod.F90 +++ b/src/biogeophys/UrbBuildTempOleson2015Mod.F90 @@ -34,6 +34,9 @@ module UrbBuildTempOleson2015Mod ! !PUBLIC MEMBER FUNCTIONS: public :: BuildingTemperature ! Calculation of interior building air temperature, inner ! surface temperatures of walls and roof, and floor temperature + + ! !PRIVATE PARAMETERS: + real(r8), parameter :: ac_latent_error_thresh = 1.e-5_r8 ! Error threshold for the AC latent-energy consistency check [W/m2 of urban area] character(len=*), parameter, private :: sourcefile = & __FILE__ @@ -215,7 +218,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, hcv_floor, hcv_floor_enhanced, hcv_sunw, hcv_shdw, & em_roof_int, em_floor_int, em_sunw_int, em_shdw_int, & dz_floor, dens_floor, cp_floor, vent_ach, & - rh_building_max, hvap, rwat, cpwvap + rh_building_max, hvap, rwat, cpwvap, secsphr, pct_to_frac use column_varcon , only : icol_roof, icol_sunwall, icol_shadewall use clm_varctl , only : iulog use abortutils , only : endrun @@ -389,55 +392,53 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) g = lun%gridcell(l) - if (urbpoi(l)) then - t_roof_inner_bef(l) = t_roof_inner(l) - t_sunw_inner_bef(l) = t_sunw_inner(l) - t_shdw_inner_bef(l) = t_shdw_inner(l) - t_floor_bef(l) = t_floor(l) - t_building_bef(l) = t_building(l) - if (IsBuildingHumidityEnabled()) then - q_building_bef(l) = q_building(l) - end if - if (t_roof_inner_bef(l) .le. t_building_bef(l)) then - hcv_roofi(l) = hcv_roof_enhanced - else - hcv_roofi(l) = hcv_roof - end if - if (t_floor_bef(l) .ge. t_building_bef(l)) then - hcv_floori(l) = hcv_floor_enhanced - else - hcv_floori(l) = hcv_floor - end if - hcv_sunwi(l) = hcv_sunw - hcv_shdwi(l) = hcv_shdw - em_roofi(l) = em_roof_int - em_sunwi(l) = em_sunw_int - em_shdwi(l) = em_shdw_int - em_floori(l) = em_floor_int - ! Concrete floor thickness (m) - dz_floori(l) = dz_floor - ! Concrete floor volumetric heat capacity (J m-3 K-1) - cp_floori(l) = cp_floor - ! Intermediate calculation for concrete floor (W m-2 K-1) - cv_floori(l) = (dz_floori(l) * cp_floori(l)) / dtime - if (IsBuildingHumidityEnabled()) then - ! Specific humidity (kg/kg) and vapor pressure (Pa) at saturation at current temperature and pressure - call QSat(t_building_bef(l), forc_pbot(g), qsat_building, es = esat_building) - ! Indoor vapor pressure (Pa) from saturation vapor pressure. The saturation ratio is capped at 1 (100% saturation) - ! so indoor vapor pressure does not exceed saturation vapor pressure - p_vapor = min(1._r8, q_building_bef(l) / qsat_building) * esat_building - ! Density (kg m-3) and specific heat capacity (J kg-1 K-1) of moist air at current temperature and pressure - rho_air(l) = (forc_pbot(g) - p_vapor) / (rair * t_building_bef(l)) & - + p_vapor / (rwat * t_building_bef(l)) - cp_air(l) = cpair + cpwvap * q_building_bef(l) - else - ! Density (kg m-3) and specific heat capacity (J kg-1 K-1) of dry air at current temperature and pressure - rho_air(l) = forc_pbot(g) / (rair*t_building_bef(l)) - cp_air(l) = cpair - end if - ! Building height to building width ratio - building_hwr(l) = canyon_hwr(l)*(1._r8-wtlunit_roof(l))/wtlunit_roof(l) + t_roof_inner_bef(l) = t_roof_inner(l) + t_sunw_inner_bef(l) = t_sunw_inner(l) + t_shdw_inner_bef(l) = t_shdw_inner(l) + t_floor_bef(l) = t_floor(l) + t_building_bef(l) = t_building(l) + if (IsBuildingHumidityEnabled()) then + q_building_bef(l) = q_building(l) + end if + if (t_roof_inner_bef(l) .le. t_building_bef(l)) then + hcv_roofi(l) = hcv_roof_enhanced + else + hcv_roofi(l) = hcv_roof end if + if (t_floor_bef(l) .ge. t_building_bef(l)) then + hcv_floori(l) = hcv_floor_enhanced + else + hcv_floori(l) = hcv_floor + end if + hcv_sunwi(l) = hcv_sunw + hcv_shdwi(l) = hcv_shdw + em_roofi(l) = em_roof_int + em_sunwi(l) = em_sunw_int + em_shdwi(l) = em_shdw_int + em_floori(l) = em_floor_int + ! Concrete floor thickness (m) + dz_floori(l) = dz_floor + ! Concrete floor volumetric heat capacity (J m-3 K-1) + cp_floori(l) = cp_floor + ! Intermediate calculation for concrete floor (W m-2 K-1) + cv_floori(l) = (dz_floori(l) * cp_floori(l)) / dtime + if (IsBuildingHumidityEnabled()) then + ! Specific humidity (kg/kg) and vapor pressure (Pa) at saturation at current temperature and pressure + call QSat(t_building_bef(l), forc_pbot(g), qsat_building, es = esat_building) + ! Indoor vapor pressure (Pa) from saturation vapor pressure. The saturation ratio is capped at 1 (100% saturation) + ! so indoor vapor pressure does not exceed saturation vapor pressure + p_vapor = min(1._r8, q_building_bef(l) / qsat_building) * esat_building + ! Density (kg m-3) and specific heat capacity (J kg-1 K-1) of moist air at current temperature and pressure + rho_air(l) = (forc_pbot(g) - p_vapor) / (rair * t_building_bef(l)) & + + p_vapor / (rwat * t_building_bef(l)) + cp_air(l) = cpair + cpwvap * q_building_bef(l) + else + ! Density (kg m-3) and specific heat capacity (J kg-1 K-1) of dry air at current temperature and pressure + rho_air(l) = forc_pbot(g) / (rair*t_building_bef(l)) + cp_air(l) = cpair + end if + ! Building height to building width ratio + building_hwr(l) = canyon_hwr(l)*(1._r8-wtlunit_roof(l))/wtlunit_roof(l) end do ! Get terms from soil temperature equations to compute conduction flux @@ -477,52 +478,48 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, ! Calculate view factors do fl = 1,num_urbanl l = filter_urbanl(fl) - if (urbpoi(l)) then - vf_rf(l) = sqrt(1._r8 + building_hwr(l)**2._r8) - building_hwr(l) - vf_fr(l) = vf_rf(l) + vf_rf(l) = sqrt(1._r8 + building_hwr(l)**2._r8) - building_hwr(l) + vf_fr(l) = vf_rf(l) - ! This view factor implicitly converts from per unit wall area to per unit floor area - vf_wf(l) = 0.5_r8*(1._r8 - vf_rf(l)) + ! This view factor implicitly converts from per unit wall area to per unit floor area + vf_wf(l) = 0.5_r8*(1._r8 - vf_rf(l)) - vf_fw(l) = vf_wf(l) + vf_fw(l) = vf_wf(l) - vf_rw(l) = vf_fw(l) + vf_rw(l) = vf_fw(l) - ! This view factor implicitly converts from per unit wall area to per unit roof area - vf_wr(l) = vf_wf(l) + ! This view factor implicitly converts from per unit wall area to per unit roof area + vf_wr(l) = vf_wf(l) - vf_ww(l) = 1._r8 - vf_rw(l) - vf_fw(l) + vf_ww(l) = 1._r8 - vf_rw(l) - vf_fw(l) - end if end do ! error check -- make sure view factor sums to one for floor, wall, and roof do fl = 1,num_urbanl l = filter_urbanl(fl) - if (urbpoi(l)) then - - sum = vf_rf(l) + 2._r8*vf_wf(l) - if (abs(sum-1._r8) > 1.e-06_r8 ) then - write (iulog,*) 'urban floor view factor error',sum - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - endif - sum = vf_rw(l) + vf_fw(l) + vf_ww(l) - if (abs(sum-1._r8) > 1.e-06_r8 ) then - write (iulog,*) 'urban wall view factor error',sum - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - endif - sum = vf_fr(l) + vf_wr(l) + vf_wr(l) - if (abs(sum-1._r8) > 1.e-06_r8 ) then - write (iulog,*) 'urban roof view factor error',sum - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - endif + sum = vf_rf(l) + 2._r8*vf_wf(l) + if (abs(sum-1._r8) > 1.e-06_r8 ) then + write (iulog,*) 'urban floor view factor error',sum + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + endif + sum = vf_rw(l) + vf_fw(l) + vf_ww(l) + if (abs(sum-1._r8) > 1.e-06_r8 ) then + write (iulog,*) 'urban wall view factor error',sum + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) endif + sum = vf_fr(l) + vf_wr(l) + vf_wr(l) + if (abs(sum-1._r8) > 1.e-06_r8 ) then + write (iulog,*) 'urban roof view factor error',sum + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + endif + end do n = neq @@ -532,458 +529,452 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) - if (urbpoi(l)) then - ! ROOF - a(1,1) = 0.5_r8*hcv_roofi(l) & - + 0.5_r8*tk_roof_innerl(l)/(zi_roof_innerl(l) - z_roof_innerl(l)) & - + 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8 & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fr(l) - - a(1,2) = - 4._r8*em_roofi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wr(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) - - a(1,3) = - 4._r8*em_roofi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) - - a(1,4) = - 4._r8*em_roofi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wr(l) - - a(1,5) = - 0.5_r8*hcv_roofi(l) - - result(1) = 0.5_r8*tk_roof_innerl(l)*t_roof_innerl(l)/(zi_roof_innerl(l) - z_roof_innerl(l)) & - - 0.5_r8*tk_roof_innerl(l)*(t_roof_inner_bef(l)-t_roof_innerl_bef(l))/(zi_roof_innerl(l) & - - z_roof_innerl(l)) & - - 3._r8*em_roofi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l) & - - 3._r8*em_roofi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l) & - - 3._r8*em_roofi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l) & - + 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8 & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fr(l) & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wr(l) & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & - - 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) - - ! SUNWALL - a(2,1) = - 4._r8*em_sunwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) - - a(2,2) = 0.5_r8*hcv_sunwi(l)*building_hwr(l) & - + 0.5_r8*tk_sunw_innerl(l)/(zi_sunw_innerl(l) - z_sunw_innerl(l))*building_hwr(l) & - + 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8 & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_ww(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) - - a(2,3) = - 4._r8*em_sunwi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) - - a(2,4) = - 4._r8*em_sunwi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_ww(l) - a(2,5) = - 0.5_r8*hcv_sunwi(l)*building_hwr(l) - - result(2) = 0.5_r8*tk_sunw_innerl(l)*t_sunw_innerl(l)/(zi_sunw_innerl(l) - z_sunw_innerl(l))*building_hwr(l) & - - 0.5_r8*tk_sunw_innerl(l)*(t_sunw_inner_bef(l)-t_sunw_innerl_bef(l))/(zi_sunw_innerl(l) & - - z_sunw_innerl(l))*building_hwr(l) & - - 3._r8*em_sunwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l) & - - 3._r8*em_sunwi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l) & - - 3._r8*em_sunwi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l) & - + 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8 & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_ww(l) & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & - - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) - - ! SHADEWALL - a(3,1) = - 4._r8*em_shdwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) - - a(3,2) = - 4._r8*em_shdwi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) - - a(3,3) = 0.5_r8*hcv_shdwi(l)*building_hwr(l) & - + 0.5_r8*tk_shdw_innerl(l)/(zi_shdw_innerl(l) - z_shdw_innerl(l))*building_hwr(l) & - + 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8 & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_ww(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) - - a(3,4) = - 4._r8*em_shdwi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_ww(l) - - a(3,5) = - 0.5_r8*hcv_shdwi(l)*building_hwr(l) - - result(3) = 0.5_r8*tk_shdw_innerl(l)*t_shdw_innerl(l)/(zi_shdw_innerl(l) - z_shdw_innerl(l))*building_hwr(l) & - - 0.5_r8*tk_shdw_innerl(l)*(t_shdw_inner_bef(l)-t_shdw_innerl_bef(l))/(zi_shdw_innerl(l) & - - z_shdw_innerl(l))*building_hwr(l) & - - 3._r8*em_shdwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l) & - - 3._r8*em_shdwi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l) & - - 3._r8*em_shdwi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l) & - + 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8 & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_ww(l) & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & - - 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) - - ! FLOOR - a(4,1) = - 4._r8*em_floori(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wf(l) - - a(4,2) = - 4._r8*em_floori(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wf(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) - - a(4,3) = - 4._r8*em_floori(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wf(l) - - a(4,4) = (cv_floori(l) + 0.5_r8*hcv_floori(l)) & - + 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8 & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rf(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wf(l) - - a(4,5) = - 0.5_r8*hcv_floori(l) - - result(4) = cv_floori(l)*t_floor_bef(l) & - - 3._r8*em_floori(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l) & - - 3._r8*em_floori(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l) & - - 3._r8*em_floori(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l) & - + 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8 & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rf(l) & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & - - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wf(l) & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wf(l) & - - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & - - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wf(l) & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & - - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wf(l) & - - 0.5_r8*hcv_floori(l)*(t_floor_bef(l) - t_building_bef(l)) - - ! Building air temperature - a(5,1) = - 0.5_r8*hcv_roofi(l) - a(5,2) = - 0.5_r8*hcv_sunwi(l)*building_hwr(l) - - a(5,3) = - 0.5_r8*hcv_shdwi(l)*building_hwr(l) - - a(5,4) = - 0.5_r8*hcv_floori(l) - - a(5,5) = ((ht_roof(l)*rho_air(l)*cp_air(l))/dtime) + & - ((ht_roof(l)*vent_ach)/3600._r8)*rho_air(l)*cp_air(l) + & - 0.5_r8*hcv_roofi(l) + & - 0.5_r8*hcv_sunwi(l)*building_hwr(l) + & - 0.5_r8*hcv_shdwi(l)*building_hwr(l) + & - 0.5_r8*hcv_floori(l) - - result(5) = (ht_roof(l)*rho_air(l)*cp_air(l)/dtime)*t_building_bef(l) & - + ((ht_roof(l)*vent_ach)/3600._r8)*rho_air(l)*cp_air(l)*taf(l) & - + 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & - + 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & - + 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & - + 0.5_r8*hcv_floori(l)*(t_floor_bef(l) - t_building_bef(l)) - - ! Solve equations - call dgesv(n, nrhs, a, lda, ipiv, result, ldb, info) - - ! If dgesv fails, abort - if (info /= 0) then - write(iulog,*)'fl: ',fl - write(iulog,*)'l: ',l - write(iulog,*)'dgesv info: ',info - write (iulog,*) 'dgesv error' - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - end if - ! Assign new temperatures - t_roof_inner(l) = result(1) - t_sunw_inner(l) = result(2) - t_shdw_inner(l) = result(3) - t_floor(l) = result(4) - t_building(l) = result(5) + ! ROOF + a(1,1) = 0.5_r8*hcv_roofi(l) & + + 0.5_r8*tk_roof_innerl(l)/(zi_roof_innerl(l) - z_roof_innerl(l)) & + + 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8 & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fr(l) + + a(1,2) = - 4._r8*em_roofi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wr(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) + + a(1,3) = - 4._r8*em_roofi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) + + a(1,4) = - 4._r8*em_roofi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wr(l) + + a(1,5) = - 0.5_r8*hcv_roofi(l) + + result(1) = 0.5_r8*tk_roof_innerl(l)*t_roof_innerl(l)/(zi_roof_innerl(l) - z_roof_innerl(l)) & + - 0.5_r8*tk_roof_innerl(l)*(t_roof_inner_bef(l)-t_roof_innerl_bef(l))/(zi_roof_innerl(l) & + - z_roof_innerl(l)) & + - 3._r8*em_roofi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l) & + - 3._r8*em_roofi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l) & + - 3._r8*em_roofi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l) & + + 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8 & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fr(l) & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wr(l) & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & + - 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) + + ! SUNWALL + a(2,1) = - 4._r8*em_sunwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) + + a(2,2) = 0.5_r8*hcv_sunwi(l)*building_hwr(l) & + + 0.5_r8*tk_sunw_innerl(l)/(zi_sunw_innerl(l) - z_sunw_innerl(l))*building_hwr(l) & + + 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8 & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_ww(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) + + a(2,3) = - 4._r8*em_sunwi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) + + a(2,4) = - 4._r8*em_sunwi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_ww(l) + a(2,5) = - 0.5_r8*hcv_sunwi(l)*building_hwr(l) + + result(2) = 0.5_r8*tk_sunw_innerl(l)*t_sunw_innerl(l)/(zi_sunw_innerl(l) - z_sunw_innerl(l))*building_hwr(l) & + - 0.5_r8*tk_sunw_innerl(l)*(t_sunw_inner_bef(l)-t_sunw_innerl_bef(l))/(zi_sunw_innerl(l) & + - z_sunw_innerl(l))*building_hwr(l) & + - 3._r8*em_sunwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l) & + - 3._r8*em_sunwi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l) & + - 3._r8*em_sunwi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l) & + + 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8 & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_ww(l) & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & + - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) + + ! SHADEWALL + a(3,1) = - 4._r8*em_shdwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) + + a(3,2) = - 4._r8*em_shdwi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) + + a(3,3) = 0.5_r8*hcv_shdwi(l)*building_hwr(l) & + + 0.5_r8*tk_shdw_innerl(l)/(zi_shdw_innerl(l) - z_shdw_innerl(l))*building_hwr(l) & + + 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8 & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_ww(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) + + a(3,4) = - 4._r8*em_shdwi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_ww(l) + + a(3,5) = - 0.5_r8*hcv_shdwi(l)*building_hwr(l) + + result(3) = 0.5_r8*tk_shdw_innerl(l)*t_shdw_innerl(l)/(zi_shdw_innerl(l) - z_shdw_innerl(l))*building_hwr(l) & + - 0.5_r8*tk_shdw_innerl(l)*(t_shdw_inner_bef(l)-t_shdw_innerl_bef(l))/(zi_shdw_innerl(l) & + - z_shdw_innerl(l))*building_hwr(l) & + - 3._r8*em_shdwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l) & + - 3._r8*em_shdwi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l) & + - 3._r8*em_shdwi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l) & + + 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8 & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_ww(l) & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & + - 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) + + ! FLOOR + a(4,1) = - 4._r8*em_floori(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wf(l) + + a(4,2) = - 4._r8*em_floori(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wf(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) + + a(4,3) = - 4._r8*em_floori(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wf(l) + + a(4,4) = (cv_floori(l) + 0.5_r8*hcv_floori(l)) & + + 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8 & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rf(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wf(l) + + a(4,5) = - 0.5_r8*hcv_floori(l) + + result(4) = cv_floori(l)*t_floor_bef(l) & + - 3._r8*em_floori(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l) & + - 3._r8*em_floori(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l) & + - 3._r8*em_floori(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l) & + + 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8 & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l)*(1._r8-em_roofi(l))*vf_rf(l) & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & + - 3._r8*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wf(l) & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wf(l) & + - 3._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & + - 3._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wf(l) & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & + - 3._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wf(l) & + - 0.5_r8*hcv_floori(l)*(t_floor_bef(l) - t_building_bef(l)) + + ! Building air temperature + a(5,1) = - 0.5_r8*hcv_roofi(l) + a(5,2) = - 0.5_r8*hcv_sunwi(l)*building_hwr(l) + + a(5,3) = - 0.5_r8*hcv_shdwi(l)*building_hwr(l) + + a(5,4) = - 0.5_r8*hcv_floori(l) + + a(5,5) = ((ht_roof(l)*rho_air(l)*cp_air(l))/dtime) + & + ((ht_roof(l)*vent_ach)/secsphr)*rho_air(l)*cp_air(l) + & + 0.5_r8*hcv_roofi(l) + & + 0.5_r8*hcv_sunwi(l)*building_hwr(l) + & + 0.5_r8*hcv_shdwi(l)*building_hwr(l) + & + 0.5_r8*hcv_floori(l) + + result(5) = (ht_roof(l)*rho_air(l)*cp_air(l)/dtime)*t_building_bef(l) & + + ((ht_roof(l)*vent_ach)/secsphr)*rho_air(l)*cp_air(l)*taf(l) & + + 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & + + 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & + + 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & + + 0.5_r8*hcv_floori(l)*(t_floor_bef(l) - t_building_bef(l)) + + ! Solve equations + call dgesv(n, nrhs, a, lda, ipiv, result, ldb, info) + + ! If dgesv fails, abort + if (info /= 0) then + write(iulog,*)'fl: ',fl + write(iulog,*)'l: ',l + write(iulog,*)'dgesv info: ',info + write (iulog,*) 'dgesv error' + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if + ! Assign new temperatures + t_roof_inner(l) = result(1) + t_sunw_inner(l) = result(2) + t_shdw_inner(l) = result(3) + t_floor(l) = result(4) + t_building(l) = result(5) end do ! Update indoor specific humidity assuming well-mixed indoor air if (IsBuildingHumidityEnabled()) then do fl = 1,num_urbanl l = filter_urbanl(fl) - if (urbpoi(l)) then - q_building(l) = qaf(l) * (vent_ach/3600._r8 * dtime) & - + q_building_bef(l) * (1 - vent_ach/3600._r8 * dtime) - end if + q_building(l) = qaf(l) * (vent_ach/secsphr * dtime) & + + q_building_bef(l) * (1 - vent_ach/secsphr * dtime) end do end if ! Energy balance checks do fl = 1,num_urbanl l = filter_urbanl(fl) - if (urbpoi(l)) then - qrd_roof(l) = - em_roofi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l) & - - 4._r8*em_roofi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - em_roofi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l) & - - 4._r8*em_roofi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - em_roofi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l) & - - 4._r8*em_roofi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l)*(t_floor(l) - t_floor_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wr(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wr(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rf(l)*(1._r8-em_floori(l))*vf_fr(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fr(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wr(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wr(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wr(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wr(l)*(t_floor(l) & - - t_floor_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wr(l)*(t_floor(l) & - - t_floor_bef(l)) & - + em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8 & - + 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*(t_roof_inner(l) - t_roof_inner_bef(l)) - - qrd_sunw(l) = - em_sunwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l) & - - 4._r8*em_sunwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - em_sunwi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l) & - - 4._r8*em_sunwi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - em_sunwi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l) & - - 4._r8*em_sunwi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(t_floor(l) - t_floor_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_shdwi(l))*vf_ww(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_ww(l)*(1._r8-em_shdwi(l))*vf_ww(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rw(l)*(1._r8-em_shdwi(l))*vf_ww(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_floor(l) & - - t_floor_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fw(l)*(1._r8-em_shdwi(l))*vf_ww(l)*(t_floor(l) & - - t_floor_bef(l)) & - + em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8 & - + 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*(t_sunw_inner(l) - t_sunw_inner_bef(l)) - - qrd_shdw(l) = - em_shdwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l) & - - 4._r8*em_shdwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - em_shdwi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l) & - - 4._r8*em_shdwi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - em_shdwi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l) & - - 4._r8*em_shdwi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(t_floor(l) - t_floor_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_sunwi(l))*vf_ww(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_ww(l)*(1._r8-em_sunwi(l))*vf_ww(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rw(l)*(1._r8-em_sunwi(l))*vf_ww(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_floor(l) & - - t_floor_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fw(l)*(1._r8-em_sunwi(l))*vf_ww(l)*(t_floor(l) & - - t_floor_bef(l)) & - + em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8 & - + 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*(t_shdw_inner(l) - t_shdw_inner_bef(l)) - - qrd_floor(l) = - em_floori(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l) & - - 4._r8*em_floori(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - em_floori(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l) & - - 4._r8*em_floori(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - em_floori(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l) & - - 4._r8*em_floori(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fr(l)*(1._r8-em_roofi(l))*vf_rf(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fr(l)*(1._r8-em_roofi(l))*vf_rf(l)*(t_floor(l) & - - t_floor_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wf(l)*(t_floor(l) & - - t_floor_bef(l)) & - - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wf(l) & - - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wf(l)*(t_floor(l) & - - t_floor_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wf(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wf(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & - - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l)*(t_sunw_inner(l) & - - t_sunw_inner_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wf(l) & - - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wf(l)*(t_shdw_inner(l) & - - t_shdw_inner_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wf(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wf(l) & - - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wf(l)*(t_roof_inner(l) & - - t_roof_inner_bef(l)) & - + em_floori(l)*sb*t_floor_bef(l)**4._r8 & - + 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*(t_floor(l) - t_floor_bef(l)) - - qrd_building(l) = qrd_roof(l) + qrd_sunw(l) + qrd_shdw(l) + qrd_floor(l) - - if (abs(qrd_building(l)) > .10_r8 ) then - write (iulog,*) 'urban inside building net longwave radiation balance error ',qrd_building(l) - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - end if + qrd_roof(l) = - em_roofi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wr(l) & + - 4._r8*em_roofi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wr(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - em_roofi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wr(l) & + - 4._r8*em_roofi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wr(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - em_roofi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fr(l) & + - 4._r8*em_roofi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fr(l)*(t_floor(l) - t_floor_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wr(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wr(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rf(l)*(1._r8-em_floori(l))*vf_fr(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(1._r8-em_floori(l))*vf_fr(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wr(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wr(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wr(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(1._r8-em_floori(l))*vf_fr(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wr(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wr(l)*(t_floor(l) & + - t_floor_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wr(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wr(l)*(t_floor(l) & + - t_floor_bef(l)) & + + em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8 & + + 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*(t_roof_inner(l) - t_roof_inner_bef(l)) + + qrd_sunw(l) = - em_sunwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l) & + - 4._r8*em_sunwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - em_sunwi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_ww(l) & + - 4._r8*em_sunwi(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_ww(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - em_sunwi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l) & + - 4._r8*em_sunwi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(t_floor(l) - t_floor_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_shdwi(l))*vf_ww(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_ww(l)*(1._r8-em_shdwi(l))*vf_ww(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rw(l)*(1._r8-em_shdwi(l))*vf_ww(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_floor(l) & + - t_floor_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_shdwi(l))*vf_ww(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fw(l)*(1._r8-em_shdwi(l))*vf_ww(l)*(t_floor(l) & + - t_floor_bef(l)) & + + em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8 & + + 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*(t_sunw_inner(l) - t_sunw_inner_bef(l)) + + qrd_shdw(l) = - em_shdwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rw(l) & + - 4._r8*em_shdwi(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rw(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - em_shdwi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_ww(l) & + - 4._r8*em_shdwi(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_ww(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - em_shdwi(l)*em_floori(l)*sb*t_floor_bef(l)**4._r8*vf_fw(l) & + - 4._r8*em_shdwi(l)*em_floori(l)*sb*t_floor_bef(l)**3._r8*vf_fw(l)*(t_floor(l) - t_floor_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_sunwi(l))*vf_ww(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_ww(l)*(1._r8-em_sunwi(l))*vf_ww(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rw(l)*(1._r8-em_sunwi(l))*vf_ww(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rf(l)*(1._r8-em_floori(l))*vf_fw(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fr(l)*(1._r8-em_roofi(l))*vf_rw(l)*(t_floor(l) & + - t_floor_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_sunwi(l))*vf_ww(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fw(l)*(1._r8-em_sunwi(l))*vf_ww(l)*(t_floor(l) & + - t_floor_bef(l)) & + + em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8 & + + 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*(t_shdw_inner(l) - t_shdw_inner_bef(l)) + + qrd_floor(l) = - em_floori(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8*vf_rf(l) & + - 4._r8*em_floori(l)*em_roofi(l)*sb*t_roof_inner_bef(l)**3._r8*vf_rf(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - em_floori(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8*vf_wf(l) & + - 4._r8*em_floori(l)*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3._r8*vf_wf(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - em_floori(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8*vf_wf(l) & + - 4._r8*em_floori(l)*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3._r8*vf_wf(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fr(l)*(1._r8-em_roofi(l))*vf_rf(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fr(l)*(1._r8-em_roofi(l))*vf_rf(l)*(t_floor(l) & + - t_floor_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fw(l)*(1._r8-em_sunwi(l))*vf_wf(l)*(t_floor(l) & + - t_floor_bef(l)) & + - (em_floori(l)*sb*t_floor_bef(l)**4._r8)*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wf(l) & + - 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*vf_fw(l)*(1._r8-em_shdwi(l))*vf_wf(l)*(t_floor(l) & + - t_floor_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wf(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_ww(l)*(1._r8-em_shdwi(l))*vf_wf(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_sunwi(l)*sb*t_sunw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & + - 4._r8*em_sunwi(l)*sb*t_sunw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l)*(t_sunw_inner(l) & + - t_sunw_inner_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_wr(l)*(1._r8-em_roofi(l))*vf_rf(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_shdwi(l)*sb*t_shdw_inner_bef(l)**4._r8)*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wf(l) & + - 4._r8*em_shdwi(l)*sb*t_shdw_inner_bef(l)**3.*vf_ww(l)*(1._r8-em_sunwi(l))*vf_wf(l)*(t_shdw_inner(l) & + - t_shdw_inner_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wf(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rw(l)*(1._r8-em_sunwi(l))*vf_wf(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + - (em_roofi(l)*sb*t_roof_inner_bef(l)**4._r8)*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wf(l) & + - 4._r8*em_roofi(l)*sb*t_roof_inner_bef(l)**3.*vf_rw(l)*(1._r8-em_shdwi(l))*vf_wf(l)*(t_roof_inner(l) & + - t_roof_inner_bef(l)) & + + em_floori(l)*sb*t_floor_bef(l)**4._r8 & + + 4._r8*em_floori(l)*sb*t_floor_bef(l)**3.*(t_floor(l) - t_floor_bef(l)) + + qrd_building(l) = qrd_roof(l) + qrd_sunw(l) + qrd_shdw(l) + qrd_floor(l) + + if (abs(qrd_building(l)) > .10_r8 ) then + write (iulog,*) 'urban inside building net longwave radiation balance error ',qrd_building(l) + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + end if - qcv_roof(l) = 0.5_r8*hcv_roofi(l)*(t_roof_inner(l) - t_building(l)) + 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) & - - t_building_bef(l)) - qcd_roof(l) = 0.5_r8*tk_roof_innerl(l)*(t_roof_inner(l) - t_roof_innerl(l))/(zi_roof_innerl(l) - z_roof_innerl(l)) & - + 0.5_r8*tk_roof_innerl(l)*(t_roof_inner_bef(l) - t_roof_innerl_bef(l))/(zi_roof_innerl(l) & - - z_roof_innerl(l)) - enrgy_bal_roof(l) = qrd_roof(l) + qcv_roof(l) + qcd_roof(l) - if (abs(enrgy_bal_roof(l)) > .10_r8 ) then - write (iulog,*) 'urban inside roof energy balance error ',enrgy_bal_roof(l) - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - end if + qcv_roof(l) = 0.5_r8*hcv_roofi(l)*(t_roof_inner(l) - t_building(l)) + 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) & + - t_building_bef(l)) + qcd_roof(l) = 0.5_r8*tk_roof_innerl(l)*(t_roof_inner(l) - t_roof_innerl(l))/(zi_roof_innerl(l) - z_roof_innerl(l)) & + + 0.5_r8*tk_roof_innerl(l)*(t_roof_inner_bef(l) - t_roof_innerl_bef(l))/(zi_roof_innerl(l) & + - z_roof_innerl(l)) + enrgy_bal_roof(l) = qrd_roof(l) + qcv_roof(l) + qcd_roof(l) + if (abs(enrgy_bal_roof(l)) > .10_r8 ) then + write (iulog,*) 'urban inside roof energy balance error ',enrgy_bal_roof(l) + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + end if - qcv_sunw(l) = 0.5_r8*hcv_sunwi(l)*(t_sunw_inner(l) - t_building(l)) + 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) & - - t_building_bef(l)) - qcd_sunw(l) = 0.5_r8*tk_sunw_innerl(l)*(t_sunw_inner(l) - t_sunw_innerl(l))/(zi_sunw_innerl(l) - z_sunw_innerl(l)) & - + 0.5_r8*tk_sunw_innerl(l)*(t_sunw_inner_bef(l) - t_sunw_innerl_bef(l))/(zi_sunw_innerl(l) & - - z_sunw_innerl(l)) - enrgy_bal_sunw(l) = qrd_sunw(l) + qcv_sunw(l)*building_hwr(l) + qcd_sunw(l)*building_hwr(l) - if (abs(enrgy_bal_sunw(l)) > .10_r8 ) then - write (iulog,*) 'urban inside sunwall energy balance error ',enrgy_bal_sunw(l) - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - end if + qcv_sunw(l) = 0.5_r8*hcv_sunwi(l)*(t_sunw_inner(l) - t_building(l)) + 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) & + - t_building_bef(l)) + qcd_sunw(l) = 0.5_r8*tk_sunw_innerl(l)*(t_sunw_inner(l) - t_sunw_innerl(l))/(zi_sunw_innerl(l) - z_sunw_innerl(l)) & + + 0.5_r8*tk_sunw_innerl(l)*(t_sunw_inner_bef(l) - t_sunw_innerl_bef(l))/(zi_sunw_innerl(l) & + - z_sunw_innerl(l)) + enrgy_bal_sunw(l) = qrd_sunw(l) + qcv_sunw(l)*building_hwr(l) + qcd_sunw(l)*building_hwr(l) + if (abs(enrgy_bal_sunw(l)) > .10_r8 ) then + write (iulog,*) 'urban inside sunwall energy balance error ',enrgy_bal_sunw(l) + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + end if - qcv_shdw(l) = 0.5_r8*hcv_shdwi(l)*(t_shdw_inner(l) - t_building(l)) + 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) & - - t_building_bef(l)) - qcd_shdw(l) = 0.5_r8*tk_shdw_innerl(l)*(t_shdw_inner(l) - t_shdw_innerl(l))/(zi_shdw_innerl(l) - z_shdw_innerl(l)) & - + 0.5_r8*tk_shdw_innerl(l)*(t_shdw_inner_bef(l) - t_shdw_innerl_bef(l))/(zi_shdw_innerl(l) & - - z_shdw_innerl(l)) - enrgy_bal_shdw(l) = qrd_shdw(l) + qcv_shdw(l)*building_hwr(l) + qcd_shdw(l)*building_hwr(l) - if (abs(enrgy_bal_shdw(l)) > .10_r8 ) then - write (iulog,*) 'urban inside shadewall energy balance error ',enrgy_bal_shdw(l) - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - end if + qcv_shdw(l) = 0.5_r8*hcv_shdwi(l)*(t_shdw_inner(l) - t_building(l)) + 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) & + - t_building_bef(l)) + qcd_shdw(l) = 0.5_r8*tk_shdw_innerl(l)*(t_shdw_inner(l) - t_shdw_innerl(l))/(zi_shdw_innerl(l) - z_shdw_innerl(l)) & + + 0.5_r8*tk_shdw_innerl(l)*(t_shdw_inner_bef(l) - t_shdw_innerl_bef(l))/(zi_shdw_innerl(l) & + - z_shdw_innerl(l)) + enrgy_bal_shdw(l) = qrd_shdw(l) + qcv_shdw(l)*building_hwr(l) + qcd_shdw(l)*building_hwr(l) + if (abs(enrgy_bal_shdw(l)) > .10_r8 ) then + write (iulog,*) 'urban inside shadewall energy balance error ',enrgy_bal_shdw(l) + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + end if - qcv_floor(l) = 0.5_r8*hcv_floori(l)*(t_floor(l) - t_building(l)) + 0.5_r8*hcv_floori(l)*(t_floor_bef(l) & - - t_building_bef(l)) - qcd_floor(l) = cv_floori(l)*(t_floor(l) - t_floor_bef(l)) - enrgy_bal_floor(l) = qrd_floor(l) + qcv_floor(l) + qcd_floor(l) - if (abs(enrgy_bal_floor(l)) > .10_r8 ) then - write (iulog,*) 'urban inside floor energy balance error ',enrgy_bal_floor(l) - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - end if + qcv_floor(l) = 0.5_r8*hcv_floori(l)*(t_floor(l) - t_building(l)) + 0.5_r8*hcv_floori(l)*(t_floor_bef(l) & + - t_building_bef(l)) + qcd_floor(l) = cv_floori(l)*(t_floor(l) - t_floor_bef(l)) + enrgy_bal_floor(l) = qrd_floor(l) + qcv_floor(l) + qcd_floor(l) + if (abs(enrgy_bal_floor(l)) > .10_r8 ) then + write (iulog,*) 'urban inside floor energy balance error ',enrgy_bal_floor(l) + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + end if - enrgy_bal_buildair(l) = (ht_roof(l)*rho_air(l)*cp_air(l)/dtime)*(t_building(l) - t_building_bef(l)) & - - ht_roof(l)*(vent_ach/3600._r8)*rho_air(l)*cp_air(l)*(taf(l) - t_building(l)) & - - 0.5_r8*hcv_roofi(l)*(t_roof_inner(l) - t_building(l)) & - - 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & - - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner(l) - t_building(l))*building_hwr(l) & - - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & - - 0.5_r8*hcv_shdwi(l)*(t_shdw_inner(l) - t_building(l))*building_hwr(l) & - - 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & - - 0.5_r8*hcv_floori(l)*(t_floor(l) - t_building(l)) & - - 0.5_r8*hcv_floori(l)*(t_floor_bef(l) - t_building_bef(l)) - if (abs(enrgy_bal_buildair(l)) > .10_r8 ) then - write (iulog,*) 'urban building air energy balance error ',enrgy_bal_buildair(l) - write (iulog,*) 'clm model is stopping' - call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) - end if + enrgy_bal_buildair(l) = (ht_roof(l)*rho_air(l)*cp_air(l)/dtime)*(t_building(l) - t_building_bef(l)) & + - ht_roof(l)*(vent_ach/secsphr)*rho_air(l)*cp_air(l)*(taf(l) - t_building(l)) & + - 0.5_r8*hcv_roofi(l)*(t_roof_inner(l) - t_building(l)) & + - 0.5_r8*hcv_roofi(l)*(t_roof_inner_bef(l) - t_building_bef(l)) & + - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner(l) - t_building(l))*building_hwr(l) & + - 0.5_r8*hcv_sunwi(l)*(t_sunw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & + - 0.5_r8*hcv_shdwi(l)*(t_shdw_inner(l) - t_building(l))*building_hwr(l) & + - 0.5_r8*hcv_shdwi(l)*(t_shdw_inner_bef(l) - t_building_bef(l))*building_hwr(l) & + - 0.5_r8*hcv_floori(l)*(t_floor(l) - t_building(l)) & + - 0.5_r8*hcv_floori(l)*(t_floor_bef(l) - t_building_bef(l)) + if (abs(enrgy_bal_buildair(l)) > .10_r8 ) then + write (iulog,*) 'urban building air energy balance error ',enrgy_bal_buildair(l) + write (iulog,*) 'clm model is stopping' + call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) + end if - ! Sensible and latent heat flux (if indoor humidity is prognosed) from ventilation. It is added as a flux to the canyon floor in SoilTemperatureMod. - ! Note that we multiply it here by wtlunit_roof which converts it from W/m2 of building area to W/m2 - ! of urban area. eflx_urban_ac and eflx_urban_heat are treated similarly below. This flux is balanced - ! by an equal and opposite flux into/out of the building and so has a net effect of zero on the energy balance - ! of the urban landunit. - if (IsBuildingHumidityEnabled()) then - eflx_ventilation(l) = wtlunit_roof(l) * ( & - - ht_roof(l) * (vent_ach/3600._r8) * rho_air(l) * cp_air(l) * (taf(l) - t_building(l)) & - - ht_roof(l) * (vent_ach/3600._r8) * rho_air(l) * hvap * (qaf(l) - q_building(l)) ) - else - eflx_ventilation(l) = wtlunit_roof(l) * ( - ht_roof(l)*(vent_ach/3600._r8) & - * rho_air(l) * cpair * (taf(l) - t_building(l)) ) - end if + ! Sensible and latent heat flux (if indoor humidity is prognosed) from ventilation. It is added as a flux to the canyon floor in SoilTemperatureMod. + ! Note that we multiply it here by wtlunit_roof which converts it from W/m2 of building area to W/m2 + ! of urban area. eflx_urban_ac and eflx_urban_heat are treated similarly below. This flux is balanced + ! by an equal and opposite flux into/out of the building and so has a net effect of zero on the energy balance + ! of the urban landunit. + if (IsBuildingHumidityEnabled()) then + eflx_ventilation(l) = wtlunit_roof(l) * ( & + - ht_roof(l) * (vent_ach/secsphr) * rho_air(l) * cp_air(l) * (taf(l) - t_building(l)) & + - ht_roof(l) * (vent_ach/secsphr) * rho_air(l) * hvap * (qaf(l) - q_building(l)) ) + else + eflx_ventilation(l) = wtlunit_roof(l) * ( & + - ht_roof(l) * (vent_ach/secsphr) * rho_air(l) * cpair * (taf(l) - t_building(l)) ) end if end do @@ -996,90 +987,84 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fl = 1,num_urbanl l = filter_urbanl(fl) g = lun%gridcell(l) - if (urbpoi(l)) then - if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then - t_building_bef_hac(l) = t_building(l) + if_hac_on: if (trim(urban_hac) == urban_hac_on .or. trim(urban_hac) == urban_wasteheat_on) then + t_building_bef_hac(l) = t_building(l) ! rho_dair(l) = pstd / (rair*t_building(l)) - if (IsACDehumidificationEnabled()) then - q_building_bef_hac(l) = q_building(l) - ! Convert maximum indoor relative humidity to maximum specific humidity - ! at the current indoor temperature and pressure. - call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) - q_building_max = rh_building_max / 100._r8 * qsat_building_max - end if - - if (t_building_bef_hac(l) > t_building_max(l)) then - if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: - - ! Sensible heat component of AC - ! Here, t_building_max is the AC saturation setpoint - eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_max(l) & - - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) - t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) & - * dtime / (ht_roof(l) * rho_air(l) * cp_air(l) * wtlunit_roof(l)) - if (IsACDehumidificationEnabled()) then - ! Apply the AC adoption rate and assign to the AC sensible heat flux in preparation for later calculations - eflx_urban_ac_sen(l) = p_ac(l) * eflx_urban_ac_sat(l) - end if + if (IsACDehumidificationEnabled()) then + q_building_bef_hac(l) = q_building(l) + ! Convert maximum indoor relative humidity to maximum specific humidity + ! at the current indoor temperature and pressure. + call QSat(t_building_bef_hac(l), forc_pbot(g), qsat_building_max) + q_building_max = rh_building_max * pct_to_frac * qsat_building_max + end if + + if_temp_control: if (t_building_bef_hac(l) > t_building_max(l)) then + if_explicit_ac: if (urban_explicit_ac) then ! use explicit ac adoption rate parameterization scheme: + ! Sensible heat component of AC + ! Here, t_building_max is the AC saturation setpoint + eflx_urban_ac_sat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_max(l) & + - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) + t_building(l) = t_building_max(l) + ( 1._r8 - p_ac(l) ) * eflx_urban_ac_sat(l) & + * dtime / (ht_roof(l) * rho_air(l) * cp_air(l) * wtlunit_roof(l)) + if_dehumidification: if (IsACDehumidificationEnabled()) then + ! Save sensible AC flux at actual adoption for URBAN_AC_SEN history output + ! and the condensate/latent-energy consistency check, before adding latent demand. + eflx_urban_ac_sen(l) = p_ac(l) * eflx_urban_ac_sat(l) ! Latent heat component of AC - if (IsACDehumidificationEnabled()) then - if (q_building_bef_hac(l) > q_building_max) then - ! Calculate latent heat flux needed to lower indoor specific humidity to q_building_max at saturated AC adoption - eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_air(l) * hvap / dtime) * q_building_max & - - (ht_roof(l) * rho_air(l) * hvap / dtime) * q_building_bef_hac(l) ) - ! Add to the sensible heat component calculated previously - eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) - ! Reset q_building based on actual moisture removed at the actual AC adoption rate - q_building(l) = q_building_max + (1._r8 - p_ac(l)) * eflx_urban_ac_sat_lat(l) & - * dtime / (ht_roof(l) * rho_air(l) * hvap * wtlunit_roof(l)) - end if - end if - eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) - else - t_building(l) = t_building_max(l) - eflx_urban_ac(l) = wtlunit_roof(l) * abs( & - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building(l) & - - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) - if (IsACDehumidificationEnabled()) then - eflx_urban_ac_sen(l) = eflx_urban_ac(l) + if (q_building_bef_hac(l) > q_building_max) then + ! Calculate latent heat flux needed to lower indoor specific humidity to q_building_max at saturated AC adoption + eflx_urban_ac_sat_lat(l) = wtlunit_roof(l) * abs( & + (ht_roof(l) * rho_air(l) * hvap / dtime) * q_building_max & + - (ht_roof(l) * rho_air(l) * hvap / dtime) * q_building_bef_hac(l) ) + ! Add to the sensible heat component calculated previously + eflx_urban_ac_sat(l) = eflx_urban_ac_sat(l) + eflx_urban_ac_sat_lat(l) + ! Reset q_building based on actual moisture removed at the actual AC adoption rate + q_building(l) = q_building_max + (1._r8 - p_ac(l)) * eflx_urban_ac_sat_lat(l) & + * dtime / (ht_roof(l) * rho_air(l) * hvap * wtlunit_roof(l)) end if - end if - - else if (t_building_bef_hac(l) < t_building_min(l)) then - ! Humidification during urban heating is not implemented. - t_building(l) = t_building_min(l) - eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building(l) & - - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) - else - if (IsACDehumidificationEnabled()) eflx_urban_ac_sen(l) = 0._r8 - eflx_urban_ac(l) = 0._r8 - eflx_urban_heat(l) = 0._r8 - end if - - else - if (IsACDehumidificationEnabled()) eflx_urban_ac_sen(l) = 0._r8 - eflx_urban_ac(l) = 0._r8 - eflx_urban_heat(l) = 0._r8 - end if - if (IsBuildingHumidityEnabled()) then - ! Calculate sensible and latent heat flux from the change in indoor air state. - eflx_building(l) = wtlunit_roof(l) * ( & - (ht_roof(l) * rho_air(l)*cp_air(l)/dtime) * (t_building(l) - t_building_bef(l)) & - + (ht_roof(l) * rho_air(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) ) - if (IsACDehumidificationEnabled()) then - ! Convert the decrease in indoor water vapor to condensate per building footprint area. - qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_air(l) - qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime - end if - ! Diagnose indoor relative humidity from the updated temperature and humidity. - call QSat(t_building(l), forc_pbot(g), qsat_building) - rh_building(l) = min(100._r8, q_building(l) / qsat_building * 100._r8) - else - eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_air(l)*cpair/dtime) & - * (t_building(l) - t_building_bef(l)) + end if if_dehumidification + eflx_urban_ac(l) = p_ac(l) * eflx_urban_ac_sat(l) + else + t_building(l) = t_building_max(l) + eflx_urban_ac(l) = wtlunit_roof(l) * abs( & + (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) + end if if_explicit_ac + + else if (t_building_bef_hac(l) < t_building_min(l)) then + ! Humidification during urban heating is not implemented. + t_building(l) = t_building_min(l) + eflx_urban_heat(l) = wtlunit_roof(l) * abs( (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building(l) & + - (ht_roof(l) * rho_air(l) * cp_air(l) / dtime) * t_building_bef_hac(l) ) + else + eflx_urban_ac(l) = 0._r8 + eflx_urban_heat(l) = 0._r8 + if (IsACDehumidificationEnabled()) eflx_urban_ac_sen(l) = 0._r8 + end if if_temp_control + + else + eflx_urban_ac(l) = 0._r8 + eflx_urban_heat(l) = 0._r8 + if (IsACDehumidificationEnabled()) eflx_urban_ac_sen(l) = 0._r8 + end if if_hac_on + + if (IsBuildingHumidityEnabled()) then + ! Calculate sensible and latent heat flux from the change in indoor air state. + eflx_building(l) = wtlunit_roof(l) * ( & + (ht_roof(l) * rho_air(l)*cp_air(l)/dtime) * (t_building(l) - t_building_bef(l)) & + + (ht_roof(l) * rho_air(l)*hvap/dtime) * (q_building(l) - q_building_bef(l)) ) + if (IsACDehumidificationEnabled()) then + ! Convert the decrease in indoor water vapor to condensate per building footprint area. + qtot_condensate(l) = max(0._r8, (-q_building(l)+q_building_bef_hac(l))) * ht_roof(l) * rho_air(l) + qflx_condensate_from_ac_lu(l) = wtlunit_roof(l) * qtot_condensate(l) / dtime end if + ! Diagnose indoor relative humidity from the updated temperature and humidity. + call QSat(t_building(l), forc_pbot(g), qsat_building) + rh_building(l) = min(100._r8, q_building(l) / (qsat_building * pct_to_frac)) + else + eflx_building(l) = wtlunit_roof(l) * (ht_roof(l) * rho_air(l)*cpair/dtime) & + * (t_building(l) - t_building_bef(l)) end if end do @@ -1091,7 +1076,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, eflx_urban_ac_lat_derived(l) = qflx_condensate_from_ac_lu(l) * hvap ! Error between the above and the Latent heat component of AC energy flux err_eflx_urban_ac_lat(l) = eflx_urban_ac_lat_derived(l) - (eflx_urban_ac(l) - eflx_urban_ac_sen(l)) - if (abs(err_eflx_urban_ac_lat(l)) > 1.e-5_r8 ) then + if (abs(err_eflx_urban_ac_lat(l)) > ac_latent_error_thresh ) then write (iulog,*) 'dehumidification energy flux derived from condensate does not match condensate output' write (iulog,*) 'dehumidification energy flux derived from condensate [W/m2 urban]: ',eflx_urban_ac_lat_derived(l) write (iulog,*) 'total AC energy flux [W/m2 urban]: ',eflx_urban_ac(l) @@ -1099,7 +1084,7 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, write (iulog,*) 'latent heat component of AC energy flux (total minus sensible) [W/m2 urban]: ', & eflx_urban_ac(l) - eflx_urban_ac_sen(l) write (iulog,*) 'error in dehumidification energy flux [W/m2 urban]: ',err_eflx_urban_ac_lat(l) - write (iulog,*) 'error tolerance [W/m2 urban]: ',1.e-5_r8 + write (iulog,*) 'error tolerance [W/m2 urban]: ',ac_latent_error_thresh write (iulog,*) 'clm model is stopping' call endrun(subgrid_index=l, subgrid_level=subgrid_level_landunit) end if @@ -1112,12 +1097,10 @@ subroutine BuildingTemperature (bounds, num_urbanl, filter_urbanl, num_nolakec, do fc = 1,num_urbanc c = filter_urbanc(fc) l = clandunit(c) - if (urbpoi(l)) then - if (ctype(c) == icol_roof) then - qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime - else - qflx_condensate_from_ac(c) = 0._r8 - end if + if (ctype(c) == icol_roof) then + qflx_condensate_from_ac(c) = qtot_condensate(l)/dtime + else + qflx_condensate_from_ac(c) = 0._r8 end if end do end if diff --git a/src/biogeophys/UrbanParamsType.F90 b/src/biogeophys/UrbanParamsType.F90 index 1a7b87aaae..785c891a89 100644 --- a/src/biogeophys/UrbanParamsType.F90 +++ b/src/biogeophys/UrbanParamsType.F90 @@ -1028,7 +1028,7 @@ logical function IsBuildingHumidityEnabled( ) !----------------------------------------------------------------------- if ( .not. ReadNamelist )then - write(iulog,*)'Testing on building_humidity_mode before urban namelist was read in' + write(iulog,*)'IsBuildingHumidityEnabled called before urban namelist was read in' call endrun(msg=errMsg(sourcefile, __LINE__)) end if IsBuildingHumidityEnabled = building_humidity_mode >= BUILDING_HUMIDITY_MODE_ON @@ -1056,7 +1056,7 @@ logical function IsACDehumidificationEnabled( ) !----------------------------------------------------------------------- if ( .not. ReadNamelist )then - write(iulog,*)'Testing on building_humidity_mode before urban namelist was read in' + write(iulog,*)'IsACDehumidificationEnabled called before urban namelist was read in' call endrun(msg=errMsg(sourcefile, __LINE__)) end if IsACDehumidificationEnabled = building_humidity_mode == BUILDING_HUMIDITY_MODE_DEHUMIDIFY diff --git a/src/biogeophys/WaterFluxType.F90 b/src/biogeophys/WaterFluxType.F90 index ecbed09b19..44ff5f8673 100644 --- a/src/biogeophys/WaterFluxType.F90 +++ b/src/biogeophys/WaterFluxType.F90 @@ -272,6 +272,8 @@ subroutine InitAllocate(this, bounds, tracer_vars) call AllocateVar1d(var = this%qflx_liqevap_from_top_layer_patch, name = 'qflx_liqevap_from_top_layer_patch', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_patch) + ! The following two vars are initialized as 0.0_r8 rather than spval + ! to prevent nan from occurring during spatial aggregation call AllocateVar1d(var = this%qflx_condensate_from_ac_col, name = 'qflx_condensate_from_ac_col', & container = tracer_vars, & bounds = bounds, subgrid_level = subgrid_level_column, ival = 0.0_r8) @@ -605,7 +607,6 @@ subroutine InitHistory(this, bounds) avgflag='A', & long_name=this%info%lname('Condensed water flux from AC dehumidification'), & ptr_col=this%qflx_condensate_from_ac_col, set_nourb=0.0_r8, c2l_scale_type='urbanf') - this%qflx_condensate_from_ac_lun(begl:endl) = 0.0_r8 end if this%qflx_snomelt_col(begc:endc) = spval From ed30f1bad64ccec3e5a134321af6d7646f620297 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 11 Sep 2026 17:40:45 -0600 Subject: [PATCH 65/89] Add this PR's new history fields to the master list .rst file --- .../setting-up-and-running-a-case/history_fields_nofates.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst index 8a8f4c6e38..512b8dfb1e 100644 --- a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst +++ b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst @@ -875,10 +875,13 @@ PSNSHADE_TO_CPOOL - C fixation from shaded cano PSNSUN - sunlit leaf photosynthesis umolCO2/m^2/s T F PSNSUN_TO_CPOOL - C fixation from sunlit canopy gC/m^2/s T F PSurf - atmospheric pressure at surface (downscaled for glacier and hillslope columns) Pa F F +P_AC - prescribed air-conditioning ownership rate a fraction between 0 and 1 F F Q2M - 2m specific humidity kg/kg T F QAF - canopy air humidity kg/kg F F QBOT - atmospheric specific humidity (downscaled to columns in glacier regions) kg/kg T F QBOT_NOT_DOWNSCALED - atmospheric specific humidity (pre-downscaling) kg/kg F F +QBUILD - internal urban building air specific humidity kg/kg T F +QCOND_FROM_AC - Condensed water flux from AC dehumidification mm/s T F QDIRECT_THROUGHFALL - direct throughfall of liquid (rain + above-canopy irrigation) mm/s F F QDIRECT_THROUGHFALL_SNOW - direct throughfall of snow mm/s F F QDRAI - sub-surface drainage mm/s T F @@ -965,6 +968,7 @@ RH2M_U - Urban 2m relative humidity RH30 - 30-day running mean of relative humidity % F F RHAF - fractional humidity of canopy air fraction F F RHAF10 - 10 day running mean of fractional humidity of canopy air fraction F F +RHBUILD - Internal urban building air relative humidity % T F RH_LEAF - fractional humidity at leaf surface fraction F F RR - root respiration (fine root MR + total root GR) gC/m^2/s T F RSSHA - shaded leaf stomatal resistance s/m T F @@ -1195,6 +1199,7 @@ UAF - canopy air speed ULRAD - upward longwave radiation above the canopy W/m^2 F F UM - wind speed plus stability effect m/s F F URBAN_AC - urban air conditioning flux W/m^2 T F +URBAN_AC_SEN - sensible heat component of urban air conditioning flux W/m^2 T F URBAN_HEAT - urban heating flux W/m^2 T F USTAR - friction velocity m/s F F UST_LAKE - friction velocity (lakes only) m/s F F From 78f95d0632293c6698bab9cd9b78952c96d93514 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Wed, 16 Sep 2026 12:53:12 -0600 Subject: [PATCH 66/89] Update history_fields_*.rst with the new fields + correct histFileMod The latter is a simple bug that I just discovered when writing history_fields_*.rst where actflag is written out in the wrong order, so I'm fixingthat --- .../history_fields_fates.rst | 5 +++++ .../history_fields_nofates.rst | 8 ++++---- src/main/histFileMod.F90 | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_fates.rst b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_fates.rst index a886a3f6ce..e57c113a24 100644 --- a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_fates.rst +++ b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_fates.rst @@ -393,10 +393,13 @@ PROD10C_LOSS - loss from 10-yr wood produc PROD10N - 10-yr wood product N gN/m^2 F PROD10N_LOSS - loss from 10-yr wood product pool gN/m^2/s F PSurf - atmospheric pressure at surface (downscaled for glacier and hillslope columns) Pa F +P_AC - prescribed air-conditioning ownership rate a fraction between 0 and 1 F Q2M - 2m specific humidity kg/kg T QAF - canopy air humidity kg/kg F QBOT - atmospheric specific humidity (downscaled to columns in glacier regions) kg/kg T QBOT_NOT_DOWNSCALED - atmospheric specific humidity (pre-downscaling) kg/kg F +QBUILD - internal urban building air specific humidity kg/kg F +QCOND_FROM_AC - Condensed water flux from AC dehumidification mm/s F QDIRECT_THROUGHFALL - direct throughfall of liquid (rain + above-canopy irrigation) mm/s F QDIRECT_THROUGHFALL_SNOW - direct throughfall of snow mm/s F QDRAI - sub-surface drainage mm/s T @@ -477,6 +480,7 @@ RH2M - 2m relative humidity RH2M_R - Rural 2m relative humidity % F RH2M_U - Urban 2m relative humidity % F RHAF - fractional humidity of canopy air fraction F +RHBUILD - Internal urban building air relative humidity % F RH_LEAF - fractional humidity at leaf surface fraction F RSCANOPY - canopy resistance s m-1 T RSSHA - shaded leaf stomatal resistance s/m T @@ -651,6 +655,7 @@ U10_ICE - 10-m wind (ice landunits on UAF - canopy air speed m/s F UM - wind speed plus stability effect m/s F URBAN_AC - urban air conditioning flux W/m^2 T +URBAN_AC_SEN - sensible heat component of urban air conditioning flux W/m^2 F URBAN_HEAT - urban heating flux W/m^2 T USTAR - aerodynamical resistance s/m F UST_LAKE - friction velocity (lakes only) m/s F diff --git a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst index 512b8dfb1e..f9e931c763 100644 --- a/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst +++ b/doc/source/users_guide/setting-up-and-running-a-case/history_fields_nofates.rst @@ -880,8 +880,8 @@ Q2M - 2m specific humidity QAF - canopy air humidity kg/kg F F QBOT - atmospheric specific humidity (downscaled to columns in glacier regions) kg/kg T F QBOT_NOT_DOWNSCALED - atmospheric specific humidity (pre-downscaling) kg/kg F F -QBUILD - internal urban building air specific humidity kg/kg T F -QCOND_FROM_AC - Condensed water flux from AC dehumidification mm/s T F +QBUILD - internal urban building air specific humidity kg/kg F F +QCOND_FROM_AC - Condensed water flux from AC dehumidification mm/s F F QDIRECT_THROUGHFALL - direct throughfall of liquid (rain + above-canopy irrigation) mm/s F F QDIRECT_THROUGHFALL_SNOW - direct throughfall of snow mm/s F F QDRAI - sub-surface drainage mm/s T F @@ -968,7 +968,7 @@ RH2M_U - Urban 2m relative humidity RH30 - 30-day running mean of relative humidity % F F RHAF - fractional humidity of canopy air fraction F F RHAF10 - 10 day running mean of fractional humidity of canopy air fraction F F -RHBUILD - Internal urban building air relative humidity % T F +RHBUILD - Internal urban building air relative humidity % F F RH_LEAF - fractional humidity at leaf surface fraction F F RR - root respiration (fine root MR + total root GR) gC/m^2/s T F RSSHA - shaded leaf stomatal resistance s/m T F @@ -1199,7 +1199,7 @@ UAF - canopy air speed ULRAD - upward longwave radiation above the canopy W/m^2 F F UM - wind speed plus stability effect m/s F F URBAN_AC - urban air conditioning flux W/m^2 T F -URBAN_AC_SEN - sensible heat component of urban air conditioning flux W/m^2 T F +URBAN_AC_SEN - sensible heat component of urban air conditioning flux W/m^2 F F URBAN_HEAT - urban heating flux W/m^2 T F USTAR - friction velocity m/s F F UST_LAKE - friction velocity (lakes only) m/s F F diff --git a/src/main/histFileMod.F90 b/src/main/histFileMod.F90 index b286817890..4544e234e3 100644 --- a/src/main/histFileMod.F90 +++ b/src/main/histFileMod.F90 @@ -496,7 +496,7 @@ subroutine hist_printflds() allhistfldlist(nf)%field%type2d, & allhistfldlist(nf)%field%long_name, & allhistfldlist(nf)%field%units, & - allhistfldlist(nf)%actflag(1,:) + allhistfldlist(nf)%actflag(1,max_split_files:1:-1) end do ! Table footer, same as header From 2f242ba9495ed51889cfa656a984a3304acde9e5 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 17 Sep 2026 16:46:50 -0600 Subject: [PATCH 67/89] First draft ChangeLog/ChangeSum --- doc/ChangeLog | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 2 ++ 2 files changed, 86 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index 4bd437d0d1..e40536d904 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,88 @@ =============================================================== +Tag name: ctsm5.4.059 +Originator(s): cathyxinchangli (Cathy Xinchang Li, U of Illinois - Urbana-Champaign) +Date: Thu Sep 17 04:13:20 PM MDT 2026 +One-line Summary: Indoor humidity and A/C dehumidification + +Purpose and description of changes +---------------------------------- + + This PR adds indoor humidity and air-conditioning dehumidification to the CLMU BEM (Building Energy Model). It prognoses indoor specific humidity, calculates sensible cooling and latent dehumidification loads, and diagnoses condensate production and routes the condensate into urban runoff. The behavior is controlled by an integer CLM namelist variable, building_humidity_mode: + + 0: use the existing CLMU formulation without indoor humidity or AC dehumidification; + 1: enable indoor humidity and latent heat exchange, but no AC dehumidification (requires prognostic building temperature, building_temp_method=1); and + 2: enable indoor humidity, latent heat exchange, dehumidification load, and condensate production (requires prognostic building temperature, urban_hac to be ON or ON_WASTEHEAT and urban_explicit_ac=.true.). + + The default is set to 0 to ensure bit-for-bit reproducibility with the original scheme. + + Indoor humidity and air-conditioning dehumidification are described by Li et al. (2026), doi:10.1038/s44284-026-00474-4. + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + Resolves #4162 + +Notes of particular relevance for users +--------------------------------------- +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + building_humidity_mode is added as a namelist variable + +Changes to documentation: + #4195 will address the need for new docs + +Substantial timing or memory changes: + slevis will check the PFS test etc. the next time he runs aux_clm (before the merge) + +Contributors: + Lei Zhao (@Face2sea) + Zhiwen Luo + Keith Oleson (@olyson) + Yifan Cheng (@yifanc17) + Xiaoxiong Xie + Alvin C. G. Varquez + Mitsuna Sekiya + +Notes of particular relevance for developers: +--------------------------------------------- +Changes to tests or testing: + 6 new tests in build-namelist_test.pl + +Testing summary: +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- + izumi ------- + + +Answer changes +-------------- + +Changes answers relative to baseline: No (read the caveat) + + Caveat: + - Results remain bit-for-bit under building_humidity_mode=0 (default). + - Comparing building_humidity_mode=1 with 0, two new variables are added (QBUILD, RHBUILD), and VENTILATION and EFLXBUILD changes because they now include latent heat exchanges between indoors and outdoors, and URBAN_AC and URBAN_HEAT changes slightly because of the changes in ventilation and higher heat capacity of moist air. + - Comparing building_humidity_mode=2 with 1, three more new variables (URBAN_AC_SEN, QCOND_FROM_AC, QCOND_FROM_AC_LUN) are added, and URBAN_AC increases because it now includes sensible (for cooling) and latent (for dehumidification) heat components of urban AC demand. URBAN_HEAT, VENTILATION, EFLXBUILD, WASTEHEAT changes slightly as an indirect results of the changes in AC. + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/4164 + +=============================================================== +=============================================================== +Tag name: ctsm5.4.058 +Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) +(placeholder) +=============================================================== +=============================================================== Tag name: ctsm5.4.057 Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) Date: Thu Sep 17 01:26:07 AM MDT 2026 diff --git a/doc/ChangeSum b/doc/ChangeSum index eafe46b445..ca04f8a81f 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,7 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.4.059 slevis 09/??/2026 Indoor humidity and A/C dehumidification + ctsm5.4.058 erik 09/??/2026 (placeholder) ctsm5.4.057 erik 09/17/2026 CDEPS/CMEPS updates for CPLHIST mode and 1850 ndep from DATM ctsm5.4.056 multiple 09/10/2026 Merge the wetlands branch to master ctsm5.4.055 sacks 09/08/2026 Add temporal smoothing of DYNBAL conservation correction fluxes From ec877a57a6585d0b564cbab999f8bccfaad111d5 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Mon, 21 Sep 2026 11:00:31 -0600 Subject: [PATCH 68/89] Updated ChangeLog/Sum --- doc/ChangeLog | 13 ++++--------- doc/ChangeSum | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index bd04076a36..d5bd80539a 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.4.059 Originator(s): cathyxinchangli (Cathy Xinchang Li, U of Illinois - Urbana-Champaign) -Date: Sun Sep 20 10:46:06 AM MDT 2026 +Date: Mon Sep 21 10:55:44 AM MDT 2026 One-line Summary: Indoor humidity and A/C dehumidification Purpose and description of changes @@ -30,9 +30,6 @@ Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): Changes to documentation: #4195 will address the need for new docs -Substantial timing or memory changes: - slevis will check the PFS test etc. the next time he runs aux_clm (before the merge) - Contributors: Lei Zhao (@Face2sea) Zhiwen Luo @@ -53,17 +50,15 @@ Testing summary: build-namelist tests (if CLMBuildNamelist.pm has changed): - derecho - + derecho - OK (2 expected fails) regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): - derecho ----- - izumi ------- - + derecho ----- OK + izumi ------- OK Answer changes -------------- - Changes answers relative to baseline: No (read the caveat) Caveat: diff --git a/doc/ChangeSum b/doc/ChangeSum index af95a23af8..40b1d6dcb1 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.4.059 slevis 09/21/2026 Indoor humidity and A/C dehumidification + ctsm5.4.059 cathyxin 09/21/2026 Indoor humidity and A/C dehumidification ctsm5.4.058 erik 09/18/2026 Merge b4b-dev to master ctsm5.4.057 erik 09/17/2026 CDEPS/CMEPS updates for CPLHIST mode and 1850 ndep from DATM ctsm5.4.056 multiple 09/10/2026 Merge the wetlands branch to master From c74d3661d20ff33590726249492d118df0dee2eb Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 21 Sep 2026 20:56:49 -0600 Subject: [PATCH 69/89] Update cdeps and cmeps with reproducable sums so that DGLC and CISM can have exact answers when B4BFLAG is set to TRUE --- .gitmodules | 4 ++-- components/cdeps | 2 +- components/cmeps | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index d52b9067ba..977a584cc3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -84,7 +84,7 @@ fxDONOTUSEurl = https://github.com/ESMCI/cime [submodule "cmeps"] path = components/cmeps url = https://github.com/ESCOMP/CMEPS.git -fxtag = cmeps1.1.69 +fxtag = cmeps1.1.71 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESCOMP/CMEPS.git @@ -92,7 +92,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/CMEPS.git [submodule "cdeps"] path = components/cdeps url = https://github.com/ESCOMP/CDEPS.git -fxtag = cdeps1.0.109 +fxtag = cdeps1.0.110 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESCOMP/CDEPS.git diff --git a/components/cdeps b/components/cdeps index 23acaf245d..51ae05e65b 160000 --- a/components/cdeps +++ b/components/cdeps @@ -1 +1 @@ -Subproject commit 23acaf245d7294fba62b2784b2c937b9fc79b5d8 +Subproject commit 51ae05e65b9ddd0843663d09d52f08d5302b34a7 diff --git a/components/cmeps b/components/cmeps index a51b39fe5b..0060d41cdb 160000 --- a/components/cmeps +++ b/components/cmeps @@ -1 +1 @@ -Subproject commit a51b39fe5bfcb9e5eebc628e9ffaa751eedea73c +Subproject commit 0060d41cdbc2349e3f2ac6d19f2dd6db681f4b20 From 29324eaab5b395499def9a2c7afb5d5067e3efc9 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 22 Sep 2026 15:39:54 -0600 Subject: [PATCH 70/89] Remove all of the expected fails for the longer DGLC threaded tests that were failing because of lack of reproducable sums --- cime_config/testdefs/ExpectedTestFails.xml | 57 ---------------------- 1 file changed, 57 deletions(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 72a641a901..7093652179 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -140,63 +140,6 @@ - - - FAIL - #4160 - - - - - - FAIL - #4160 - - - - - - FAIL - #4160 - - - - - - FAIL - #4160 - - - - - - FAIL - #4160 - - - - - - FAIL - #4160 - - - - - - FAIL - #4160 - - - - - - FAIL - #4160 - Does this also relate to #2619? - - - From e9f98fce90cae24ccc79da3954c3ae2047592a96 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 22 Sep 2026 16:37:39 -0600 Subject: [PATCH 71/89] Start change files --- doc/ChangeLog | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 81 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index d5bd80539a..2bfebf4e0f 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,84 @@ =============================================================== +Tag name: ctsm5.4.060 +Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) +Date: Tue Sep 22 04:26:21 PM MDT 2026 +One-line Summary: Update CDEPS/CMEPS to versions with reproducable sums to fix some failing tests + +Purpose and description of changes +---------------------------------- + +Bring in use of reproducable sums in CDEPS and CMEPS so that our longer threaded tests with DGLC will now PASS. These are turned on with the CMEPS BFBFLAG which was previusly not used for anything. + +Bugs fixed +---------- + +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + - Resolves Threaded exact restart tests that change task/thread count fail with DGLC or CISM fail when run to a year or more #4160 + +Notes of particular relevance for users +--------------------------------------- + +Changes to CTSM's user interface (e.g., new/renamed XML or namelist variables): + The xml variable BFBFLAG now actually does something + +Contributors: + - @billsacks did the underlying CDEPS/CMEPS tags + +Notes of particular relevance for developers: +--------------------------------------------- + +Caveats for developers (e.g., code that is duplicated that requires double maintenance): + +Changes to tests or testing: + +Testing summary: regular + ctsm_sci +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + any other testing (give details below): + + ctsm_sci + derecho ---- + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + + +Answer changes +-------------- + +Changes answers relative to baseline: Potentially roundoff different + + Summarize any changes to answers, i.e., + - what code configurations: compset with either DGLC or CISM AND BfBFLAG==TRUE + - what platforms/compilers: all + - nature of change: roundoff + + If bitwise differences were observed, how did you show they were no worse + than roundoff? + + @billsacks did the evaulation for this in the CMEPS/CDEPS tags + Also since most tests were identical even with the change it gives assurance that the change + often doesn't change answers, or only when run long enough + The previous exact restart tests that change PE layouts that failed now PASS + +Other details +------------- + +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): cdeps and cmeps + cdeps to cmeps1.1.71 (NOTE: this skips past cmeps1.1.70 which was b4b with changes for threading) + cmeps to cdeps1.0.110 + +Pull Requests that document the changes (include PR ids): + Reproduable sums in CDEPS and CMEPS so that longer threaded tests will PASS #4224 + + +=============================================================== +=============================================================== Tag name: ctsm5.4.059 Originator(s): cathyxinchangli (Cathy Xinchang Li, U of Illinois - Urbana-Champaign) Date: Mon Sep 21 10:55:44 AM MDT 2026 diff --git a/doc/ChangeSum b/doc/ChangeSum index 40b1d6dcb1..00ccd00777 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.4.060 erik 09/22/2026 Update CDEPS/CMEPS to versions with reproducable sums to fix some failing tests ctsm5.4.059 cathyxin 09/21/2026 Indoor humidity and A/C dehumidification ctsm5.4.058 erik 09/18/2026 Merge b4b-dev to master ctsm5.4.057 erik 09/17/2026 CDEPS/CMEPS updates for CPLHIST mode and 1850 ndep from DATM From 06b45eb0bf36c04fb5140caa1316347e611a68fe Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 22 Sep 2026 19:10:07 -0600 Subject: [PATCH 72/89] Remove the 364 day tests that were there until #4160 was resolved --- cime_config/testdefs/testlist_clm.xml | 30 --------------------------- 1 file changed, 30 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 345eedc3d3..1f3578cd4d 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -2213,16 +2213,6 @@ - - - - - - - - - - @@ -2233,16 +2223,6 @@ - - - - - - - - - - @@ -2253,16 +2233,6 @@ - - - - - - - - - - From 137389326e1ab92c77d4065818677e2a7c19bc1c Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 24 Sep 2026 11:27:47 -0600 Subject: [PATCH 73/89] Update doc/ChangeSum Co-authored-by: Samuel Levis --- doc/ChangeSum | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ChangeSum b/doc/ChangeSum index 00ccd00777..6bbe981ba1 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.4.060 erik 09/22/2026 Update CDEPS/CMEPS to versions with reproducable sums to fix some failing tests + ctsm5.4.060 erik 09/22/2026 Update CDEPS/CMEPS to versions with reproducible sums to fix some failing tests ctsm5.4.059 cathyxin 09/21/2026 Indoor humidity and A/C dehumidification ctsm5.4.058 erik 09/18/2026 Merge b4b-dev to master ctsm5.4.057 erik 09/17/2026 CDEPS/CMEPS updates for CPLHIST mode and 1850 ndep from DATM From 0371528b54fe822b38267ef738ae53cdc172d77a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 24 Sep 2026 12:53:26 -0600 Subject: [PATCH 74/89] Update dates --- doc/ChangeLog | 2 +- doc/ChangeSum | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 2bfebf4e0f..1383ee65bf 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.4.060 Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) -Date: Tue Sep 22 04:26:21 PM MDT 2026 +Date: Thu Sep 24 10:47:52 AM MDT 2026 One-line Summary: Update CDEPS/CMEPS to versions with reproducable sums to fix some failing tests Purpose and description of changes diff --git a/doc/ChangeSum b/doc/ChangeSum index 00ccd00777..b8a994e28b 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.4.060 erik 09/22/2026 Update CDEPS/CMEPS to versions with reproducable sums to fix some failing tests + ctsm5.4.060 erik 09/24/2026 Update CDEPS/CMEPS to versions with reproducable sums to fix some failing tests ctsm5.4.059 cathyxin 09/21/2026 Indoor humidity and A/C dehumidification ctsm5.4.058 erik 09/18/2026 Merge b4b-dev to master ctsm5.4.057 erik 09/17/2026 CDEPS/CMEPS updates for CPLHIST mode and 1850 ndep from DATM From 2a02d9f72f6efebf271a98a466bb2ae2327e8b93 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 24 Sep 2026 13:24:32 -0600 Subject: [PATCH 75/89] Lower wallclock for two tests that didn't need to be so long --- cime_config/testdefs/testlist_clm.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 1f3578cd4d..153b5aa222 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -5014,7 +5014,7 @@ - + @@ -5027,7 +5027,7 @@ - + From 638ff8929e4d63e5cc5f35dc958073659bc1357b Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Thu, 24 Sep 2026 13:38:12 -0600 Subject: [PATCH 76/89] Some spelling/gramamar updates from code review by @slevis and claude --- doc/ChangeLog | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 1383ee65bf..18bf3d2d19 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,19 +1,19 @@ =============================================================== Tag name: ctsm5.4.060 Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) -Date: Thu Sep 24 10:47:52 AM MDT 2026 -One-line Summary: Update CDEPS/CMEPS to versions with reproducable sums to fix some failing tests +Date: Thu Sep 24 01:15:52 PM MDT 2026 +One-line Summary: Update CDEPS/CMEPS to versions with reproducible sums to fix some failing tests Purpose and description of changes ---------------------------------- -Bring in use of reproducable sums in CDEPS and CMEPS so that our longer threaded tests with DGLC will now PASS. These are turned on with the CMEPS BFBFLAG which was previusly not used for anything. +Bring in use of reproducible sums in CDEPS and CMEPS so that our longer threaded tests with DGLC will now PASS. These are turned on with the CMEPS BFBFLAG which was previously not used for anything. Bugs fixed ---------- List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: - - Resolves Threaded exact restart tests that change task/thread count fail with DGLC or CISM fail when run to a year or more #4160 + - Resolves Threaded exact restart tests that change task/thread count fail with DGLC or CISM when run to a year or more #4160 Notes of particular relevance for users --------------------------------------- @@ -27,9 +27,10 @@ Contributors: Notes of particular relevance for developers: --------------------------------------------- -Caveats for developers (e.g., code that is duplicated that requires double maintenance): - Changes to tests or testing: + - Remove 364-day tests that were there because the longer ones weren't passing previously + - Lower wallclock for two ctsm_sci tests that didn't need to be so long + - Remove tests that now pass from expected fails Testing summary: regular + ctsm_sci ---------------- @@ -43,7 +44,7 @@ Testing summary: regular + ctsm_sci any other testing (give details below): ctsm_sci - derecho ---- + derecho ---- OK If the tag used for baseline comparisons was NOT the previous tag, note that here: @@ -54,28 +55,26 @@ Answer changes Changes answers relative to baseline: Potentially roundoff different Summarize any changes to answers, i.e., - - what code configurations: compset with either DGLC or CISM AND BfBFLAG==TRUE + - what code configurations: compset with either DGLC or CISM AND BFBFLAG==TRUE - what platforms/compilers: all - nature of change: roundoff If bitwise differences were observed, how did you show they were no worse than roundoff? - @billsacks did the evaulation for this in the CMEPS/CDEPS tags - Also since most tests were identical even with the change it gives assurance that the change - often doesn't change answers, or only when run long enough - The previous exact restart tests that change PE layouts that failed now PASS + - @billsacks did the evaluation for this in the CMEPS/CDEPS tags + - Since most tests were identical even with the change, this gives assurance that the change often doesn't change answers, or only does so when run long enough + - The exact restart tests that change PE layouts, which previously failed, now PASS Other details ------------- List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): cdeps and cmeps - cdeps to cmeps1.1.71 (NOTE: this skips past cmeps1.1.70 which was b4b with changes for threading) - cmeps to cdeps1.0.110 + - cmeps to cmeps1.1.71 (NOTE: this skips past cmeps1.1.70, which was b4b with changes for threading) + - cdeps to cdeps1.0.110 Pull Requests that document the changes (include PR ids): - Reproduable sums in CDEPS and CMEPS so that longer threaded tests will PASS #4224 - + Reproducible sums in CDEPS and CMEPS so that longer threaded tests will PASS #4224 =============================================================== =============================================================== From 8eb9eca551424a53de845d7994a36ac0795a3a26 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Fri, 25 Sep 2026 12:53:53 -0600 Subject: [PATCH 77/89] Final change files --- doc/ChangeLog | 5 +++-- doc/ChangeSum | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 18bf3d2d19..abffeffe87 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.4.060 Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) -Date: Thu Sep 24 01:15:52 PM MDT 2026 +Date: Fri Sep 25 12:53:38 PM MDT 2026 One-line Summary: Update CDEPS/CMEPS to versions with reproducible sums to fix some failing tests Purpose and description of changes @@ -62,9 +62,10 @@ Changes answers relative to baseline: Potentially roundoff different If bitwise differences were observed, how did you show they were no worse than roundoff? + - The changes were just a few coupled fields and only to roundoff level + - The exact restart tests that change PE layouts, which previously failed, now PASS - @billsacks did the evaluation for this in the CMEPS/CDEPS tags - Since most tests were identical even with the change, this gives assurance that the change often doesn't change answers, or only does so when run long enough - - The exact restart tests that change PE layouts, which previously failed, now PASS Other details ------------- diff --git a/doc/ChangeSum b/doc/ChangeSum index 97bd24e58d..7adb9342a3 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.4.060 erik 09/24/2026 Update CDEPS/CMEPS to versions with reproducible sums to fix some failing tests + ctsm5.4.060 erik 09/25/2026 Update CDEPS/CMEPS to versions with reproducible sums to fix some failing tests ctsm5.4.059 cathyxin 09/21/2026 Indoor humidity and A/C dehumidification ctsm5.4.058 erik 09/18/2026 Merge b4b-dev to master ctsm5.4.057 erik 09/17/2026 CDEPS/CMEPS updates for CPLHIST mode and 1850 ndep from DATM From 5201dab8be74f0514f74b4e2b1ab03d4185b61fe Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Sep 2026 02:31:00 -0600 Subject: [PATCH 78/89] Update cime and ccs_config to latest in cesm3_0_beta10 includes NorESM changes for cime --- .gitmodules | 4 ++-- ccs_config | 2 +- cime | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index 977a584cc3..102f9e6df9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -68,7 +68,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/mizuRoute [submodule "ccs_config"] path = ccs_config url = https://github.com/ESMCI/ccs_config_cesm.git -fxtag = ccs_config_cesm1.0.88 +fxtag = ccs_config_cesm1.0.91 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESMCI/ccs_config_cesm.git @@ -76,7 +76,7 @@ fxDONOTUSEurl = https://github.com/ESMCI/ccs_config_cesm.git [submodule "cime"] path = cime url = https://github.com/ESMCI/cime -fxtag = cime6.5.5 +fxtag = cime6.5.20 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESMCI/cime diff --git a/ccs_config b/ccs_config index 7c8bd604c8..52335e96df 160000 --- a/ccs_config +++ b/ccs_config @@ -1 +1 @@ -Subproject commit 7c8bd604c818e4e832dda02b8584260fb7e22efc +Subproject commit 52335e96df9884e3c4735bcc514474415ecb2d19 diff --git a/cime b/cime index 92ae0fd813..b9e65323db 160000 --- a/cime +++ b/cime @@ -1 +1 @@ -Subproject commit 92ae0fd8133a3397a95f1cfcfa40dc138562f305 +Subproject commit b9e65323db198ac14ab3a78ae162c9782ac43c09 From aa0a323e7abd09d63e6143a6a58307e755ebd2f5 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Sep 2026 02:31:39 -0600 Subject: [PATCH 79/89] Add a little test to run with NorESM, will be needed later --- cime_config/testdefs/testlist_clm.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cime_config/testdefs/testlist_clm.xml b/cime_config/testdefs/testlist_clm.xml index 153b5aa222..16c4aade05 100644 --- a/cime_config/testdefs/testlist_clm.xml +++ b/cime_config/testdefs/testlist_clm.xml @@ -317,6 +317,16 @@ + + + + + + + + + + From e4875bfee4aad698e2e66a08f30bb0ee22eabe21 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Mon, 28 Sep 2026 02:32:51 -0600 Subject: [PATCH 80/89] norESM testmod --- .../testdefs/testmods_dirs/clm/norESMTest/shell_commands | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 cime_config/testdefs/testmods_dirs/clm/norESMTest/shell_commands diff --git a/cime_config/testdefs/testmods_dirs/clm/norESMTest/shell_commands b/cime_config/testdefs/testmods_dirs/clm/norESMTest/shell_commands new file mode 100755 index 0000000000..564c30a2a0 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/norESMTest/shell_commands @@ -0,0 +1,3 @@ +#!/bin/bash + +./xmlchange MODEL="noresm" From e7ca8814e4097744088f1bd29cc6bc99eb9826fe Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Tue, 29 Sep 2026 17:02:24 -0600 Subject: [PATCH 81/89] Update to ccs_config that has more t233 and t201 grid aliases for MOM masks --- .gitmodules | 2 +- ccs_config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 102f9e6df9..6ff4b67f13 100644 --- a/.gitmodules +++ b/.gitmodules @@ -68,7 +68,7 @@ fxDONOTUSEurl = https://github.com/ESCOMP/mizuRoute [submodule "ccs_config"] path = ccs_config url = https://github.com/ESMCI/ccs_config_cesm.git -fxtag = ccs_config_cesm1.0.91 +fxtag = ccs_config_cesm1.0.92 fxrequired = ToplevelRequired # Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed fxDONOTUSEurl = https://github.com/ESMCI/ccs_config_cesm.git diff --git a/ccs_config b/ccs_config index 52335e96df..c71cdfba50 160000 --- a/ccs_config +++ b/ccs_config @@ -1 +1 @@ -Subproject commit 52335e96df9884e3c4735bcc514474415ecb2d19 +Subproject commit c71cdfba50aedc452a96fe3dd033f8bfdcf7c0fb From 927367947036c105ec2304a0fd3f3b6ee4bf02ca Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Sep 2026 01:28:38 -0600 Subject: [PATCH 82/89] Start the change files --- doc/ChangeLog | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 69 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index abffeffe87..70bee14973 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,72 @@ =============================================================== +Tag name: ctsm5.4.061 +Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) +Date: Wed Sep 30 01:23:20 AM MDT 2026 +One-line Summary: Update to cesm3_0_beta10 externals cime/ccs_config, including more ccs_config grid aliases with MOM grids + +Purpose and description of changes +---------------------------------- + +Update cime and ccs_config to latest version as in the cesm3_0_beta10 tag. Also includes changes so that CIME_MODEL can be set to noresm. + +Also include new ccs_config version that has more t233/t201 grid aliases from @slevis-lmwg + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: + +Notes of particular relevance for developers: +--------------------------------------------- + +Changes to tests or testing: + +Testing summary: regular + fates + ctsm_sci +---------------- + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - + + python testing (if python code has changed; see instructions in python/README.md; document testing done): + + derecho - + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- OK + izumi ------- OK + + fates tests: (fates-sci.1.93.1_api.46.0.0-ctsm5.4.060) + derecho ----- + izumi ------- + + any other testing (give details below): + + ctsm_sci + derecho ---- + +If the tag used for baseline comparisons was NOT the previous tag, note that here: + + +Answer changes +-------------- + +Changes answers relative to baseline: No b4b + +Other details +------------- + +List any git submodules updated (cime, rtm, mosart, cism, fates, etc.): + cime to cime6.5.20 + ccs_config to ccs_config_cesm1.0.92 + +Pull Requests that document the changes (include PR ids): +(https://github.com/ESCOMP/ctsm/pull) + Update submodules as for final cesm3_0_beta10, cime and ccs_config to latest including more t233 grid aliases #4232 + +=============================================================== +=============================================================== Tag name: ctsm5.4.060 Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) Date: Fri Sep 25 12:53:38 PM MDT 2026 diff --git a/doc/ChangeSum b/doc/ChangeSum index 7adb9342a3..f6cba48e06 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.4.061 erik 09/30/2026 Update to cesm3_0_beta10 externals cime/ccs_config, including more ccs_config grid aliases with MOM grids ctsm5.4.060 erik 09/25/2026 Update CDEPS/CMEPS to versions with reproducible sums to fix some failing tests ctsm5.4.059 cathyxin 09/21/2026 Indoor humidity and A/C dehumidification ctsm5.4.058 erik 09/18/2026 Merge b4b-dev to master From 5501e6d34f8191380cda6e90b20e34cc33305abf Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Sep 2026 15:24:31 -0600 Subject: [PATCH 83/89] Fix state of expected FAIL to SETUP phase --- cime_config/testdefs/ExpectedTestFails.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 7093652179..4f9ec2e53e 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -30,7 +30,7 @@ - + FAIL CDEPS/#243 and/or #2122 From 326b7068e52a244174555ff8f438a50687ab082e Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Sep 2026 15:53:42 -0600 Subject: [PATCH 84/89] Add expected fail for the NorESM test --- cime_config/testdefs/ExpectedTestFails.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cime_config/testdefs/ExpectedTestFails.xml b/cime_config/testdefs/ExpectedTestFails.xml index 4f9ec2e53e..bb6e1b6493 100644 --- a/cime_config/testdefs/ExpectedTestFails.xml +++ b/cime_config/testdefs/ExpectedTestFails.xml @@ -35,6 +35,12 @@ CDEPS/#243 and/or #2122 + + + FAIL + #4238 + + From d4edea00a92d2494895fe118ee53d443ef895c3a Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Sep 2026 16:52:05 -0600 Subject: [PATCH 85/89] Changelog should be finalized now, also add a note to run python testing if CIME is updated --- doc/.ChangeLog_template | 2 +- doc/ChangeLog | 21 +++++++-------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/doc/.ChangeLog_template b/doc/.ChangeLog_template index 7dd14135c1..a5bbdbbb0a 100644 --- a/doc/.ChangeLog_template +++ b/doc/.ChangeLog_template @@ -95,7 +95,7 @@ infrastructure should be run when appropriate, as described below. derecho - - python testing (if python code has changed; see instructions in python/README.md; document testing done): + python testing (if python or CIME code has changed; see instructions in python/README.md; document testing done): derecho - diff --git a/doc/ChangeLog b/doc/ChangeLog index 70bee14973..6251bad584 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.4.061 Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) -Date: Wed Sep 30 01:23:20 AM MDT 2026 +Date: Wed Sep 30 04:51:11 PM MDT 2026 One-line Summary: Update to cesm3_0_beta10 externals cime/ccs_config, including more ccs_config grid aliases with MOM grids Purpose and description of changes @@ -11,26 +11,19 @@ Update cime and ccs_config to latest version as in the cesm3_0_beta10 tag. Also Also include new ccs_config version that has more t233/t201 grid aliases from @slevis-lmwg -Bugs fixed ----------- -List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: - Notes of particular relevance for developers: --------------------------------------------- Changes to tests or testing: + Add a new test for NorESM, that currently fails. It may be a test to remove. Testing summary: regular + fates + ctsm_sci ---------------- [PASS means all tests PASS; OK means tests PASS other than expected fails.] - build-namelist tests (if CLMBuildNamelist.pm has changed): - - derecho - - - python testing (if python code has changed; see instructions in python/README.md; document testing done): + python testing (if python or CIME code has changed; see instructions in python/README.md; document testing done): - derecho - + derecho - OK regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): @@ -38,13 +31,13 @@ Testing summary: regular + fates + ctsm_sci izumi ------- OK fates tests: (fates-sci.1.93.1_api.46.0.0-ctsm5.4.060) - derecho ----- - izumi ------- + derecho ----- OK + izumi ------- OK any other testing (give details below): ctsm_sci - derecho ---- + derecho ---- OK If the tag used for baseline comparisons was NOT the previous tag, note that here: From f87023d31b8349151c61ee1a76dff778109b846d Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Sep 2026 17:40:41 -0600 Subject: [PATCH 86/89] Remove tests on file existance as that is done in check_input_data, this resolves #3050 --- bld/unit_testers/build-namelist_test.pl | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/bld/unit_testers/build-namelist_test.pl b/bld/unit_testers/build-namelist_test.pl index 1526064eca..e28aac880a 100755 --- a/bld/unit_testers/build-namelist_test.pl +++ b/bld/unit_testers/build-namelist_test.pl @@ -165,7 +165,7 @@ sub cat_and_create_namelistinfile { # # Figure out number of tests that will run # -my $ntests = 3417; +my $ntests = 3415; if ( defined($opts{'compare'}) ) { $ntests += 2061; @@ -1241,10 +1241,6 @@ sub cat_and_create_namelistinfile { namelst=>"use_fates_inventory_init=.true.", phys=>"clm4_5", }, - "inventoryfileDNE" =>{ options=>"-bgc fates -envxml_dir . -no-megan", - namelst=>"use_fates_inventory_init=.true., fates_inventory_ctrl_filename='zztop'", - phys=>"clm4_5", - }, "useFATESLUH2butnotfile" =>{ options=>"--res 0.9x1.25 --bgc fates --envxml_dir . --no-megan", namelst=>"use_fates_luh=.true.", phys=>"clm4_5", @@ -1253,10 +1249,6 @@ sub cat_and_create_namelistinfile { namelst=>"use_fates_lupft=.true.", phys=>"clm4_5", }, - "useFATESLUH2fileDNE" =>{ options=>"-bgc fates -envxml_dir . -no-megan", - namelst=>"use_fates_luh=.true., fluh_timeseries='zztop'", - phys=>"clm4_5", - }, "useFATESLUH2invalidlogic" =>{ options=>"-bgc fates -envxml_dir . -no-megan", namelst=>"use_fates_luh=.true., fates_lu_transition_logic=0", phys=>"clm6_0", From 8326f3d9428f2964fa1adaff180b1b9df482dc90 Mon Sep 17 00:00:00 2001 From: Erik Kluzek Date: Wed, 30 Sep 2026 23:22:32 -0600 Subject: [PATCH 87/89] Final changelog --- doc/ChangeLog | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 6251bad584..3186ebc090 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.4.061 Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) -Date: Wed Sep 30 04:51:11 PM MDT 2026 +Date: Wed Sep 30 11:22:16 PM MDT 2026 One-line Summary: Update to cesm3_0_beta10 externals cime/ccs_config, including more ccs_config grid aliases with MOM grids Purpose and description of changes @@ -21,6 +21,10 @@ Testing summary: regular + fates + ctsm_sci ---------------- [PASS means all tests PASS; OK means tests PASS other than expected fails.] + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - PASS + python testing (if python or CIME code has changed; see instructions in python/README.md; document testing done): derecho - OK From 2cf72372ded16f13a9c607021d3540dd9543d01d Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Thu, 1 Oct 2026 16:26:38 -0600 Subject: [PATCH 88/89] Draft ChangeLog/ChangeSum --- doc/ChangeLog | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ChangeSum | 1 + 2 files changed, 75 insertions(+) diff --git a/doc/ChangeLog b/doc/ChangeLog index 3186ebc090..b1e2cb0b42 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,4 +1,78 @@ =============================================================== +Tag name: ctsm5.4.062 +Originator(s): slevis (Samuel Levis,UCAR/TSS,+1 303 497 1234) +Date: Thu Oct 1 04:14:40 PM MDT 2026 +One-line Summary: Merge b4b-dev to master + +Purpose and description of changes +---------------------------------- + +Includes these PRs +#4199 Make additional history fields active in prep. for CMIP7 +#4236 Make the Python unit-test job fail when a test fails +#4231 test(subset_data): make unit test work outside NCAR cluster, like its siblings do +#4229 Specify q10 for HR and MR +#4185 refactor(biogeophys): Rename frac_sno and frac_sno_eff to clarify albedo vs flux roles +#4225 Fix test_unit_neon_site error +#4222 Fix test_sys_plumber2_surf_wrapper.py failures +#4220 Change GLC_NCPL to 4 for DAE test to pass + +Bugs fixed +---------- +List of CTSM issues fixed (include CTSM Issue # and description) [one per line]: +Resolves #4181 +Resolves #4230 Contributes to #3236 +Resolves #4196 +Resolves #822 +Resolves #4216 +Resolves #4215 +Resolves #4202 + +Notes of particular relevance for users +--------------------------------------- +Changes to documentation: Minor, as needed + +Contributors in addition to originator: +@Santoshkumarpuppala +@johnpaulalex +@wwieder +@olyson + +Notes of particular relevance for developers: +--------------------------------------------- +Changes to tests or testing: + Removed DAE test from ExpectedTestFails.xml. See titles of included PRs for other test-related work. + +Testing summary: +---------------- + + [PASS means all tests PASS; OK means tests PASS other than expected fails.] + + build-namelist tests (if CLMBuildNamelist.pm has changed): + + derecho - PASS + + python testing (if python or CIME code has changed; see instructions in python/README.md; document testing done): + + derecho - PASS + + regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): + + derecho ----- + izumi ------- OK + +Answer changes +-------------- +Changes answers relative to baseline: No, only field lists + + +Other details +------------- +Pull Requests that document the changes (include PR ids): + https://github.com/ESCOMP/ctsm/pull/4241 and the PRs listed above + +=============================================================== +=============================================================== Tag name: ctsm5.4.061 Originator(s): erik (Erik Kluzek,UCAR/TSS,+1 303 497 1326) Date: Wed Sep 30 11:22:16 PM MDT 2026 diff --git a/doc/ChangeSum b/doc/ChangeSum index f6cba48e06..a19526f260 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,5 +1,6 @@ Tag Who Date Summary ============================================================================================================================ + ctsm5.4.062 slevis 10/01/2026 Merge b4b-dev to master ctsm5.4.061 erik 09/30/2026 Update to cesm3_0_beta10 externals cime/ccs_config, including more ccs_config grid aliases with MOM grids ctsm5.4.060 erik 09/25/2026 Update CDEPS/CMEPS to versions with reproducible sums to fix some failing tests ctsm5.4.059 cathyxin 09/21/2026 Indoor humidity and A/C dehumidification From a11118fc6a1c159bc81f5f7b57231b8a00dee0a1 Mon Sep 17 00:00:00 2001 From: Samuel Levis Date: Fri, 2 Oct 2026 07:29:20 -0600 Subject: [PATCH 89/89] Finalize ChangeLog/Sum --- doc/ChangeLog | 7 ++++--- doc/ChangeSum | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index b1e2cb0b42..dfce821863 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,7 +1,7 @@ =============================================================== Tag name: ctsm5.4.062 Originator(s): slevis (Samuel Levis,UCAR/TSS,+1 303 497 1234) -Date: Thu Oct 1 04:14:40 PM MDT 2026 +Date: Fri Oct 2 07:23:31 AM MDT 2026 One-line Summary: Merge b4b-dev to master Purpose and description of changes @@ -42,6 +42,7 @@ Notes of particular relevance for developers: --------------------------------------------- Changes to tests or testing: Removed DAE test from ExpectedTestFails.xml. See titles of included PRs for other test-related work. + ERP_P64x2_Ld396.f10_f10_mg37.IHistClm60Bgc.derecho_intel.clm-monthly--clm-matrixcnOn_ignore_warnings passed in COMPARE_base_rest when expected to fail according to issue #2619; I recorded this in #2619 but did not remove the test from the expected fails, yet Testing summary: ---------------- @@ -58,12 +59,12 @@ Testing summary: regular tests (aux_clm: https://github.com/ESCOMP/CTSM/wiki/System-Testing-Guide#pre-merge-system-testing): - derecho ----- + derecho ----- OK izumi ------- OK Answer changes -------------- -Changes answers relative to baseline: No, only field lists +Changes answers relative to baseline: No, only field lists differ due to #4199 Other details diff --git a/doc/ChangeSum b/doc/ChangeSum index a19526f260..fe55a6ff87 100644 --- a/doc/ChangeSum +++ b/doc/ChangeSum @@ -1,6 +1,6 @@ Tag Who Date Summary ============================================================================================================================ - ctsm5.4.062 slevis 10/01/2026 Merge b4b-dev to master + ctsm5.4.062 slevis 10/02/2026 Merge b4b-dev to master ctsm5.4.061 erik 09/30/2026 Update to cesm3_0_beta10 externals cime/ccs_config, including more ccs_config grid aliases with MOM grids ctsm5.4.060 erik 09/25/2026 Update CDEPS/CMEPS to versions with reproducible sums to fix some failing tests ctsm5.4.059 cathyxin 09/21/2026 Indoor humidity and A/C dehumidification