From 51e570cc9316911038c8a8f32c9d591ad317ee51 Mon Sep 17 00:00:00 2001
From: "Samuel Trahan (NOAA contractor)"
<39415369+SamuelTrahanNOAA@users.noreply.github.com>
Date: Tue, 29 Aug 2023 10:47:34 -0400
Subject: [PATCH 1/6] Bug fixes for 32-bit physics & correct the lake scheme in
FV3_HRRR_c3 & FV3_HRRR_gf (#692)
* fix fortran coding error in dynamical core
* use clm lake in fv3_hrrr_c3
* initialize arrays after allocation
* ressurect FV3_HRRR_gf suite and give it the clm lake model
* bug fix from Dusan to use the correct type kind when reading lan & lon in quilt server
---
ccpp/suites/suite_FV3_HRRR_c3.xml | 2 +-
.../suite_FV3_HRRR_gf.xml | 2 +-
io/fv3atm_clm_lake_io.F90 | 60 ++++++++++++++++++-
io/fv3atm_restart_io.F90 | 3 +
io/module_wrt_grid_comp.F90 | 49 ++++++++++++---
5 files changed, 104 insertions(+), 12 deletions(-)
rename ccpp/{suites_not_used => suites}/suite_FV3_HRRR_gf.xml (98%)
diff --git a/ccpp/suites/suite_FV3_HRRR_c3.xml b/ccpp/suites/suite_FV3_HRRR_c3.xml
index ec55ee1ec..fe4feedc7 100644
--- a/ccpp/suites/suite_FV3_HRRR_c3.xml
+++ b/ccpp/suites/suite_FV3_HRRR_c3.xml
@@ -43,7 +43,7 @@
mynnsfc_wrapper
GFS_surface_loop_control_part1
lsm_ruc
- flake_driver
+ clm_lake
GFS_surface_loop_control_part2
diff --git a/ccpp/suites_not_used/suite_FV3_HRRR_gf.xml b/ccpp/suites/suite_FV3_HRRR_gf.xml
similarity index 98%
rename from ccpp/suites_not_used/suite_FV3_HRRR_gf.xml
rename to ccpp/suites/suite_FV3_HRRR_gf.xml
index f8aade231..7e594e621 100644
--- a/ccpp/suites_not_used/suite_FV3_HRRR_gf.xml
+++ b/ccpp/suites/suite_FV3_HRRR_gf.xml
@@ -43,7 +43,7 @@
mynnsfc_wrapper
GFS_surface_loop_control_part1
lsm_ruc
- flake_driver
+ clm_lake
GFS_surface_loop_control_part2
diff --git a/io/fv3atm_clm_lake_io.F90 b/io/fv3atm_clm_lake_io.F90
index 5c61a26be..80c7bb586 100644
--- a/io/fv3atm_clm_lake_io.F90
+++ b/io/fv3atm_clm_lake_io.F90
@@ -22,7 +22,7 @@ module fv3atm_clm_lake_io
public :: clm_lake_data_type, clm_lake_register_axes, clm_lake_allocate_data, &
clm_lake_register_fields, clm_lake_deallocate_data, clm_lake_write_axes, &
clm_lake_copy_from_grid, clm_lake_copy_to_grid, clm_lake_bundle_fields, &
- clm_lake_final
+ clm_lake_final, clm_lake_fill_data
!>\defgroup CLM Lake Model restart public interface
!> @{
@@ -73,6 +73,9 @@ module fv3atm_clm_lake_io
! each axis, containing the appropriate information
procedure, public :: write_axes => clm_lake_write_axes
+ ! fills internal arrays with zero:
+ procedure, public :: fill_data => clm_lake_fill_data
+
! copy_from_grid copies from Sfcprop to internal pointers (declared above)
procedure, public :: copy_from_grid => clm_lake_copy_from_grid
@@ -194,6 +197,61 @@ subroutine clm_lake_write_axes(clm_lake, Model, Sfc_restart)
call write_data(Sfc_restart, 'levsnowsoil1_clm_lake', clm_lake%levsnowsoil1_clm_lake)
end subroutine clm_lake_write_axes
+ !>@ This is clm_lake%fill_data. It fills internal arrays with zero
+ !! Terrible things will happen if you don't call
+ !! clm_lake%allocate_data first.
+ subroutine clm_lake_fill_data(clm_lake, Model, Atm_block, Sfcprop)
+ implicit none
+ class(clm_lake_data_type) :: clm_lake
+ type(GFS_sfcprop_type), intent(in) :: Sfcprop(:)
+ type(GFS_control_type), intent(in) :: Model
+ type(block_control_type), intent(in) :: Atm_block
+
+ real(kind_phys), parameter :: zero = 0
+ integer :: nb, ix, isc, jsc, i, j
+ isc = Model%isc
+ jsc = Model%jsc
+
+ ! Copy data to temporary arrays
+
+ !$omp parallel do default(shared) private(i, j, nb, ix)
+ do nb = 1, Atm_block%nblks
+ do ix = 1, Atm_block%blksz(nb)
+ i = Atm_block%index(nb)%ii(ix) - isc + 1
+ j = Atm_block%index(nb)%jj(ix) - jsc + 1
+
+ clm_lake%T_snow(i,j) = zero
+ clm_lake%T_ice(i,j) = zero
+ clm_lake%lake_snl2d(i,j) = zero
+ clm_lake%lake_h2osno2d(i,j) = zero
+ clm_lake%lake_tsfc(i,j) = zero
+ clm_lake%lake_savedtke12d(i,j) = zero
+ clm_lake%lake_sndpth2d(i,j) = zero
+ clm_lake%clm_lakedepth(i,j) = zero
+ clm_lake%clm_lake_initialized(i,j) = zero
+
+ clm_lake%lake_z3d(i,j,:) = zero
+ clm_lake%lake_dz3d(i,j,:) = zero
+ clm_lake%lake_soil_watsat3d(i,j,:) = zero
+ clm_lake%lake_csol3d(i,j,:) = zero
+ clm_lake%lake_soil_tkmg3d(i,j,:) = zero
+ clm_lake%lake_soil_tkdry3d(i,j,:) = zero
+ clm_lake%lake_soil_tksatu3d(i,j,:) = zero
+ clm_lake%lake_snow_z3d(i,j,:) = zero
+ clm_lake%lake_snow_dz3d(i,j,:) = zero
+ clm_lake%lake_snow_zi3d(i,j,:) = zero
+ clm_lake%lake_h2osoi_vol3d(i,j,:) = zero
+ clm_lake%lake_h2osoi_liq3d(i,j,:) = zero
+ clm_lake%lake_h2osoi_ice3d(i,j,:) = zero
+ clm_lake%lake_t_soisno3d(i,j,:) = zero
+ clm_lake%lake_t_lake3d(i,j,:) = zero
+ clm_lake%lake_icefrac3d(i,j,:) = zero
+ clm_lake%lake_clay3d(i,j,:) = zero
+ clm_lake%lake_sand3d(i,j,:) = zero
+ enddo
+ enddo
+ end subroutine clm_lake_fill_data
+
!>@ This is clm_lake%copy_from_grid. It copies from Sfcprop
!! variables to the corresponding data temporary variables.
!! Terrible things will happen if you don't call
diff --git a/io/fv3atm_restart_io.F90 b/io/fv3atm_restart_io.F90
index ccdc6d719..487722601 100644
--- a/io/fv3atm_restart_io.F90
+++ b/io/fv3atm_restart_io.F90
@@ -651,6 +651,7 @@ subroutine sfc_prop_restart_read (Sfcprop, Atm_block, Model, fv_domain, warm_sta
! Tell CLM Lake to allocate data, and register its axes and fields
if(Model%lkm>0 .and. Model%iopt_lake==Model%iopt_lake_clm) then
call clm_lake%allocate_data(Model)
+ call clm_lake%fill_data(Model,Atm_block,Sfcprop)
call clm_lake%copy_from_grid(Model,Atm_block,Sfcprop)
call clm_lake%register_axes(Model, Sfc_restart)
call clm_lake%register_fields(Sfc_restart)
@@ -985,10 +986,12 @@ subroutine fv3atm_restart_register (Sfcprop, GFS_restart, Atm_block, Model)
if(Model%iopt_lake == 2 .and. Model%lkm > 0) then
call clm_lake_quilt%allocate_data(Model)
+ call clm_lake_quilt%fill_data(Model, Atm_block, Sfcprop)
endif
if(Model%rrfs_sd) then
call rrfs_sd_quilt%allocate_data(Model)
+ call rrfs_sd_quilt%fill_data(Model, Atm_block, Sfcprop)
endif
end subroutine fv3atm_restart_register
diff --git a/io/module_wrt_grid_comp.F90 b/io/module_wrt_grid_comp.F90
index 97dcf2d1b..c8fc139e2 100644
--- a/io/module_wrt_grid_comp.F90
+++ b/io/module_wrt_grid_comp.F90
@@ -2040,13 +2040,10 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
endif
-!recover fields from cartesian vector and sfc pressure
+ !recover fields from cartesian vector and sfc pressure
call recover_fields(file_bundle,rc)
- ! FIXME rrfs_smoke_conus13km_fast_phy32_qr crashes with teh following error in recover_fields
- ! 20230720 121647.816 ERROR PET147 ESMF_Grid.F90:20442 ESMF_GridGetCoord2DR8 Arguments are incompatible - - farrayPtr typekind does not match Grid typekind
- ! 20230720 121647.816 ERROR PET147 module_wrt_grid_comp.F90:2450 Arguments are incompatible - Passing error in return code
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
- ! if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
enddo
!
!-----------------------------------------------------------------------
@@ -2485,6 +2482,7 @@ subroutine recover_fields(file_bundle,rc)
type(ESMF_TypeKind_Flag) typekind
character(100) fieldName,uwindname,vwindname
type(ESMF_Field), allocatable :: fcstField(:)
+ real(ESMF_KIND_R4), dimension(:,:), pointer :: lonr4, latr4
real(ESMF_KIND_R8), dimension(:,:), pointer :: lon, lat
real(ESMF_KIND_R8), dimension(:,:), pointer :: lonloc, latloc
real(ESMF_KIND_R4), dimension(:,:), pointer :: pressfc
@@ -2493,6 +2491,8 @@ subroutine recover_fields(file_bundle,rc)
real(ESMF_KIND_R4), dimension(:,:,:), pointer :: cart3dPtr2dr4
real(ESMF_KIND_R4), dimension(:,:,:,:), pointer :: cart3dPtr3dr4
real(ESMF_KIND_R8) :: coslon, sinlon, sinlat
+
+ type(ESMF_Array) :: lon_array, lat_array
!
! get filed count
call ESMF_FieldBundleGet(file_bundle, fieldCount=fieldCount, rc=rc)
@@ -2510,10 +2510,26 @@ subroutine recover_fields(file_bundle,rc)
call ESMF_LogWrite("call recover field get coord 1",ESMF_LOGMSG_INFO,rc=RC)
- call ESMF_GridGetCoord(fieldgrid, coordDim=1, farrayPtr=lon, rc=rc)
-
+ call ESMF_GridGetCoord(fieldgrid, coordDim=1, array=lon_array, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_ArrayGet(lon_array, typekind=typekind, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ if (typekind == ESMF_TYPEKIND_R4) then
+ call ESMF_GridGetCoord(fieldgrid, coordDim=1, farrayPtr=lonr4, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ allocate(lon(lbound(lonr4,1):ubound(lonr4,1),lbound(lonr4,2):ubound(lonr4,2)))
+ lon = lonr4
+ else if (typekind == ESMF_TYPEKIND_R8) then
+ call ESMF_GridGetCoord(fieldgrid, coordDim=1, farrayPtr=lon, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ else
+ write(0,*)'lon_array unknown typekind'
+ rc = 1
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ endif
+
+
allocate(lonloc(lbound(lon,1):ubound(lon,1),lbound(lon,2):ubound(lon,2)))
istart = lbound(lon,1)
iend = ubound(lon,1)
@@ -2529,9 +2545,24 @@ subroutine recover_fields(file_bundle,rc)
call ESMF_LogWrite("call recover field get coord 2",ESMF_LOGMSG_INFO,rc=RC)
- call ESMF_GridGetCoord(fieldgrid, coordDim=2, farrayPtr=lat, rc=rc)
-
+ call ESMF_GridGetCoord(fieldgrid, coordDim=2, array=lat_array, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ call ESMF_ArrayGet(lat_array, typekind=typekind, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+
+ if (typekind == ESMF_TYPEKIND_R4) then
+ call ESMF_GridGetCoord(fieldgrid, coordDim=2, farrayPtr=latr4, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ allocate(lat(lbound(latr4,1):ubound(latr4,1),lbound(latr4,2):ubound(latr4,2)))
+ lat = latr4
+ else if (typekind == ESMF_TYPEKIND_R8) then
+ call ESMF_GridGetCoord(fieldgrid, coordDim=2, farrayPtr=lat, rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ else
+ write(0,*)'lon_array unknown typekind'
+ rc = 1
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ endif
allocate(latloc(lbound(lat,1):ubound(lat,1),lbound(lat,2):ubound(lat,2)))
istart = lbound(lat,1)
From d9525db44bc4fbc97cfd976970fa71bd721aa4f9 Mon Sep 17 00:00:00 2001
From: Dusan Jovic <48258889+DusanJovic-NOAA@users.noreply.github.com>
Date: Thu, 31 Aug 2023 15:43:09 -0400
Subject: [PATCH 2/6] Use optional chunksizes argument in
register_restart_field calls (#595)
* Change the format of domain restart files to netcdf4 and set chunksizes
* Remove nc_format="netcdf4" argument when opening restart files
* Set chunksize of zaxis and time axis to 1
* Update clm_lake and rrfs_sd modules to support chunksizes
* Make quilting restart files identical to fms files
---
atmos_cubed_sphere | 2 +-
io/fv3atm_clm_lake_io.F90 | 64 +++++++++++++++++-------------
io/fv3atm_restart_io.F90 | 9 +++--
io/fv3atm_rrfs_sd_io.F90 | 23 +++++++----
io/fv3atm_sfc_io.F90 | 42 ++++++++++++++------
io/module_write_restart_netcdf.F90 | 7 +++-
6 files changed, 94 insertions(+), 53 deletions(-)
diff --git a/atmos_cubed_sphere b/atmos_cubed_sphere
index 49f15ecbb..52bf918c1 160000
--- a/atmos_cubed_sphere
+++ b/atmos_cubed_sphere
@@ -1 +1 @@
-Subproject commit 49f15ecbbc16405025fae8d672dced19c2073d9e
+Subproject commit 52bf918c194b7d906776447c6324bc75558133db
diff --git a/io/fv3atm_clm_lake_io.F90 b/io/fv3atm_clm_lake_io.F90
index 80c7bb586..c930e1df9 100644
--- a/io/fv3atm_clm_lake_io.F90
+++ b/io/fv3atm_clm_lake_io.F90
@@ -12,7 +12,7 @@ module fv3atm_clm_lake_io
use block_control_mod, only: block_control_type
use fms2_io_mod, only: FmsNetcdfDomainFile_t, register_axis, &
register_restart_field, write_data, &
- register_variable_attribute, register_field
+ register_variable_attribute, register_field, get_dimension_size
use fv3atm_common_io, only: create_2d_field_and_add_to_bundle, &
create_3d_field_and_add_to_bundle
@@ -370,81 +370,89 @@ subroutine clm_lake_register_fields(clm_lake, Sfc_restart)
class(clm_lake_data_type) :: clm_lake
type(FmsNetcdfDomainFile_t) :: Sfc_restart
+ integer :: xaxis_1_chunk, yaxis_1_chunk
+ integer :: chunksizes2d(3), chunksizes3d(4)
+
+ call get_dimension_size(Sfc_restart, 'xaxis_1', xaxis_1_chunk)
+ call get_dimension_size(Sfc_restart, 'yaxis_1', yaxis_1_chunk)
+ chunksizes2d = (/xaxis_1_chunk, yaxis_1_chunk, 1/)
+ chunksizes3d = (/xaxis_1_chunk, yaxis_1_chunk, 1, 1/)
+
! Register 2D fields
call register_restart_field(Sfc_restart, 'T_snow', clm_lake%T_snow, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'T_ice', clm_lake%T_ice, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'lake_snl2d', clm_lake%lake_snl2d, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'lake_h2osno2d', clm_lake%lake_h2osno2d, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'lake_tsfc', clm_lake%lake_tsfc, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'lake_savedtke12d', clm_lake%lake_savedtke12d, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'lake_sndpth2d', clm_lake%lake_sndpth2d, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'clm_lakedepth', clm_lake%clm_lakedepth, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'clm_lake_initialized', clm_lake%clm_lake_initialized, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
! Register 3D fields
call register_restart_field(Sfc_restart, 'lake_z3d', clm_lake%lake_z3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'lake_dz3d', clm_lake%lake_dz3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_soil_watsat3d', clm_lake%lake_soil_watsat3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_csol3d', clm_lake%lake_csol3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_soil_tkmg3d', clm_lake%lake_soil_tkmg3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_soil_tkdry3d', clm_lake%lake_soil_tkdry3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_soil_tksatu3d', clm_lake%lake_soil_tksatu3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_snow_z3d', clm_lake%lake_snow_z3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ 'levsnowsoil1_clm_lake', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_snow_dz3d', clm_lake%lake_snow_dz3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ 'levsnowsoil1_clm_lake', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_snow_zi3d', clm_lake%lake_snow_zi3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsnowsoil_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levsnowsoil_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_h2osoi_vol3d', clm_lake%lake_h2osoi_vol3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ 'levsnowsoil1_clm_lake', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_h2osoi_liq3d', clm_lake%lake_h2osoi_liq3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ 'levsnowsoil1_clm_lake', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_h2osoi_ice3d', clm_lake%lake_h2osoi_ice3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ 'levsnowsoil1_clm_lake', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_t_soisno3d', clm_lake%lake_t_soisno3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsnowsoil1_clm_lake', 'Time '/), is_optional=.true.)
+ 'levsnowsoil1_clm_lake', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_t_lake3d', clm_lake%lake_t_lake3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_icefrac3d', clm_lake%lake_icefrac3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levlake_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levlake_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_clay3d', clm_lake%lake_clay3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsoil_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levsoil_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
call register_restart_field(Sfc_restart,'lake_sand3d', clm_lake%lake_sand3d, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
- 'levsoil_clm_lake ', 'Time '/), is_optional=.true.)
+ 'levsoil_clm_lake ', 'Time '/), chunksizes=chunksizes3d, is_optional=.true.)
end subroutine clm_lake_register_fields
!>@ This is clm_lake%bundle_fields, and it is only used in the
diff --git a/io/fv3atm_restart_io.F90 b/io/fv3atm_restart_io.F90
index 487722601..1edb985a8 100644
--- a/io/fv3atm_restart_io.F90
+++ b/io/fv3atm_restart_io.F90
@@ -14,7 +14,7 @@ module fv3atm_restart_io_mod
register_axis, register_restart_field, &
register_variable_attribute, register_field, &
read_restart, write_restart, write_data, &
- get_global_io_domain_indices
+ get_global_io_domain_indices, get_dimension_size
use mpp_domains_mod, only: domain2d
use fv3atm_common_io, only: create_2d_field_and_add_to_bundle, &
create_3d_field_and_add_to_bundle, copy_from_gfs_data
@@ -891,6 +891,7 @@ subroutine phys_restart_write (GFS_Restart, Atm_block, Model, fv_domain, timesta
character(7) :: indir='RESTART'
character(72) :: infile
logical :: amiopen, allocated_something
+ integer :: xaxis_1_chunk, yaxis_1_chunk
type(phy_data_type) :: phy
type(FmsNetcdfDomainFile_t) :: Phy_restart
@@ -917,6 +918,7 @@ subroutine phys_restart_write (GFS_Restart, Atm_block, Model, fv_domain, timesta
call get_global_io_domain_indices(Phy_restart, 'xaxis_1', is, ie, indices=buffer)
call write_data(Phy_restart, "xaxis_1", buffer)
deallocate(buffer)
+ call get_dimension_size(Phy_restart, 'xaxis_1', xaxis_1_chunk)
call register_axis(Phy_restart, 'yaxis_1', 'Y')
call register_field(Phy_restart, 'yaxis_1', 'double', (/'yaxis_1'/))
@@ -924,6 +926,7 @@ subroutine phys_restart_write (GFS_Restart, Atm_block, Model, fv_domain, timesta
call get_global_io_domain_indices(Phy_restart, 'yaxis_1', is, ie, indices=buffer)
call write_data(Phy_restart, "yaxis_1", buffer)
deallocate(buffer)
+ call get_dimension_size(Phy_restart, 'yaxis_1', yaxis_1_chunk)
call register_axis(Phy_restart, 'zaxis_1', phy%npz)
call register_field(Phy_restart, 'zaxis_1', 'double', (/'zaxis_1'/))
@@ -946,12 +949,12 @@ subroutine phys_restart_write (GFS_Restart, Atm_block, Model, fv_domain, timesta
do num = 1,phy%nvar2d
var2_p => phy%var2(:,:,num)
call register_restart_field(Phy_restart, trim(GFS_Restart%name2d(num)), var2_p, dimensions=(/'xaxis_1','yaxis_1','Time '/),&
- &is_optional=.true.)
+ & chunksizes=(/xaxis_1_chunk,yaxis_1_chunk,1/), is_optional=.true.)
enddo
do num = 1,phy%nvar3d
var3_p => phy%var3(:,:,:,num)
call register_restart_field(Phy_restart, trim(GFS_Restart%name3d(num)), var3_p, dimensions=(/'xaxis_1','yaxis_1','zaxis_1','Time '/),&
- &is_optional=.true.)
+ & chunksizes=(/xaxis_1_chunk,yaxis_1_chunk,1,1/), is_optional=.true.)
enddo
nullify(var2_p)
nullify(var3_p)
diff --git a/io/fv3atm_rrfs_sd_io.F90 b/io/fv3atm_rrfs_sd_io.F90
index c6dc44e34..16410c8be 100644
--- a/io/fv3atm_rrfs_sd_io.F90
+++ b/io/fv3atm_rrfs_sd_io.F90
@@ -6,7 +6,8 @@ module fv3atm_rrfs_sd_io
use block_control_mod, only: block_control_type
use fms2_io_mod, only: FmsNetcdfDomainFile_t, write_data, &
register_axis, register_restart_field, &
- register_variable_attribute, register_field
+ register_variable_attribute, register_field, &
+ get_dimension_size
use GFS_typedefs, only: GFS_sfcprop_type, GFS_control_type, kind_phys
use fv3atm_common_io, only: get_nx_ny_from_atm, create_2d_field_and_add_to_bundle, &
create_3d_field_and_add_to_bundle
@@ -193,23 +194,31 @@ subroutine rrfs_sd_state_register_fields(data,Sfc_restart)
class(rrfs_sd_state_type) :: data
type(FmsNetcdfDomainFile_t) :: Sfc_restart
+ integer :: xaxis_1_chunk, yaxis_1_chunk
+ integer :: chunksizes2d(3), chunksizes3d(4)
+
+ call get_dimension_size(Sfc_restart, 'xaxis_1', xaxis_1_chunk)
+ call get_dimension_size(Sfc_restart, 'yaxis_1', yaxis_1_chunk)
+ chunksizes2d = (/xaxis_1_chunk, yaxis_1_chunk, 1/)
+ chunksizes3d = (/xaxis_1_chunk, yaxis_1_chunk, 1, 1/)
+
! Register 2D fields
call register_restart_field(Sfc_restart, 'emdust', data%emdust, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'emseas', data%emseas, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'emanoc', data%emanoc, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'fhist', data%fhist, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
call register_restart_field(Sfc_restart, 'coef_bb_dc', data%coef_bb_dc, &
- dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), is_optional=.true.)
+ dimensions=(/'xaxis_1', 'yaxis_1', 'Time '/), chunksizes=chunksizes2d, is_optional=.true.)
! Register 3D field
call register_restart_field(Sfc_restart, 'fire_in', data%fire_in, &
dimensions=(/'xaxis_1 ', 'yaxis_1 ', &
'fire_aux_data_levels', 'Time '/), &
- is_optional=.true.)
+ chunksizes=chunksizes3d, is_optional=.true.)
end subroutine rrfs_sd_state_register_fields
! --------------------------------------------------------------------
diff --git a/io/fv3atm_sfc_io.F90 b/io/fv3atm_sfc_io.F90
index 6cd007761..90942e211 100644
--- a/io/fv3atm_sfc_io.F90
+++ b/io/fv3atm_sfc_io.F90
@@ -9,7 +9,8 @@ module fv3atm_sfc_io
use fms2_io_mod, only: FmsNetcdfDomainFile_t, unlimited, write_data,&
register_axis, register_restart_field, &
register_variable_attribute, register_field, &
- get_global_io_domain_indices, variable_exists
+ get_global_io_domain_indices, variable_exists, &
+ get_dimension_size
use fv3atm_common_io, only: GFS_Data_transfer, &
create_2d_field_and_add_to_bundle, create_3d_field_and_add_to_bundle
use GFS_typedefs, only: GFS_sfcprop_type, GFS_control_type, kind_phys
@@ -575,8 +576,15 @@ subroutine Sfc_io_register_2d_fields(sfc,Model,Sfc_restart,reading,warm_start)
character(len=7) :: time2d(3)
+ integer :: xaxis_1_chunk, yaxis_1_chunk
+ integer :: chunksizes2d(3)
+
+ call get_dimension_size(Sfc_restart, 'xaxis_1', xaxis_1_chunk)
+ call get_dimension_size(Sfc_restart, 'yaxis_1', yaxis_1_chunk)
+
if(.not.reading) then
time2d=(/'xaxis_1','yaxis_1','Time '/)
+ chunksizes2d=(/xaxis_1_chunk, yaxis_1_chunk, 1/)
else
time2d=(/'Time ','yaxis_1','xaxis_1'/)
endif
@@ -599,13 +607,13 @@ subroutine Sfc_io_register_2d_fields(sfc,Model,Sfc_restart,reading,warm_start)
call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=(/'lat','lon'/), is_optional=.true.)
else
call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=time2d,&
- &is_optional=.true.)
+ & chunksizes=chunksizes2d, is_optional=.true.)
end if
else
if(reading .and. sfc%is_lsoil) then
call register_restart_field(Sfc_restart,sfc%name2(num),var2_p, dimensions=(/'lat','lon'/))
else
- call register_restart_field(Sfc_restart,sfc%name2(num),var2_p, dimensions=time2d)
+ call register_restart_field(Sfc_restart,sfc%name2(num),var2_p, dimensions=time2d, chunksizes=chunksizes2d)
end if
endif
enddo
@@ -618,7 +626,7 @@ subroutine Sfc_io_register_2d_fields(sfc,Model,Sfc_restart,reading,warm_start)
if(sfc%is_lsoil) then
call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=(/'lat','lon'/), is_optional=.not.mand)
else
- call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=time2d, is_optional=.not.mand)
+ call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=time2d, chunksizes=chunksizes2d, is_optional=.not.mand)
endif
enddo
endif
@@ -629,7 +637,7 @@ subroutine Sfc_io_register_2d_fields(sfc,Model,Sfc_restart,reading,warm_start)
if(sfc%is_lsoil) then
call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=(/'lat','lon'/) )
else
- call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=time2d)
+ call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=time2d, chunksizes=chunksizes2d)
end if
enddo
endif ! mp/ruc
@@ -643,7 +651,7 @@ subroutine Sfc_io_register_2d_fields(sfc,Model,Sfc_restart,reading,warm_start)
if(sfc%is_lsoil) then
call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=(/'lat','lon'/), is_optional=.not.mand)
else
- call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=time2d, is_optional=.not.mand)
+ call register_restart_field(Sfc_restart, sfc%name2(num), var2_p, dimensions=time2d, chunksizes=chunksizes2d, is_optional=.not.mand)
end if
enddo
endif ! noahmp
@@ -656,7 +664,7 @@ subroutine Sfc_io_register_2d_fields(sfc,Model,Sfc_restart,reading,warm_start)
if(sfc%is_lsoil) then
call register_restart_field(Sfc_restart, sfc%name2(num),var2_p,dimensions=(/'lat','lon'/), is_optional=.not.mand)
else
- call register_restart_field(Sfc_restart, sfc%name2(num),var2_p,dimensions=time2d, is_optional=.not.mand)
+ call register_restart_field(Sfc_restart, sfc%name2(num),var2_p,dimensions=time2d, chunksizes=chunksizes2d, is_optional=.not.mand)
endif
enddo
endif
@@ -684,9 +692,17 @@ subroutine Sfc_io_register_3d_fields(sfc,Model,Sfc_restart,reading,warm_start)
character(len=7), parameter :: xyz3_time(4) = (/'xaxis_1', 'yaxis_1', 'zaxis_3', 'Time '/)
character(len=7), parameter :: xyz4_time(4) = (/'xaxis_1', 'yaxis_1', 'zaxis_4', 'Time '/)
+ integer :: xaxis_1_chunk, yaxis_1_chunk
+ integer :: chunksizes3d(4)
+
+ call get_dimension_size(Sfc_restart, 'xaxis_1', xaxis_1_chunk)
+ call get_dimension_size(Sfc_restart, 'yaxis_1', yaxis_1_chunk)
+
+ chunksizes3d = (/xaxis_1_chunk, yaxis_1_chunk, 1, 1/)
+
!--- register the 3D fields
var3_p => sfc%var3ice(:,:,:)
- call register_restart_field(Sfc_restart, sfc%name3(0), var3_p, dimensions=xyz1_time, is_optional=.true.)
+ call register_restart_field(Sfc_restart, sfc%name3(0), var3_p, dimensions=xyz1_time, chunksizes=chunksizes3d, is_optional=.true.)
if(reading) then
do num = 1,sfc%nvar3
@@ -706,13 +722,13 @@ subroutine Sfc_io_register_3d_fields(sfc,Model,Sfc_restart,reading,warm_start)
elseif(Model%lsm == Model%lsm_ruc) then
do num = 1,sfc%nvar3
var3_p => sfc%var3(:,:,:,num)
- call register_restart_field(Sfc_restart, sfc%name3(num), var3_p, dimensions=xyz1_time)
+ call register_restart_field(Sfc_restart, sfc%name3(num), var3_p, dimensions=xyz1_time, chunksizes=chunksizes3d)
enddo
nullify(var3_p)
else ! writing something other than ruc
do num = 1,sfc%nvar3
var3_p => sfc%var3(:,:,:,num)
- call register_restart_field(Sfc_restart, sfc%name3(num), var3_p, dimensions=xyz2_time)
+ call register_restart_field(Sfc_restart, sfc%name3(num), var3_p, dimensions=xyz2_time, chunksizes=chunksizes3d)
enddo
nullify(var3_p)
endif
@@ -721,14 +737,14 @@ subroutine Sfc_io_register_3d_fields(sfc,Model,Sfc_restart,reading,warm_start)
mand = .not.reading
do num = sfc%nvar3+1,sfc%nvar3+3
var3_p1 => sfc%var3sn(:,:,:,num)
- call register_restart_field(Sfc_restart, sfc%name3(num), var3_p1, dimensions=xyz3_time, is_optional=.not.mand)
+ call register_restart_field(Sfc_restart, sfc%name3(num), var3_p1, dimensions=xyz3_time, chunksizes=chunksizes3d, is_optional=.not.mand)
enddo
var3_p2 => sfc%var3eq(:,:,:,7)
- call register_restart_field(Sfc_restart, sfc%name3(7), var3_p2, dimensions=xyz2_time, is_optional=.not.mand)
+ call register_restart_field(Sfc_restart, sfc%name3(7), var3_p2, dimensions=xyz2_time, chunksizes=chunksizes3d, is_optional=.not.mand)
var3_p3 => sfc%var3zn(:,:,:,8)
- call register_restart_field(Sfc_restart, sfc%name3(8), var3_p3, dimensions=xyz4_time, is_optional=.not.mand)
+ call register_restart_field(Sfc_restart, sfc%name3(8), var3_p3, dimensions=xyz4_time, chunksizes=chunksizes3d, is_optional=.not.mand)
endif !mp
end subroutine Sfc_io_register_3d_fields
diff --git a/io/module_write_restart_netcdf.F90 b/io/module_write_restart_netcdf.F90
index 259079bb2..53a1f719c 100644
--- a/io/module_write_restart_netcdf.F90
+++ b/io/module_write_restart_netcdf.F90
@@ -565,7 +565,12 @@ subroutine write_out_ungridded_dim_atts_from_field(field, dimLabel, dimid, rc)
ncerr = nf90_def_dim(ncid, trim(dimLabel), valueCount, dimid=dimid); NC_ERR_STOP(ncerr); NC_ERR_STOP(ncerr)
endif
if( typekind == ESMF_TYPEKIND_R4 ) then
- ncerr = nf90_def_var(ncid, trim(dimLabel), NF90_FLOAT, dimids=(/dimid/), varid=varid); NC_ERR_STOP(ncerr)
+ !!! FIXME Use NF90_DOUBLE as axis type, even though axis data are float
+ !!! This is needed to make phy/sfc restart files identical to FMS
+ !!! restart files which always defines all axis as double
+
+ ! ncerr = nf90_def_var(ncid, trim(dimLabel), NF90_FLOAT, dimids=(/dimid/), varid=varid); NC_ERR_STOP(ncerr)
+ ncerr = nf90_def_var(ncid, trim(dimLabel), NF90_DOUBLE, dimids=(/dimid/), varid=varid); NC_ERR_STOP(ncerr)
ncerr = nf90_put_att(ncid, varid, trim(axis_attr_name), "Z"); NC_ERR_STOP(ncerr)
ncerr = nf90_enddef(ncid=ncid); NC_ERR_STOP(ncerr)
ncerr = nf90_put_var(ncid, varid, values=valueListr4); NC_ERR_STOP(ncerr)
From 379ef21b1a117848fca255de4da048778e561c95 Mon Sep 17 00:00:00 2001
From: lisa-bengtsson <54411948+lisa-bengtsson@users.noreply.github.com>
Date: Tue, 5 Sep 2023 10:46:53 -0600
Subject: [PATCH 3/6] 2D advection of cellular automata (#686)
* 2D advection of cellular automata
---
atmos_model.F90 | 2 +-
ccpp/data/GFS_typedefs.F90 | 6 +++++-
ccpp/data/GFS_typedefs.meta | 6 ++++++
.../stochastic_physics_wrapper.F90 | 20 +++++++++++++++++--
4 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/atmos_model.F90 b/atmos_model.F90
index 2fa6788cd..e2e776030 100644
--- a/atmos_model.F90
+++ b/atmos_model.F90
@@ -748,7 +748,7 @@ subroutine atmos_model_init (Atmos, Time_init, Time, Time_step)
call fv3atm_restart_read (GFS_data, GFS_restart_var, Atm_block, GFS_control, Atmos%domain_for_read, &
Atm(mygrid)%flagstruct%warm_start, ignore_rst_cksum)
if(GFS_control%do_ca .and. Atm(mygrid)%flagstruct%warm_start)then
- call read_ca_restart (Atmos%domain,GFS_control%ncells,GFS_control%nca,GFS_control%ncells_g,GFS_control%nca_g)
+ call read_ca_restart (Atmos%domain,3,GFS_control%ncells,GFS_control%nca,GFS_control%ncells_g,GFS_control%nca_g)
endif
! Populate the GFS_data%Statein container with the prognostic state
! in Atm_block, which contains the initial conditions/restart data.
diff --git a/ccpp/data/GFS_typedefs.F90 b/ccpp/data/GFS_typedefs.F90
index 80826ba42..ec3893ba9 100644
--- a/ccpp/data/GFS_typedefs.F90
+++ b/ccpp/data/GFS_typedefs.F90
@@ -1328,6 +1328,7 @@ module GFS_typedefs
integer :: nseed !< cellular automata seed frequency
integer :: nseed_g !< cellular automata seed frequency
logical :: do_ca !< cellular automata main switch
+ logical :: ca_advect !< Advection of cellular automata
logical :: ca_sgs !< switch for sgs ca
logical :: ca_global !< switch for global ca
logical :: ca_smooth !< switch for gaussian spatial filter
@@ -3765,6 +3766,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
integer :: iseed_ca = 1
integer :: nspinup = 1
logical :: do_ca = .false.
+ logical :: ca_advect = .false.
logical :: ca_sgs = .false.
logical :: ca_global = .false.
logical :: ca_smooth = .false.
@@ -3974,7 +3976,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
h0facu, h0facs, &
!--- cellular automata
nca, ncells, nlives, nca_g, ncells_g, nlives_g, nfracseed, &
- nseed, nseed_g, nthresh, do_ca, &
+ nseed, nseed_g, nthresh, do_ca, ca_advect, &
ca_sgs, ca_global,iseed_ca,ca_smooth, &
nspinup,ca_amplitude,nsmooth,ca_closure,ca_entr,ca_trigger, &
!--- IAU
@@ -4943,6 +4945,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
Model%nseed_g = nseed_g
Model%ca_global = ca_global
Model%do_ca = do_ca
+ Model%ca_advect = ca_advect
Model%ca_sgs = ca_sgs
Model%iseed_ca = iseed_ca
Model%ca_smooth = ca_smooth
@@ -6705,6 +6708,7 @@ subroutine control_print(Model)
print *, ' ca_global : ', Model%ca_global
print *, ' ca_sgs : ', Model%ca_sgs
print *, ' do_ca : ', Model%do_ca
+ print *, ' ca_advect : ', Model%ca_advect
print *, ' iseed_ca : ', Model%iseed_ca
print *, ' ca_smooth : ', Model%ca_smooth
print *, ' nspinup : ', Model%nspinup
diff --git a/ccpp/data/GFS_typedefs.meta b/ccpp/data/GFS_typedefs.meta
index 9b54e5c2c..635112ad4 100644
--- a/ccpp/data/GFS_typedefs.meta
+++ b/ccpp/data/GFS_typedefs.meta
@@ -5698,6 +5698,12 @@
units = flag
dimensions = ()
type = logical
+[ca_advect]
+ standard_name = flag_for_cellular_automata_advection
+ long_name = cellular automata main switch
+ units = flag
+ dimensions = ()
+ type = logical
[ca_sgs]
standard_name = flag_for_sgs_cellular_automata
long_name = switch for sgs ca
diff --git a/stochastic_physics/stochastic_physics_wrapper.F90 b/stochastic_physics/stochastic_physics_wrapper.F90
index 8096ddbb4..3bae38fe3 100644
--- a/stochastic_physics/stochastic_physics_wrapper.F90
+++ b/stochastic_physics/stochastic_physics_wrapper.F90
@@ -37,6 +37,10 @@ module stochastic_physics_wrapper_mod
real(kind=kind_phys), dimension(:,:), allocatable, save :: sst
real(kind=kind_phys), dimension(:,:), allocatable, save :: lmsk
real(kind=kind_phys), dimension(:,:), allocatable, save :: lake
+ real(kind=kind_phys), dimension(:,:,:), allocatable, save :: uwind
+ real(kind=kind_phys), dimension(:,:,:), allocatable, save :: vwind
+ real(kind=kind_phys), dimension(:,:,:), allocatable, save :: height
+ real(kind=kind_phys), dimension(:,:), allocatable, save :: dx
real(kind=kind_phys), dimension(:,:), allocatable, save :: condition
real(kind=kind_phys), dimension(:,:), allocatable, save :: ca_deep_cpl, ca_turb_cpl, ca_shal_cpl
real(kind=kind_phys), dimension(:,:), allocatable, save :: ca1_cpl, ca2_cpl, ca3_cpl
@@ -189,7 +193,11 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr)
allocate(sst (1:nblks, maxblk))
allocate(lmsk (1:nblks, maxblk))
allocate(lake (1:nblks, maxblk))
+ allocate(uwind (1:nblks, maxblk, 1:levs))
+ allocate(vwind (1:nblks, maxblk, 1:levs))
+ allocate(height (1:nblks, maxblk, 1:levs))
allocate(condition (1:nblks, maxblk))
+ allocate(dx (1:nblks, maxblk))
allocate(ca_deep_cpl (1:nblks, maxblk))
allocate(ca_turb_cpl (1:nblks, maxblk))
allocate(ca_shal_cpl (1:nblks, maxblk))
@@ -374,16 +382,20 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr)
sst (nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%tsfco(:)
lmsk (nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%slmsk(:)
lake (nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%lakefrac(:)
+ uwind (nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Statein%ugrs(:,:)
+ vwind (nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Statein%vgrs(:,:)
+ height (nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Statein%phil(:,:)
+ dx (nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Grid%dx(:)
condition (nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Coupling%condition(:)
ca_deep_cpl(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Coupling%ca_deep(:)
ca_turb_cpl(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Coupling%ca_turb(:)
ca_shal_cpl(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Coupling%ca_shal(:)
enddo
call cellular_automata_sgs(GFS_Control%kdt,GFS_control%dtp,GFS_control%restart,GFS_Control%first_time_step, &
- sst,lmsk,lake,condition,ca_deep_cpl,ca_turb_cpl,ca_shal_cpl, Atm(mygrid)%domain_for_coupler,nblks, &
+ sst,lmsk,lake,uwind,vwind,height,dx,condition,ca_deep_cpl,ca_turb_cpl,ca_shal_cpl, Atm(mygrid)%domain_for_coupler,nblks, &
Atm_block%isc,Atm_block%iec,Atm_block%jsc,Atm_block%jec,Atm(mygrid)%npx,Atm(mygrid)%npy, levs, &
GFS_Control%nthresh,GFS_Control%tile_num,GFS_Control%nca,GFS_Control%ncells,GFS_Control%nlives, &
- GFS_Control%nfracseed, GFS_Control%nseed,GFS_Control%iseed_ca, &
+ GFS_Control%nfracseed, GFS_Control%nseed,GFS_Control%iseed_ca,GFS_Control%ca_advect, &
GFS_Control%nspinup,GFS_Control%ca_trigger,Atm_block%blksz(1),GFS_Control%master,GFS_Control%communicator)
! Copy contiguous data back as needed
do nb=1,nblks
@@ -461,6 +473,10 @@ subroutine stochastic_physics_wrapper_end (GFS_Control)
deallocate(sst )
deallocate(lmsk )
deallocate(lake )
+ deallocate(uwind )
+ deallocate(vwind )
+ deallocate(height )
+ deallocate(dx )
deallocate(condition )
deallocate(ca_deep_cpl )
deallocate(ca_turb_cpl )
From a9fa26e3c03b2ae4d9294225c043ffd962028e72 Mon Sep 17 00:00:00 2001
From: Jun Wang <37633869+junwang-noaa@users.noreply.github.com>
Date: Thu, 7 Sep 2023 16:00:46 -0400
Subject: [PATCH 4/6] Add run time info and upp (#678)
* update missing value
* adding timing information
* add write_runtimelog option
* update upp and not include dycore updates that change results
---
fv3_cap.F90 | 41 +++++++++++++++++++++++++++++++++----
io/module_wrt_grid_comp.F90 | 10 ++++++---
io/post_fv3.F90 | 28 +++++++++++++++++--------
upp | 2 +-
4 files changed, 64 insertions(+), 17 deletions(-)
diff --git a/fv3_cap.F90 b/fv3_cap.F90
index 1bca9b004..fa8a549d6 100644
--- a/fv3_cap.F90
+++ b/fv3_cap.F90
@@ -70,11 +70,14 @@ module fv3atm_cap_mod
logical, allocatable :: is_moving_FB(:)
logical :: profile_memory = .true.
+ logical :: write_runtimelog = .false.
+ logical :: lprint = .false.
integer :: mype = -1
integer :: dbug = 0
integer :: frestart(999) = -1
+ real(kind=8) :: timere, timep2re
!-----------------------------------------------------------------------
contains
@@ -246,6 +249,11 @@ subroutine InitializeAdvertise(gcomp, rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
profile_memory = (trim(value)/="false")
+ call ESMF_AttributeGet(gcomp, name="RunTimeLog", value=value, defaultValue="false", &
+ convention="NUOPC", purpose="Instance", rc=rc)
+ if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
+ write_runtimelog = (trim(value)=="true")
+
call ESMF_AttributeGet(gcomp, name="DumpFields", value=value, defaultValue="false", &
convention="NUOPC", purpose="Instance", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
@@ -347,6 +355,7 @@ subroutine InitializeAdvertise(gcomp, rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
first_kdt = 1
+ if( mype == 0) lprint = .true.
!
!#######################################################################
! set up fcst grid component
@@ -486,6 +495,7 @@ subroutine InitializeAdvertise(gcomp, rc)
enddo
k = k + wrttasks_per_group_from_parent
last_wrttask(i) = k - 1
+ if( mype == lead_wrttask(i) ) lprint = .true.
! if(mype==0)print *,'af wrtComp(i)=',i,'k=',k
! prepare name of the wrtComp(i)
@@ -971,8 +981,7 @@ subroutine InitializeAdvertise(gcomp, rc)
if (ESMF_LogFoundError(rcToCheck=urc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__, rcToReturn=rc)) return
- if(mype==0) print *,'in fv3_cap, aft import, export fields in atmos'
- if(mype==0) print *,'in fv3_cap, init time=',MPI_Wtime()-timeis
+ if(write_runtimelog .and. lprint) print *,'in fv3_cap, init time=',MPI_Wtime()-timeis,mype
!-----------------------------------------------------------------------
!
end subroutine InitializeAdvertise
@@ -989,7 +998,10 @@ subroutine InitializeRealize(gcomp, rc)
type(ESMF_State) :: importState, exportState
integer :: urc
+ real(8) :: MPI_Wtime, timeirs
+
rc = ESMF_SUCCESS
+ timeirs = MPI_Wtime()
! query for importState and exportState
call NUOPC_ModelGet(gcomp, driverClock=clock, importState=importState, exportState=exportState, rc=rc)
@@ -1004,6 +1016,11 @@ subroutine InitializeRealize(gcomp, rc)
if (ESMF_LogFoundError(rcToCheck=urc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__, rcToReturn=rc)) return
+ timere = 0.
+ timep2re = 0.
+
+ if(write_runtimelog .and. lprint) print *,'in fv3_cap, initirealz time=',MPI_Wtime()-timeirs,mype
+
end subroutine InitializeRealize
!-----------------------------------------------------------------------------
@@ -1012,10 +1029,13 @@ subroutine ModelAdvance(gcomp, rc)
type(ESMF_GridComp) :: gcomp
integer, intent(out) :: rc
+ real(kind=8) :: MPI_Wtime, timers
!-----------------------------------------------------------------------------
rc = ESMF_SUCCESS
+ timers = MPI_Wtime()
+ if(write_runtimelog .and. timere>0. .and. lprint) print *,'in fv3_cap, time between fv3 run step=', timers-timere,mype
if (profile_memory) call ESMF_VMLogMemInfo("Entering FV3 ModelAdvance: ")
@@ -1027,6 +1047,9 @@ subroutine ModelAdvance(gcomp, rc)
if (profile_memory) call ESMF_VMLogMemInfo("Leaving FV3 ModelAdvance: ")
+ timere = MPI_Wtime()
+ if(write_runtimelog .and. lprint) print *,'in fv3_cap, time in fv3 run step=', timere-timers, mype
+
end subroutine ModelAdvance
!-----------------------------------------------------------------------------
@@ -1041,10 +1064,13 @@ subroutine ModelAdvance_phase1(gcomp, rc)
logical :: fcstpe
character(len=*),parameter :: subname='(fv3_cap:ModelAdvance_phase1)'
character(240) :: msgString
+ real(kind=8) :: MPI_Wtime, timep1rs, timep1re
!-----------------------------------------------------------------------------
rc = ESMF_SUCCESS
+ timep1rs = MPI_Wtime()
+ if(write_runtimelog .and. timep2re>0. .and. lprint) print *,'in fv3_cap, time between fv3 run phase2 and phase1 ', timep1rs-timep2re,mype
if(profile_memory) call ESMF_VMLogMemInfo("Entering FV3 ModelAdvance_phase1: ")
@@ -1074,6 +1100,8 @@ subroutine ModelAdvance_phase1(gcomp, rc)
call diagnose_cplFields(gcomp, clock, fcstpe, cplprint_flag, dbug, 'import')
endif
+ timep1re = MPI_Wtime()
+ if(write_runtimelog .and. lprint) print *,'in fv3_cap,modeladvance phase1 time ', timep1re-timep1rs,mype
if (profile_memory) call ESMF_VMLogMemInfo("Leaving FV3 ModelAdvance_phase1: ")
end subroutine ModelAdvance_phase1
@@ -1100,9 +1128,12 @@ subroutine ModelAdvance_phase2(gcomp, rc)
type(ESMF_Clock) :: clock, clock_out
integer :: fieldCount
+ real(kind=8) :: MPI_Wtime, timep2rs
+
!-----------------------------------------------------------------------------
rc = ESMF_SUCCESS
+ timep2rs = MPI_Wtime()
if(profile_memory) call ESMF_VMLogMemInfo("Entering FV3 ModelAdvance_phase2: ")
@@ -1206,6 +1237,8 @@ subroutine ModelAdvance_phase2(gcomp, rc)
call diagnose_cplFields(gcomp, clock_out, fcstpe, cplprint_flag, dbug, 'export')
end if
+ timep2re = MPI_Wtime()
+ if(write_runtimelog .and. lprint) print *,'in fv3_cap,modeladvance phase2 time ', timep2re-timep2rs, mype
if(profile_memory) call ESMF_VMLogMemInfo("Leaving FV3 ModelAdvance_phase2: ")
end subroutine ModelAdvance_phase2
@@ -1380,8 +1413,8 @@ subroutine ModelFinalize(gcomp, rc)
!-----------------------------------------------------------------------------
!*** finialize forecast
- timeffs = MPI_Wtime()
rc = ESMF_SUCCESS
+ timeffs = MPI_Wtime()
!
call ESMF_GridCompGet(gcomp,vm=vm,rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
@@ -1414,7 +1447,7 @@ subroutine ModelFinalize(gcomp, rc)
call ESMF_GridCompDestroy(fcstComp, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
!
- if(mype==0)print *,' wrt grid comp destroy time=',MPI_Wtime()-timeffs
+ if(write_runtimelog .and. lprint) print *,'in fv3_cap, finalize time=',MPI_Wtime()-timeffs, mype
end subroutine ModelFinalize
!
diff --git a/io/module_wrt_grid_comp.F90 b/io/module_wrt_grid_comp.F90
index c8fc139e2..162362466 100644
--- a/io/module_wrt_grid_comp.F90
+++ b/io/module_wrt_grid_comp.F90
@@ -2090,7 +2090,9 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
if (mype == lead_write_task) then
!** write out inline post log file
open(newunit=nolog,file='log.atm.inlinepost.f'//trim(cfhour),form='FORMATTED')
- write(nolog,"(' completed fv3atm fhour=',f10.3,2x,6(i4,2x))") nfhour, idate(1:6)
+ write(nolog,"('completed: fv3atm')")
+ write(nolog,"('forecast hour: ',f10.3)") nfhour
+ write(nolog,"('valid time: ',6(i4,2x))") wrt_int_state%fdate(1:6)
close(nolog)
endif
if (lprnt) then
@@ -2224,7 +2226,7 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
endif
call mpi_bcast(kchunk3d(grid_id),1,mpi_integer,0,wrt_mpi_comm,rc)
endif
- if (wrt_int_state%mype == 0) then
+ if (lprnt) then
print *,'ichunk2d,jchunk2d',ichunk2d(grid_id),jchunk2d(grid_id)
print *,'ichunk3d,jchunk3d,kchunk3d',ichunk3d(grid_id),jchunk3d(grid_id),kchunk3d(grid_id)
endif
@@ -2393,7 +2395,9 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
if (out_phase == 1 .and. mype == lead_write_task) then
!** write out log file
open(newunit=nolog,file='log.atm.f'//trim(cfhour),form='FORMATTED')
- write(nolog,"(' completed fv3atm fhour=',f10.3,2x,6(i4,2x))") nfhour, idate(1:6)
+ write(nolog,"('completed: fv3atm')")
+ write(nolog,"('forecast hour: ',f10.3)") nfhour
+ write(nolog,"('valid time: ',6(i4,2x))") wrt_int_state%fdate(1:6)
close(nolog)
endif
enddo two_phase_loop
diff --git a/io/post_fv3.F90 b/io/post_fv3.F90
index 696a6b026..2026b67d9 100644
--- a/io/post_fv3.F90
+++ b/io/post_fv3.F90
@@ -93,7 +93,7 @@ subroutine post_run_fv3(wrt_int_state,grid_id,mype,mpicomp,lead_write, &
its = wrt_int_state%out_grid_info(grid_id)%i_start !<-- Starting I of this write task's subsection
ite = wrt_int_state%out_grid_info(grid_id)%i_end !<-- Ending I of this write task's subsection
- if(mype==0) print *,'in post_run,jts=',jts,'jte=',jte,'nwtpg=',nwtpg, &
+ if(mype==0) print *,'in post_run, numx=',numx,'its=',its,'ite=',ite,'nwtpg=',nwtpg, &
'jts=',jts,'jte=',jte,'maptype=',maptype,'wrt_int_state%FBCount=',wrt_int_state%FBCount
!
@@ -508,7 +508,7 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp)
use vrbls3d, only: t, q, uh, vh, wh, alpint, dpres, zint, zmid, o3, &
qqr, qqs, cwm, qqi, qqw, qqg, omga, cfr, pmid, &
q2, rlwtt, rswtt, tcucn, tcucns, train, el_pbl, &
- pint, exch_h, ref_10cm, qqni, qqnr, qqnwfa, &
+ pint, exch_h, ref_10cm, qqni, qqnr, qqnw, qqnwfa, &
qqnifa, effri, effrl, effrs, aextc55, taod5503d, &
duem, dusd, dudp, duwt, dusv, ssem, sssd, ssdp, &
sswt, sssv, bcem, bcsd, bcdp, bcwt, bcsv, ocem, &
@@ -3642,8 +3642,8 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp)
endif
if(imp_physics == 8) then
- ! model level rain number
- if(trim(fieldname)=='ncrain') then
+ ! model level rain water number
+ if(trim(fieldname)=='rain_nc') then
!$omp parallel do default(none) private(i,j,l) shared(lm,jsta,jend,ista,iend,qqnr,arrayr43d,spval,fillvalue)
do l=1,lm
do j=jsta,jend
@@ -3655,8 +3655,8 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp)
enddo
endif
- ! model level rain number
- if(trim(fieldname)=='ncice') then
+ ! model level cloud ice number
+ if(trim(fieldname)=='nicp') then
!$omp parallel do default(none) private(i,j,l) shared(lm,jsta,jend,ista,iend,qqni,arrayr43d,spval,fillvalue)
do l=1,lm
do j=jsta,jend
@@ -3668,6 +3668,19 @@ subroutine set_postvars_fv3(wrt_int_state,grid_id,mype,mpicomp)
enddo
endif
+ ! model level cloud water number
+ if(trim(fieldname)=='water_nc') then
+ !$omp parallel do default(none) private(i,j,l) shared(lm,jsta,jend,ista,iend,qqnw,arrayr43d,spval,fillvalue)
+ do l=1,lm
+ do j=jsta,jend
+ do i=ista, iend
+ qqnw(i,j,l)=arrayr43d(i,j,l)
+ if(abs(arrayr43d(i,j,l)-fillvalue)
Date: Fri, 8 Sep 2023 13:04:44 -0400
Subject: [PATCH 5/6] add SPP support to G-F deep convection (#688)
* add SPP support to G-F deep convection
---
ccpp/data/GFS_typedefs.F90 | 7 ++++++-
ccpp/data/GFS_typedefs.meta | 16 +++++++++++++++-
ccpp/driver/GFS_diagnostics.F90 | 13 +++++++++++++
ccpp/physics | 2 +-
.../stochastic_physics_wrapper.F90 | 6 ++++++
5 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/ccpp/data/GFS_typedefs.F90 b/ccpp/data/GFS_typedefs.F90
index ec3893ba9..171591a53 100644
--- a/ccpp/data/GFS_typedefs.F90
+++ b/ccpp/data/GFS_typedefs.F90
@@ -612,6 +612,7 @@ module GFS_typedefs
real (kind=kind_phys), pointer :: spp_wts_mp (:,:) => null() ! spp-mp-perts
real (kind=kind_phys), pointer :: spp_wts_gwd (:,:) => null() ! spp-gwd-perts
real (kind=kind_phys), pointer :: spp_wts_rad (:,:) => null() ! spp-rad-perts
+ real (kind=kind_phys), pointer :: spp_wts_cu_deep (:,:) => null() ! spp-cu-deep-perts
!--- aerosol surface emissions for Thompson microphysics
real (kind=kind_phys), pointer :: nwfa2d (:) => null() !< instantaneous water-friendly sfc aerosol source
@@ -1370,8 +1371,9 @@ module GFS_typedefs
integer :: spp_mp
integer :: spp_rad
integer :: spp_gwd
+ integer :: spp_cu_deep
integer :: n_var_spp
- character(len=3) , pointer :: spp_var_list(:)
+ character(len=10) , pointer :: spp_var_list(:)
real(kind=kind_phys), pointer :: spp_prt_list(:)
real(kind=kind_phys), pointer :: spp_stddev_cutoff(:)
@@ -3121,6 +3123,8 @@ subroutine coupling_create (Coupling, IM, Model)
Coupling%spp_wts_gwd = clear_val
allocate (Coupling%spp_wts_rad (IM,Model%levs))
Coupling%spp_wts_rad = clear_val
+ allocate (Coupling%spp_wts_cu_deep (IM,Model%levs))
+ Coupling%spp_wts_cu_deep = clear_val
endif
!--- needed for Thompson's aerosol option
@@ -3817,6 +3821,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, &
integer :: spp_mp = 0
integer :: spp_rad = 0
integer :: spp_gwd = 0
+ integer :: spp_cu_deep = 0
logical :: do_spp = .false.
integer :: ichoice = 0 !< flag for closure of C3/GF deep convection
diff --git a/ccpp/data/GFS_typedefs.meta b/ccpp/data/GFS_typedefs.meta
index 635112ad4..a8ce4f016 100644
--- a/ccpp/data/GFS_typedefs.meta
+++ b/ccpp/data/GFS_typedefs.meta
@@ -2938,6 +2938,14 @@
type = real
kind = kind_phys
active = (do_stochastically_perturbed_parameterizations)
+[spp_wts_cu_deep]
+ standard_name = spp_weights_for_cu_deep_scheme
+ long_name = spp weights for cu deep scheme
+ units = 1
+ dimensions = (horizontal_loop_extent,vertical_layer_dimension)
+ type = real
+ kind = kind_phys
+ active = (do_stochastically_perturbed_parameterizations)
[sfc_wts]
standard_name = surface_stochastic_weights_from_coupled_process
long_name = weights for stochastic surface physics perturbation
@@ -5859,7 +5867,7 @@
units = none
dimensions = (number_of_perturbed_spp_schemes)
type = character
- kind = len=3
+ kind = len=10
active = (do_stochastically_perturbed_parameterizations)
[spp_pbl]
standard_name = control_for_pbl_spp_perturbations
@@ -5891,6 +5899,12 @@
units = count
dimensions = ()
type = integer
+[spp_cu_deep]
+ standard_name = control_for_deep_convection_spp_perturbations
+ long_name = control for deep convection spp perturbations
+ units = count
+ dimensions = ()
+ type = integer
[ntrac]
standard_name = number_of_tracers
long_name = number of tracers
diff --git a/ccpp/driver/GFS_diagnostics.F90 b/ccpp/driver/GFS_diagnostics.F90
index 71c125bfe..0974fdc8d 100644
--- a/ccpp/driver/GFS_diagnostics.F90
+++ b/ccpp/driver/GFS_diagnostics.F90
@@ -2510,6 +2510,19 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop
enddo
endif
+ if (Model%do_spp) then
+ idx = idx + 1
+ ExtDiag(idx)%axes = 3
+ ExtDiag(idx)%name = 'spp_wts_cu_deep'
+ ExtDiag(idx)%desc = 'spp cu deep perturbation wts'
+ ExtDiag(idx)%unit = 'm/s'
+ ExtDiag(idx)%mod_name = 'gfs_phys'
+ allocate (ExtDiag(idx)%data(nblks))
+ do nb = 1,nblks
+ ExtDiag(idx)%data(nb)%var3 => Coupling(nb)%spp_wts_cu_deep(:,:)
+ enddo
+ endif
+
if (Model%lndp_type /= 0) then
idx = idx + 1
ExtDiag(idx)%axes = 3
diff --git a/ccpp/physics b/ccpp/physics
index 5b946850a..7efb112e0 160000
--- a/ccpp/physics
+++ b/ccpp/physics
@@ -1 +1 @@
-Subproject commit 5b946850af58e1cea8c37661158b661df21e9390
+Subproject commit 7efb112e0e1a57fdf54c4a07574b8acd7a55ece6
diff --git a/stochastic_physics/stochastic_physics_wrapper.F90 b/stochastic_physics/stochastic_physics_wrapper.F90
index 3bae38fe3..b76c52a39 100644
--- a/stochastic_physics/stochastic_physics_wrapper.F90
+++ b/stochastic_physics/stochastic_physics_wrapper.F90
@@ -141,6 +141,8 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr)
GFS_Control%spp_rad = 1
case('gwd')
GFS_Control%spp_gwd = 1
+ case('cu_deep')
+ GFS_Control%spp_cu_deep = 1
end select
end do
end if
@@ -257,6 +259,10 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr)
do nb=1,Atm_block%nblks
GFS_Data(nb)%Coupling%spp_wts_rad(:,:) = spp_wts(nb,1:GFS_Control%blksz(nb),:,n)
end do
+ case('cu_deep')
+ do nb=1,Atm_block%nblks
+ GFS_Data(nb)%Coupling%spp_wts_cu_deep(:,:) = spp_wts(nb,1:GFS_Control%blksz(nb),:,n)
+ end do
end select
end do
end if
From 6e75cfc40f165774e199084d7508164df9c5b037 Mon Sep 17 00:00:00 2001
From: Grant Firl
Date: Wed, 24 Jan 2024 22:36:47 +0000
Subject: [PATCH 6/6] update ccpp/physics pointer and .gitmodules
---
.gitmodules | 6 ++----
ccpp/physics | 2 +-
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/.gitmodules b/.gitmodules
index 8cb5b5930..6bb663df1 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -8,10 +8,8 @@
branch = main
[submodule "ccpp/physics"]
path = ccpp/physics
- #url = https://github.com/NCAR/ccpp-physics
- #branch = main
- url = https://github.com/grantfirl/ccpp-physics
- branch = ufs-dev-PR98
+ url = https://github.com/NCAR/ccpp-physics
+ branch = main
[submodule "upp"]
path = upp
url = https://github.com/NOAA-EMC/UPP
diff --git a/ccpp/physics b/ccpp/physics
index 8cf9374da..378517c81 160000
--- a/ccpp/physics
+++ b/ccpp/physics
@@ -1 +1 @@
-Subproject commit 8cf9374da99d7932752173b40c6932e1f52caaac
+Subproject commit 378517c81dac9cbe4f0bee41284b46ae070b4323