From 1e128d9938627b8d7d03074ead051e7394fb1de0 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 26 Apr 2026 16:38:57 +0200 Subject: [PATCH 01/12] add nl vars --- bld/build-namelist | 2 ++ bld/namelist_files/namelist_defaults_cam.xml | 5 +++++ bld/namelist_files/namelist_definition.xml | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/bld/build-namelist b/bld/build-namelist index 63917171d1..5f309bdb74 100755 --- a/bld/build-namelist +++ b/bld/build-namelist @@ -3073,6 +3073,8 @@ if ($cfg->get('microphys') =~ /^mg/) { add_default($nl, 'forestfileBR'); add_default($nl, 'forestfileBRwarm'); } + add_default($nl, 'rafwbf_on'); + add_default($nl, 'forestfileWBF'); } # Ice nucleation options diff --git a/bld/namelist_files/namelist_defaults_cam.xml b/bld/namelist_files/namelist_defaults_cam.xml index 2f8f0384bc..5717c2856e 100644 --- a/bld/namelist_files/namelist_defaults_cam.xml +++ b/bld/namelist_files/namelist_defaults_cam.xml @@ -1275,6 +1275,11 @@ atm/cam/RaFSIP/forestBR.txt atm/cam/RaFSIP/forestBRwarm.txt + +.false. +atm/cam/RaFWBF/forestWBF_c260424.txt + + .true. .false. diff --git a/bld/namelist_files/namelist_definition.xml b/bld/namelist_files/namelist_definition.xml index cb01ba7a90..9e9b6ef532 100644 --- a/bld/namelist_files/namelist_definition.xml +++ b/bld/namelist_files/namelist_definition.xml @@ -2770,6 +2770,19 @@ Default: .true. Default: None + + + If .true., compute factor for Bergeron using random forests method. + Default: .false. + + + + ML parameters for Damman et al., ... + Default: None + + From 0a769c06cfea6c0063c2fffedfb8b3e7f6354575 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 26 Apr 2026 16:39:31 +0200 Subject: [PATCH 02/12] add var processing --- src/NorESM/module_random_forests.F90 | 119 ++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 3 deletions(-) diff --git a/src/NorESM/module_random_forests.F90 b/src/NorESM/module_random_forests.F90 index 917d6ad647..40e6aa3949 100644 --- a/src/NorESM/module_random_forests.F90 +++ b/src/NorESM/module_random_forests.F90 @@ -1,14 +1,17 @@ -!PG RaFSIP PARAMETERS +!PG RaFSIP and RafWBF PARAMETERS !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ !This MODULE holds the subroutines which are used to initialize all + !built random forest regressors. + +!For both RafSIP and RafWBF parameteriztions + +!Routines with postfix 'wbf' and vars with 'b' are related to RafWBF.+ !This MODULE CONTAINS the following routines: + ! *forestbrhm + ! *forestbr + ! *forestall + ! *forestbrds + ! *forestbrwarm + +! *forestwbf + !Each subroutine opens, reads and stores the parameters of all 4 + !random forest regressors. The initial .txt files are first + !converted into binary files so that the processing is faster. + @@ -19,6 +22,7 @@ ! *runforest + ! *runforestriv + ! *runforestmulti + +!RafWBF uses *runforest routine + !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ module module_random_forests @@ -30,23 +34,31 @@ module module_random_forests PRIVATE PUBLIC :: sec_ice_readnl + PUBLIC :: wbf_readnl PUBLIC :: sec_ice_init + PUBLIC :: wbf_init PUBLIC :: runforest PUBLIC :: runforestriv PUBLIC :: runforestmulti + PUBLIC :: runforestwbf !!MDIM DEFINES THE NUMBER OF FEATURES/INPUTS TO THE RaFSIP PARAMETERIZATION INTEGER, PARAMETER, PUBLIC :: MDIM5=5 - INTEGER, PARAMETER, PUBLIC :: MDIM6=6 + INTEGER, PARAMETER, PUBLIC :: MDIM6=6 INTEGER, PARAMETER, PUBLIC :: JBT=10 !!The number of trees in each random forest regressor + !! NUMBER OF FEATURES/INPUTS TO THE RaFWBF PARAMETERIZATION + INTEGER, PARAMETER, PUBLIC :: MDIMB=6 ! for WBF + INTEGER, PARAMETER, PUBLIC :: JBTB=10 !!The number of trees in each random forest regressor + !!The maximum number of nodes across trees INTEGER, PARAMETER, PUBLIC :: MAX_NODES1=7705 !forestBRHM INTEGER, PARAMETER, PUBLIC :: MAX_NODES2=8219 !forestBR INTEGER, PARAMETER, PUBLIC :: MAX_NODES3=7833 !forestALL INTEGER, PARAMETER, PUBLIC :: MAX_NODES4=7093 !forestBRDS INTEGER, PARAMETER, PUBLIC :: MAX_NODES5=8593 !forestBRwarm + INTEGER, PARAMETER, PUBLIC :: MAX_NODESB=123881 !forestWBF !!Thresh = threshold value at each internal node !!Outi = prediction for a given node @@ -55,6 +67,7 @@ module module_random_forests REAL(r8), DIMENSION(JBT,MAX_NODES3), PUBLIC :: THRESH3,OUT31,OUT32,OUT33,OUT34,OUT35 REAL(r8), DIMENSION(JBT,MAX_NODES4), PUBLIC :: THRESH4,OUT41,OUT42,OUT43 REAL(r8), DIMENSION(JBT,MAX_NODES5), PUBLIC :: THRESH5,OUT51 + REAL(r8), DIMENSION(JBTB,MAX_NODESB), PUBLIC :: THRESHB,OUTB !!Splitfeat = feature used for splitting the node !!Leftchild = left child of node @@ -64,21 +77,25 @@ module module_random_forests INTEGER, DIMENSION(JBT,MAX_NODES3), PUBLIC, PROTECTED :: SPLITFEAT3,LEFTCHILD3,RIGHTCHILD3 INTEGER, DIMENSION(JBT,MAX_NODES4), PUBLIC, PROTECTED :: SPLITFEAT4,LEFTCHILD4,RIGHTCHILD4 INTEGER, DIMENSION(JBT,MAX_NODES5), PUBLIC, PROTECTED :: SPLITFEAT5,LEFTCHILD5,RIGHTCHILD5 + INTEGER, DIMENSION(JBTB,MAX_NODESB), PUBLIC, PROTECTED :: SPLITFEATB,LEFTCHILDB,RIGHTCHILDB !!The exact number of nodes across in consecutive trees of the forest - INTEGER, DIMENSION(JBT), PUBLIC, PROTECTED :: NRNODES1,NRNODES2,NRNODES3,NRNODES4,NRNODES5 + INTEGER, DIMENSION(JBT), PUBLIC, PROTECTED :: NRNODES1,NRNODES2,NRNODES3,NRNODES4,NRNODES5,NRNODESB !! Namelist variables logical, public, protected :: rafsip_on = .false. + logical, public, protected :: wbfsip_on = .false. character(len=256) :: forestfileALL = 'NONE' character(len=256) :: forestfileBRDS = 'NONE' character(len=256) :: forestfileBRHM = 'NONE' character(len=256) :: forestfileBR = 'NONE' character(len=256) :: forestfileBRwarm = 'NONE' + character(len=256) :: forestfileWBF = 'NONE' !! Make sure init is only called once logical :: rafsip_initialized = .false. + logical :: rafbdf_initialized = .false. CONTAINS @@ -155,6 +172,54 @@ end subroutine sec_ice_readnl !------------------------------------------------------------------------+ + subroutine wbf_readnl(nlfile) + ! Read files needed for random forest tables of wbf factor + + use mpi, only: mpi_character, mpi_logical + use spmd_utils, only: masterproc, mstrid=>masterprocid, mpicom + use namelist_utils, only: find_group_name + use cam_logfile, only: iulog + + character(len=*), intent(in) :: nlfile ! path to file containing namelist input + + ! Local variables + integer :: unitn, ierr + character(len=*), parameter :: subname = 'wbf_readnl' + + namelist /sec_ice_nl/ rafwbf_on, & + forestfileWBF, & + ! Initialize all namelist variables + rafwbf_on = .false. + forestfileWBF = 'None' + + if (masterproc) then + open(newunit=unitn, file=trim(nlfile), status='old' ) + call find_group_name(unitn, 'wbf_nl', status=ierr) + if (ierr == 0) then + read(unitn, sec_ice_nl, iostat=ierr) + if (ierr /= 0) then + call endrun(subname//':: ERROR reading namelist') + end if + end if + close(unitn) + end if + + call MPI_Bcast(rafwbf_on, 1, mpi_logical, mstrid, mpicom, ierr) + + call MPI_Bcast(forestfileWBF, len(forestfileWBF), mpi_character, & + mstrid, mpicom, ierr) + + if (masterproc) then + write(iulog ,*) 'Microphysics WBF factor namelist:' + write(iulog ,*) ' rafsip_on = ', rafsip_on + if (rafsip_on) then + write(iulog, *) ' forestfileWBF = ', trim(forestfileWBF) + end if + end if + end subroutine wbf_readnl + + !------------------------------------------------------------------------+ + subroutine sec_ice_init() use mpi, only: mpi_integer, mpi_real8 use spmd_utils, only: masterproc, mstrid=>masterprocid, mpicom @@ -320,6 +385,54 @@ end subroutine sec_ice_init !------------------------------------------------------------------------+ + subroutine wbf_init() + use mpi, only: mpi_integer, mpi_real8 + use spmd_utils, only: masterproc, mstrid=>masterprocid, mpicom + + integer :: j_ind, n_ind + integer :: unitn + integer :: ierr + + if (.not. rafwbf_initialized) then + !--------------------------------------------------------------------- + ! RaFWBF: INITIALIZE THE RANDOM FOREST PARAMETERS + ! Initialize on the root processor, then broadcast + !--------------------------------------------------------------------- + + if (masterproc) then + ! Initialize forestBRHM parameters + ! Initialize forestALL parameters + open(newunit=unitn, file=trim(forestfileALL), status="old", & + action="read") + do j_ind = 1, JBTB + read(unitn, *) nrnodesb(j_ind) + read(unitn, *) (leftchildb(j_ind, n_ind), & + rightchildb(j_ind, n_ind), & + outb(j_ind, n_ind), threshb(j_ind, n_ind), & + splitfeatb(j_ind, n_ind), n_ind=1,nrnodesb(j_ind)) + end do + + close(unitn) + end if ! masterproc + + ! Broadcast + call MPI_Bcast(nrnodesb, JBTB, mpi_integer, & + mstrid, mpicom, ierr) + call MPI_Bcast(leftchildb, JBTB*MAX_NODESB, mpi_integer, & + mstrid, mpicom, ierr) + call MPI_Bcast(rightchildb, JBTB*MAX_NODESB, mpi_integer, & + mstrid, mpicom, ierr) + call MPI_Bcast(outb, JBTB*MAX_NODESB, mpi_real8, & + mstrid, mpicom, ierr) + call MPI_Bcast(splitfeatb, JBTB*MAX_NODESB, mpi_integer, & + mstrid, mpicom, ierr) + + rafwbf_initialized = .true. + end if + + end subroutine wbf_init + !------------------------------------------------------------------------+ + !======================================================================+ ! THREE SUBROUTINES CALLED BY THE RaFSIP PARAMETERIZATION ! !======================================================================+ From ab01817937b8ea30bb6d7bd989a03d7fbbe636f4 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 26 Apr 2026 20:11:44 +0200 Subject: [PATCH 03/12] pipe inputs and add calcs --- src/NorESM/micro_mg2_0.F90 | 60 +++++++++++++++++++++++++--- src/NorESM/micro_mg_cam.F90 | 27 +++++++++++-- src/NorESM/module_random_forests.F90 | 5 ++- src/NorESM/physpkg.F90 | 4 +- 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/src/NorESM/micro_mg2_0.F90 b/src/NorESM/micro_mg2_0.F90 index eacf43cab0..bc9136ded5 100644 --- a/src/NorESM/micro_mg2_0.F90 +++ b/src/NorESM/micro_mg2_0.F90 @@ -146,6 +146,11 @@ module micro_mg2_0 use module_random_forests, only: max_nodes5, leftchild5, rightchild5, splitfeat5 use module_random_forests, only: thresh5, out51 +!RafWBF +use module_random_forests, only: rafwbf_on, jbtb +use module_random_forests, only: max_nodesb, leftchildb, rightchildb, splitfeatb +use module_random_forests, only: threshb, outb + implicit none private save @@ -364,7 +369,10 @@ subroutine micro_mg_init( & ! RaFSIP: INITIALIZE THE RANDOM FOREST PARAMETERS call sec_ice_init() end if - + if (rafwbf_on) then + ! RaFWBF: INITIALIZE THE RANDOM FOREST PARAMETERS + call wbf_init() + end if end subroutine micro_mg_init @@ -373,7 +381,7 @@ end subroutine micro_mg_init subroutine micro_mg_tend ( & mgncol, nlev, deltatin, & - t, q, & + t, q, tsk, pblh, & qcn, qin, & ncn, nin, & qrn, qsn, & @@ -471,7 +479,7 @@ subroutine micro_mg_tend ( & evaporate_sublimate_precip, & bergeron_process_snow - use module_random_forests, only: MDIM5, MDIM6 + use module_random_forests, only: MDIM5, MDIM6, MDIMB use module_random_forests, only: runforestmulti use module_random_forests, only: runforestriv use module_random_forests, only: runforest @@ -485,6 +493,8 @@ subroutine micro_mg_tend ( & real(r8), intent(in) :: deltatin ! time step (s) real(r8), intent(in) :: t(mgncol,nlev) ! input temperature (K) real(r8), intent(in) :: q(mgncol,nlev) ! input h20 vapor mixing ratio (kg/kg) + real(r8), intent(in) :: tsk(mgncol) ! input skin temperature for RaFWBF (K) + real(r8), intent(in) :: pblh(mgncol) ! input planetary boundary layer for RaFWBF (K) ! note: all input cloud variables are grid-averaged real(r8), intent(in) :: qcn(mgncol,nlev) ! cloud water mixing ratio (kg/kg) @@ -519,6 +529,7 @@ subroutine micro_mg_tend ( & real(r8), intent(in) :: rndst(:,:,:) ! radius of each dust bin, for contact freezing (from microp_aero_ts) (m) real(r8), intent(in) :: nacon(:,:,:) ! number in each dust bin, for contact freezing (from microp_aero_ts) (1/m^3) + ! output arguments real(r8), intent(out) :: qcsinksum_rate1ord(mgncol,nlev) ! 1st order rate for @@ -928,6 +939,10 @@ subroutine micro_mg_tend ( & real(r8) :: FEATURES5(MDIM5),FEATURES6(MDIM6) real(r8) :: YPRED1,YPRED2,YPRED3,YPRED4,YPRED5 + ! RaFWBF variables: + real(r8) :: Pb, LWCb, IWCb, Tb, PBLHb, TSKb ! INPUT, dummy + real(r8) :: FEATURESB(MDIMB),YPREDB + real(r8) :: wbf_factor(mgncol,nlev) ! will be applied regardless if RafWBF is ON or OFF !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc @@ -1272,7 +1287,17 @@ subroutine micro_mg_tend ( & SIP_RATE=0._r8 QIRSIP=0._r8 QICSIP=0._r8 - + + ! RaFWBF zero vars + Pb = 0._r8 + LWCb = 0._r8 + IWCb = 0._r8 + Tb = 0._r8 + PBLHb = 0._r8 + TSKb = 0._r8 + FEATURESB(:) = 0._r8 + YPREDB = 0._r8 + wbf_factor(:,:) = 1._r8 ! this should default to 1 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc @@ -1725,11 +1750,34 @@ subroutine micro_mg_tend ( & qric(:,k), qsic(:,k), lamr(:,k), n0r(:,k), lams(:,k), n0s(:,k), & pre(:,k), prds(:,k), am_evp_st(:,k), mgncol) + ! RaFWBF parameterisattion: + if (rafwbf_on) then + do i = 1,mgncol + if (t(i,k) .le. 273.15_r8 .and. t(i,k) .ge. 235.15_r8) then + ! make inputs: + Pb = p(i,k) ! Pa + LWCb = qcic(i,k) + qric(i,k) !kg/kg + IWCb = qiic(i,k) + qsic(i,k) !kg/kg + Tb = t(i,k) - 273.15_r8 ! DegC + PBLHb = pblh(i) !m + TSKb = tsk(i) - 273.15 ! DegC + FEATURESB =(/ Pb, LWCb, IWCb, Tb, PBLHb, TSKb /) + call runforest(MDIMB, MAX_NODESB, JBTB, FEATURESB, YPREDB, + LEFTCHILDB, RIGHTCHILDB, SPLITFEATB, THRESHB, OUTB) + wbf_factor(i,k) = max(0.0_r8, YPREDB) + else + wbf_factor(i,k) = 1.0_r8 + end if + end do + else + wbf_factor(:,:) = 1.0_r8 + end if + call bergeron_process_snow(t(:,k), rho(:,k), dv(:,k), mu(:,k), sc(:,k), & qvl(:,k), qvi(:,k), asn(:,k), qcic(1:mgncol,k), qsic(:,k), lams(:,k), n0s(:,k), & bergs(:,k), mgncol) - bergs(:,k)=bergs(:,k)*micro_mg_berg_eff_factor + bergs(:,k)=bergs(:,k)*micro_mg_berg_eff_factor * wbf_factor(:,k) !+++PMC 12/3/12 - NEW VAPOR DEP/SUBLIMATION GOES HERE!!! if (do_cldice) then @@ -1738,7 +1786,7 @@ subroutine micro_mg_tend ( & icldm(:,k), rho(:,k), dv(:,k), qvl(:,k), qvi(:,k), & berg(:,k), vap_dep(:,k), ice_sublim(:,k), mgncol) - berg(:,k)=berg(:,k)*micro_mg_berg_eff_factor + berg(:,k)=berg(:,k)*micro_mg_berg_eff_factor * * wbf_factor(:,k) where (ice_sublim(:,k) < 0._r8 .and. qi(:,k) > qsmall .and. icldm(:,k) > mincld) nsubi(:,k) = sublim_factor*ice_sublim(:,k) / qi(:,k) * ni(:,k) / icldm(:,k) diff --git a/src/NorESM/micro_mg_cam.F90 b/src/NorESM/micro_mg_cam.F90 index dc82410c6f..98de41251a 100644 --- a/src/NorESM/micro_mg_cam.F90 +++ b/src/NorESM/micro_mg_cam.F90 @@ -87,6 +87,8 @@ module micro_mg_cam use cam_history, only: addfld, add_default, outfld, horiz_only +use camsrfexch, only: cam_in_t + use cam_logfile, only: iulog use cam_abortutils, only: endrun use scamMod, only: single_column @@ -258,7 +260,7 @@ subroutine micro_mg_cam_readnl(nlfile) use units, only: getunit, freeunit use spmd_utils, only: mpicom, mstrid=>masterprocid, mpi_integer, & mpi_real8, mpi_logical, mpi_character - use module_random_forests, only: sec_ice_readnl + use module_random_forests, only: sec_ice_readnl, wbf_readnl character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input @@ -389,6 +391,8 @@ subroutine micro_mg_cam_readnl(nlfile) call sec_ice_readnl(nlfile) + call wbf_readnl(nlfile) + contains subroutine bad_version_endrun @@ -1193,7 +1197,7 @@ end subroutine micro_mg_cam_init !=============================================================================== -subroutine micro_mg_cam_tend(state, ptend, dtime, pbuf) +subroutine micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) use micro_mg1_0, only: micro_mg_get_cols1_0 => micro_mg_get_cols use micro_mg2_0, only: micro_mg_get_cols2_0 => micro_mg_get_cols @@ -1201,6 +1205,7 @@ subroutine micro_mg_cam_tend(state, ptend, dtime, pbuf) type(physics_state), intent(in) :: state type(physics_ptend), intent(out) :: ptend real(r8), intent(in) :: dtime + type(cam_in_t), intent(in) :: cam_in type(physics_buffer_desc), pointer :: pbuf(:) ! Local variables @@ -1221,11 +1226,11 @@ subroutine micro_mg_cam_tend(state, ptend, dtime, pbuf) mgncol, mgcols) end select - call micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nlev) + call micro_mg_cam_tend_pack(state, ptend, dtime, cam_in, pbuf, mgncol, mgcols, nlev) end subroutine micro_mg_cam_tend -subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nlev) +subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgcols, nlev) use micro_mg_utils, only: size_dist_param_basic, size_dist_param_liq, & mg_liq_props, mg_ice_props, avg_diameter, rhoi, rhosn, rhow, rhows, & @@ -1244,6 +1249,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle type(physics_state), intent(in) :: state type(physics_ptend), intent(out) :: ptend real(r8), intent(in) :: dtime + type(cam_in_t), intent(in) :: cam_in type(physics_buffer_desc), pointer :: pbuf(:) integer, intent(in) :: nlev @@ -1285,6 +1291,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle real(r8), pointer :: mu(:,:) ! Size distribution shape parameter for radiation real(r8), pointer :: lambdac(:,:) ! Size distribution slope parameter for radiation real(r8), pointer :: des(:,:) ! Snow effective diameter (m) + real(r8), pointer :: pblh(:) ! Planetary boundary layer height (m) for RaFWBF real(r8) :: rho(state%psetcols,pver) real(r8) :: cldmax(state%psetcols,pver) @@ -1434,6 +1441,8 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle real(r8), allocatable :: packed_rndst(:,:,:) real(r8), allocatable :: packed_nacon(:,:,:) + real(r8) :: packed_tsk(mgncol) + real(r8) :: packed_pblh(mgncol) ! Optional outputs. real(r8) :: packed_tnd_qsnow(mgncol,nlev) @@ -1816,6 +1825,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle logical :: use_subcol_microp integer :: col_type ! Flag to store whether accessing grid or sub-columns in pbuf_get_field + integer :: lpblh_idx ! local version of pblh index character(128) :: errstring ! return status (non-blank for error return) @@ -1853,6 +1863,8 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle call pbuf_get_field(pbuf, relvar_idx, relvar, col_type=col_type, copy_if_needed=use_subcol_microp) call pbuf_get_field(pbuf, accre_enhan_idx, accre_enhan, col_type=col_type, copy_if_needed=use_subcol_microp) call pbuf_get_field(pbuf, cmeliq_idx, cmeliq, col_type=col_type, copy_if_needed=use_subcol_microp) + lpblh_idx = pbuf_get_index('pblh') + call pbuf_get_field(pbuf, lpblh_idx, pblh, col_type=col_type, copy_if_needed=use_subcol_microp) call pbuf_get_field(pbuf, cld_idx, cld, start=(/1,1,itim_old/), kount=(/psetcols,pver,1/), & col_type=col_type, copy_if_needed=use_subcol_microp) @@ -2257,6 +2269,11 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle packed_frzdep = packer%pack(frzdep) end if + if (micro_mg_version > 1) then + packed_tsk = packer%pack(cam_in%ts) + packed_pblh - packer%pack(pblh) + end if + do it = 1, num_steps ! Pack input variables that are updated during substeps. @@ -2266,6 +2283,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle packed_nc = packer%pack(state_loc%q(:,:,ixnumliq)) packed_qi = packer%pack(state_loc%q(:,:,ixcldice)) packed_ni = packer%pack(state_loc%q(:,:,ixnumice)) + if (micro_mg_version > 1) then packed_qr = packer%pack(state_loc%q(:,:,ixrain)) packed_nr = packer%pack(state_loc%q(:,:,ixnumrain)) @@ -2321,6 +2339,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime, pbuf, mgncol, mgcols, nle call micro_mg_tend2_0( & mgncol, nlev, dtime/num_steps,& packed_t, packed_q, & + packed_tsk, packed_pblh, & packed_qc, packed_qi, & packed_nc, packed_ni, & packed_qr, packed_qs, & diff --git a/src/NorESM/module_random_forests.F90 b/src/NorESM/module_random_forests.F90 index 40e6aa3949..bc94f1bd8c 100644 --- a/src/NorESM/module_random_forests.F90 +++ b/src/NorESM/module_random_forests.F90 @@ -67,7 +67,7 @@ module module_random_forests REAL(r8), DIMENSION(JBT,MAX_NODES3), PUBLIC :: THRESH3,OUT31,OUT32,OUT33,OUT34,OUT35 REAL(r8), DIMENSION(JBT,MAX_NODES4), PUBLIC :: THRESH4,OUT41,OUT42,OUT43 REAL(r8), DIMENSION(JBT,MAX_NODES5), PUBLIC :: THRESH5,OUT51 - REAL(r8), DIMENSION(JBTB,MAX_NODESB), PUBLIC :: THRESHB,OUTB + REAL(r8), DIMENSION(JBTB,MAX_NODESB), PUBLIC :: THRESHB,OUTB !!Splitfeat = feature used for splitting the node !!Leftchild = left child of node @@ -80,7 +80,8 @@ module module_random_forests INTEGER, DIMENSION(JBTB,MAX_NODESB), PUBLIC, PROTECTED :: SPLITFEATB,LEFTCHILDB,RIGHTCHILDB !!The exact number of nodes across in consecutive trees of the forest - INTEGER, DIMENSION(JBT), PUBLIC, PROTECTED :: NRNODES1,NRNODES2,NRNODES3,NRNODES4,NRNODES5,NRNODESB + INTEGER, DIMENSION(JBT), PUBLIC, PROTECTED :: NRNODES1,NRNODES2,NRNODES3,NRNODES4,NRNODES5 + INTEGER, DIMENSION(JBTB), PUBLIC, PROTECTED :: NRNODESB !! Namelist variables logical, public, protected :: rafsip_on = .false. diff --git a/src/NorESM/physpkg.F90 b/src/NorESM/physpkg.F90 index 053e29d8b1..fe98661c6d 100644 --- a/src/NorESM/physpkg.F90 +++ b/src/NorESM/physpkg.F90 @@ -2206,7 +2206,7 @@ subroutine tphysbc (ztodt, state, & call t_startf('microp_tend') if (use_subcol_microp) then - call microp_driver_tend(state_sc, ptend_sc, cld_macmic_ztodt, pbuf) + call microp_driver_tend(state_sc, ptend_sc, cld_macmic_ztodt, cam_in, pbuf) ! Average the sub-column ptend for use in gridded update - will not contain ptend_aero call subcol_ptend_avg(ptend_sc, state_sc%ngrdcol, lchnk, ptend) @@ -2230,7 +2230,7 @@ subroutine tphysbc (ztodt, state, & call physics_tend_dealloc(tend_sc) call physics_ptend_dealloc(ptend_sc) else - call microp_driver_tend(state, ptend, cld_macmic_ztodt, pbuf) + call microp_driver_tend(state, ptend, cld_macmic_ztodt, cam_in, pbuf) end if ! combine aero and micro tendencies for the grid call physics_ptend_sum(ptend_aero, ptend, ncol) From 149f4ea2c6cd3a3cb320ebdf22f628d49c7f4332 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 26 Apr 2026 20:12:07 +0200 Subject: [PATCH 04/12] make normal cam accept same args --- src/physics/cam/micro_mg_cam.F90 | 5 ++++- src/physics/cam/microp_driver.F90 | 7 ++++--- src/physics/cam/physpkg.F90 | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/physics/cam/micro_mg_cam.F90 b/src/physics/cam/micro_mg_cam.F90 index d36978ac29..5e0b9af445 100644 --- a/src/physics/cam/micro_mg_cam.F90 +++ b/src/physics/cam/micro_mg_cam.F90 @@ -1085,14 +1085,17 @@ end subroutine micro_mg_cam_init !=============================================================================== -subroutine micro_mg_cam_tend(state, ptend, dtime, pbuf) +subroutine micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) use micro_mg1_0, only: micro_mg_get_cols1_0 => micro_mg_get_cols use micro_mg2_0, only: micro_mg_get_cols2_0 => micro_mg_get_cols + use camsrfexch, only: cam_in_t type(physics_state), intent(in) :: state type(physics_ptend), intent(out) :: ptend real(r8), intent(in) :: dtime + type(cam_in_t), intent(in) :: cam_in + type(physics_buffer_desc), pointer :: pbuf(:) ! Local variables diff --git a/src/physics/cam/microp_driver.F90 b/src/physics/cam/microp_driver.F90 index 00e18f8364..1362f97c57 100644 --- a/src/physics/cam/microp_driver.F90 +++ b/src/physics/cam/microp_driver.F90 @@ -159,14 +159,15 @@ end subroutine microp_driver_init !=============================================================================== -subroutine microp_driver_tend(state, ptend, dtime, pbuf) +subroutine microp_driver_tend(state, ptend, dtime,cam_in, pbuf) ! Call the microphysics parameterization run methods. - + use camsrfexch, only: cam_in_t ! Input arguments type(physics_state), intent(in) :: state ! State variables type(physics_ptend), intent(out) :: ptend ! Package tendencies + type(cam_in_t), intent(in) :: cam_in ! type(physics_buffer_desc), pointer :: pbuf(:) real(r8), intent(in) :: dtime ! Timestep @@ -186,7 +187,7 @@ subroutine microp_driver_tend(state, ptend, dtime, pbuf) select case (microp_scheme) case ('MG') call t_startf('microp_mg_tend') - call micro_mg_cam_tend(state, ptend, dtime, pbuf) + call micro_mg_cam_tend(state, ptend, dtime,, cam_in, pbuf) call t_stopf('microp_mg_tend') case ('RK') ! microp_driver doesn't handle this one diff --git a/src/physics/cam/physpkg.F90 b/src/physics/cam/physpkg.F90 index 842f57c34b..b733283907 100644 --- a/src/physics/cam/physpkg.F90 +++ b/src/physics/cam/physpkg.F90 @@ -2137,7 +2137,7 @@ subroutine tphysbc (ztodt, state, & call t_startf('microp_tend') if (use_subcol_microp) then - call microp_driver_tend(state_sc, ptend_sc, cld_macmic_ztodt, pbuf) + call microp_driver_tend(state_sc, ptend_sc, cld_macmic_ztodt, cam_in, pbuf) ! Average the sub-column ptend for use in gridded update - will not contain ptend_aero call subcol_ptend_avg(ptend_sc, state_sc%ngrdcol, lchnk, ptend) @@ -2161,7 +2161,7 @@ subroutine tphysbc (ztodt, state, & call physics_tend_dealloc(tend_sc) call physics_ptend_dealloc(ptend_sc) else - call microp_driver_tend(state, ptend, cld_macmic_ztodt, pbuf) + call microp_driver_tend(state, ptend, cld_macmic_ztodt, cam_in, pbuf) end if ! combine aero and micro tendencies for the grid call physics_ptend_sum(ptend_aero, ptend, ncol) From 849508dadc55922979d75b4465cec20de9279348 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 26 Apr 2026 20:20:04 +0200 Subject: [PATCH 05/12] bound rf output fix typo --- src/NorESM/micro_mg2_0.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NorESM/micro_mg2_0.F90 b/src/NorESM/micro_mg2_0.F90 index bc9136ded5..e62415f85e 100644 --- a/src/NorESM/micro_mg2_0.F90 +++ b/src/NorESM/micro_mg2_0.F90 @@ -1764,7 +1764,7 @@ subroutine micro_mg_tend ( & FEATURESB =(/ Pb, LWCb, IWCb, Tb, PBLHb, TSKb /) call runforest(MDIMB, MAX_NODESB, JBTB, FEATURESB, YPREDB, LEFTCHILDB, RIGHTCHILDB, SPLITFEATB, THRESHB, OUTB) - wbf_factor(i,k) = max(0.0_r8, YPREDB) + wbf_factor(i,k) = max(0.0_r8, min(1.0_r8,YPREDB)) else wbf_factor(i,k) = 1.0_r8 end if @@ -1786,7 +1786,7 @@ subroutine micro_mg_tend ( & icldm(:,k), rho(:,k), dv(:,k), qvl(:,k), qvi(:,k), & berg(:,k), vap_dep(:,k), ice_sublim(:,k), mgncol) - berg(:,k)=berg(:,k)*micro_mg_berg_eff_factor * * wbf_factor(:,k) + berg(:,k)=berg(:,k)*micro_mg_berg_eff_factor * wbf_factor(:,k) where (ice_sublim(:,k) < 0._r8 .and. qi(:,k) > qsmall .and. icldm(:,k) > mincld) nsubi(:,k) = sublim_factor*ice_sublim(:,k) / qi(:,k) * ni(:,k) / icldm(:,k) From 5c5a2f082335d285a76e33d47777f7f9a8191db4 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Mon, 27 Apr 2026 19:40:11 +0200 Subject: [PATCH 06/12] fix compile errors and namelists --- bld/build-namelist | 14 +++++- bld/namelist_files/namelist_defaults_cam.xml | 2 +- src/NorESM/micro_mg2_0.F90 | 9 ++-- src/NorESM/micro_mg_cam.F90 | 33 +++++++++++-- src/NorESM/module_random_forests.F90 | 49 +++++++++++--------- src/physics/cam/microp_driver.F90 | 2 +- 6 files changed, 77 insertions(+), 32 deletions(-) diff --git a/bld/build-namelist b/bld/build-namelist index 5f309bdb74..893647cdde 100755 --- a/bld/build-namelist +++ b/bld/build-namelist @@ -3074,7 +3074,19 @@ if ($cfg->get('microphys') =~ /^mg/) { add_default($nl, 'forestfileBRwarm'); } add_default($nl, 'rafwbf_on'); - add_default($nl, 'forestfileWBF'); + if ($nl->get_value('rafwbf_on') =~ m/$TRUE/io) { + if ($nl->get_value('micro_mg_do_cldice') =~ m/$FALSE/io) { + # Generate an error since both of these variables would have to be + # set manually for this condition + die "$ProgName - Error: Cannot set rafwbf_on = .true. if micro_mg_do_cldice = .false.\n"; + } + if ( ! $nl->get_value('micro_mg_version') == '2') { + # Generate an error since both of these variables would have to be + # set manually for this condition + die "$ProgName - Error: Cannot set rafwbf_on = .true. if micro_mg_versuin /= 2\n"; + } + add_default($nl, 'forestfileWBF'); + } } # Ice nucleation options diff --git a/bld/namelist_files/namelist_defaults_cam.xml b/bld/namelist_files/namelist_defaults_cam.xml index 5717c2856e..c6eb171846 100644 --- a/bld/namelist_files/namelist_defaults_cam.xml +++ b/bld/namelist_files/namelist_defaults_cam.xml @@ -1276,7 +1276,7 @@ atm/cam/RaFSIP/forestBRwarm.txt -.false. +.false. atm/cam/RaFWBF/forestWBF_c260424.txt diff --git a/src/NorESM/micro_mg2_0.F90 b/src/NorESM/micro_mg2_0.F90 index e62415f85e..2afcda6816 100644 --- a/src/NorESM/micro_mg2_0.F90 +++ b/src/NorESM/micro_mg2_0.F90 @@ -259,7 +259,7 @@ subroutine micro_mg_init( & allow_sed_supersat_in, do_sb_physics_in, & nccons_in, nicons_in, ncnst_in, ninst_in, errstring) - use module_random_forests, only: sec_ice_init + use module_random_forests, only: sec_ice_init, wbf_init use micro_mg_utils, only: micro_mg_utils_init !----------------------------------------------------------------------- @@ -416,7 +416,7 @@ subroutine micro_mg_tend ( & qrsedten, qssedten, & pratot, prctot, & mnuccctot, mnuccttot, msacwitot, & - psacwstot, bergstot, bergtot, & + psacwstot, bergstot, bergtot, bergf, & melttot, homotot, & qcrestot, prcitot, praitot, & qirestot, mnuccrtot, pracstot, & @@ -592,6 +592,7 @@ subroutine micro_mg_tend ( & real(r8), intent(out) :: psacwstot(mgncol,nlev) ! collection of cloud water by snow real(r8), intent(out) :: bergstot(mgncol,nlev) ! bergeron process on snow real(r8), intent(out) :: bergtot(mgncol,nlev) ! bergeron process on cloud ice + real(r8), intent(out) :: bergf(mgncol,nlev) ! factor for bergeron process in RafWBF real(r8), intent(out) :: melttot(mgncol,nlev) ! melting of cloud ice real(r8), intent(out) :: homotot(mgncol,nlev) ! homogeneous freezing cloud water real(r8), intent(out) :: qcrestot(mgncol,nlev) ! residual cloud condensation due to removal of excess supersat @@ -1298,6 +1299,7 @@ subroutine micro_mg_tend ( & FEATURESB(:) = 0._r8 YPREDB = 0._r8 wbf_factor(:,:) = 1._r8 ! this should default to 1 + bergf=1.0_r8 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc @@ -1762,7 +1764,7 @@ subroutine micro_mg_tend ( & PBLHb = pblh(i) !m TSKb = tsk(i) - 273.15 ! DegC FEATURESB =(/ Pb, LWCb, IWCb, Tb, PBLHb, TSKb /) - call runforest(MDIMB, MAX_NODESB, JBTB, FEATURESB, YPREDB, + call runforest(MDIMB, MAX_NODESB, JBTB, FEATURESB, YPREDB, & LEFTCHILDB, RIGHTCHILDB, SPLITFEATB, THRESHB, OUTB) wbf_factor(i,k) = max(0.0_r8, min(1.0_r8,YPREDB)) else @@ -2478,6 +2480,7 @@ subroutine micro_mg_tend ( & psacwstot(i,k) = psacws(i,k)*lcldm(i,k) bergstot(i,k) = bergs(i,k)*lcldm(i,k) bergtot(i,k) = berg(i,k) + bergf(i,k) = wbf_factor(i,k) prcitot(i,k) = prci(i,k)*icldm(i,k) praitot(i,k) = prai(i,k)*icldm(i,k) mnuccdtot(i,k) = mnuccd(i,k)*icldm(i,k) diff --git a/src/NorESM/micro_mg_cam.F90 b/src/NorESM/micro_mg_cam.F90 index 98de41251a..7d267e1155 100644 --- a/src/NorESM/micro_mg_cam.F90 +++ b/src/NorESM/micro_mg_cam.F90 @@ -391,7 +391,7 @@ subroutine micro_mg_cam_readnl(nlfile) call sec_ice_readnl(nlfile) - call wbf_readnl(nlfile) + call wbf_readnl(nlfile, micro_mg_version) contains @@ -411,7 +411,6 @@ subroutine micro_mg_cam_register ! Register microphysics constituents and fields in the physics buffer. !----------------------------------------------------------------------- - logical :: prog_modal_aero logical :: use_subcol_microp ! If true, then are using subcolumns in microphysics @@ -647,7 +646,7 @@ subroutine micro_mg_cam_init(pbuf2d) use micro_mg_utils, only: micro_mg_utils_init use micro_mg1_0, only: micro_mg_init1_0 => micro_mg_init use micro_mg2_0, only: micro_mg_init2_0 => micro_mg_init - + use module_random_forests, only: rafwbf_on !----------------------------------------------------------------------- ! ! Initialization for MG microphysics @@ -969,6 +968,9 @@ subroutine micro_mg_cam_init(pbuf2d) if (micro_mg_version > 1) then call addfld('UMR', (/ 'lev' /), 'A', 'm/s', 'Mass-weighted rain fallspeed' ) call addfld('UMS', (/ 'lev' /), 'A', 'm/s', 'Mass-weighted snow fallspeed' ) + if (rafwbf_on) then + call addfld ('BERGF', (/ 'lev' /), 'A', 'unitless', 'RaFWBF factor for bergeron' ) + end if end if ! qc limiter (only output in versions 1.5 and later) @@ -1061,6 +1063,9 @@ subroutine micro_mg_cam_init(pbuf2d) call add_default ('CMEIOUT ', budget_histfile, ' ') call add_default ('BERGSO ', budget_histfile, ' ') call add_default ('BERGO ', budget_histfile, ' ') + if (rafwbf_on) then + call add_default ('BERGF ', budget_histfile, ' ') + end if !AL call add_default ('NNUCCCO ', budget_histfile, ' ') call add_default ('NNUCCTO ', budget_histfile, ' ') @@ -1120,6 +1125,7 @@ subroutine micro_mg_cam_init(pbuf2d) call add_default(bpcnst (ixsnow), budget_histfile, ' ') end if + end if ! physics buffer indices @@ -1201,6 +1207,7 @@ subroutine micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) use micro_mg1_0, only: micro_mg_get_cols1_0 => micro_mg_get_cols use micro_mg2_0, only: micro_mg_get_cols2_0 => micro_mg_get_cols + use module_random_forests, only: rafwbf_on type(physics_state), intent(in) :: state type(physics_ptend), intent(out) :: ptend @@ -1245,6 +1252,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco use subcol, only: subcol_field_avg use tropopause, only: tropopause_find, TROP_ALG_CPP, TROP_ALG_NONE, NOTFOUND use wv_saturation, only: qsat + use module_random_forests, only: rafwbf_on type(physics_state), intent(in) :: state type(physics_ptend), intent(out) :: ptend @@ -1343,6 +1351,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco real(r8), target :: psacwso(state%psetcols,pver) real(r8), target :: bergso(state%psetcols,pver) real(r8), target :: bergo(state%psetcols,pver) + real(r8), target :: bergf(state%psetcols,pver) real(r8), target :: melto(state%psetcols,pver) real(r8), target :: homoo(state%psetcols,pver) real(r8), target :: qcreso(state%psetcols,pver) @@ -1504,6 +1513,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco real(r8), target :: packed_psacws(mgncol,nlev) real(r8), target :: packed_bergs(mgncol,nlev) real(r8), target :: packed_berg(mgncol,nlev) + real(r8), target :: packed_bergf(mgncol,nlev) real(r8), target :: packed_melt(mgncol,nlev) real(r8), target :: packed_homo(mgncol,nlev) real(r8), target :: packed_qcres(mgncol,nlev) @@ -1760,6 +1770,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco real(r8) :: mnuccco_grid(pcols,pver) real(r8) :: mnuccto_grid(pcols,pver) real(r8) :: bergo_grid(pcols,pver) + real(r8) :: bergf_grid(pcols,pver) real(r8) :: homoo_grid(pcols,pver) real(r8) :: msacwio_grid(pcols,pver) real(r8) :: psacwso_grid(pcols,pver) @@ -2138,6 +2149,9 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco call post_proc%add_field(p(psacwso), p(packed_psacws)) call post_proc%add_field(p(bergso), p(packed_bergs)) call post_proc%add_field(p(bergo), p(packed_berg)) + if (rafwbf_on) then + call post_proc%add_field(p(bergf), p(packed_bergf)) + endif call post_proc%add_field(p(melto), p(packed_melt)) call post_proc%add_field(p(homoo), p(packed_homo)) call post_proc%add_field(p(qcreso), p(packed_qcres)) @@ -2271,7 +2285,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco if (micro_mg_version > 1) then packed_tsk = packer%pack(cam_in%ts) - packed_pblh - packer%pack(pblh) + packed_pblh = packer%pack(pblh) end if do it = 1, num_steps @@ -2375,7 +2389,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco packed_pra, packed_prc, & packed_mnuccc, packed_mnucct, packed_msacwi, & packed_psacws, packed_bergs, packed_berg, & - packed_melt, packed_homo, & + packed_bergf, packed_melt, packed_homo, & packed_qcres, packed_prci, packed_prai, & packed_qires, packed_mnuccr, packed_pracs, & packed_meltsdt, packed_frzrdt, packed_mnuccd, & @@ -2635,6 +2649,9 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco call subcol_field_avg(mnuccco, ngrdcol, lchnk, mnuccco_grid) call subcol_field_avg(mnuccto, ngrdcol, lchnk, mnuccto_grid) call subcol_field_avg(bergo, ngrdcol, lchnk, bergo_grid) + if (rafwbf_on) then + call subcol_field_avg(bergf, ngrdcol, lchnk, bergf_grid) + end if call subcol_field_avg(homoo, ngrdcol, lchnk, homoo_grid) call subcol_field_avg(msacwio, ngrdcol, lchnk, msacwio_grid) call subcol_field_avg(psacwso, ngrdcol, lchnk, psacwso_grid) @@ -2701,6 +2718,9 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco mnuccco_grid = mnuccco mnuccto_grid = mnuccto bergo_grid = bergo + if (rafwbf_on) then + bergf_grid = bergf + end if homoo_grid = homoo msacwio_grid = msacwio psacwso_grid = psacwso @@ -3350,6 +3370,9 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco call outfld('PSACWSO', psacwso_grid, pcols, lchnk) call outfld('BERGSO', bergso_grid, pcols, lchnk) call outfld('BERGO', bergo_grid, pcols, lchnk) + if (rafwbf_on) then + call outfld('BERGF', bergf_grid, pcols, lchnk) + end if call outfld('MELTO', melto_grid, pcols, lchnk) call outfld('HOMOO', homoo_grid, pcols, lchnk) call outfld('PRCIO', prcio_grid, pcols, lchnk) diff --git a/src/NorESM/module_random_forests.F90 b/src/NorESM/module_random_forests.F90 index bc94f1bd8c..922964f1a9 100644 --- a/src/NorESM/module_random_forests.F90 +++ b/src/NorESM/module_random_forests.F90 @@ -41,7 +41,6 @@ module module_random_forests PUBLIC :: runforest PUBLIC :: runforestriv PUBLIC :: runforestmulti - PUBLIC :: runforestwbf !!MDIM DEFINES THE NUMBER OF FEATURES/INPUTS TO THE RaFSIP PARAMETERIZATION INTEGER, PARAMETER, PUBLIC :: MDIM5=5 @@ -58,7 +57,7 @@ module module_random_forests INTEGER, PARAMETER, PUBLIC :: MAX_NODES3=7833 !forestALL INTEGER, PARAMETER, PUBLIC :: MAX_NODES4=7093 !forestBRDS INTEGER, PARAMETER, PUBLIC :: MAX_NODES5=8593 !forestBRwarm - INTEGER, PARAMETER, PUBLIC :: MAX_NODESB=123881 !forestWBF + INTEGER, PARAMETER, PUBLIC :: MAX_NODESB=124209 !forestWBF !!Thresh = threshold value at each internal node !!Outi = prediction for a given node @@ -85,7 +84,7 @@ module module_random_forests !! Namelist variables logical, public, protected :: rafsip_on = .false. - logical, public, protected :: wbfsip_on = .false. + logical, public, protected :: rafwbf_on = .false. character(len=256) :: forestfileALL = 'NONE' character(len=256) :: forestfileBRDS = 'NONE' @@ -96,7 +95,7 @@ module module_random_forests !! Make sure init is only called once logical :: rafsip_initialized = .false. - logical :: rafbdf_initialized = .false. + logical :: rafwbf_initialized = .false. CONTAINS @@ -173,7 +172,7 @@ end subroutine sec_ice_readnl !------------------------------------------------------------------------+ - subroutine wbf_readnl(nlfile) + subroutine wbf_readnl(nlfile, mg_ver) ! Read files needed for random forest tables of wbf factor use mpi, only: mpi_character, mpi_logical @@ -182,28 +181,32 @@ subroutine wbf_readnl(nlfile) use cam_logfile, only: iulog character(len=*), intent(in) :: nlfile ! path to file containing namelist input + integer, intent(in) :: mg_ver ! Local variables integer :: unitn, ierr character(len=*), parameter :: subname = 'wbf_readnl' - namelist /sec_ice_nl/ rafwbf_on, & - forestfileWBF, & + namelist /wbf_nl/ rafwbf_on, forestfileWBF + ! Initialize all namelist variables rafwbf_on = .false. forestfileWBF = 'None' - - if (masterproc) then - open(newunit=unitn, file=trim(nlfile), status='old' ) - call find_group_name(unitn, 'wbf_nl', status=ierr) - if (ierr == 0) then - read(unitn, sec_ice_nl, iostat=ierr) - if (ierr /= 0) then - call endrun(subname//':: ERROR reading namelist') - end if - end if - close(unitn) - end if + if (mg_ver>1) then + if (masterproc) then + open(newunit=unitn, file=trim(nlfile), status='old' ) + call find_group_name(unitn, 'wbf_nl', status=ierr) + if (ierr == 0) then + read(unitn, wbf_nl, iostat=ierr) + if (ierr /= 0) then + call endrun(subname//':: ERROR reading namelist') + end if + end if + close(unitn) + end if + else + call endrun(subname//':: ERROR rafwbf_on = .true. is incompatible with micro_mg_version=2') + endif call MPI_Bcast(rafwbf_on, 1, mpi_logical, mstrid, mpicom, ierr) @@ -212,7 +215,7 @@ subroutine wbf_readnl(nlfile) if (masterproc) then write(iulog ,*) 'Microphysics WBF factor namelist:' - write(iulog ,*) ' rafsip_on = ', rafsip_on + write(iulog ,*) ' rafwbf_on = ', rafwbf_on if (rafsip_on) then write(iulog, *) ' forestfileWBF = ', trim(forestfileWBF) end if @@ -393,6 +396,7 @@ subroutine wbf_init() integer :: j_ind, n_ind integer :: unitn integer :: ierr + character(len=*), parameter :: subname = 'wbf_init' if (.not. rafwbf_initialized) then !--------------------------------------------------------------------- @@ -403,7 +407,7 @@ subroutine wbf_init() if (masterproc) then ! Initialize forestBRHM parameters ! Initialize forestALL parameters - open(newunit=unitn, file=trim(forestfileALL), status="old", & + open(newunit=unitn, file=trim(forestfileWBF), status="old", & action="read") do j_ind = 1, JBTB read(unitn, *) nrnodesb(j_ind) @@ -414,6 +418,9 @@ subroutine wbf_init() end do close(unitn) + if (any(SPLITFEATB<-1)) then + call endrun(subname//':: ERROR tree has split feature index invalid') + end if end if ! masterproc ! Broadcast diff --git a/src/physics/cam/microp_driver.F90 b/src/physics/cam/microp_driver.F90 index 1362f97c57..37a4e0bce1 100644 --- a/src/physics/cam/microp_driver.F90 +++ b/src/physics/cam/microp_driver.F90 @@ -187,7 +187,7 @@ subroutine microp_driver_tend(state, ptend, dtime,cam_in, pbuf) select case (microp_scheme) case ('MG') call t_startf('microp_mg_tend') - call micro_mg_cam_tend(state, ptend, dtime,, cam_in, pbuf) + call micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) call t_stopf('microp_mg_tend') case ('RK') ! microp_driver doesn't handle this one From dd93f6c1acded1d5dd493651e621f25e9504d40f Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Mon, 27 Apr 2026 19:40:35 +0200 Subject: [PATCH 07/12] add testmod --- .../testmods_dirs/cam/rafwbf/shell_commands | 2 ++ .../testmods_dirs/cam/rafwbf/user_nl_cam | 6 +++++ .../testmods_dirs/cam/rafwbf/user_nl_clm | 26 +++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 cime_config/testdefs/testmods_dirs/cam/rafwbf/shell_commands create mode 100644 cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_cam create mode 100644 cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_clm diff --git a/cime_config/testdefs/testmods_dirs/cam/rafwbf/shell_commands b/cime_config/testdefs/testmods_dirs/cam/rafwbf/shell_commands new file mode 100644 index 0000000000..eb40ad83e0 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/cam/rafwbf/shell_commands @@ -0,0 +1,2 @@ +./xmlchange ROF_NCPL=\$ATM_NCPL +./xmlchange GLC_NCPL=\$ATM_NCPL diff --git a/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_cam b/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_cam new file mode 100644 index 0000000000..078fb2fd09 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_cam @@ -0,0 +1,6 @@ +mfilt = 1,1,1,1,1,1 +ndens = 1,1,1,1,1,1 +nhtfrq = 3,3,3,3,3,3 +inithist = 'ENDOFRUN' +history_budget = .true. +rafwbf_on = .true. diff --git a/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_clm b/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_clm new file mode 100644 index 0000000000..58c05c23c2 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_clm @@ -0,0 +1,26 @@ +!---------------------------------------------------------------------------------- +! Users should add all user specific namelist changes below in the form of +! namelist_var = new_namelist_value +! +! Include namelist variables for drv_flds_in ONLY if -megan and/or -drydep options +! are set in the CLM_NAMELIST_OPTS env variable. +! +! EXCEPTIONS: +! Set use_cndv by the compset you use and the CLM_BLDNML_OPTS -dynamic_vegetation setting +! Set use_vichydro by the compset you use and the CLM_BLDNML_OPTS -vichydro setting +! Set use_cn by the compset you use and CLM_BLDNML_OPTS -bgc setting +! Set use_crop by the compset you use and CLM_BLDNML_OPTS -crop setting +! Set spinup_state by the CLM_BLDNML_OPTS -bgc_spinup setting +! Set irrigate by the CLM_BLDNML_OPTS -irrig setting +! Set dtime with L_NCPL option +! Set fatmlndfrc with LND_DOMAIN_PATH/LND_DOMAIN_FILE options +! Set finidat with RUN_REFCASE/RUN_REFDATE/RUN_REFTOD options for hybrid or branch cases +! (includes $inst_string for multi-ensemble cases) +! Set glc_grid with CISM_GRID option +! Set glc_smb with GLC_SMB option +! Set maxpatch_glcmec with GLC_NEC option +! Set glc_do_dynglacier with GLC_TWO_WAY_COUPLING env variable +!---------------------------------------------------------------------------------- +hist_nhtfrq = 9 +hist_mfilt = 1 +hist_ndens = 1 From a04007bb9f4f3b6a74ed605a940afeb1d301b604 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 29 Apr 2026 16:48:00 +0200 Subject: [PATCH 08/12] add tests and address comments. --- bld/namelist_files/namelist_definition.xml | 2 +- cime_config/testdefs/testlist_cam.xml | 10 ++++++++++ .../testdefs/testmods_dirs/cam/rafwbf/user_nl_cam | 2 +- src/NorESM/micro_mg2_0.F90 | 4 ++-- src/NorESM/micro_mg_cam.F90 | 13 ++++++------- src/NorESM/module_random_forests.F90 | 4 ++++ src/NorESM/physpkg.F90 | 4 ++-- src/physics/cam/micro_mg_cam.F90 | 5 ++--- src/physics/cam/microp_driver.F90 | 6 +++--- src/physics/cam/physpkg.F90 | 2 +- 10 files changed, 32 insertions(+), 20 deletions(-) diff --git a/bld/namelist_files/namelist_definition.xml b/bld/namelist_files/namelist_definition.xml index 9e9b6ef532..1cf6bd8d34 100644 --- a/bld/namelist_files/namelist_definition.xml +++ b/bld/namelist_files/namelist_definition.xml @@ -2779,7 +2779,7 @@ Default: .true. - ML parameters for Damman et al., ... + ML parameters for Damman et al., in preparation to submission to ACP. Default: None diff --git a/cime_config/testdefs/testlist_cam.xml b/cime_config/testdefs/testlist_cam.xml index 514d5bada6..651ef57145 100644 --- a/cime_config/testdefs/testlist_cam.xml +++ b/cime_config/testdefs/testlist_cam.xml @@ -50,6 +50,16 @@ + + + + + + + + + + diff --git a/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_cam b/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_cam index 078fb2fd09..343695eae8 100644 --- a/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_cam +++ b/cime_config/testdefs/testmods_dirs/cam/rafwbf/user_nl_cam @@ -1,6 +1,6 @@ mfilt = 1,1,1,1,1,1 ndens = 1,1,1,1,1,1 -nhtfrq = 3,3,3,3,3,3 +nhtfrq = 9,9,9,9,9,9 inithist = 'ENDOFRUN' history_budget = .true. rafwbf_on = .true. diff --git a/src/NorESM/micro_mg2_0.F90 b/src/NorESM/micro_mg2_0.F90 index 2afcda6816..9d0fe5447d 100644 --- a/src/NorESM/micro_mg2_0.F90 +++ b/src/NorESM/micro_mg2_0.F90 @@ -147,7 +147,7 @@ module micro_mg2_0 use module_random_forests, only: thresh5, out51 !RafWBF -use module_random_forests, only: rafwbf_on, jbtb +use module_random_forests, only: rafwbf_on, jbtb, tupb, tlob use module_random_forests, only: max_nodesb, leftchildb, rightchildb, splitfeatb use module_random_forests, only: threshb, outb @@ -1755,7 +1755,7 @@ subroutine micro_mg_tend ( & ! RaFWBF parameterisattion: if (rafwbf_on) then do i = 1,mgncol - if (t(i,k) .le. 273.15_r8 .and. t(i,k) .ge. 235.15_r8) then + if (t(i,k) >= tupb .and. t(i,k) <= tlob) then ! make inputs: Pb = p(i,k) ! Pa LWCb = qcic(i,k) + qric(i,k) !kg/kg diff --git a/src/NorESM/micro_mg_cam.F90 b/src/NorESM/micro_mg_cam.F90 index 7d267e1155..812197f0a9 100644 --- a/src/NorESM/micro_mg_cam.F90 +++ b/src/NorESM/micro_mg_cam.F90 @@ -87,7 +87,6 @@ module micro_mg_cam use cam_history, only: addfld, add_default, outfld, horiz_only -use camsrfexch, only: cam_in_t use cam_logfile, only: iulog use cam_abortutils, only: endrun @@ -1203,7 +1202,7 @@ end subroutine micro_mg_cam_init !=============================================================================== -subroutine micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) +subroutine micro_mg_cam_tend(state, ptend, dtime, tskin, pbuf) use micro_mg1_0, only: micro_mg_get_cols1_0 => micro_mg_get_cols use micro_mg2_0, only: micro_mg_get_cols2_0 => micro_mg_get_cols @@ -1212,7 +1211,7 @@ subroutine micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) type(physics_state), intent(in) :: state type(physics_ptend), intent(out) :: ptend real(r8), intent(in) :: dtime - type(cam_in_t), intent(in) :: cam_in + real(r8), intent(in) :: tskin(:) type(physics_buffer_desc), pointer :: pbuf(:) ! Local variables @@ -1233,11 +1232,11 @@ subroutine micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) mgncol, mgcols) end select - call micro_mg_cam_tend_pack(state, ptend, dtime, cam_in, pbuf, mgncol, mgcols, nlev) + call micro_mg_cam_tend_pack(state, ptend, dtime, tskin, pbuf, mgncol, mgcols, nlev) end subroutine micro_mg_cam_tend -subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgcols, nlev) +subroutine micro_mg_cam_tend_pack(state, ptend, dtime,tskin, pbuf, mgncol, mgcols, nlev) use micro_mg_utils, only: size_dist_param_basic, size_dist_param_liq, & mg_liq_props, mg_ice_props, avg_diameter, rhoi, rhosn, rhow, rhows, & @@ -1257,7 +1256,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco type(physics_state), intent(in) :: state type(physics_ptend), intent(out) :: ptend real(r8), intent(in) :: dtime - type(cam_in_t), intent(in) :: cam_in + real(r8), intent(in) :: tskin(pcols) type(physics_buffer_desc), pointer :: pbuf(:) integer, intent(in) :: nlev @@ -2284,7 +2283,7 @@ subroutine micro_mg_cam_tend_pack(state, ptend, dtime,cam_in, pbuf, mgncol, mgco end if if (micro_mg_version > 1) then - packed_tsk = packer%pack(cam_in%ts) + packed_tsk = packer%pack(tskin) packed_pblh = packer%pack(pblh) end if diff --git a/src/NorESM/module_random_forests.F90 b/src/NorESM/module_random_forests.F90 index 922964f1a9..bef63803b4 100644 --- a/src/NorESM/module_random_forests.F90 +++ b/src/NorESM/module_random_forests.F90 @@ -82,6 +82,10 @@ module module_random_forests INTEGER, DIMENSION(JBT), PUBLIC, PROTECTED :: NRNODES1,NRNODES2,NRNODES3,NRNODES4,NRNODES5 INTEGER, DIMENSION(JBTB), PUBLIC, PROTECTED :: NRNODESB + ! RAFWBF specific parameters + REAL(r8), PUBLIC, PARAMETER :: TUPB = 273.15 ! Upper bound for temperature for running RF [K] + REAL(r8), PUBLIC, PARAMETER :: TLOB = 238.15 ! Lower bound for temperature for running RF [K] + !! Namelist variables logical, public, protected :: rafsip_on = .false. logical, public, protected :: rafwbf_on = .false. diff --git a/src/NorESM/physpkg.F90 b/src/NorESM/physpkg.F90 index fe98661c6d..e6a2871f00 100644 --- a/src/NorESM/physpkg.F90 +++ b/src/NorESM/physpkg.F90 @@ -2206,7 +2206,7 @@ subroutine tphysbc (ztodt, state, & call t_startf('microp_tend') if (use_subcol_microp) then - call microp_driver_tend(state_sc, ptend_sc, cld_macmic_ztodt, cam_in, pbuf) + call microp_driver_tend(state_sc, ptend_sc, cld_macmic_ztodt, cam_in%ts, pbuf) ! Average the sub-column ptend for use in gridded update - will not contain ptend_aero call subcol_ptend_avg(ptend_sc, state_sc%ngrdcol, lchnk, ptend) @@ -2230,7 +2230,7 @@ subroutine tphysbc (ztodt, state, & call physics_tend_dealloc(tend_sc) call physics_ptend_dealloc(ptend_sc) else - call microp_driver_tend(state, ptend, cld_macmic_ztodt, cam_in, pbuf) + call microp_driver_tend(state, ptend, cld_macmic_ztodt, cam_in%ts, pbuf) end if ! combine aero and micro tendencies for the grid call physics_ptend_sum(ptend_aero, ptend, ncol) diff --git a/src/physics/cam/micro_mg_cam.F90 b/src/physics/cam/micro_mg_cam.F90 index 5e0b9af445..4a0dc6b358 100644 --- a/src/physics/cam/micro_mg_cam.F90 +++ b/src/physics/cam/micro_mg_cam.F90 @@ -1085,16 +1085,15 @@ end subroutine micro_mg_cam_init !=============================================================================== -subroutine micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) +subroutine micro_mg_cam_tend(state, ptend, dtime, tskin, pbuf) use micro_mg1_0, only: micro_mg_get_cols1_0 => micro_mg_get_cols use micro_mg2_0, only: micro_mg_get_cols2_0 => micro_mg_get_cols - use camsrfexch, only: cam_in_t type(physics_state), intent(in) :: state type(physics_ptend), intent(out) :: ptend real(r8), intent(in) :: dtime - type(cam_in_t), intent(in) :: cam_in + real(r8), intent(in) :: tskin(:) ! dummy here, only used in NorESM type(physics_buffer_desc), pointer :: pbuf(:) diff --git a/src/physics/cam/microp_driver.F90 b/src/physics/cam/microp_driver.F90 index 37a4e0bce1..aaa57c450f 100644 --- a/src/physics/cam/microp_driver.F90 +++ b/src/physics/cam/microp_driver.F90 @@ -159,7 +159,7 @@ end subroutine microp_driver_init !=============================================================================== -subroutine microp_driver_tend(state, ptend, dtime,cam_in, pbuf) +subroutine microp_driver_tend(state, ptend, dtime, tskin, pbuf) ! Call the microphysics parameterization run methods. use camsrfexch, only: cam_in_t @@ -167,7 +167,7 @@ subroutine microp_driver_tend(state, ptend, dtime,cam_in, pbuf) type(physics_state), intent(in) :: state ! State variables type(physics_ptend), intent(out) :: ptend ! Package tendencies - type(cam_in_t), intent(in) :: cam_in ! + real(r8), intent(in) :: tskin(:) ! Radiative surface temperature type(physics_buffer_desc), pointer :: pbuf(:) real(r8), intent(in) :: dtime ! Timestep @@ -187,7 +187,7 @@ subroutine microp_driver_tend(state, ptend, dtime,cam_in, pbuf) select case (microp_scheme) case ('MG') call t_startf('microp_mg_tend') - call micro_mg_cam_tend(state, ptend, dtime, cam_in, pbuf) + call micro_mg_cam_tend(state, ptend, dtime, tskin, pbuf) call t_stopf('microp_mg_tend') case ('RK') ! microp_driver doesn't handle this one diff --git a/src/physics/cam/physpkg.F90 b/src/physics/cam/physpkg.F90 index b733283907..490e91eac9 100644 --- a/src/physics/cam/physpkg.F90 +++ b/src/physics/cam/physpkg.F90 @@ -2137,7 +2137,7 @@ subroutine tphysbc (ztodt, state, & call t_startf('microp_tend') if (use_subcol_microp) then - call microp_driver_tend(state_sc, ptend_sc, cld_macmic_ztodt, cam_in, pbuf) + call microp_driver_tend(state_sc, ptend_sc, cld_macmic_ztodt, cam_in%ts, pbuf) ! Average the sub-column ptend for use in gridded update - will not contain ptend_aero call subcol_ptend_avg(ptend_sc, state_sc%ngrdcol, lchnk, ptend) From 67a2068c78262f34d423b2470db6b9e0205f6fe4 Mon Sep 17 00:00:00 2001 From: mvdebolskiy <80036033+mvdebolskiy@users.noreply.github.com> Date: Wed, 29 Apr 2026 17:05:28 +0200 Subject: [PATCH 09/12] fix mg version exception Co-authored-by: goldy <1588651+gold2718@users.noreply.github.com> --- src/NorESM/module_random_forests.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NorESM/module_random_forests.F90 b/src/NorESM/module_random_forests.F90 index bef63803b4..03ef3625f2 100644 --- a/src/NorESM/module_random_forests.F90 +++ b/src/NorESM/module_random_forests.F90 @@ -209,7 +209,7 @@ subroutine wbf_readnl(nlfile, mg_ver) close(unitn) end if else - call endrun(subname//':: ERROR rafwbf_on = .true. is incompatible with micro_mg_version=2') + call endrun(subname//':: ERROR rafwbf_on = .true. is incompatible with micro_mg_version=1') endif call MPI_Bcast(rafwbf_on, 1, mpi_logical, mstrid, mpicom, ierr) From a82ecc149e565a15cc3814b06cba270aee579d29 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Wed, 29 Apr 2026 20:20:59 +0200 Subject: [PATCH 10/12] fix missed arg --- src/physics/cam/physpkg.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/physics/cam/physpkg.F90 b/src/physics/cam/physpkg.F90 index 490e91eac9..0308f15865 100644 --- a/src/physics/cam/physpkg.F90 +++ b/src/physics/cam/physpkg.F90 @@ -2161,7 +2161,7 @@ subroutine tphysbc (ztodt, state, & call physics_tend_dealloc(tend_sc) call physics_ptend_dealloc(ptend_sc) else - call microp_driver_tend(state, ptend, cld_macmic_ztodt, cam_in, pbuf) + call microp_driver_tend(state, ptend, cld_macmic_ztodt, cam_in%ts, pbuf) end if ! combine aero and micro tendencies for the grid call physics_ptend_sum(ptend_aero, ptend, ncol) From 18d4edf907c54bb187bc6100dbdb8e24dc2ba4f9 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Thu, 30 Apr 2026 14:57:09 +0200 Subject: [PATCH 11/12] swtich input to grid content and not just cloud --- src/NorESM/micro_mg2_0.F90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/NorESM/micro_mg2_0.F90 b/src/NorESM/micro_mg2_0.F90 index 9d0fe5447d..e8106e70c9 100644 --- a/src/NorESM/micro_mg2_0.F90 +++ b/src/NorESM/micro_mg2_0.F90 @@ -1758,8 +1758,10 @@ subroutine micro_mg_tend ( & if (t(i,k) >= tupb .and. t(i,k) <= tlob) then ! make inputs: Pb = p(i,k) ! Pa - LWCb = qcic(i,k) + qric(i,k) !kg/kg - IWCb = qiic(i,k) + qsic(i,k) !kg/kg + ! input contents are used to be consistent + ! with WRF data used to constract RF + LWCb = qcn(i,k) + qrn(i,k) !kg/kg + IWCb = qin(i,k) + qsn(i,k) !kg/kg Tb = t(i,k) - 273.15_r8 ! DegC PBLHb = pblh(i) !m TSKb = tsk(i) - 273.15 ! DegC From b4a8ee431a0271363099ecdfb46c12996ee6ef69 Mon Sep 17 00:00:00 2001 From: mvdebolskiy Date: Sun, 3 May 2026 13:43:56 +0200 Subject: [PATCH 12/12] fix tyypi in condition --- src/NorESM/micro_mg2_0.F90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NorESM/micro_mg2_0.F90 b/src/NorESM/micro_mg2_0.F90 index e8106e70c9..225c65b5de 100644 --- a/src/NorESM/micro_mg2_0.F90 +++ b/src/NorESM/micro_mg2_0.F90 @@ -1755,7 +1755,7 @@ subroutine micro_mg_tend ( & ! RaFWBF parameterisattion: if (rafwbf_on) then do i = 1,mgncol - if (t(i,k) >= tupb .and. t(i,k) <= tlob) then + if (t(i,k) >= tlob .and. t(i,k) <= tupb) then ! make inputs: Pb = p(i,k) ! Pa ! input contents are used to be consistent