Skip to content

Commit

Permalink
Merge pull request #232 from nusbaume/updated_standard_names
Browse files Browse the repository at this point in the history
Update CAM-SIMA to run Kessler and Held-Suarez bit-for-bit with CAM
  • Loading branch information
nusbaume committed Nov 8, 2023
2 parents ef838aa + 59fca03 commit 7d299b6
Show file tree
Hide file tree
Showing 54 changed files with 1,453 additions and 1,422 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python_unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
strategy:
matrix:
#All of these python versions will be used to run tests:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
fail-fast: false
steps:
# Acquire github action routines:
Expand Down
2 changes: 1 addition & 1 deletion Externals.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ local_path = libraries/parallelio
required = True

[cime]
tag = cime6.0.156
tag = cime6.0.175
protocol = git
repo_url = https://github.com/ESMCI/cime
local_path = cime
Expand Down
27 changes: 3 additions & 24 deletions Externals_CAM.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,15 @@
local_path = ccpp_framework
protocol = git
repo_url = https://github.com/peverwhee/ccpp-framework
tag = CPF_0.2.045
tag = CPF_0.2.050
required = True

[cosp2]
local_path = src/physics/cosp2/src
protocol = svn
repo_url = https://github.com/CFMIP/COSPv2.0/tags/
tag = v2.0.3cesm/src
required = False

[clubb]
local_path = src/physics/clubb
protocol = svn
repo_url = https://svn-ccsm-models.cgd.ucar.edu/clubb_core/vendor_tags/
tag = clubb_ncar_backwards_compat_20181205_c20190528
required = False

[ncar-physics]
local_path = src/physics/ncar_ccpp
protocol = git
repo_url = https://github.com/NCAR/atmospheric_physics
tag = atmos_phys0_00_020
repo_url = https://github.com/ESCOMP/atmospheric_physics
tag = atmos_phys0_01_000
required = True

[silhs]
local_path = src/physics/silhs
protocol = svn
repo_url = https://svn-ccsm-models.cgd.ucar.edu/silhs/vendor_tags/
tag = silhs_ncar_backwards_compat_20181205
required = False

[externals_description]
schema_version = 1.0.0
32 changes: 28 additions & 4 deletions cime_config/cam_autogen.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,8 @@ def generate_physics_suites(build_cache, preproc_defs, host_name,
os.makedirs(physics_blddir)
# End if
# Collect all source directories
source_search = [source_mods_dir,
os.path.join(atm_root, "src", "physics", "ncar_ccpp")]
atm_phys_src_dir = os.path.join(atm_root, "src", "physics", "ncar_ccpp")
source_search = [source_mods_dir, atm_phys_src_dir]
# Find all metadata files, organize by scheme name
all_scheme_files = _find_metadata_files(source_search, find_scheme_names)

Expand All @@ -449,8 +449,8 @@ def generate_physics_suites(build_cache, preproc_defs, host_name,
for sdf in phys_suites_str.split(';'):
sdf_path = _find_file(f"suite_{sdf}.xml", source_search)
if not sdf_path:
emsg = "ERROR: Unable to find SDF for suite '{}'"
raise CamAutoGenError(emsg.format(sdf))
emsg = f"ERROR: Unable to find SDF for suite '{sdf}'"
raise CamAutoGenError(emsg)
# End if
sdfs.append(sdf_path)
# Given an SDF, find all the schemes it calls
Expand Down Expand Up @@ -581,6 +581,30 @@ def generate_physics_suites(build_cache, preproc_defs, host_name,
capgen_db = None
# end if

# Several SIMA dycores need some of the physics schemes
# located in the "utilities" CCPP physics directory,
# even if the actual physics suites don't need them.
# So go-ahead and copy all of the source code from
# there to the bld directory:
if do_gen_ccpp:
# Set CCPP physics "utilities" path
atm_phys_util_dir = os.path.join(atm_phys_src_dir, "utilities")

# Check that directory exists
if not os.path.isdir(atm_phys_util_dir):
#CAM-SIMA will likely not run without this, so raise an error
emsg = "ERROR: Unable to find CCPP physics utilities directory:\n"
emsg += f" {atm_phys_util_dir}\n Have you run 'checkout_externals'?"
raise CamAutoGenError(emsg)
# end if

# Copy all utility source files to the build directory
atm_phys_util_files = glob.glob(os.path.join(atm_phys_util_dir, "*.F90"))
for util_file in atm_phys_util_files:
shutil.copy(util_file, physics_blddir)
# end for
# end if

if do_gen_ccpp or do_gen_nl:
# save build details in the build cache
build_cache.update_ccpp(sdfs, scheme_files, host_files, xml_files,
Expand Down
7 changes: 3 additions & 4 deletions cime_config/cam_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,9 @@ def __init__(self, case, case_log):
and associated dictionary.
"""

# Check if using python 3.7 or later. If not,
# then end build here:
if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and sys.version_info[1] < 7):
emsg = "CAM requires python 3.7 or later, currently using python version"
# Check if using python 3.8 or later. If not, then end build here:
if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and sys.version_info[1] < 8):
emsg = "SIMA requires python 3.8 or later, currently using python version"
emsg += f" {sys.version_info[0]}.{sys.version_info[1]}"
raise SystemError(emsg)
#End if
Expand Down
2 changes: 1 addition & 1 deletion cime_config/config_component.xml
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@
<value compset="_CAM%HS94">-phys held_suarez</value>
<value compset="_CAM%KESSLER">-phys kessler -chem terminator -analytic_ic</value> -->
<value compset="_CAM%KESSLER">--physics-suites kessler --analytic_ic</value>
<value compset="_CAM%FHS94">--physics-suites held_suarez_1994 --analytic_ic</value>
<value compset="_CAM%HS94">--physics-suites held_suarez_1994 --analytic_ic</value>
<value compset="_CAM%PHYSTEST">--dyn none --physics-suites adiabatic</value>

<!-- Aquaplanet -->
Expand Down
19 changes: 8 additions & 11 deletions cime_config/config_compsets.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,6 @@
<science_support grid="T42_T42"/>
</compset>

<compset>
<alias>FHS94</alias>
<lname>2000_CAM%HS94_SLND_SICE_SOCN_SROF_SGLC_SWAV</lname>
<science_support grid="T42z30_T42_mg17"/>
<science_support grid="T85z30_T85_mg17"/>
<science_support grid="T85z60_T85_mg17"/>
</compset>

<!-- CAM aquaplanet compsets -->

<compset>
Expand Down Expand Up @@ -149,6 +141,11 @@
<lname>2000_CAM%ADIAB_SLND_SICE_SOCN_SROF_SGLC_SWAV</lname>
</compset>

<compset>
<alias>FHS94</alias>
<lname>2000_CAM%HS94_SLND_SICE_SOCN_SROF_SGLC_SWAV</lname>
</compset>

<!-- CAM Dycore test compsets -->
<compset>
<alias>FHIST_DARTC6</alias>
Expand Down Expand Up @@ -267,7 +264,7 @@
</compset>

<!-- Untested simple model compsets -->


<!-- ****************************** -->
<!-- WACCM science supported compsets -->
Expand Down Expand Up @@ -540,7 +537,7 @@
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9x1.25_r%r05_g%gland4_w%null_m%gx1v7" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM2%NOEVOLVE_SWAV" >hybrid</value> -->
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9_1.25_r%r05_m%gx1v6" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM1%NOEVOLVE_SWAV">hybrid</value> -->
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9_1.25_r%r05_m%gx1v6" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM2%NOEVOLVE_SWAV">hybrid</value> -->

<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9_1.25_r%r05_m%gx1v7" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM1%NOEVOLVE_SWAV">hybrid</value> -->
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9_1.25_r%r05_m%gx1v7" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM2%NOEVOLVE_SWAV">hybrid</value> -->
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9x1.25_r%r05_g%gland4_w%null_m%gx1v7" compset="HIST_CAM60%WC.*_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM2%NOEVOLVE_SWAV">hybrid</value> -->
Expand All @@ -554,7 +551,7 @@
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9x1.25_r%r05_g%gland4_w%null_m%gx1v7" compset="HIST_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM2%NOEVOLVE_SWAV" >b.e20.BHIST.f09_g17.20thC.297_01_v2</value> -->
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9_1.25_r%r05_m%gx1v6" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM1%NOEVOLVE_SWAV">b.e16.B1850_WW3.f09_g16.lang_redi_2hr_frz_chl.003</value> -->
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9_1.25_r%r05_m%gx1v6" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM2%NOEVOLVE_SWAV">b.e20.B1850.f09_g16.pi_control.all.123</value> -->

<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9_1.25_r%r05_m%gx1v7" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM1%NOEVOLVE_SWAV">b.e16.B1850_WW3.f09_g16.lang_redi_2hr_frz_chl.003</value> -->
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9_1.25_r%r05_m%gx1v7" compset="2000_CAM60_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM2%NOEVOLVE_SWAV">b.e20.B1850.f09_g16.pi_control.all.123</value> -->
<!-- <value grid="a%0.9x1.25_l%0.9x1.25_oi%0.9x1.25_r%r05_g%gland4_w%null_m%gx1v7" compset="HIST_CAM60%WC.*_CLM50%BGC-CROP_CICE%PRES_DOCN%DOM_MOSART_CISM2%NOEVOLVE_SWAV">b.e21.BWHIST.f09_g17.CMIP6-historical-WACCM.001</value> -->
Expand Down
96 changes: 78 additions & 18 deletions src/control/cam_comp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,10 @@ module cam_comp

logical :: BFB_CAM_SCAM_IOP = .false.

! Currently, the host (CAM) only adds water vapor (specific_humidity)
! as a constituent.
! Does this need to be a configurable variable?
integer, parameter :: num_host_advected = 1
type(ccpp_constituent_properties_t), target :: host_constituents(num_host_advected)
! Currently, the host (CAM-SIMA) adds only water vapor (specific humidity)
! as a constituent when not requested by the physics. However, it is
! unclear if this is actually necessary.
type(ccpp_constituent_properties_t), allocatable, target :: host_constituents(:)

! Private interface (here to avoid circular dependency)
private :: cam_register_constituents
Expand Down Expand Up @@ -492,41 +491,86 @@ end subroutine cam_final
subroutine cam_register_constituents(cam_runtime_opts)
! Call the CCPP interface to register all constituents for the
! physics suite being invoked during this run.
use cam_abortutils, only: endrun
use cam_abortutils, only: endrun, check_allocate
use runtime_obj, only: runtime_options
use phys_comp, only: phys_suite_name
use cam_constituents, only: cam_constituents_init
use cam_constituents, only: const_set_qmin, const_get_index
use ccpp_kinds, only: kind_phys
use ccpp_constituent_prop_mod, only: ccpp_constituent_prop_ptr_t
use cam_ccpp_cap, only: cam_ccpp_register_constituents
use cam_ccpp_cap, only: cam_ccpp_number_constituents
use cam_ccpp_cap, only: cam_model_const_properties
use cam_ccpp_cap, only: cam_const_get_index
use cam_ccpp_cap, only: cam_ccpp_is_scheme_constituent

! Dummy arguments
type(runtime_options), intent(in) :: cam_runtime_opts
! Local variables
integer :: index
logical :: is_constituent
integer :: num_advect
integer, allocatable :: ind_water_spec(:)
integer :: const_idx
integer :: errflg
character(len=cx) :: errmsg
character(len=512) :: errmsg
type(ccpp_constituent_prop_ptr_t), pointer :: const_props(:)
character(len=*), parameter :: subname = 'cam_register_constituents: '

! Register the constituents to find out what needs advecting
call host_constituents(1)%instantiate(std_name="specific_humidity", &
long_name="Specific humidity", units="kg kg-1", &
vertical_dim="vertical_layer_dimension", advected=.true., &
errcode=errflg, errmsg=errmsg)
! Initalize error flag and message:
errflg = 0
errmsg = ''

! Check if water vapor is already marked as a constituent by the
! physics:
call cam_ccpp_is_scheme_constituent( &
"water_vapor_mixing_ratio_wrt_moist_air_and_condensed_water", &
is_constituent, errflg, errmsg)

if (errflg /= 0) then
call endrun(subname//trim(errmsg), file=__FILE__, line=__LINE__)
end if
call cam_ccpp_register_constituents(cam_runtime_opts%suite_as_list(), &

!If not requested by the physics, then add water vapor to the
!constituents object:
!-------------------------------------------
if (.not. is_constituent) then

! Allocate host_constituents object:
allocate(host_constituents(1), stat=errflg)
call check_allocate(errflg, subname, 'host_constituents(1)', &
file=__FILE__, line=__LINE__)

! Register the constituents so they can be advected:
call host_constituents(1)%instantiate( &
std_name="water_vapor_mixing_ratio_wrt_moist_air_and_condensed_water", &
long_name="water vapor mixing ratio w.r.t moist air and condensed_water", &
units="kg kg-1", &
default_value=0._kind_phys, &
vertical_dim="vertical_layer_dimension", &
advected=.true., &
errcode=errflg, errmsg=errmsg)

if (errflg /= 0) then
call endrun(subname//trim(errmsg), file=__FILE__, line=__LINE__)
end if
else
! Allocate zero-size object so nothing is added
! to main constituents object:
allocate(host_constituents(0), stat=errflg)
call check_allocate(errflg, subname, 'host_constituents(0)', &
file=__FILE__, line=__LINE__)
end if
!-------------------------------------------

!Combine host and physics constituents into a single
!constituents object:
call cam_ccpp_register_constituents(cam_runtime_opts%suite_as_list(), &
host_constituents, errcode=errflg, errmsg=errmsg)

if (errflg /= 0) then
call endrun(subname//trim(errmsg), file=__FILE__, line=__LINE__)
end if
call cam_ccpp_number_constituents(num_advect, advected=.true., &

!Determine total number of advected constituents:
call cam_ccpp_number_constituents(num_advect, advected=.true., &
errcode=errflg, errmsg=errmsg)

if (errflg /= 0) then
Expand All @@ -536,9 +580,25 @@ subroutine cam_register_constituents(cam_runtime_opts)
! Grab a pointer to the constituent array
const_props => cam_model_const_properties()

! Finally, initialize the constituents module
! Initialize the constituents module
call cam_constituents_init(const_props, num_advect)

! Finally, for CAM moist physics, one will need to use a
! non-zero minimum value for water vapor, so update that
! value here:
!-------------------------------------------
if (phys_suite_name /= 'held_suarez_1994') then !Held-Suarez is "dry" physics

! Get constituent index for water vapor:
call const_get_index("water_vapor_mixing_ratio_wrt_moist_air_and_condensed_water", &
const_idx)

! Set new minimum value:
call const_set_qmin(const_idx, 1.E-12_kind_phys)
end if
!-------------------------------------------


end subroutine cam_register_constituents

!-----------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 7d299b6

Please sign in to comment.