diff --git a/docs/source/setup.rst b/docs/source/setup.rst index eb13b4b6f3..b042b1d9f6 100644 --- a/docs/source/setup.rst +++ b/docs/source/setup.rst @@ -84,12 +84,13 @@ The following command examples include variables for reference but users should :: cd workflow - ./setup_expt.py forecast-only --idate $IDATE --edate $EDATE [--app $APP] [--start $START] [--gfs_cyc $GFS_CYC] [--resdet $RESDET] + ./setup_expt.py gfs forecast-only --idate $IDATE --edate $EDATE [--app $APP] [--start $START] [--gfs_cyc $GFS_CYC] [--resdet $RESDET] [--pslot $PSLOT] [--configdir $CONFIGDIR] [--comrot $COMROT] [--expdir $EXPDIR] where: - * ``forecast-only`` is the first positional argument that instructs the setup script to produce an experiment directory for forecast only experiments. + * ``gfs`` is the first positional argument that instructs the setup script to produce a GFS experiment directory + * ``forecast-only`` is the second positional argument that instructs the setup script to produce an experiment directory for forecast only experiments. * ``$APP`` is the target application, one of: - ATM: atmosphere-only [default] @@ -116,21 +117,21 @@ Atm-only: :: cd workflow - ./setup_expt.py forecast-only --pslot test --idate 2020010100 --edate 2020010118 --resdet 384 --gfs_cyc 4 --comrot /some_large_disk_area/Joe.Schmo/comrot --expdir /some_safe_disk_area/Joe.Schmo/expdir + ./setup_expt.py gfs forecast-only --pslot test --idate 2020010100 --edate 2020010118 --resdet 384 --gfs_cyc 4 --comrot /some_large_disk_area/Joe.Schmo/comrot --expdir /some_safe_disk_area/Joe.Schmo/expdir Coupled: :: cd workflow - ./setup_expt.py forecast-only --app S2SW --pslot coupled_test --idate 2013040100 --edate 2013040100 --resdet 384 --comrot /some_large_disk_area/Joe.Schmo/comrot --expdir /some_safe_disk_area/Joe.Schmo/expdir + ./setup_expt.py gfs forecast-only --app S2SW --pslot coupled_test --idate 2013040100 --edate 2013040100 --resdet 384 --comrot /some_large_disk_area/Joe.Schmo/comrot --expdir /some_safe_disk_area/Joe.Schmo/expdir Coupled with aerosols: :: cd workflow - ./setup_expt.py forecast-only --app S2SWA --pslot coupled_test --idate 2013040100 --edate 2013040100 --resdet 384 --comrot /some_large_disk_area/Joe.Schmo/comrot --expdir /some_safe_disk_area/Joe.Schmo/expdir + ./setup_expt.py gfs forecast-only --app S2SWA --pslot coupled_test --idate 2013040100 --edate 2013040100 --resdet 384 --comrot /some_large_disk_area/Joe.Schmo/comrot --expdir /some_safe_disk_area/Joe.Schmo/expdir **************************************** Step 2: Set user and experiment settings @@ -193,13 +194,14 @@ The following command examples include variables for reference but users should :: cd workflow - ./setup_expt.py cycled --idate $IDATE --edate $EDATE [--app $APP] [--start $START] [--gfs_cyc $GFS_CYC] + ./setup_expt.py gfs cycled --idate $IDATE --edate $EDATE [--app $APP] [--start $START] [--gfs_cyc $GFS_CYC] [--resdet $RESDET] [--resens $RESENS] [--nens $NENS] [--cdump $CDUMP] [--pslot $PSLOT] [--configdir $CONFIGDIR] [--comrot $COMROT] [--expdir $EXPDIR] [--icsdir $ICSDIR] where: - * ``cycled`` is the first positional argument that instructs the setup script to produce an experiment directory for cycled experiments. + * ``gfs`` is the first positional argument that instructs the setup script to produce a GFS experiment directory + * ``cycled`` is the second positional argument that instructs the setup script to produce an experiment directory for cycled experiments. * ``$APP`` is the target application, one of: - ATM: atmosphere-only [default] @@ -226,13 +228,13 @@ Example: :: cd workflow - ./setup_expt.py cycled --pslot test --configdir /home/Joe.Schmo/git/global-workflow/parm/config --idate 2020010100 --edate 2020010118 --comrot /some_large_disk_area/Joe.Schmo/comrot --expdir /some_safe_disk_area/Joe.Schmo/expdir --resdet 384 --resens 192 --nens 80 --gfs_cyc 4 + ./setup_expt.py gfs cycled --pslot test --configdir /home/Joe.Schmo/git/global-workflow/parm/config --idate 2020010100 --edate 2020010118 --comrot /some_large_disk_area/Joe.Schmo/comrot --expdir /some_safe_disk_area/Joe.Schmo/expdir --resdet 384 --resens 192 --nens 80 --gfs_cyc 4 Example ``setup_expt.py`` on Orion: :: - Orion-login-3$ ./setup_expt.py cycled --pslot test --idate 2022010118 --edate 2022010200 --resdet 192 --resens 96 --nens 80 --comrot /work/noaa/stmp/jschmo/comrot --expdir /work/noaa/global/jschmo/expdir + Orion-login-3$ ./setup_expt.py gfs cycled --pslot test --idate 2022010118 --edate 2022010200 --resdet 192 --resens 96 --nens 80 --comrot /work/noaa/stmp/jschmo/comrot --expdir /work/noaa/global/jschmo/expdir EDITED: /work/noaa/global/jschmo/expdir/test/config.base as per user input. EDITED: /work/noaa/global/jschmo/expdir/test/config.aeroanl as per user input. EDITED: /work/noaa/global/jschmo/expdir/test/config.ocnanal as per user input. @@ -243,7 +245,7 @@ What happens if I run ``setup_expt.py`` again for an experiment that already exi :: - Orion-login-3$ ./setup_expt.py cycled --pslot test --idate 2022010118 --edate 2022010200 --resdet 192 --resens 96 --nens 80 --comrot /work/noaa/stmp/jschmo/comrot --expdir /work/noaa/global/jschmo/expdir + Orion-login-3$ ./setup_expt.py gfs cycled --pslot test --idate 2022010118 --edate 2022010200 --resdet 192 --resens 96 --nens 80 --comrot /work/noaa/stmp/jschmo/comrot --expdir /work/noaa/global/jschmo/expdir directory already exists in /work/noaa/stmp/jschmo/comrot/test diff --git a/jobs/JGDAS_ENKF_DIAG b/jobs/JGDAS_ENKF_DIAG index e2684fded2..40f2968869 100755 --- a/jobs/JGDAS_ENKF_DIAG +++ b/jobs/JGDAS_ENKF_DIAG @@ -24,7 +24,7 @@ export gcyc=${GDATE:8:2} export GDUMP="gdas" export GDUMP_ENS="enkf${GDUMP}" -export CASE=${CASE_ENKF} +export CASE=${CASE_ENS} export OPREFIX="${CDUMP}.t${cyc}z." export APREFIX="${RUN}.t${cyc}z." diff --git a/jobs/JGDAS_ENKF_ECEN b/jobs/JGDAS_ENKF_ECEN index 9c2f09a0dc..cd77eebb55 100755 --- a/jobs/JGDAS_ENKF_ECEN +++ b/jobs/JGDAS_ENKF_ECEN @@ -21,7 +21,7 @@ export gcyc=${GDATE:8:2} export GDUMP="gdas" export GDUMP_ENS="enkf${GDUMP}" -export CASE=${CASE_ENKF} +export CASE=${CASE_ENS} export OPREFIX="${CDUMP}.t${cyc}z." export APREFIX="${CDUMP}.t${cyc}z." diff --git a/jobs/JGDAS_ENKF_FCST b/jobs/JGDAS_ENKF_FCST index 77c8b7c059..45d0ad8b1d 100755 --- a/jobs/JGDAS_ENKF_FCST +++ b/jobs/JGDAS_ENKF_FCST @@ -14,7 +14,7 @@ export rCDUMP="enkfgdas" # Begin JOB SPECIFIC work ############################################## -export CASE=${CASE_ENKF} +export CASE=${CASE_ENS} YMD=${PDY} HH=${cyc} generate_com -rx COM_TOP diff --git a/jobs/JGDAS_ENKF_SFC b/jobs/JGDAS_ENKF_SFC index 9e6196fbd7..3214812db8 100755 --- a/jobs/JGDAS_ENKF_SFC +++ b/jobs/JGDAS_ENKF_SFC @@ -25,7 +25,7 @@ export OPREFIX="${CDUMP}.t${cyc}z." export GPREFIX="${GDUMP}.t${gcyc}z." export APREFIX="${CDUMP}.t${cyc}z." -export CASE=${CASE_ENKF} +export CASE=${CASE_ENS} export OPREFIX="${CDUMP}.t${cyc}z." export APREFIX="${CDUMP}.t${cyc}z." diff --git a/parm/config/config.base.emc.dyn b/parm/config/gefs/config.base.emc.dyn similarity index 98% rename from parm/config/config.base.emc.dyn rename to parm/config/gefs/config.base.emc.dyn index 95a071dc9b..8ebcafe6cf 100644 --- a/parm/config/config.base.emc.dyn +++ b/parm/config/gefs/config.base.emc.dyn @@ -75,7 +75,6 @@ export MODE="@MODE@" # cycled/forecast-only #################################################### # Build paths relative to $HOMEgfs export FIXgsi="${HOMEgfs}/fix/gsi" -export HOMEfv3gfs="${HOMEgfs}/sorc/fv3gfs.fd" export HOMEpost="${HOMEgfs}" export HOMEobsproc="${BASE_GIT}/obsproc/v1.1.2" @@ -159,8 +158,8 @@ export OPS_RES="C768" # Do not change # Resolution specific parameters export LEVS=128 export CASE="@CASECTL@" -export CASE_ENKF="@CASEENS@" -# TODO: This should not depend on $CASE or $CASE_ENKF +export CASE_ENS="@CASEENS@" +# TODO: This should not depend on $CASE or $CASE_ENS # These are the currently available grid-combinations case "${CASE}" in "C48") export OCNRES=500;; @@ -306,8 +305,8 @@ export DO_MERGENSST="NO" # Hybrid related export DOHYBVAR="@DOHYBVAR@" -export NMEM_ENKF=@NMEM_ENKF@ -export NMEM_EFCS=30 +export NMEM_ENS=@NMEM_ENS@ +export NMEM_ENS_GFS=@NMEM_ENS@ export SMOOTH_ENKF="NO" export l4densvar=".true." export lwrite4danl=".true." diff --git a/parm/config/gefs/config.com b/parm/config/gefs/config.com new file mode 120000 index 0000000000..6a3754559c --- /dev/null +++ b/parm/config/gefs/config.com @@ -0,0 +1 @@ +../gfs/config.com \ No newline at end of file diff --git a/parm/config/config.coupled_ic b/parm/config/gefs/config.coupled_ic similarity index 100% rename from parm/config/config.coupled_ic rename to parm/config/gefs/config.coupled_ic diff --git a/parm/config/config.efcs b/parm/config/gefs/config.efcs similarity index 97% rename from parm/config/config.efcs rename to parm/config/gefs/config.efcs index a9b410e416..95c2cb58de 100644 --- a/parm/config/config.efcs +++ b/parm/config/gefs/config.efcs @@ -13,7 +13,7 @@ export DO_WAVE=${DO_WAVE_ENKF:-"NO"} # TODO: Possibly need OCNRES_ENKF, ICERES_ENKF, WAVRES_ENKF too if [[ ${DO_OCN} == "YES" ]]; then - case "$CASE_ENKF" in + case "${CASE_ENS}" in "C48") export OCNRES=500;; "C96") export OCNRES=100;; "C192") export OCNRES=050;; @@ -26,7 +26,7 @@ fi [[ ${DO_WAVE} == "YES" ]] && export waveGRD=${waveGRD_ENKF:-$waveGRD} # TODO: will we run waves with a different resolution in the ensemble? # Source model specific information that is resolution dependent -string="--fv3 $CASE_ENKF" +string="--fv3 ${CASE_ENS}" [[ ${DO_OCN} == "YES" ]] && string="$string --mom6 $OCNRES" [[ ${DO_ICE} == "YES" ]] && string="$string --cice6 $ICERES" [[ ${DO_WAVE} == "YES" ]] && string="$string --ww3 ${waveGRD// /;}" @@ -84,7 +84,7 @@ fi export cplwav=.false. # ocean model resolution -case "$CASE_ENKF" in +case "${CASE_ENS}" in "C48") export OCNRES=500;; "C96") export OCNRES=100;; "C192") export OCNRES=050;; diff --git a/parm/config/config.resources b/parm/config/gefs/config.resources similarity index 100% rename from parm/config/config.resources rename to parm/config/gefs/config.resources diff --git a/parm/config/config.ufs b/parm/config/gefs/config.ufs similarity index 100% rename from parm/config/config.ufs rename to parm/config/gefs/config.ufs diff --git a/parm/config/gefs/yaml/defaults.yaml b/parm/config/gefs/yaml/defaults.yaml new file mode 100644 index 0000000000..6e7633bfe0 --- /dev/null +++ b/parm/config/gefs/yaml/defaults.yaml @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/parm/config/config.aero b/parm/config/gfs/config.aero similarity index 100% rename from parm/config/config.aero rename to parm/config/gfs/config.aero diff --git a/parm/config/config.aeroanl b/parm/config/gfs/config.aeroanl similarity index 100% rename from parm/config/config.aeroanl rename to parm/config/gfs/config.aeroanl diff --git a/parm/config/config.aeroanlfinal b/parm/config/gfs/config.aeroanlfinal similarity index 100% rename from parm/config/config.aeroanlfinal rename to parm/config/gfs/config.aeroanlfinal diff --git a/parm/config/config.aeroanlinit b/parm/config/gfs/config.aeroanlinit similarity index 100% rename from parm/config/config.aeroanlinit rename to parm/config/gfs/config.aeroanlinit diff --git a/parm/config/config.aeroanlrun b/parm/config/gfs/config.aeroanlrun similarity index 100% rename from parm/config/config.aeroanlrun rename to parm/config/gfs/config.aeroanlrun diff --git a/parm/config/config.aerosol_init b/parm/config/gfs/config.aerosol_init similarity index 100% rename from parm/config/config.aerosol_init rename to parm/config/gfs/config.aerosol_init diff --git a/parm/config/config.anal b/parm/config/gfs/config.anal similarity index 100% rename from parm/config/config.anal rename to parm/config/gfs/config.anal diff --git a/parm/config/config.analcalc b/parm/config/gfs/config.analcalc similarity index 100% rename from parm/config/config.analcalc rename to parm/config/gfs/config.analcalc diff --git a/parm/config/config.analdiag b/parm/config/gfs/config.analdiag similarity index 100% rename from parm/config/config.analdiag rename to parm/config/gfs/config.analdiag diff --git a/parm/config/config.arch b/parm/config/gfs/config.arch similarity index 100% rename from parm/config/config.arch rename to parm/config/gfs/config.arch diff --git a/parm/config/config.atmanl b/parm/config/gfs/config.atmanl similarity index 100% rename from parm/config/config.atmanl rename to parm/config/gfs/config.atmanl diff --git a/parm/config/config.atmanlfinal b/parm/config/gfs/config.atmanlfinal similarity index 100% rename from parm/config/config.atmanlfinal rename to parm/config/gfs/config.atmanlfinal diff --git a/parm/config/config.atmanlinit b/parm/config/gfs/config.atmanlinit similarity index 100% rename from parm/config/config.atmanlinit rename to parm/config/gfs/config.atmanlinit diff --git a/parm/config/config.atmanlrun b/parm/config/gfs/config.atmanlrun similarity index 100% rename from parm/config/config.atmanlrun rename to parm/config/gfs/config.atmanlrun diff --git a/parm/config/config.atmensanl b/parm/config/gfs/config.atmensanl similarity index 100% rename from parm/config/config.atmensanl rename to parm/config/gfs/config.atmensanl diff --git a/parm/config/config.atmensanlfinal b/parm/config/gfs/config.atmensanlfinal similarity index 100% rename from parm/config/config.atmensanlfinal rename to parm/config/gfs/config.atmensanlfinal diff --git a/parm/config/config.atmensanlinit b/parm/config/gfs/config.atmensanlinit similarity index 100% rename from parm/config/config.atmensanlinit rename to parm/config/gfs/config.atmensanlinit diff --git a/parm/config/config.atmensanlrun b/parm/config/gfs/config.atmensanlrun similarity index 100% rename from parm/config/config.atmensanlrun rename to parm/config/gfs/config.atmensanlrun diff --git a/parm/config/config.awips b/parm/config/gfs/config.awips similarity index 100% rename from parm/config/config.awips rename to parm/config/gfs/config.awips diff --git a/parm/config/gfs/config.base.emc.dyn b/parm/config/gfs/config.base.emc.dyn new file mode 100644 index 0000000000..863df89170 --- /dev/null +++ b/parm/config/gfs/config.base.emc.dyn @@ -0,0 +1,388 @@ +#! /usr/bin/env bash + +########## config.base ########## +# Common to all steps + +echo "BEGIN: config.base" + +# Machine environment +export machine="@MACHINE@" + +# EMC parallel or NCO production +export RUN_ENVIR="emc" + +# Account, queue, etc. +export ACCOUNT="@ACCOUNT@" +export QUEUE="@QUEUE@" +export QUEUE_SERVICE="@QUEUE_SERVICE@" +export PARTITION_BATCH="@PARTITION_BATCH@" +export PARTITION_SERVICE="@PARTITION_SERVICE@" + +# Project to use in mass store: +HPSS_PROJECT=emc-global + +# Directories relative to installation areas: +export HOMEgfs=@HOMEgfs@ +export PARMgfs=${HOMEgfs}/parm +export FIXgfs=${HOMEgfs}/fix +export USHgfs=${HOMEgfs}/ush +export UTILgfs=${HOMEgfs}/util +export EXECgfs=${HOMEgfs}/exec +export SCRgfs=${HOMEgfs}/scripts + +export FIXcice=${HOMEgfs}/fix/cice +export FIXmom=${HOMEgfs}/fix/mom6 +export FIXreg2grb2=${HOMEgfs}/fix/reg2grb2 + +######################################################################## + +# GLOBAL static environment parameters +export PACKAGEROOT="@PACKAGEROOT@" # TODO: set via prod_envir in Ops +export COMROOT="@COMROOT@" # TODO: set via prod_envir in Ops +export COMINsyn="@COMINsyn@" +export DMPDIR="@DMPDIR@" + +# USER specific paths +export HOMEDIR="@HOMEDIR@" +export STMP="@STMP@" +export PTMP="@PTMP@" +export NOSCRUB="@NOSCRUB@" + +# Base directories for various builds +export BASE_GIT="@BASE_GIT@" + +# Toggle to turn on/off GFS downstream processing. +export DO_BUFRSND="NO" # BUFR sounding products +export DO_GEMPAK="NO" # GEMPAK products +export DO_AWIPS="NO" # AWIPS products +export WAFSF="NO" # WAFS products +export DO_VRFY="YES" # VRFY step + +# NO for retrospective parallel; YES for real-time parallel +# arch.sh uses REALTIME for MOS. Need to set REALTIME=YES +# if want MOS written to HPSS. Should update arch.sh to +# use RUNMOS flag (currently in config.vrfy) +export REALTIME="YES" + +# Experiment mode (cycled or forecast-only) +export MODE="@MODE@" # cycled/forecast-only + +#################################################### +# DO NOT ADD MACHINE DEPENDENT STUFF BELOW THIS LINE +# IF YOU HAVE TO MAKE MACHINE SPECIFIC CHANGES BELOW +# FEEL FREE TO MOVE THEM ABOVE THIS LINE TO KEEP IT +# CLEAR +#################################################### +# Build paths relative to $HOMEgfs +export FIXgsi="${HOMEgfs}/fix/gsi" +export HOMEpost="${HOMEgfs}" +export HOMEobsproc="${BASE_GIT}/obsproc/v1.1.2" + +# CONVENIENT utility scripts and other environment parameters +export NCP="/bin/cp -p" +export NMV="/bin/mv" +export NLN="/bin/ln -sf" +export VERBOSE="YES" +export KEEPDATA="NO" +export CHGRP_RSTPROD="@CHGRP_RSTPROD@" +export CHGRP_CMD="@CHGRP_CMD@" +export NCDUMP="$NETCDF/bin/ncdump" +export NCLEN="$HOMEgfs/ush/getncdimlen" + +# Machine environment, jobs, and other utility scripts +export BASE_ENV="${HOMEgfs}/env" +export BASE_JOB="${HOMEgfs}/jobs/rocoto" + +# EXPERIMENT specific environment parameters +export SDATE=@SDATE@ +export EDATE=@EDATE@ +export EXP_WARM_START="@EXP_WARM_START@" +export assim_freq=6 +export PSLOT="@PSLOT@" +export EXPDIR="@EXPDIR@/${PSLOT}" +export ROTDIR="@ROTDIR@/${PSLOT}" +export ROTDIR_DUMP="YES" #Note: A value of "NO" does not currently work +export DUMP_SUFFIX="" +if [[ "${PDY}${cyc}" -ge "2019092100" && "${PDY}${cyc}" -le "2019110700" ]]; then + export DUMP_SUFFIX="p" # Use dumps from NCO GFS v15.3 parallel +fi +export DATAROOT="${STMP}/RUNDIRS/${PSLOT}" # TODO: set via prod_envir in Ops +export RUNDIR="${DATAROOT}" # TODO: Should be removed; use DATAROOT instead +export ARCDIR="${NOSCRUB}/archive/${PSLOT}" +export ATARDIR="@ATARDIR@" + +# Commonly defined parameters in JJOBS +export envir=${envir:-"prod"} +export NET="gfs" # NET is defined in the job-card (ecf) +export RUN=${RUN:-${CDUMP:-"gfs"}} # RUN is defined in the job-card (ecf); CDUMP is used at EMC as a RUN proxy +# TODO: determine where is RUN actually used in the workflow other than here +# TODO: is it possible to replace all instances of ${CDUMP} to ${RUN} to be +# consistent w/ EE2? + +# Get all the COM path templates +source "${EXPDIR}/config.com" + +export ERRSCRIPT=${ERRSCRIPT:-'eval [[ $err = 0 ]]'} +export LOGSCRIPT=${LOGSCRIPT:-""} +#export ERRSCRIPT=${ERRSCRIPT:-"err_chk"} +#export LOGSCRIPT=${LOGSCRIPT:-"startmsg"} +export REDOUT="1>" +export REDERR="2>" + +export SENDECF=${SENDECF:-"NO"} +export SENDCOM=${SENDCOM:-"YES"} +export SENDSDM=${SENDSDM:-"NO"} +export SENDDBN_NTC=${SENDDBN_NTC:-"NO"} +export SENDDBN=${SENDDBN:-"NO"} +export DBNROOT=${DBNROOT:-${UTILROOT}/fakedbn} + +# APP settings +export APP=@APP@ + +# Defaults: +export DO_ATM="YES" +export DO_COUPLED="NO" +export DO_WAVE="NO" +export DO_OCN="NO" +export DO_ICE="NO" +export DO_AERO="NO" +export CCPP_SUITE="@CCPP_SUITE@" +export WAVE_CDUMP="" # When to include wave suite: gdas, gfs, or both +export DOBNDPNT_WAVE="NO" +export cplwav2atm=".false." +export FRAC_GRID=".true." + +# Set operational resolution +export OPS_RES="C768" # Do not change + +# Resolution specific parameters +export LEVS=128 +export CASE="@CASECTL@" +export CASE_ENS="@CASEENS@" +# TODO: This should not depend on $CASE or $CASE_ENS +# These are the currently available grid-combinations +case "${CASE}" in + "C48") export OCNRES=500;; + "C96") export OCNRES=100;; + "C192") export OCNRES=050;; + "C384") export OCNRES=025;; + "C768") export OCNRES=025;; + *) export OCNRES=025;; +esac +export ICERES=${OCNRES} +export waveGRD='gnh_10m aoc_9km gsh_15m' + +case "${APP}" in + ATM) + export confignamevarfornems="atm" + ;; + ATMA) + export DO_AERO="YES" + export confignamevarfornems="atm_aero" + ;; + ATMW) + export DO_COUPLED="YES" + export DO_WAVE="YES" + export WAVE_CDUMP="both" + export confignamevarfornems="leapfrog_atm_wav" + ;; + NG-GODAS) + export DO_ATM="NO" + export DO_OCN="YES" + export DO_ICE="YES" + ;; + S2S*) + export DO_COUPLED="YES" + export DO_OCN="YES" + export DO_ICE="YES" + export CCPP_SUITE="FV3_GFS_v17_coupled_p8" + export confignamevarfornems="cpld" + + if [[ "${APP}" =~ A$ ]]; then + export DO_AERO="YES" + export confignamevarfornems="${confignamevarfornems}_aero" + fi + + if [[ "${APP}" =~ ^S2SW ]]; then + export DO_WAVE="YES" + export WAVE_CDUMP="both" + export cplwav2atm=".true." + export confignamevarfornems="${confignamevarfornems}_outerwave" + fi + + source ${EXPDIR}/config.defaults.s2sw + + ;; + *) + echo "Unrecognized APP: ${1}" + exit 1 + ;; +esac + +# Surface cycle update frequency +if [[ "${CDUMP}" =~ "gdas" ]] ; then + export FHCYC=1 + export FTSFS=10 +elif [[ "${CDUMP}" =~ "gfs" ]] ; then + export FHCYC=24 +fi + +# Output frequency of the forecast model (for cycling) +export FHMIN=0 +export FHMAX=9 +export FHOUT=3 # Will be changed to 1 in config.base if DO_GLDAS is set or (DOHYBVAR set to NO and l4densvar set to false) + +# Cycle to run EnKF (set to BOTH for both gfs and gdas) +export EUPD_CYC="gdas" + +# GFS cycle info +export gfs_cyc=@gfs_cyc@ # 0: no GFS cycle, 1: 00Z only, 2: 00Z and 12Z only, 4: all 4 cycles. + +# GFS output and frequency +export FHMIN_GFS=0 + +export FHMAX_GFS_00=${FHMAX_GFS_00:-120} +export FHMAX_GFS_06=${FHMAX_GFS_06:-120} +export FHMAX_GFS_12=${FHMAX_GFS_12:-120} +export FHMAX_GFS_18=${FHMAX_GFS_18:-120} +export FHMAX_GFS=$(eval echo \${FHMAX_GFS_${cyc}}) + +export FHOUT_GFS=${FHOUT_GFS:-3} +export FHMAX_HF_GFS=${FHMAX_HF_GFS:-0} +export FHOUT_HF_GFS=${FHOUT_HF_GFS:-1} +if (( gfs_cyc != 0 )); then + export STEP_GFS=$(( 24 / gfs_cyc )) +else + export STEP_GFS="0" +fi +export ILPOST=1 # gempak output frequency up to F120 + +# GFS restart interval in hours +export restart_interval_gfs=0 + +export QUILTING=".true." +export OUTPUT_GRID="gaussian_grid" +export WRITE_DOPOST=".true." # WRITE_DOPOST=true, use inline POST +export WRITE_NSFLIP=".true." + +# IAU related parameters +export DOIAU="YES" # Enable 4DIAU for control with 3 increments +export IAUFHRS="3,6,9" +export IAU_FHROT=$(echo ${IAUFHRS} | cut -c1) +export IAU_DELTHRS=6 +export IAU_OFFSET=6 +export DOIAU_ENKF=${DOIAU:-"YES"} # Enable 4DIAU for EnKF ensemble +export IAUFHRS_ENKF="3,6,9" +export IAU_DELTHRS_ENKF=6 + +# Use Jacobians in eupd and thereby remove need to run eomg +export lobsdiag_forenkf=".true." + +# run GLDAS to spin up land ICs +export DO_GLDAS="NO" +export gldas_cyc=00 + +# Exception handling that when DO_GLDAS is set, the FHOUT must be 1 +if [[ ${DO_GLDAS} = "YES" ]]; then + export FHOUT=1 +fi + +# if [[ "$SDATE" -lt "2019020100" ]]; then # no rtofs in GDA +# export DO_WAVE="NO" +# echo "WARNING: Wave suite turned off due to lack of RTOFS in GDA for SDATE" +# fi + +# Microphysics Options: 99-ZhaoCarr, 8-Thompson; 6-WSM6, 10-MG, 11-GFDL +export imp_physics=@IMP_PHYSICS@ + +# Shared parameters +# DA engine +export DO_JEDIVAR="NO" +export DO_JEDIENS="NO" +export DO_JEDIOCNVAR="NO" +export DO_JEDILANDDA="NO" +export DO_MERGENSST="NO" + +# Hybrid related +export DOHYBVAR="@DOHYBVAR@" +export NMEM_ENS=@NMEM_ENS@ +export NMEM_ENS_GFS=@NMEM_ENS@ +export SMOOTH_ENKF="NO" +export l4densvar=".true." +export lwrite4danl=".true." + +# EnKF output frequency +if [[ ${DOHYBVAR} = "YES" ]]; then + export FHMIN_ENKF=3 + export FHMAX_ENKF=9 + export FHMAX_ENKF_GFS=120 + export FHOUT_ENKF_GFS=3 + if [ $l4densvar = ".true." ]; then + export FHOUT=1 + export FHOUT_ENKF=1 + else + export FHOUT_ENKF=3 + fi +fi + +# if 3DVAR and IAU +if [[ ${DOHYBVAR} == "NO" && ${DOIAU} == "YES" ]]; then + export IAUFHRS="6" + export IAU_FHROT="3" + export IAU_FILTER_INCREMENTS=".true." + export IAUFHRS_ENKF="6" +fi + +# Check if cycle is cold starting, DOIAU off, or free-forecast mode +if [[ "${MODE}" = "cycled" && "${SDATE}" = "${PDY}${cyc}" && ${EXP_WARM_START} = ".false." ]] || [[ "${DOIAU}" = "NO" ]] || [[ "${MODE}" = "forecast-only" && ${EXP_WARM_START} = ".false." ]] ; then + export IAU_OFFSET=0 + export IAU_FHROT=0 +fi + +# turned on nsst in anal and/or fcst steps, and turn off rtgsst +export DONST="YES" +if [[ ${DONST} = "YES" ]]; then export FNTSFA=" "; fi + +# The switch to apply SST elevation correction or not +export nst_anl=.true. + +# Make the nsstbufr file on the fly or use the GDA version +export MAKE_NSSTBUFR="@MAKE_NSSTBUFR@" + +# Make the aircraft prepbufr file on the fly or use the GDA version +export MAKE_ACFTBUFR="@MAKE_ACFTBUFR@" + +# Analysis increments to zero in CALCINCEXEC +export INCREMENTS_TO_ZERO="'liq_wat_inc','icmr_inc'" + +# Write analysis files for early cycle EnKF +export DO_CALC_INCREMENT_ENKF_GFS="YES" + +# Stratospheric increments to zero +export INCVARS_ZERO_STRAT="'sphum_inc','liq_wat_inc','icmr_inc'" +export INCVARS_EFOLD="5" + +# Swith to generate netcdf or binary diagnostic files. If not specified, +# script default to binary diagnostic files. Set diagnostic file +# variables here since used in both DA and vrfy jobs +export netcdf_diag=".true." +export binary_diag=".false." + +# Verification options +export DO_METP="YES" # Run METPLUS jobs - set METPLUS settings in config.metp +export DO_FIT2OBS="NO" # Run fit to observations package + +# Archiving options +export HPSSARCH="@HPSSARCH@" # save data to HPSS archive +export LOCALARCH="@LOCALARCH@" # save data to local archive +if [[ ${HPSSARCH} = "YES" ]] && [[ ${LOCALARCH} = "YES" ]]; then + echo "Both HPSS and local archiving selected. Please choose one or the other." + exit 2 +fi +export ARCH_CYC=00 # Archive data at this cycle for warm_start capability +export ARCH_WARMICFREQ=4 # Archive frequency in days for warm_start capability +export ARCH_FCSTICFREQ=1 # Archive frequency in days for gdas and gfs forecast-only capability + +export DELETE_COM_IN_ARCHIVE_JOB="YES" # NO=retain ROTDIR. YES default in arch.sh and earc.sh. + +echo "END: config.base" diff --git a/parm/config/config.base.nco.static b/parm/config/gfs/config.base.nco.static similarity index 100% rename from parm/config/config.base.nco.static rename to parm/config/gfs/config.base.nco.static diff --git a/parm/config/config.com b/parm/config/gfs/config.com similarity index 100% rename from parm/config/config.com rename to parm/config/gfs/config.com diff --git a/parm/config/gfs/config.coupled_ic b/parm/config/gfs/config.coupled_ic new file mode 100644 index 0000000000..50fab283b5 --- /dev/null +++ b/parm/config/gfs/config.coupled_ic @@ -0,0 +1,43 @@ +#! /usr/bin/env bash + +########## config.coupled_ic ########## + +echo "BEGIN: config.coupled_ic" + +# Get task specific resources +source ${EXPDIR}/config.resources coupled_ic + +if [[ "${machine}" == "WCOSS2" ]]; then + export BASE_CPLIC="/lfs/h2/emc/couple/noscrub/Jiande.Wang/IC" +elif [[ "${machine}" == "HERA" ]]; then + export BASE_CPLIC="/scratch1/NCEPDEV/climate/role.ufscpara/IC" +elif [[ "${machine}" == "ORION" ]]; then + export BASE_CPLIC="/work/noaa/global/glopara/data/ICSDIR/prototype_ICs" +elif [[ "${machine}" == "S4" ]]; then + export BASE_CPLIC="/data/prod/glopara/coupled_ICs" +elif [[ "${machine}" == "JET" ]]; then + export BASE_CPLIC="/mnt/lfs4/HFIP/hfv3gfs/glopara/data/ICSDIR/prototype_ICs" +fi + + +case "${CASE}" in + "C384") + #C384 and P8 ICs + export CPL_ATMIC=GEFS-NoahMP-aerosols-p8c + export CPL_ICEIC=CPC + export CPL_OCNIC=CPC3Dvar + export CPL_WAVIC=GEFSwave20210528v2 + ;; + "C768") + export CPL_ATMIC=HR1 + export CPL_ICEIC=HR1 + export CPL_OCNIC=HR1 + export CPL_WAVIC=HR1 + ;; + *) + echo "Unrecognized case: ${1}" + exit 1 + ;; +esac + +echo "END: config.coupled_ic" diff --git a/parm/config/config.defaults.s2sw b/parm/config/gfs/config.defaults.s2sw similarity index 100% rename from parm/config/config.defaults.s2sw rename to parm/config/gfs/config.defaults.s2sw diff --git a/parm/config/config.earc b/parm/config/gfs/config.earc similarity index 100% rename from parm/config/config.earc rename to parm/config/gfs/config.earc diff --git a/parm/config/config.ecen b/parm/config/gfs/config.ecen similarity index 100% rename from parm/config/config.ecen rename to parm/config/gfs/config.ecen diff --git a/parm/config/config.echgres b/parm/config/gfs/config.echgres similarity index 100% rename from parm/config/config.echgres rename to parm/config/gfs/config.echgres diff --git a/parm/config/config.ediag b/parm/config/gfs/config.ediag similarity index 100% rename from parm/config/config.ediag rename to parm/config/gfs/config.ediag diff --git a/parm/config/gfs/config.efcs b/parm/config/gfs/config.efcs new file mode 100644 index 0000000000..95c2cb58de --- /dev/null +++ b/parm/config/gfs/config.efcs @@ -0,0 +1,97 @@ +#! /usr/bin/env bash + +########## config.efcs ########## +# Ensemble forecast specific, dependency: config.fcst + +echo "BEGIN: config.efcs" + +# TODO: the _ENKF counterparts need to be defined in config.base +export DO_AERO=${DO_AERO_ENKF:-"NO"} +export DO_OCN=${DO_OCN_ENKF:-"NO"} +export DO_ICE=${DO_ICE_ENKF:-"NO"} +export DO_WAVE=${DO_WAVE_ENKF:-"NO"} + +# TODO: Possibly need OCNRES_ENKF, ICERES_ENKF, WAVRES_ENKF too +if [[ ${DO_OCN} == "YES" ]]; then + case "${CASE_ENS}" in + "C48") export OCNRES=500;; + "C96") export OCNRES=100;; + "C192") export OCNRES=050;; + "C384") export OCNRES=025;; + "C768") export OCNRES=025;; + *) export OCNRES=025;; + esac +fi +[[ ${DO_ICE} == "YES" ]] && export ICERES=$OCNRES +[[ ${DO_WAVE} == "YES" ]] && export waveGRD=${waveGRD_ENKF:-$waveGRD} # TODO: will we run waves with a different resolution in the ensemble? + +# Source model specific information that is resolution dependent +string="--fv3 ${CASE_ENS}" +[[ ${DO_OCN} == "YES" ]] && string="$string --mom6 $OCNRES" +[[ ${DO_ICE} == "YES" ]] && string="$string --cice6 $ICERES" +[[ ${DO_WAVE} == "YES" ]] && string="$string --ww3 ${waveGRD// /;}" +source $EXPDIR/config.ufs ${string} + +# Get task specific resources +. $EXPDIR/config.resources efcs + +# Use serial I/O for ensemble (lustre?) +export OUTPUT_FILETYPE_ATM="netcdf" +export OUTPUT_FILETYPE_SFC="netcdf" + +# Number of enkf members per fcst job +export NMEM_EFCSGRP=2 +export NMEM_EFCSGRP_GFS=1 +export RERUN_EFCSGRP="NO" + +# Turn off inline UPP for EnKF forecast +export WRITE_DOPOST=".false." + +# Stochastic physics parameters (only for ensemble forecasts) +export DO_SKEB="YES" +export SKEB=0.3 +export SKEB_TAU=21600. +export SKEB_LSCALE=250000. +export SKEBNORM=0 +export SKEB_NPASS=30 +export SKEB_VDOF=5 +export DO_SHUM="YES" +export SHUM=0.005 +export SHUM_TAU=21600. +export SHUM_LSCALE=500000. +export DO_SPPT="YES" +export SPPT=0.5 +export SPPT_TAU=21600. +export SPPT_LSCALE=500000. +export SPPT_LOGIT=".true." +export SPPT_SFCLIMIT=".true." + +if [ $QUILTING = ".true." -a $OUTPUT_GRID = "gaussian_grid" ]; then + export DIAG_TABLE="$HOMEgfs/parm/parm_fv3diag/diag_table_da" +else + export DIAG_TABLE="$HOMEgfs/parm/parm_fv3diag/diag_table_da_orig" +fi + +# FV3 model namelist parameters to over-ride +export restart_interval=${restart_interval:-6} + +# For IAU, write restarts at beginning of window also +if [ $DOIAU_ENKF = "YES" ]; then + export restart_interval="3 -1" +fi + +# wave model +export cplwav=.false. + +# ocean model resolution +case "${CASE_ENS}" in + "C48") export OCNRES=500;; + "C96") export OCNRES=100;; + "C192") export OCNRES=050;; + "C384") export OCNRES=025;; + "C768") export OCNRES=025;; + *) export OCNRES=025;; +esac +export ICERES=$OCNRES + +echo "END: config.efcs" diff --git a/parm/config/config.eobs b/parm/config/gfs/config.eobs similarity index 100% rename from parm/config/config.eobs rename to parm/config/gfs/config.eobs diff --git a/parm/config/config.epos b/parm/config/gfs/config.epos similarity index 100% rename from parm/config/config.epos rename to parm/config/gfs/config.epos diff --git a/parm/config/config.esfc b/parm/config/gfs/config.esfc similarity index 100% rename from parm/config/config.esfc rename to parm/config/gfs/config.esfc diff --git a/parm/config/config.eupd b/parm/config/gfs/config.eupd similarity index 100% rename from parm/config/config.eupd rename to parm/config/gfs/config.eupd diff --git a/parm/config/config.fcst b/parm/config/gfs/config.fcst similarity index 100% rename from parm/config/config.fcst rename to parm/config/gfs/config.fcst diff --git a/parm/config/config.fit2obs b/parm/config/gfs/config.fit2obs similarity index 100% rename from parm/config/config.fit2obs rename to parm/config/gfs/config.fit2obs diff --git a/parm/config/config.fv3.nco.static b/parm/config/gfs/config.fv3.nco.static similarity index 100% rename from parm/config/config.fv3.nco.static rename to parm/config/gfs/config.fv3.nco.static diff --git a/parm/config/config.gempak b/parm/config/gfs/config.gempak similarity index 100% rename from parm/config/config.gempak rename to parm/config/gfs/config.gempak diff --git a/parm/config/config.gldas b/parm/config/gfs/config.gldas similarity index 100% rename from parm/config/config.gldas rename to parm/config/gfs/config.gldas diff --git a/parm/config/config.ice b/parm/config/gfs/config.ice similarity index 100% rename from parm/config/config.ice rename to parm/config/gfs/config.ice diff --git a/parm/config/config.landanl b/parm/config/gfs/config.landanl similarity index 100% rename from parm/config/config.landanl rename to parm/config/gfs/config.landanl diff --git a/parm/config/config.landanlfinal b/parm/config/gfs/config.landanlfinal similarity index 100% rename from parm/config/config.landanlfinal rename to parm/config/gfs/config.landanlfinal diff --git a/parm/config/config.landanlinit b/parm/config/gfs/config.landanlinit similarity index 100% rename from parm/config/config.landanlinit rename to parm/config/gfs/config.landanlinit diff --git a/parm/config/config.landanlprep b/parm/config/gfs/config.landanlprep similarity index 100% rename from parm/config/config.landanlprep rename to parm/config/gfs/config.landanlprep diff --git a/parm/config/config.landanlrun b/parm/config/gfs/config.landanlrun similarity index 100% rename from parm/config/config.landanlrun rename to parm/config/gfs/config.landanlrun diff --git a/parm/config/config.metp b/parm/config/gfs/config.metp similarity index 100% rename from parm/config/config.metp rename to parm/config/gfs/config.metp diff --git a/parm/config/config.nsst b/parm/config/gfs/config.nsst similarity index 100% rename from parm/config/config.nsst rename to parm/config/gfs/config.nsst diff --git a/parm/config/config.ocn b/parm/config/gfs/config.ocn similarity index 100% rename from parm/config/config.ocn rename to parm/config/gfs/config.ocn diff --git a/parm/config/config.ocnanal b/parm/config/gfs/config.ocnanal similarity index 100% rename from parm/config/config.ocnanal rename to parm/config/gfs/config.ocnanal diff --git a/parm/config/config.ocnanalbmat b/parm/config/gfs/config.ocnanalbmat similarity index 100% rename from parm/config/config.ocnanalbmat rename to parm/config/gfs/config.ocnanalbmat diff --git a/parm/config/config.ocnanalchkpt b/parm/config/gfs/config.ocnanalchkpt similarity index 100% rename from parm/config/config.ocnanalchkpt rename to parm/config/gfs/config.ocnanalchkpt diff --git a/parm/config/config.ocnanalpost b/parm/config/gfs/config.ocnanalpost similarity index 100% rename from parm/config/config.ocnanalpost rename to parm/config/gfs/config.ocnanalpost diff --git a/parm/config/config.ocnanalprep b/parm/config/gfs/config.ocnanalprep similarity index 100% rename from parm/config/config.ocnanalprep rename to parm/config/gfs/config.ocnanalprep diff --git a/parm/config/config.ocnanalrun b/parm/config/gfs/config.ocnanalrun similarity index 100% rename from parm/config/config.ocnanalrun rename to parm/config/gfs/config.ocnanalrun diff --git a/parm/config/config.ocnanalvrfy b/parm/config/gfs/config.ocnanalvrfy similarity index 100% rename from parm/config/config.ocnanalvrfy rename to parm/config/gfs/config.ocnanalvrfy diff --git a/parm/config/config.ocnpost b/parm/config/gfs/config.ocnpost similarity index 100% rename from parm/config/config.ocnpost rename to parm/config/gfs/config.ocnpost diff --git a/parm/config/config.post b/parm/config/gfs/config.post similarity index 100% rename from parm/config/config.post rename to parm/config/gfs/config.post diff --git a/parm/config/config.postsnd b/parm/config/gfs/config.postsnd similarity index 100% rename from parm/config/config.postsnd rename to parm/config/gfs/config.postsnd diff --git a/parm/config/config.prep b/parm/config/gfs/config.prep similarity index 100% rename from parm/config/config.prep rename to parm/config/gfs/config.prep diff --git a/parm/config/gfs/config.resources b/parm/config/gfs/config.resources new file mode 100644 index 0000000000..3eb9c8535e --- /dev/null +++ b/parm/config/gfs/config.resources @@ -0,0 +1,979 @@ +#! /usr/bin/env bash + +########## config.resources ########## +# Set resource information for job tasks +# e.g. walltime, node, cores per node, memory etc. + +if [[ $# -ne 1 ]]; then + + echo "Must specify an input task argument to set resource variables!" + echo "argument can be any one of the following:" + echo "getic init coupled_ic aerosol_init" + echo "atmanlinit atmanlrun atmanlfinal" + echo "atmensanlinit atmensanlrun atmensanlfinal" + echo "landanlprep landanlinit landanlrun landanlfinal" + echo "aeroanlinit aeroanlrun aeroanlfinal" + echo "anal sfcanl analcalc analdiag gldas fcst post vrfy fit2obs metp arch echgres" + echo "eobs ediag eomg eupd ecen esfc efcs epos earc" + echo "init_chem mom6ic ocnpost" + echo "waveinit waveprep wavepostsbs wavepostbndpnt wavepostbndpntbll wavepostpnt" + echo "wavegempak waveawipsbulls waveawipsgridded" + echo "postsnd awips gempak" + echo "wafs wafsgrib2 wafsblending wafsgrib20p25 wafsblending0p25 wafsgcip" + echo "ocnanalprep ocnanalbmat ocnanalrun ocnanalchkpt ocnanalpost ocnanalvrfy" + exit 1 + +fi + +step=$1 + +echo "BEGIN: config.resources" + +if [[ "${machine}" = "WCOSS2" ]]; then + export npe_node_max=128 +elif [[ "${machine}" = "JET" ]]; then + if [[ ${PARTITION_BATCH} = "xjet" ]]; then + export npe_node_max=24 + elif [[ ${PARTITION_BATCH} = "vjet" || ${PARTITION_BATCH} = "sjet" ]]; then + export npe_node_max=16 + elif [[ ${PARTITION_BATCH} = "kjet" ]]; then + export npe_node_max=40 + fi +elif [[ ${machine} = "HERA" ]]; then + export npe_node_max=40 +elif [[ ${machine} = "S4" ]]; then + if [[ ${PARTITION_BATCH} = "s4" ]]; then + export npe_node_max=32 + elif [[ ${PARTITION_BATCH} = "ivy" ]]; then + export npe_node_max=20 + fi +elif [[ ${machine} = "ORION" ]]; then + export npe_node_max=40 +fi + +if [[ ${step} = "prep" ]]; then + export wtime_prep='00:30:00' + export npe_prep=4 + export npe_node_prep=2 + export nth_prep=1 + if [[ "${machine}" = "WCOSS2" ]]; then + export is_exclusive=True + else + export memory_prep="40G" + fi + +elif [[ "${step}" = "aerosol_init" ]]; then + export wtime_aerosol_init="00:05:00" + export npe_aerosol_init=1 + export nth_aerosol_init=1 + npe_node_aerosol_init=$(echo "${npe_node_max} / ${nth_aerosol_init}" | bc) + export npe_node_aerosol_init + export NTASKS=${npe_aerosol_init} + export memory_aerosol_init="6G" + +elif [[ ${step} = "waveinit" ]]; then + + export wtime_waveinit="00:10:00" + export npe_waveinit=12 + export nth_waveinit=1 + npe_node_waveinit=$(echo "${npe_node_max} / ${nth_waveinit}" | bc) + export npe_node_waveinit + export NTASKS=${npe_waveinit} + export memory_waveinit="2GB" + +elif [[ ${step} = "waveprep" ]]; then + + export wtime_waveprep="00:10:00" + export npe_waveprep=5 + export npe_waveprep_gfs=65 + export nth_waveprep=1 + export nth_waveprep_gfs=1 + npe_node_waveprep=$(echo "${npe_node_max} / ${nth_waveprep}" | bc) + export npe_node_waveprep + npe_node_waveprep_gfs=$(echo "${npe_node_max} / ${nth_waveprep_gfs}" | bc) + export npe_node_waveprep_gfs + export NTASKS=${npe_waveprep} + export NTASKS_gfs=${npe_waveprep_gfs} + export memory_waveprep="100GB" + export memory_waveprep_gfs="150GB" + +elif [[ ${step} = "wavepostsbs" ]]; then + + export wtime_wavepostsbs="00:20:00" + export wtime_wavepostsbs_gfs="03:00:00" + export npe_wavepostsbs=8 + export nth_wavepostsbs=1 + npe_node_wavepostsbs=$(echo "${npe_node_max} / ${nth_wavepostsbs}" | bc) + export npe_node_wavepostsbs + export NTASKS=${npe_wavepostsbs} + export memory_wavepostsbs="10GB" + export memory_wavepostsbs_gfs="10GB" + +elif [[ ${step} = "wavepostbndpnt" ]]; then + + export wtime_wavepostbndpnt="01:00:00" + export npe_wavepostbndpnt=240 + export nth_wavepostbndpnt=1 + npe_node_wavepostbndpnt=$(echo "${npe_node_max} / ${nth_wavepostbndpnt}" | bc) + export npe_node_wavepostbndpnt + export NTASKS=${npe_wavepostbndpnt} + export is_exclusive=True + +elif [[ ${step} = "wavepostbndpntbll" ]]; then + + export wtime_wavepostbndpntbll="01:00:00" + export npe_wavepostbndpntbll=448 + export nth_wavepostbndpntbll=1 + npe_node_wavepostbndpntbll=$(echo "${npe_node_max} / ${nth_wavepostbndpntbll}" | bc) + export npe_node_wavepostbndpntbll + export NTASKS=${npe_wavepostbndpntbll} + export is_exclusive=True + +elif [[ ${step} = "wavepostpnt" ]]; then + + export wtime_wavepostpnt="01:30:00" + export npe_wavepostpnt=200 + export nth_wavepostpnt=1 + npe_node_wavepostpnt=$(echo "${npe_node_max} / ${nth_wavepostpnt}" | bc) + export npe_node_wavepostpnt + export NTASKS=${npe_wavepostpnt} + export is_exclusive=True + +elif [[ ${step} = "wavegempak" ]]; then + + export wtime_wavegempak="02:00:00" + export npe_wavegempak=1 + export nth_wavegempak=1 + npe_node_wavegempak=$(echo "${npe_node_max} / ${nth_wavegempak}" | bc) + export npe_node_wavegempak + export NTASKS=${npe_wavegempak} + export memory_wavegempak="1GB" + +elif [[ ${step} = "waveawipsbulls" ]]; then + + export wtime_waveawipsbulls="00:20:00" + export npe_waveawipsbulls=1 + export nth_waveawipsbulls=1 + npe_node_waveawipsbulls=$(echo "${npe_node_max} / ${nth_waveawipsbulls}" | bc) + export npe_node_waveawipsbulls + export NTASKS=${npe_waveawipsbulls} + export is_exclusive=True + +elif [[ ${step} = "waveawipsgridded" ]]; then + + export wtime_waveawipsgridded="02:00:00" + export npe_waveawipsgridded=1 + export nth_waveawipsgridded=1 + npe_node_waveawipsgridded=$(echo "${npe_node_max} / ${nth_waveawipsgridded}" | bc) + export npe_node_waveawipsgridded + export NTASKS=${npe_waveawipsgridded} + export memory_waveawipsgridded_gfs="1GB" + +elif [[ "${step}" = "atmanlinit" ]]; then + + export wtime_atmanlinit="00:10:00" + export npe_atmanlinit=1 + export nth_atmanlinit=1 + npe_node_atmanlinit=$(echo "${npe_node_max} / ${nth_atmanlinit}" | bc) + export npe_node_atmanlinit + export memory_atmanlinit="3072M" + +elif [[ "${step}" = "atmanlrun" ]]; then + + # make below case dependent later + export layout_x=1 + export layout_y=1 + + export wtime_atmanlrun="00:30:00" + npe_atmanlrun=$(echo "${layout_x} * ${layout_y} * 6" | bc) + export npe_atmanlrun + npe_atmanlrun_gfs=$(echo "${layout_x} * ${layout_y} * 6" | bc) + export npe_atmanlrun_gfs + export nth_atmanlrun=1 + export nth_atmanlrun_gfs=${nth_atmanlrun} + npe_node_atmanlrun=$(echo "${npe_node_max} / ${nth_atmanlrun}" | bc) + export npe_node_atmanlrun + export is_exclusive=True + +elif [[ "${step}" = "atmanlfinal" ]]; then + + export wtime_atmanlfinal="00:30:00" + export npe_atmanlfinal=${npe_node_max} + export nth_atmanlfinal=1 + npe_node_atmanlfinal=$(echo "${npe_node_max} / ${nth_atmanlfinal}" | bc) + export npe_node_atmanlfinal + export is_exclusive=True + +elif [[ "${step}" = "landanlprep" || "${step}" = "landanlinit" || "${step}" = "landanlrun" || "${step}" = "landanlfinal" ]]; then + # below lines are for creating JEDI YAML + case ${CASE} in + C768) + layout_x=6 + layout_y=6 + ;; + C384) + layout_x=5 + layout_y=5 + ;; + C192 | C96 | C48) + layout_x=1 + layout_y=1 + ;; + *) + echo "FATAL ERROR: Resolution not supported for land analysis'" + exit 1 + esac + + export layout_x + export layout_y + + if [[ "${step}" = "landanlinit" || "${step}" = "landanlfinal" ]]; then + declare -x "wtime_${step}"="00:10:00" + declare -x "npe_${step}"=1 + declare -x "nth_${step}"=1 + temp_stepname="nth_${step}" + declare -x "npe_node_${step}"="$(echo "${npe_node_max} / ${!temp_stepname}" | bc)" + declare -x "memory_${step}"="3072M" + elif [[ "${step}" = "landanlrun" ]]; then + export wtime_landanlrun="00:30:00" + npe_landanlrun=$(echo "${layout_x} * ${layout_y} * 6" | bc) + export npe_landanlrun + export nth_landanlrun=1 + npe_node_landanlrun=$(echo "${npe_node_max} / ${nth_landanlrun}" | bc) + export npe_node_landanlrun + export is_exclusive=True + elif [[ "${step}" = "landanlprep" ]]; then + export wtime_landanlprep="00:30:00" + npe_landanlprep=$(echo "${layout_x} * ${layout_y} * 6" | bc) + export npe_landanlprep + export nth_landanlprep=1 + npe_node_landanlprep=$(echo "${npe_node_max} / ${nth_landanlprep}" | bc) + export npe_node_landanlprep + export is_exclusive=True + fi + +elif [[ "${step}" = "aeroanlinit" ]]; then + + # below lines are for creating JEDI YAML + case ${CASE} in + C768) + layout_x=6 + layout_y=6 + ;; + C384) + layout_x=5 + layout_y=5 + ;; + C192 | C96 | C48) + layout_x=8 + layout_y=8 + ;; + *) + echo "FATAL ERROR: Resolution not supported for aerosol analysis'" + exit 1 + esac + + export layout_x + export layout_y + + export wtime_aeroanlinit="00:10:00" + export npe_aeroanlinit=1 + export nth_aeroanlinit=1 + npe_node_aeroanlinit=$(echo "${npe_node_max} / ${nth_aeroanlinit}" | bc) + export npe_node_aeroanlinit + export memory_aeroanlinit="3072M" + +elif [[ "${step}" = "aeroanlrun" ]]; then + + case ${CASE} in + C768) + layout_x=6 + layout_y=6 + ;; + C384) + layout_x=5 + layout_y=5 + ;; + C192 | C96 | C48) + layout_x=8 + layout_y=8 + ;; + *) + echo "FATAL ERROR: Resolution ${CASE} is not supported, ABORT!" + exit 1 + esac + + export layout_x + export layout_y + + export wtime_aeroanlrun="00:30:00" + npe_aeroanlrun=$(echo "${layout_x} * ${layout_y} * 6" | bc) + export npe_aeroanlrun + npe_aeroanlrun_gfs=$(echo "${layout_x} * ${layout_y} * 6" | bc) + export npe_aeroanlrun_gfs + export nth_aeroanlrun=1 + export nth_aeroanlrun_gfs=1 + npe_node_aeroanlrun=$(echo "${npe_node_max} / ${nth_aeroanlrun}" | bc) + export npe_node_aeroanlrun + export is_exclusive=True + +elif [[ "${step}" = "aeroanlfinal" ]]; then + + export wtime_aeroanlfinal="00:10:00" + export npe_aeroanlfinal=1 + export nth_aeroanlfinal=1 + npe_node_aeroanlfinal=$(echo "${npe_node_max} / ${nth_aeroanlfinal}" | bc) + export npe_node_aeroanlfinal + export memory_aeroanlfinal="3072M" + +elif [[ "${step}" = "ocnanalprep" ]]; then + + export wtime_ocnanalprep="00:10:00" + export npe_ocnanalprep=1 + export nth_ocnanalprep=1 + npe_node_ocnanalprep=$(echo "${npe_node_max} / ${nth_ocnanalprep}" | bc) + export npe_node_ocnanalprep + export memory_ocnanalprep="24GB" + +elif [[ "${step}" = "ocnanalbmat" ]]; then + npes=16 + case ${CASE} in + C384) + npes=480 + ;; + C48) + npes=16 + ;; + *) + echo "FATAL: Resolution not supported'" + exit 1 + esac + + export wtime_ocnanalbmat="00:30:00" + export npe_ocnanalbmat=${npes} + export nth_ocnanalbmat=1 + export is_exclusive=True + npe_node_ocnanalbmat=$(echo "${npe_node_max} / ${nth_ocnanalbmat}" | bc) + export npe_node_ocnanalbmat + +elif [[ "${step}" = "ocnanalrun" ]]; then + npes=16 + case ${CASE} in + C384) + npes=480 + ;; + C48) + npes=16 + ;; + *) + echo "FATAL: Resolution not supported'" + exit 1 + esac + + export wtime_ocnanalrun="00:30:00" + export npe_ocnanalrun=${npes} + export nth_ocnanalrun=1 + export is_exclusive=True + npe_node_ocnanalrun=$(echo "${npe_node_max} / ${nth_ocnanalrun}" | bc) + export npe_node_ocnanalrun + +elif [[ "${step}" = "ocnanalchkpt" ]]; then + + export wtime_ocnanalchkpt="00:10:00" + export npe_ocnanalchkpt=1 + export nth_ocnanalchkpt=1 + npe_node_ocnanalchkpt=$(echo "${npe_node_max} / ${nth_ocnanalchkpt}" | bc) + export npe_node_ocnanalchkpt + case ${CASE} in + C384) + export memory_ocnanalchkpt="128GB" + ;; + C48) + export memory_ocnanalchkpt="32GB" + ;; + *) + echo "FATAL: Resolution not supported'" + exit 1 + esac + +elif [[ "${step}" = "ocnanalpost" ]]; then + + export wtime_ocnanalpost="00:30:00" + export npe_ocnanalpost=${npe_node_max} + export nth_ocnanalpost=1 + npe_node_ocnanalpost=$(echo "${npe_node_max} / ${nth_ocnanalpost}" | bc) + export npe_node_ocnanalpost + +elif [[ "${step}" = "ocnanalvrfy" ]]; then + + export wtime_ocnanalvrfy="00:35:00" + export npe_ocnanalvrfy=1 + export nth_ocnanalvrfy=1 + npe_node_ocnanalvrfy=$(echo "${npe_node_max} / ${nth_ocnanalvrfy}" | bc) + export npe_node_ocnanalvrfy + export memory_ocnanalvrfy="24GB" + +elif [[ ${step} = "anal" ]]; then + + export wtime_anal="00:50:00" + export wtime_anal_gfs="00:40:00" + export npe_anal=780 + export nth_anal=5 + export npe_anal_gfs=825 + export nth_anal_gfs=5 + if [[ "${machine}" = "WCOSS2" ]]; then + export nth_anal=8 + export nth_anal_gfs=8 + fi + if [[ ${CASE} = "C384" ]]; then + export npe_anal=160 + export npe_anal_gfs=160 + export nth_anal=10 + export nth_anal_gfs=10 + if [[ ${machine} = "S4" ]]; then + #On the S4-s4 partition, this is accomplished by increasing the task + #count to a multiple of 32 + if [[ ${PARTITION_BATCH} = "s4" ]]; then + export npe_anal=416 + export npe_anal_gfs=416 + fi + #S4 is small, so run this task with just 1 thread + export nth_anal=1 + export nth_anal_gfs=1 + export wtime_anal="02:00:00" + fi + fi + if [[ ${CASE} = "C192" || ${CASE} = "C96" || ${CASE} = "C48" ]]; then + export npe_anal=84 + export npe_anal_gfs=84 + if [[ ${machine} = "S4" ]]; then + export nth_anal=4 + export nth_anal_gfs=4 + #Adjust job count for S4 + if [[ ${PARTITION_BATCH} = "s4" ]]; then + export npe_anal=88 + export npe_anal_gfs=88 + elif [[ ${PARTITION_BATCH} = "ivy" ]]; then + export npe_anal=90 + export npe_anal_gfs=90 + fi + fi + fi + npe_node_anal=$(echo "${npe_node_max} / ${nth_anal}" | bc) + export npe_node_anal + export nth_cycle=${nth_anal} + npe_node_cycle=$(echo "${npe_node_max} / ${nth_cycle}" | bc) + export npe_node_cycle + export is_exclusive=True + +elif [[ ${step} = "analcalc" ]]; then + + export wtime_analcalc="00:10:00" + export npe_analcalc=127 + export ntasks="${npe_analcalc}" + export nth_analcalc=1 + export nth_echgres=4 + export nth_echgres_gfs=12 + npe_node_analcalc=$(echo "${npe_node_max} / ${nth_analcalc}" | bc) + export npe_node_analcalc + export is_exclusive=True + +elif [[ ${step} = "analdiag" ]]; then + + export wtime_analdiag="00:15:00" + export npe_analdiag=96 # Should be at least twice npe_ediag + export nth_analdiag=1 + npe_node_analdiag=$(echo "${npe_node_max} / ${nth_analdiag}" | bc) + export npe_node_analdiag + export memory_analdiag="48GB" + +elif [[ ${step} = "sfcanl" ]]; then + + export wtime_sfcanl="00:10:00" + export npe_sfcanl=6 + export nth_sfcanl=1 + npe_node_sfcanl=$(echo "${npe_node_max} / ${nth_sfcanl}" | bc) + export npe_node_sfcanl + export is_exclusive=True + +elif [[ ${step} = "gldas" ]]; then + + export wtime_gldas="00:10:00" + export npe_gldas=112 + export nth_gldas=1 + npe_node_gldas=$(echo "${npe_node_max} / ${nth_gldas}" | bc) + export npe_node_gldas + export npe_gaussian=96 + export nth_gaussian=1 + npe_node_gaussian=$(echo "${npe_node_max} / ${nth_gaussian}" | bc) + export npe_node_gaussian + export is_exclusive=True + +elif [[ "${step}" = "fcst" || "${step}" = "efcs" ]]; then + + export is_exclusive=True + + if [[ "${step}" = "fcst" ]]; then + _CDUMP_LIST=${CDUMP:-"gdas gfs"} + elif [[ "${step}" = "efcs" ]]; then + _CDUMP_LIST=${CDUMP:-"enkfgdas enkfgfs"} + fi + + # During workflow creation, we need resources for all CDUMPs and CDUMP is undefined + for _CDUMP in ${_CDUMP_LIST}; do + if [[ "${_CDUMP}" =~ "gfs" ]]; then + export layout_x=${layout_x_gfs} + export layout_y=${layout_y_gfs} + export WRITE_GROUP=${WRITE_GROUP_GFS} + export WRTTASK_PER_GROUP_PER_THREAD=${WRTTASK_PER_GROUP_PER_THREAD_GFS} + ntasks_fv3=${ntasks_fv3_gfs} + ntasks_quilt=${ntasks_quilt_gfs} + nthreads_fv3=${nthreads_fv3_gfs} + fi + + # PETS for the atmosphere dycore + (( FV3PETS = ntasks_fv3 * nthreads_fv3 )) + echo "FV3 using (nthreads, PETS) = (${nthreads_fv3}, ${FV3PETS})" + + # PETS for quilting + if [[ "${QUILTING:-}" = ".true." ]]; then + (( QUILTPETS = ntasks_quilt * nthreads_fv3 )) + (( WRTTASK_PER_GROUP = WRTTASK_PER_GROUP_PER_THREAD )) + export WRTTASK_PER_GROUP + else + QUILTPETS=0 + fi + echo "QUILT using (nthreads, PETS) = (${nthreads_fv3}, ${QUILTPETS})" + + # Total PETS for the atmosphere component + ATMTHREADS=${nthreads_fv3} + (( ATMPETS = FV3PETS + QUILTPETS )) + export ATMPETS ATMTHREADS + echo "FV3ATM using (nthreads, PETS) = (${ATMTHREADS}, ${ATMPETS})" + + # Total PETS for the coupled model (starting w/ the atmosphere) + NTASKS_TOT=${ATMPETS} + + # The mediator PETS can overlap with other components, usually it lands on the atmosphere tasks. + # However, it is suggested limiting mediator PETS to 300, as it may cause the slow performance. + # See https://docs.google.com/document/d/1bKpi-52t5jIfv2tuNHmQkYUe3hkKsiG_DG_s6Mnukog/edit + # TODO: Update reference when moved to ufs-weather-model RTD + MEDTHREADS=${nthreads_mediator:-1} + MEDPETS=${MEDPETS:-ATMPETS} + [[ "${MEDPETS}" -gt 300 ]] && MEDPETS=300 + export MEDPETS MEDTHREADS + echo "MEDIATOR using (threads, PETS) = (${MEDTHREADS}, ${MEDPETS})" + + if [[ "${DO_AERO}" = "YES" ]]; then + # GOCART shares the same grid and forecast tasks as FV3 (do not add write grid component tasks). + (( CHMTHREADS = ATMTHREADS )) + (( CHMPETS = FV3PETS )) + # Do not add to NTASKS_TOT + export CHMPETS CHMTHREADS + echo "GOCART using (threads, PETS) = (${CHMTHREADS}, ${CHMPETS})" + fi + + if [[ "${DO_WAVE}" = "YES" ]]; then + (( WAVPETS = ntasks_ww3 * nthreads_ww3 )) + (( WAVTHREADS = nthreads_ww3 )) + export WAVPETS WAVTHREADS + echo "WW3 using (threads, PETS) = (${WAVTHREADS}, ${WAVPETS})" + (( NTASKS_TOT = NTASKS_TOT + WAVPETS )) + fi + + if [[ "${DO_OCN}" = "YES" ]]; then + (( OCNPETS = ntasks_mom6 * nthreads_mom6 )) + (( OCNTHREADS = nthreads_mom6 )) + export OCNPETS OCNTHREADS + echo "MOM6 using (threads, PETS) = (${OCNTHREADS}, ${OCNPETS})" + (( NTASKS_TOT = NTASKS_TOT + OCNPETS )) + fi + + if [[ "${DO_ICE}" = "YES" ]]; then + (( ICEPETS = ntasks_cice6 * nthreads_cice6 )) + (( ICETHREADS = nthreads_cice6 )) + export ICEPETS ICETHREADS + echo "CICE6 using (threads, PETS) = (${ICETHREADS}, ${ICEPETS})" + (( NTASKS_TOT = NTASKS_TOT + ICEPETS )) + fi + + echo "Total PETS for ${_CDUMP} = ${NTASKS_TOT}" + + if [[ "${_CDUMP}" =~ "gfs" ]]; then + declare -x "npe_${step}_gfs"="${NTASKS_TOT}" + declare -x "nth_${step}_gfs"=1 # ESMF handles threading for the UFS-weather-model + declare -x "npe_node_${step}_gfs"="${npe_node_max}" + else + declare -x "npe_${step}"="${NTASKS_TOT}" + declare -x "nth_${step}"=1 # ESMF handles threading for the UFS-weather-model + declare -x "npe_node_${step}"="${npe_node_max}" + fi + + done + + case "${CASE}" in + "C48" | "C96" | "C192") + declare -x "wtime_${step}"="00:30:00" + declare -x "wtime_${step}_gfs"="03:00:00" + ;; + "C384" | "C768" | "C1152") + declare -x "wtime_${step}"="01:00:00" + declare -x "wtime_${step}_gfs"="06:00:00" + ;; + *) + echo "FATAL ERROR: Resolution ${CASE} not supported in ${step}" + exit 1 + ;; + esac + + unset _CDUMP _CDUMP_LIST + unset NTASKS_TOT + +elif [[ ${step} = "ocnpost" ]]; then + + export wtime_ocnpost="00:30:00" + export npe_ocnpost=1 + export npe_node_ocnpost=1 + export nth_ocnpost=1 + export memory_ocnpost="96G" + if [[ ${machine} == "JET" ]]; then + # JET only has 88GB of requestable memory per node + # so a second node is required to meet the requiremtn + npe_ocnpost=2 + fi + +elif [[ ${step} = "post" ]]; then + + export wtime_post="00:12:00" + export wtime_post_gfs="01:00:00" + export npe_post=126 + res=$(echo "${CASE}" | cut -c2-) + if (( npe_post > res )); then + export npe_post=${res} + fi + export nth_post=1 + export npe_node_post=${npe_post} + export npe_node_post_gfs=${npe_post} + export npe_node_dwn=${npe_node_max} + if [[ "${npe_node_post}" -gt "${npe_node_max}" ]]; then export npe_node_post=${npe_node_max} ; fi + if [[ "${npe_node_post_gfs}" -gt "${npe_node_max}" ]]; then export npe_node_post_gfs=${npe_node_max} ; fi + export is_exclusive=True + +elif [[ ${step} = "wafs" ]]; then + + export wtime_wafs="00:30:00" + export npe_wafs=1 + export npe_node_wafs=${npe_wafs} + export nth_wafs=1 + export memory_wafs="1GB" + +elif [[ ${step} = "wafsgcip" ]]; then + + export wtime_wafsgcip="00:30:00" + export npe_wafsgcip=2 + export nth_wafsgcip=1 + export npe_node_wafsgcip=1 + export memory_wafsgcip="50GB" + +elif [[ ${step} = "wafsgrib2" ]]; then + + export wtime_wafsgrib2="00:30:00" + export npe_wafsgrib2=18 + export nth_wafsgrib2=1 + npe_node_wafsgrib2=$(echo "${npe_node_max} / ${nth_wafsgrib2}" | bc) + export npe_node_wafsgrib2 + export memory_wafsgrib2="80GB" + +elif [[ ${step} = "wafsblending" ]]; then + + export wtime_wafsblending="00:30:00" + export npe_wafsblending=1 + export nth_wafsblending=1 + npe_node_wafsblending=$(echo "${npe_node_max} / ${nth_wafsblending}" | bc) + export npe_node_wafsblending + export memory_wafsblending="15GB" + +elif [[ ${step} = "wafsgrib20p25" ]]; then + + export wtime_wafsgrib20p25="00:30:00" + export npe_wafsgrib20p25=11 + export nth_wafsgrib20p25=1 + npe_node_wafsgrib20p25=$(echo "${npe_node_max} / ${nth_wafsgrib20p25}" | bc) + export npe_node_wafsgrib20p25 + export memory_wafsgrib20p25="80GB" + +elif [[ ${step} = "wafsblending0p25" ]]; then + + export wtime_wafsblending0p25="00:30:00" + export npe_wafsblending0p25=1 + export nth_wafsblending0p25=1 + npe_node_wafsblending0p25=$(echo "${npe_node_max} / ${nth_wafsblending0p25}" | bc) + export npe_node_wafsblending0p25 + export memory_wafsblending0p25="15GB" + +elif [[ ${step} = "vrfy" ]]; then + + export wtime_vrfy="03:00:00" + export wtime_vrfy_gfs="06:00:00" + export npe_vrfy=3 + export nth_vrfy=1 + export npe_node_vrfy=1 + export npe_vrfy_gfs=1 + export npe_node_vrfy_gfs=1 + if [[ ${machine} == "HERA" ]]; then + export memory_vrfy="16384M" + fi + export is_exclusive=True + +elif [[ "${step}" = "fit2obs" ]]; then + + export wtime_fit2obs="00:20:00" + export npe_fit2obs=3 + export nth_fit2obs=1 + export npe_node_fit2obs=1 + export memory_fit2obs="20G" + if [[ ${machine} == "WCOSS2" ]]; then export npe_node_fit2obs=3 ; fi + +elif [[ "${step}" = "metp" ]]; then + + export nth_metp=1 + export wtime_metp="03:00:00" + export npe_metp=4 + export npe_node_metp=4 + export wtime_metp_gfs="06:00:00" + export npe_metp_gfs=4 + export npe_node_metp_gfs=4 + export is_exclusive=True + +elif [[ ${step} = "echgres" ]]; then + + export wtime_echgres="00:10:00" + export npe_echgres=3 + export nth_echgres=${npe_node_max} + export npe_node_echgres=1 + if [[ "${machine}" = "WCOSS2" ]]; then + export memory_echgres="200GB" + fi + +elif [[ ${step} = "init" ]]; then + + export wtime_init="00:30:00" + export npe_init=24 + export nth_init=1 + export npe_node_init=6 + export memory_init="70G" + +elif [[ ${step} = "init_chem" ]]; then + + export wtime_init_chem="00:30:00" + export npe_init_chem=1 + export npe_node_init_chem=1 + export is_exclusive=True + +elif [[ ${step} = "mom6ic" ]]; then + + export wtime_mom6ic="00:30:00" + export npe_mom6ic=24 + export npe_node_mom6ic=24 + export is_exclusive=True + +elif [[ ${step} = "arch" || ${step} = "earc" || ${step} = "getic" ]]; then + + eval "export wtime_${step}='06:00:00'" + eval "export npe_${step}=1" + eval "export npe_node_${step}=1" + eval "export nth_${step}=1" + eval "export memory_${step}=4096M" + if [[ "${machine}" = "WCOSS2" ]]; then + eval "export memory_${step}=50GB" + fi + +elif [[ ${step} = "coupled_ic" ]]; then + + export wtime_coupled_ic="00:15:00" + export npe_coupled_ic=1 + export npe_node_coupled_ic=1 + export nth_coupled_ic=1 + export is_exclusive=True + +elif [[ "${step}" = "atmensanlinit" ]]; then + + export wtime_atmensanlinit="00:10:00" + export npe_atmensanlinit=1 + export nth_atmensanlinit=1 + npe_node_atmensanlinit=$(echo "${npe_node_max} / ${nth_atmensanlinit}" | bc) + export npe_node_atmensanlinit + export memory_atmensanlinit="3072M" + +elif [[ "${step}" = "atmensanlrun" ]]; then + + # make below case dependent later + export layout_x=1 + export layout_y=1 + + export wtime_atmensanlrun="00:30:00" + npe_atmensanlrun=$(echo "${layout_x} * ${layout_y} * 6" | bc) + export npe_atmensanlrun + npe_atmensanlrun_gfs=$(echo "${layout_x} * ${layout_y} * 6" | bc) + export npe_atmensanlrun_gfs + export nth_atmensanlrun=1 + export nth_atmensanlrun_gfs=${nth_atmensanlrun} + npe_node_atmensanlrun=$(echo "${npe_node_max} / ${nth_atmensanlrun}" | bc) + export npe_node_atmensanlrun + export is_exclusive=True + +elif [[ "${step}" = "atmensanlfinal" ]]; then + + export wtime_atmensanlfinal="00:30:00" + export npe_atmensanlfinal=${npe_node_max} + export nth_atmensanlfinal=1 + npe_node_atmensanlfinal=$(echo "${npe_node_max} / ${nth_atmensanlfinal}" | bc) + export npe_node_atmensanlfinal + export is_exclusive=True + +elif [[ ${step} = "eobs" || ${step} = "eomg" ]]; then + + export wtime_eobs="00:15:00" + export wtime_eomg="01:00:00" + if [[ ${CASE} = "C768" ]]; then + export npe_eobs=200 + elif [[ ${CASE} = "C384" ]]; then + export npe_eobs=100 + elif [[ ${CASE} = "C192" || ${CASE} = "C96" || ${CASE} = "C48" ]]; then + export npe_eobs=40 + fi + export npe_eomg=${npe_eobs} + export nth_eobs=2 + export nth_eomg=${nth_eobs} + npe_node_eobs=$(echo "${npe_node_max} / ${nth_eobs}" | bc) + export npe_node_eobs + export npe_node_eomg=${npe_node_eobs} + export is_exclusive=True + #The number of tasks and cores used must be the same for eobs + #For S4, this is accomplished by running 10 tasks/node + if [[ ${machine} = "S4" ]]; then + export npe_node_eobs=10 + fi + +elif [[ ${step} = "ediag" ]]; then + + export wtime_ediag="00:15:00" + export npe_ediag=48 + export nth_ediag=1 + npe_node_ediag=$(echo "${npe_node_max} / ${nth_ediag}" | bc) + export npe_node_ediag + export memory_ediag="30GB" + +elif [[ ${step} = "eupd" ]]; then + + export wtime_eupd="00:30:00" + if [[ ${CASE} = "C768" ]]; then + export npe_eupd=480 + export nth_eupd=6 + if [[ "${machine}" = "WCOSS2" ]]; then + export npe_eupd=315 + export nth_eupd=14 + fi + elif [[ ${CASE} = "C384" ]]; then + export npe_eupd=270 + export nth_eupd=2 + if [[ "${machine}" = "WCOSS2" ]]; then + export npe_eupd=315 + export nth_eupd=14 + elif [[ "${machine}" = "HERA" || "${machine}" = "JET" ]]; then + export nth_eupd=8 + elif [[ ${machine} = "S4" ]]; then + export npe_eupd=160 + export nth_eupd=2 + fi + elif [[ ${CASE} = "C192" || ${CASE} = "C96" || ${CASE} = "C48" ]]; then + export npe_eupd=42 + export nth_eupd=2 + if [[ "${machine}" = "HERA" || "${machine}" = "JET" ]]; then + export nth_eupd=4 + fi + fi + npe_node_eupd=$(echo "${npe_node_max} / ${nth_eupd}" | bc) + export npe_node_eupd + export is_exclusive=True + +elif [[ ${step} = "ecen" ]]; then + + export wtime_ecen="00:10:00" + export npe_ecen=80 + export nth_ecen=4 + if [[ "${machine}" = "HERA" ]]; then export nth_ecen=6; fi + if [[ ${CASE} = "C384" || ${CASE} = "C192" || ${CASE} = "C96" || ${CASE} = "C48" ]]; then export nth_ecen=2; fi + npe_node_ecen=$(echo "${npe_node_max} / ${nth_ecen}" | bc) + export npe_node_ecen + export nth_cycle=${nth_ecen} + npe_node_cycle=$(echo "${npe_node_max} / ${nth_cycle}" | bc) + export npe_node_cycle + export is_exclusive=True + +elif [[ ${step} = "esfc" ]]; then + + export wtime_esfc="00:06:00" + export npe_esfc=80 + export nth_esfc=1 + npe_node_esfc=$(echo "${npe_node_max} / ${nth_esfc}" | bc) + export npe_node_esfc + export nth_cycle=${nth_esfc} + npe_node_cycle=$(echo "${npe_node_max} / ${nth_cycle}" | bc) + export npe_node_cycle + export memory_esfc="80GB" + +elif [[ ${step} = "epos" ]]; then + + export wtime_epos="00:15:00" + export npe_epos=80 + export nth_epos=4 + if [[ "${machine}" == "HERA" ]]; then + export nth_epos=6 + fi + npe_node_epos=$(echo "${npe_node_max} / ${nth_epos}" | bc) + export npe_node_epos + export is_exclusive=True + +elif [[ ${step} = "postsnd" ]]; then + + export wtime_postsnd="02:00:00" + export npe_postsnd=40 + export nth_postsnd=8 + export npe_node_postsnd=10 + export npe_postsndcfp=9 + export npe_node_postsndcfp=1 + postsnd_req_cores=$(echo "${npe_node_postsnd} * ${nth_postsnd}" | bc) + if [[ ${postsnd_req_cores} -gt "${npe_node_max}" ]]; then + npe_node_postsnd=$(echo "${npe_node_max} / ${nth_postsnd}" | bc) + export npe_node_postsnd + fi + export is_exclusive=True + +elif [[ ${step} = "awips" ]]; then + + export wtime_awips="03:30:00" + export npe_awips=1 + export npe_node_awips=1 + export nth_awips=1 + export memory_awips="3GB" + +elif [[ ${step} = "gempak" ]]; then + + export wtime_gempak="03:00:00" + export npe_gempak=2 + export npe_gempak_gfs=28 + export npe_node_gempak=2 + export npe_node_gempak_gfs=28 + export nth_gempak=1 + export memory_gempak="4GB" + export memory_gempak_gfs="2GB" + +else + + echo "Invalid step = ${step}, ABORT!" + exit 2 + +fi + +echo "END: config.resources" diff --git a/parm/config/config.resources.nco.static b/parm/config/gfs/config.resources.nco.static similarity index 100% rename from parm/config/config.resources.nco.static rename to parm/config/gfs/config.resources.nco.static diff --git a/parm/config/config.sfcanl b/parm/config/gfs/config.sfcanl similarity index 100% rename from parm/config/config.sfcanl rename to parm/config/gfs/config.sfcanl diff --git a/parm/config/gfs/config.ufs b/parm/config/gfs/config.ufs new file mode 100644 index 0000000000..a96ba126e2 --- /dev/null +++ b/parm/config/gfs/config.ufs @@ -0,0 +1,370 @@ +#! /usr/bin/env bash + +########## config.ufs ########## +# UFS model resolution specific parameters +# e.g. time-step, processor layout, physics and dynamics parameters +# This config sets default variables for FV3, MOM6, CICE6 for their resolutions +# User can over-ride after sourcing this config file + +echo "BEGIN: config.ufs" + +if [ $# -le 1 ]; then + + echo "Must specify an input resolution argument to set variables!" + echo "argument can be any one of the following:" + echo "--fv3 C48|C96|C192|C384|C768|C1152|C3072" + echo "--mom6 500|100|025" + echo "--cice6 500|100|025" + echo "--ww3 gnh_10m;aoc_9km;gsh_15m|gwes_30m|mx050|mx025" + + exit 1 + +fi + +# Initialize +skip_mom6=true +skip_cice6=true +skip_ww3=true +skip_mediator=true + +# Loop through named arguments +while [[ $# -gt 0 ]]; do + key="$1" + case "${key}" in + "--fv3") + fv3_res="$2" + ;; + "--mom6") + mom6_res="$2" + skip_mom6=false + ;; + "--cice6") + cice6_res="$2" + skip_cice6=false + ;; + "--ww3") + ww3_res="$2" + skip_ww3=false + ;; + *) # unknown option + echo "FATAL ERROR: Unknown option: ${key}, ABORT!" + exit 1 + ;; + esac + shift + shift +done + +# Mediator is required if any of the non-ATM components are used +if [[ "${skip_mom6}" == "false" ]] || [[ "${skip_cice6}" == "false" ]] || [[ "${skip_ww3}" == "false" ]]; then + skip_mediator=false +fi + +case "${machine}" in + "WCOSS2") + npe_node_max=128 + ;; + "HERA" | "ORION") + npe_node_max=40 + ;; + "JET") + case "${PARTITION_BATCH}" in + "xjet") + npe_node_max=24 + ;; + "vjet" | "sjet") + npe_node_max=16 + ;; + "kjet") + npe_node_max=40 + ;; + *) + echo "FATAL ERROR: Unsupported ${machine} PARTITION_BATCH = ${PARTITION_BATCH}, ABORT!" + exit 1 + ;; + esac + ;; + "S4") + case "${PARTITION_BATCH}" in + "s4") + npe_node_max=32 + ;; + "ivy") + npe_node_max=20 + ;; + *) + echo "FATAL ERROR: Unsupported ${machine} PARTITION_BATCH = ${PARTITION_BATCH}, ABORT!" + exit 1 + ;; + esac + ;; +esac +export npe_node_max + +# (Standard) Model resolution dependent variables +case "${fv3_res}" in + "C48") + export DELTIM=1200 + export layout_x=1 + export layout_y=1 + export layout_x_gfs=1 + export layout_y_gfs=1 + export nthreads_fv3=1 + export nthreads_fv3_gfs=1 + export cdmbgwd="0.071,2.1,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export WRITE_GROUP=1 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=1 + export WRITE_GROUP_GFS=1 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=1 + ;; + "C96") + export DELTIM=600 + export layout_x=2 + export layout_y=2 + export layout_x_gfs=2 + export layout_y_gfs=2 + export nthreads_fv3=1 + export nthreads_fv3_gfs=1 + export cdmbgwd="0.14,1.8,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export WRITE_GROUP=1 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=1 + export WRITE_GROUP_GFS=1 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=1 + ;; + "C192") + export DELTIM=450 + export layout_x=4 + export layout_y=6 + export layout_x_gfs=4 + export layout_y_gfs=6 + export nthreads_fv3=1 + export nthreads_fv3_gfs=2 + export cdmbgwd="0.23,1.5,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export WRITE_GROUP=1 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 + export WRITE_GROUP_GFS=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=5 + ;; + "C384") + export DELTIM=300 + export layout_x=6 + export layout_y=8 + export layout_x_gfs=8 + export layout_y_gfs=8 + export nthreads_fv3=1 + export nthreads_fv3_gfs=2 + export cdmbgwd="1.1,0.72,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export WRITE_GROUP=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=8 + export WRITE_GROUP_GFS=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=4 + ;; + "C768") + export DELTIM=150 + export layout_x=8 + export layout_y=12 + export layout_x_gfs=12 + export layout_y_gfs=16 + export nthreads_fv3=4 + export nthreads_fv3_gfs=4 + export cdmbgwd="4.0,0.15,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export WRITE_GROUP=2 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 + export WRITE_GROUP_GFS=4 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=10 + ;; + "C1152") + export DELTIM=120 + export layout_x=8 + export layout_y=16 + export layout_x_gfs=8 + export layout_y_gfs=16 + export nthreads_fv3=4 + export nthreads_fv3_gfs=4 + export cdmbgwd="4.0,0.10,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export WRITE_GROUP=4 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 # TODO: refine these numbers when a case is available + export WRITE_GROUP_GFS=4 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=10 # TODO: refine these numbers when a case is available + ;; + "C3072") + export DELTIM=90 + export layout_x=16 + export layout_y=32 + export layout_x_gfs=16 + export layout_y_gfs=32 + export nthreads_fv3=4 + export nthreads_fv3_gfs=4 + export cdmbgwd="4.0,0.05,1.0,1.0" # mountain blocking, ogwd, cgwd, cgwd src scaling + export WRITE_GROUP=4 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE=10 # TODO: refine these numbers when a case is available + export WRITE_GROUP_GFS=4 + export WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS=10 # TODO: refine these numbers when a case is available + ;; + *) + echo "FATAL ERROR: Unsupported FV3 resolution = ${fv3_res}, ABORT!" + exit 1 + ;; +esac + +(( WRTTASK_PER_GROUP_PER_THREAD = WRTTASK_PER_GROUP_PER_THREAD_PER_TILE * 6 )) +(( WRTTASK_PER_GROUP_PER_THREAD_GFS = WRTTASK_PER_GROUP_PER_THREAD_PER_TILE_GFS * 6 )) +export WRTTASK_PER_GROUP_PER_THREAD +export WRTTASK_PER_GROUP_PER_THREAD_GFS + +(( ntasks_fv3 = layout_x * layout_y * 6 )) +(( ntasks_fv3_gfs = layout_x_gfs * layout_y_gfs * 6 )) +export ntasks_fv3 +export ntasks_fv3_gfs + +(( ntasks_quilt = WRITE_GROUP * WRTTASK_PER_GROUP_PER_THREAD )) +(( ntasks_quilt_gfs = WRITE_GROUP_GFS * WRTTASK_PER_GROUP_PER_THREAD_GFS )) +export ntasks_quilt +export ntasks_quilt_gfs + +# Determine whether to use parallel NetCDF based on resolution +case ${fv3_res} in + "C48" | "C96" | "C192" | "C384") + OUTPUT_FILETYPE_ATM="netcdf" + OUTPUT_FILETYPE_SFC="netcdf" + ;; + "C768" | "C1152" | "C3072") + OUTPUT_FILETYPE_ATM="netcdf_parallel" + OUTPUT_FILETYPE_SFC="netcdf_parallel" + ;; +esac +export OUTPUT_FILETYPE_ATM OUTPUT_FILETYPE_SFC + +# Mediator specific settings +if [[ "${skip_mediator}" == "false" ]]; then + export nthreads_mediator=${nthreads_fv3} # Use same threads as FV3 +fi + +# MOM6 specific settings +if [[ "${skip_mom6}" == "false" ]]; then + nthreads_mom6=1 + case "${mom6_res}" in + "500") + ntasks_mom6=8 + OCNTIM=3600 + NX_GLB=72 + NY_GLB=35 + DT_DYNAM_MOM6='3600' + DT_THERM_MOM6='3600' + FRUNOFF="" + CHLCLIM="seawifs_1998-2006_smoothed_2X.nc" + MOM6_RESTART_SETTING='r' + MOM6_RIVER_RUNOFF='False' + ;; + "100") + ntasks_mom6=20 + OCNTIM=3600 + NX_GLB=360 + NY_GLB=320 + DT_DYNAM_MOM6='1800' + DT_THERM_MOM6='3600' + FRUNOFF="" + CHLCLIM="seawifs_1998-2006_smoothed_2X.nc" + MOM6_RESTART_SETTING='n' + MOM6_RIVER_RUNOFF='False' + ;; + "50") + ntasks_mom6=60 + OCNTIM=3600 + NX_GLB=720 + NY_GLB=576 + DT_DYNAM_MOM6='1800' + DT_THERM_MOM6='3600' + FRUNOFF="runoff.daitren.clim.${NX_GLB}x${NY_GLB}.v20180328.nc" + CHLCLIM="seawifs-clim-1997-2010.${NX_GLB}x${NY_GLB}.v20180328.nc" + MOM6_RESTART_SETTING='n' + MOM6_RIVER_RUNOFF='True' + ;; + "025") + ntasks_mom6=220 + OCNTIM=1800 + NX_GLB=1440 + NY_GLB=1080 + DT_DYNAM_MOM6='900' + DT_THERM_MOM6='1800' + FRUNOFF="runoff.daitren.clim.${NX_GLB}x${NY_GLB}.v20180328.nc" + CHLCLIM="seawifs-clim-1997-2010.${NX_GLB}x${NY_GLB}.v20180328.nc" + MOM6_RIVER_RUNOFF='True' + MOM6_RESTART_SETTING="r" + ;; + *) + echo "FATAL ERROR: Unsupported MOM6 resolution = ${mom6_res}, ABORT!" + exit 1 + ;; + esac + export nthreads_mom6 ntasks_mom6 + export OCNTIM + export NX_GLB NY_GLB + export DT_DYNAM_MOM6 DT_THERM_MOM6 + export FRUNOFF + export CHLCLIM + export MOM6_RIVER_RUNOFF + export MOM6_RESTART_SETTING +fi + +# CICE6 specific settings +if [[ "${skip_cice6}" == "false" ]]; then + # Ensure we sourced the MOM6 section + if [[ "${skip_mom6}" == "true" ]]; then + echo "FATAL ERROR: CICE6 cannot be configured without MOM6, ABORT!" + exit 1 + fi + nthreads_cice6=${nthreads_mom6} # CICE6 needs to run on same threads as MOM6 + case "${cice6_res}" in + "500") + ntasks_cice6=4 + cice6_processor_shape="slenderX1" + ;; + "100") + ntasks_cice6=10 + cice6_processor_shape="slenderX2" + ;; + "050") + ntasks_cice6=30 + cice6_processor_shape="slenderX2" + ;; + "025") + ntasks_cice6=120 + cice6_processor_shape="slenderX2" + ;; + *) + echo "FATAL ERROR: Unsupported CICE6 resolution = ${cice6_res}, ABORT!" + exit 1 + ;; + esac + # NX_GLB and NY_GLB are set in the MOM6 section above + # CICE6 runs on the same domain decomposition as MOM6 + export nthreads_cice6 ntasks_cice6 + export cice6_processor_shape +fi + +# WW3 specific settings +if [[ "${skip_ww3}" == "false" ]]; then + nthreads_ww3=2 + case "${ww3_res}" in + "gnh_10m;aoc_9km;gsh_15m") + ntasks_ww3=140 + ;; + "gwes_30m") + ntasks_ww3=100 + ;; + "mx050") + ntasks_ww3=240 + ;; + "mx025") + ntasks_ww3=80 + ;; + *) + echo "FATAL ERROR: Unsupported WW3 resolution = ${ww3_res}, ABORT!" + exit 1 + ;; + esac + export ntasks_ww3 nthreads_ww3 +fi + +echo "END: config.ufs" diff --git a/parm/config/config.vrfy b/parm/config/gfs/config.vrfy similarity index 100% rename from parm/config/config.vrfy rename to parm/config/gfs/config.vrfy diff --git a/parm/config/config.wafs b/parm/config/gfs/config.wafs similarity index 100% rename from parm/config/config.wafs rename to parm/config/gfs/config.wafs diff --git a/parm/config/config.wafsblending b/parm/config/gfs/config.wafsblending similarity index 100% rename from parm/config/config.wafsblending rename to parm/config/gfs/config.wafsblending diff --git a/parm/config/config.wafsblending0p25 b/parm/config/gfs/config.wafsblending0p25 similarity index 100% rename from parm/config/config.wafsblending0p25 rename to parm/config/gfs/config.wafsblending0p25 diff --git a/parm/config/config.wafsgcip b/parm/config/gfs/config.wafsgcip similarity index 100% rename from parm/config/config.wafsgcip rename to parm/config/gfs/config.wafsgcip diff --git a/parm/config/config.wafsgrib2 b/parm/config/gfs/config.wafsgrib2 similarity index 100% rename from parm/config/config.wafsgrib2 rename to parm/config/gfs/config.wafsgrib2 diff --git a/parm/config/config.wafsgrib20p25 b/parm/config/gfs/config.wafsgrib20p25 similarity index 100% rename from parm/config/config.wafsgrib20p25 rename to parm/config/gfs/config.wafsgrib20p25 diff --git a/parm/config/config.wave b/parm/config/gfs/config.wave similarity index 100% rename from parm/config/config.wave rename to parm/config/gfs/config.wave diff --git a/parm/config/config.waveawipsbulls b/parm/config/gfs/config.waveawipsbulls similarity index 100% rename from parm/config/config.waveawipsbulls rename to parm/config/gfs/config.waveawipsbulls diff --git a/parm/config/config.waveawipsgridded b/parm/config/gfs/config.waveawipsgridded similarity index 100% rename from parm/config/config.waveawipsgridded rename to parm/config/gfs/config.waveawipsgridded diff --git a/parm/config/config.wavegempak b/parm/config/gfs/config.wavegempak similarity index 100% rename from parm/config/config.wavegempak rename to parm/config/gfs/config.wavegempak diff --git a/parm/config/config.waveinit b/parm/config/gfs/config.waveinit similarity index 100% rename from parm/config/config.waveinit rename to parm/config/gfs/config.waveinit diff --git a/parm/config/config.wavepostbndpnt b/parm/config/gfs/config.wavepostbndpnt similarity index 100% rename from parm/config/config.wavepostbndpnt rename to parm/config/gfs/config.wavepostbndpnt diff --git a/parm/config/config.wavepostbndpntbll b/parm/config/gfs/config.wavepostbndpntbll similarity index 100% rename from parm/config/config.wavepostbndpntbll rename to parm/config/gfs/config.wavepostbndpntbll diff --git a/parm/config/config.wavepostpnt b/parm/config/gfs/config.wavepostpnt similarity index 100% rename from parm/config/config.wavepostpnt rename to parm/config/gfs/config.wavepostpnt diff --git a/parm/config/config.wavepostsbs b/parm/config/gfs/config.wavepostsbs similarity index 100% rename from parm/config/config.wavepostsbs rename to parm/config/gfs/config.wavepostsbs diff --git a/parm/config/config.waveprep b/parm/config/gfs/config.waveprep similarity index 100% rename from parm/config/config.waveprep rename to parm/config/gfs/config.waveprep diff --git a/parm/config/yaml/defaults.yaml b/parm/config/gfs/yaml/defaults.yaml similarity index 100% rename from parm/config/yaml/defaults.yaml rename to parm/config/gfs/yaml/defaults.yaml diff --git a/scripts/exgdas_enkf_earc.sh b/scripts/exgdas_enkf_earc.sh index 79e43d1a17..8f1928042f 100755 --- a/scripts/exgdas_enkf_earc.sh +++ b/scripts/exgdas_enkf_earc.sh @@ -196,8 +196,8 @@ if [[ "${ENSGRP}" -eq 0 ]]; then set_strict if [ "${rc}" -eq 0 ]; then case ${CDUMP} in - gdas) nmem=${NMEM_ENKF};; - gfs) nmem=${NMEM_EFCS};; + gdas) nmem="${NMEM_ENS}";; + gfs) nmem="${NMEM_ENS_GFS}";; *) echo "FATAL ERROR: Unknown CDUMP ${CDUMP} during cleanup" exit 10 diff --git a/scripts/exgdas_enkf_ecen.sh b/scripts/exgdas_enkf_ecen.sh index 3d54cf001f..de603cba3f 100755 --- a/scripts/exgdas_enkf_ecen.sh +++ b/scripts/exgdas_enkf_ecen.sh @@ -52,7 +52,7 @@ GPREFIX=${GPREFIX:-""} GPREFIX_ENS=${GPREFIX_ENS:-$GPREFIX} # Variables -NMEM_ENKF=${NMEM_ENKF:-80} +NMEM_ENS=${NMEM_ENS:-80} imp_physics=${imp_physics:-99} INCREMENTS_TO_ZERO=${INCREMENTS_TO_ZERO:-"'NONE'"} DOIAU=${DOIAU_ENKF:-"NO"} @@ -108,7 +108,7 @@ ENKF_SUFFIX="s" # Link ensemble member guess, analysis and increment files for FHR in $(seq $FHMIN $FHOUT $FHMAX); do -for imem in $(seq 1 $NMEM_ENKF); do +for imem in $(seq 1 $NMEM_ENS); do memchar="mem"$(printf %03i $imem) MEMDIR=${memchar} YMD=${PDY} HH=${cyc} generate_com -x \ @@ -166,7 +166,7 @@ if [ $DO_CALC_INCREMENT = "YES" ]; then . prep_step $NCP $GETATMENSMEANEXEC $DATA - $APRUN_ECEN ${DATA}/$(basename $GETATMENSMEANEXEC) $DATAPATH $ATMANLMEANNAME $ATMANLNAME $NMEM_ENKF + $APRUN_ECEN ${DATA}/$(basename $GETATMENSMEANEXEC) $DATAPATH $ATMANLMEANNAME $ATMANLNAME $NMEM_ENS export err=$?; err_chk else # Link ensemble mean increment @@ -186,7 +186,7 @@ else . prep_step $NCP $GETATMENSMEANEXEC $DATA - $APRUN_ECEN ${DATA}/$(basename $GETATMENSMEANEXEC) $DATAPATH $ATMINCMEANNAME $ATMINCNAME $NMEM_ENKF + $APRUN_ECEN ${DATA}/$(basename $GETATMENSMEANEXEC) $DATAPATH $ATMINCMEANNAME $ATMINCNAME $NMEM_ENS export err=$?; err_chk # If available, link to ensemble mean guess. Otherwise, compute ensemble mean guess @@ -202,7 +202,7 @@ else . prep_step $NCP $GETATMENSMEANEXEC $DATA - $APRUN_ECEN ${DATA}/$(basename $GETATMENSMEANEXEC) $DATAPATH $ATMGESMEANNAME $ATMGESNAME $NMEM_ENKF + $APRUN_ECEN ${DATA}/$(basename $GETATMENSMEANEXEC) $DATAPATH $ATMGESMEANNAME $ATMGESNAME $NMEM_ENS export err=$?; err_chk fi fi @@ -279,7 +279,7 @@ EOF . prep_step $NCP $RECENATMEXEC $DATA - $APRUN_ECEN ${DATA}/$(basename $RECENATMEXEC) $FILENAMEIN $FILENAME_MEANIN $FILENAME_MEANOUT $FILENAMEOUT $NMEM_ENKF + $APRUN_ECEN ${DATA}/$(basename $RECENATMEXEC) $FILENAMEIN $FILENAME_MEANIN $FILENAME_MEANOUT $FILENAMEOUT $NMEM_ENS export err=$?; err_chk else ################################################################################ @@ -307,7 +307,7 @@ cat recenter.nml . prep_step $NCP $RECENATMEXEC $DATA - $APRUN_ECEN ${DATA}/$(basename $RECENATMEXEC) $FILENAMEIN $FILENAME_INCMEANIN $FILENAME_GSIDET $FILENAMEOUT $NMEM_ENKF $FILENAME_GESMEANIN + $APRUN_ECEN ${DATA}/$(basename $RECENATMEXEC) $FILENAMEIN $FILENAME_INCMEANIN $FILENAME_GSIDET $FILENAMEOUT $NMEM_ENS $FILENAME_GESMEANIN export err=$?; err_chk fi fi @@ -336,7 +336,7 @@ if [ $DO_CALC_INCREMENT = "YES" ]; then firstguess_filename = 'atmges' increment_filename = 'atminc' debug = .false. - nens = $NMEM_ENKF + nens = $NMEM_ENS imp_physics = $imp_physics / &zeroinc diff --git a/scripts/exgdas_enkf_fcst.sh b/scripts/exgdas_enkf_fcst.sh index fae4dde7f3..bc126d5906 100755 --- a/scripts/exgdas_enkf_fcst.sh +++ b/scripts/exgdas_enkf_fcst.sh @@ -88,7 +88,7 @@ export TYPE=${TYPE_ENKF:-${TYPE:-nh}} # choices: nh, hydro export MONO=${MONO_ENKF:-${MONO:-non-mono}} # choices: mono, non-mono # fv_core_nml -export CASE=${CASE_ENKF:-${CASE:-C768}} +export CASE=${CASE_ENS:-${CASE:-C768}} export layout_x=${layout_x_ENKF:-${layout_x:-8}} export layout_y=${layout_y_ENKF:-${layout_y:-16}} export LEVS=${LEVS_ENKF:-${LEVS:-64}} diff --git a/scripts/exgdas_enkf_post.sh b/scripts/exgdas_enkf_post.sh index 0bdea980ec..86ab9071a4 100755 --- a/scripts/exgdas_enkf_post.sh +++ b/scripts/exgdas_enkf_post.sh @@ -47,9 +47,9 @@ FHMAX=${FHMAX_EPOS:-9} FHOUT=${FHOUT_EPOS:-3} if [[ $CDUMP == "gfs" ]]; then - NMEM_ENKF=${NMEM_EFCS:-${NMEM_ENKF:-30}} + NMEM_ENS=${NMEM_ENS_GFS:-${NMEM_ENS:-30}} fi -NMEM_ENKF=${NMEM_ENKF:-80} +NMEM_ENS=${NMEM_ENS:-80} SMOOTH_ENKF=${SMOOTH_ENKF:-"NO"} ENKF_SPREAD=${ENKF_SPREAD:-"NO"} @@ -67,7 +67,7 @@ export OMP_NUM_THREADS=$NTHREADS_EPOS ################################################################################ # Forecast ensemble member files -for imem in $(seq 1 $NMEM_ENKF); do +for imem in $(seq 1 $NMEM_ENS); do memchar="mem"$(printf %03i "${imem}") MEMDIR=${memchar} YMD=${PDY} HH=${cyc} generate_com -x COM_ATMOS_HISTORY:COM_ATMOS_HISTORY_TMPL @@ -87,7 +87,7 @@ for fhr in $(seq $FHMIN $FHOUT $FHMAX); do ${NLN} "${COM_ATMOS_HISTORY_STAT}/${PREFIX}sfcf${fhrchar}.ensmean.nc" "sfcf${fhrchar}.ensmean" ${NLN} "${COM_ATMOS_HISTORY_STAT}/${PREFIX}atmf${fhrchar}.ensmean.nc" "atmf${fhrchar}.ensmean" if [ $SMOOTH_ENKF = "YES" ]; then - for imem in $(seq 1 $NMEM_ENKF); do + for imem in $(seq 1 $NMEM_ENS); do memchar="mem"$(printf %03i "${imem}") MEMDIR="${memchar}" YMD=${PDY} HH=${cyc} generate_com -x COM_ATMOS_HISTORY ${NLN} "${COM_ATMOS_HISTORY}/${PREFIX}atmf${fhrchar}${ENKF_SUFFIX}.nc" "atmf${fhrchar}${ENKF_SUFFIX}_${memchar}" @@ -108,7 +108,7 @@ for fhr in $(seq $FHMIN $FHOUT $FHMAX); do export pgm=$GETSFCENSMEANEXEC . prep_step - $APRUN_EPOS ${DATA}/$(basename $GETSFCENSMEANEXEC) ./ sfcf${fhrchar}.ensmean sfcf${fhrchar} $NMEM_ENKF + $APRUN_EPOS ${DATA}/$(basename $GETSFCENSMEANEXEC) ./ sfcf${fhrchar}.ensmean sfcf${fhrchar} $NMEM_ENS ra=$? rc=$((rc+ra)) @@ -116,9 +116,9 @@ for fhr in $(seq $FHMIN $FHOUT $FHMAX); do . prep_step if [ $ENKF_SPREAD = "YES" ]; then - $APRUN_EPOS ${DATA}/$(basename $GETATMENSMEANEXEC) ./ atmf${fhrchar}.ensmean atmf${fhrchar} $NMEM_ENKF atmf${fhrchar}.ensspread + $APRUN_EPOS ${DATA}/$(basename $GETATMENSMEANEXEC) ./ atmf${fhrchar}.ensmean atmf${fhrchar} $NMEM_ENS atmf${fhrchar}.ensspread else - $APRUN_EPOS ${DATA}/$(basename $GETATMENSMEANEXEC) ./ atmf${fhrchar}.ensmean atmf${fhrchar} $NMEM_ENKF + $APRUN_EPOS ${DATA}/$(basename $GETATMENSMEANEXEC) ./ atmf${fhrchar}.ensmean atmf${fhrchar} $NMEM_ENS fi ra=$? rc=$((rc+ra)) @@ -132,7 +132,7 @@ if [ $SMOOTH_ENKF = "YES" ]; then fhrchar=$(printf %03i $fhr) if [ ! -s atmf${fhrchar}${ENKF_SUFFIX}_mem001 ]; then echo WARNING! no smoothed ensemble member for fhour = $fhrchar >&2 - for imem in $(seq 1 $NMEM_ENKF); do + for imem in $(seq 1 $NMEM_ENS); do memchar="mem"$(printf %03i $imem) ${NCP} "atmf${fhrchar}_${memchar}" "atmf${fhrchar}${ENKF_SUFFIX}_${memchar}" done diff --git a/scripts/exgdas_enkf_sfc.sh b/scripts/exgdas_enkf_sfc.sh index d74306a8b3..5bbe7a460f 100755 --- a/scripts/exgdas_enkf_sfc.sh +++ b/scripts/exgdas_enkf_sfc.sh @@ -46,7 +46,7 @@ GPREFIX=${GPREFIX:-""} GPREFIX_ENS=${GPREFIX_ENS:-${GPREFIX}} # Variables -NMEM_ENKF=${NMEM_ENKF:-80} +NMEM_ENS=${NMEM_ENS:-80} DOIAU=${DOIAU_ENKF:-"NO"} # Global_cycle stuff @@ -123,7 +123,7 @@ fi export APRUNCY=${APRUN_CYCLE:-$APRUN_ESFC} export OMP_NUM_THREADS_CY=${NTHREADS_CYCLE:-$NTHREADS_ESFC} -export MAX_TASKS_CY=$NMEM_ENKF +export MAX_TASKS_CY=$NMEM_ENS if [ $DOIAU = "YES" ]; then # Update surface restarts at beginning of window when IAU is ON @@ -133,7 +133,7 @@ if [ $DOIAU = "YES" ]; then export TILE_NUM=$n - for imem in $(seq 1 $NMEM_ENKF); do + for imem in $(seq 1 $NMEM_ENS); do cmem=$(printf %03i $imem) memchar="mem$cmem" @@ -169,7 +169,7 @@ if [ $DOSFCANL_ENKF = "YES" ]; then export TILE_NUM=$n - for imem in $(seq 1 $NMEM_ENKF); do + for imem in $(seq 1 $NMEM_ENS); do cmem=$(printf %03i $imem) memchar="mem$cmem" diff --git a/scripts/exgdas_enkf_update.sh b/scripts/exgdas_enkf_update.sh index dfe00effd9..2bb749e226 100755 --- a/scripts/exgdas_enkf_update.sh +++ b/scripts/exgdas_enkf_update.sh @@ -57,7 +57,7 @@ ENKFSTAT=${ENKFSTAT:-${APREFIX}enkfstat} # Namelist parameters USE_CORRELATED_OBERRS=${USE_CORRELATED_OBERRS:-"NO"} -NMEM_ENKF=${NMEM_ENKF:-80} +NMEM_ENS=${NMEM_ENS:-80} NAM_ENKF=${NAM_ENKF:-""} SATOBS_ENKF=${SATOBS_ENKF:-""} OZOBS_ENKF=${OZOBS_ENKF:-""} @@ -178,7 +178,7 @@ else done fi nfhrs=$(echo $IAUFHRS_ENKF | sed 's/,/ /g') -for imem in $(seq 1 $NMEM_ENKF); do +for imem in $(seq 1 $NMEM_ENS); do memchar="mem"$(printf %03i $imem) MEMDIR=${memchar} RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} generate_com -x \ @@ -264,7 +264,7 @@ cat > enkf.nml << EOFnml obtimelnh=1.e30,obtimelsh=1.e30,obtimeltr=1.e30, saterrfact=1.0,numiter=0, sprd_tol=1.e30,paoverpb_thresh=0.98, - nlons=$LONA_ENKF,nlats=$LATA_ENKF,nlevs=$LEVS_ENKF,nanals=$NMEM_ENKF, + nlons=$LONA_ENKF,nlats=$LATA_ENKF,nlevs=$LEVS_ENKF,nanals=$NMEM_ENS, deterministic=.true.,sortinc=.true.,lupd_satbiasc=.false., reducedgrid=${reducedgrid},readin_localization=${readin_localization_enkf}., use_gfs_nemsio=${use_gfs_nemsio},use_gfs_ncio=${use_gfs_ncio},imp_physics=$imp_physics,lupp=$lupp, diff --git a/scripts/exglobal_atmos_analysis.sh b/scripts/exglobal_atmos_analysis.sh index 6ab24523c8..f81f7f0a33 100755 --- a/scripts/exglobal_atmos_analysis.sh +++ b/scripts/exglobal_atmos_analysis.sh @@ -216,7 +216,7 @@ DIAG_DIR=${DIAG_DIR:-${COM_ATMOS_ANALYSIS}/gsidiags} # Set script / GSI control parameters DOHYBVAR=${DOHYBVAR:-"NO"} -NMEM_ENKF=${NMEM_ENKF:-0} +NMEM_ENS=${NMEM_ENS:-0} export DONST=${DONST:-"NO"} NST_GSI=${NST_GSI:-0} NSTINFO=${NSTINFO:-0} @@ -530,7 +530,7 @@ if [ ${DOHYBVAR} = "YES" ]; then nhr_obsbin=1 fi - for imem in $(seq 1 ${NMEM_ENKF}); do + for imem in $(seq 1 ${NMEM_ENS}); do memchar="mem$(printf %03i "${imem}")" MEMDIR=${memchar} RUN=${GDUMP_ENS} YMD=${gPDY} HH=${gcyc} generate_com COM_ATMOS_HISTORY @@ -673,7 +673,7 @@ fi # if [ $USE_RADSTAT = "YES" ] ############################################################## # GSI Namelist options if [ ${DOHYBVAR} = "YES" ]; then - HYBRID_ENSEMBLE="n_ens=${NMEM_ENKF},jcap_ens=${JCAP_ENKF},nlat_ens=${NLAT_ENKF},nlon_ens=${NLON_ENKF},jcap_ens_test=${JCAP_ENKF},${HYBRID_ENSEMBLE}" + HYBRID_ENSEMBLE="n_ens=${NMEM_ENS},jcap_ens=${JCAP_ENKF},nlat_ens=${NLAT_ENKF},nlon_ens=${NLON_ENKF},jcap_ens_test=${JCAP_ENKF},${HYBRID_ENSEMBLE}" if [ ${l4densvar} = ".true." ]; then SETUP="niter(1)=50,niter(2)=150,niter_no_qc(1)=25,niter_no_qc(2)=0,thin4d=.true.,ens_nstarthr=3,l4densvar=${l4densvar},lwrite4danl=${lwrite4danl},${SETUP}" JCOPTS="ljc4tlevs=.true.,${JCOPTS}" diff --git a/ush/hpssarch_gen.sh b/ush/hpssarch_gen.sh index c2a84441bf..9b55fe04bd 100755 --- a/ush/hpssarch_gen.sh +++ b/ush/hpssarch_gen.sh @@ -472,11 +472,11 @@ if [[ ${type} == "enkfgdas" || ${type} == "enkfgfs" ]]; then IAUFHRS_ENKF=${IAUFHRS_ENKF:-6} lobsdiag_forenkf=${lobsdiag_forenkf:-".false."} nfhrs="${IAUFHRS_ENKF/,/}" - NMEM_ENKF=${NMEM_ENKF:-80} + NMEM_ENS=${NMEM_ENS:-80} NMEM_EARCGRP=${NMEM_EARCGRP:-10} ##number of ens memebers included in each tarball - NTARS=$((NMEM_ENKF/NMEM_EARCGRP)) + NTARS=$((NMEM_ENS/NMEM_EARCGRP)) [[ ${NTARS} -eq 0 ]] && NTARS=1 - [[ $((NTARS*NMEM_EARCGRP)) -lt ${NMEM_ENKF} ]] && NTARS=$((NTARS+1)) + [[ $((NTARS*NMEM_EARCGRP)) -lt ${NMEM_ENS} ]] && NTARS=$((NTARS+1)) ##NTARS2=$((NTARS/2)) # number of earc groups to include analysis/increments NTARS2=${NTARS} diff --git a/ush/python/pygfs/task/aero_analysis.py b/ush/python/pygfs/task/aero_analysis.py index 2a0b2c2dd6..e3c9ad50a2 100644 --- a/ush/python/pygfs/task/aero_analysis.py +++ b/ush/python/pygfs/task/aero_analysis.py @@ -30,7 +30,7 @@ def __init__(self, config): super().__init__(config) _res = int(self.config['CASE'][1:]) - _res_enkf = int(self.config['CASE_ENKF'][1:]) + _res_enkf = int(self.config['CASE_ENS'][1:]) _window_begin = add_to_datetime(self.runtime_config.current_cycle, -to_timedelta(f"{self.config['assim_freq']}H") / 2) _fv3jedi_yaml = os.path.join(self.runtime_config.DATA, f"{self.runtime_config.CDUMP}.t{self.runtime_config['cyc']:02d}z.aerovar.yaml") diff --git a/ush/python/pygfs/task/atmens_analysis.py b/ush/python/pygfs/task/atmens_analysis.py index 28b121644a..64f61d8df3 100644 --- a/ush/python/pygfs/task/atmens_analysis.py +++ b/ush/python/pygfs/task/atmens_analysis.py @@ -29,7 +29,7 @@ class AtmEnsAnalysis(Analysis): def __init__(self, config): super().__init__(config) - _res = int(self.config.CASE_ENKF[1:]) + _res = int(self.config.CASE_ENS[1:]) _res_anl = int(self.config.CASE_ANL[1:]) _window_begin = add_to_datetime(self.runtime_config.current_cycle, -to_timedelta(f"{self.config.assim_freq}H") / 2) _fv3jedi_yaml = os.path.join(self.runtime_config.DATA, f"{self.runtime_config.CDUMP}.t{self.runtime_config.cyc:02d}z.atmens.yaml") @@ -88,7 +88,7 @@ def initialize(self: Analysis) -> None: 'HH': self.task_config.current_cycle.strftime('%H') } dirlist = [] - for imem in range(1, self.task_config.NMEM_ENKF + 1): + for imem in range(1, self.task_config.NMEM_ENS + 1): dirlist.append(os.path.join(self.task_config.DATA, 'bkg', f'mem{imem:03d}')) dirlist.append(os.path.join(self.task_config.DATA, 'anl', f'mem{imem:03d}')) @@ -267,7 +267,7 @@ def jedi2fv3inc(self: Analysis) -> None: } # loop over ensemble members - for imem in range(1, self.task_config.NMEM_ENKF + 1): + for imem in range(1, self.task_config.NMEM_ENS + 1): memchar = f"mem{imem:03d}" # create output path for member analysis increment @@ -322,7 +322,7 @@ def get_bkg_dict(self: Analysis) -> Dict[str, List[str]]: 'MEMDIR': None } - for imem in range(1, self.task_config.NMEM_ENKF + 1): + for imem in range(1, self.task_config.NMEM_ENS + 1): memchar = f"mem{imem:03d}" # get FV3 restart files, this will be a lot simpler when using history files diff --git a/workflow/rocoto/workflow_tasks.py b/workflow/rocoto/workflow_tasks.py index d45c13bff7..3520c717db 100644 --- a/workflow/rocoto/workflow_tasks.py +++ b/workflow/rocoto/workflow_tasks.py @@ -1186,7 +1186,7 @@ def eomg(self): eomgenvars = self.envars.copy() eomgenvars.append(rocoto.create_envar(name='ENSGRP', value='#grp#')) - groups = self._get_hybgroups(self._base['NMEM_ENKF'], self._configs['eobs']['NMEM_EOMGGRP']) + groups = self._get_hybgroups(self._base['NMEM_ENS'], self._configs['eobs']['NMEM_EOMGGRP']) resources = self.get_resource('eomg') task = create_wf_task('eomg', resources, cdump=self.cdump, envar=eomgenvars, dependency=dependencies, @@ -1344,10 +1344,10 @@ def efcs(self): efcsenvars = self.envars.copy() efcsenvars.append(rocoto.create_envar(name='ENSGRP', value='#grp#')) - groups = self._get_hybgroups(self._base['NMEM_ENKF'], self._configs['efcs']['NMEM_EFCSGRP']) + groups = self._get_hybgroups(self._base['NMEM_ENS'], self._configs['efcs']['NMEM_EFCSGRP']) if self.cdump == "enkfgfs": - groups = self._get_hybgroups(self._base['NMEM_EFCS'], self._configs['efcs']['NMEM_EFCSGRP_GFS']) + groups = self._get_hybgroups(self._base['NMEM_ENS_GFS'], self._configs['efcs']['NMEM_EFCSGRP_GFS']) cycledef = 'gdas_half,gdas' if self.cdump in ['enkfgdas'] else self.cdump.replace('enkf', '') resources = self.get_resource('efcs') task = create_wf_task('efcs', resources, cdump=self.cdump, envar=efcsenvars, dependency=dependencies, @@ -1431,7 +1431,7 @@ def earc(self): earcenvars = self.envars.copy() earcenvars.append(rocoto.create_envar(name='ENSGRP', value='#grp#')) - groups = self._get_hybgroups(self._base['NMEM_ENKF'], self._configs['earc']['NMEM_EARCGRP'], start_index=0) + groups = self._get_hybgroups(self._base['NMEM_ENS'], self._configs['earc']['NMEM_EARCGRP'], start_index=0) cycledef = 'gdas_half,gdas' if self.cdump in ['enkfgdas'] else self.cdump.replace('enkf', '') diff --git a/workflow/setup_expt.py b/workflow/setup_expt.py index e948a29528..314efb8cb2 100755 --- a/workflow/setup_expt.py +++ b/workflow/setup_expt.py @@ -8,7 +8,7 @@ import glob import shutil import warnings -from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter +from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, SUPPRESS from hosts import Host @@ -271,10 +271,16 @@ def edit_baseconfig(host, inputs): tmpl_dict = dict(tmpl_dict, **extend_dict) extend_dict = dict() - if inputs.mode in ['cycled']: + if getattr(inputs, 'nens', 0) > 0: extend_dict = { "@CASEENS@": f'C{inputs.resens}', - "@NMEM_ENKF@": inputs.nens, + "@NMEM_ENS@": inputs.nens, + } + tmpl_dict = dict(tmpl_dict, **extend_dict) + + extend_dict = dict() + if inputs.mode in ['cycled']: + extend_dict = { "@DOHYBVAR@": "YES" if inputs.nens > 0 else "NO", } tmpl_dict = dict(tmpl_dict, **extend_dict) @@ -336,14 +342,16 @@ def input_args(): formatter_class=ArgumentDefaultsHelpFormatter) # Set up sub-parsers for various modes of experimentation - subparser = parser.add_subparsers(dest='mode') - cycled = subparser.add_parser( - 'cycled', help='arguments for cycled mode') - forecasts = subparser.add_parser( - 'forecast-only', help='arguments for forecast-only mode') + sysparser = parser.add_subparsers(dest='system') + gfs = sysparser.add_parser('gfs', help='arguments for GFS') + gefs = sysparser.add_parser('gefs', help='arguments for GEFS') + + modeparser = gfs.add_subparsers(dest='mode') + cycled = modeparser.add_parser('cycled', help='arguments for cycled mode') + forecasts = modeparser.add_parser('forecast-only', help='arguments for forecast-only mode') # Common arguments across all modes - for subp in [cycled, forecasts]: + for subp in [cycled, forecasts, gefs]: subp.add_argument('--pslot', help='parallel experiment name', type=str, required=False, default='test') subp.add_argument('--resdet', help='resolution of the deterministic model forecast', @@ -355,32 +363,51 @@ def input_args(): subp.add_argument('--idate', help='starting date of experiment, initial conditions must exist!', required=True, type=lambda dd: to_datetime(dd)) subp.add_argument('--edate', help='end date experiment', required=True, type=lambda dd: to_datetime(dd)) - subp.add_argument('--configdir', help='full path to directory containing the config files', - type=str, required=False, default=os.path.join(_top, 'parm/config')) - subp.add_argument('--cdump', help='CDUMP to start the experiment', - type=str, required=False, default='gdas') - subp.add_argument('--gfs_cyc', help='GFS cycles to run', type=int, - choices=[0, 1, 2, 4], default=1, required=False) + + ufs_apps = ['ATM', 'ATMA', 'ATMW', 'S2S', 'S2SW'] + + # GFS-only arguments + for subp in [cycled, forecasts]: subp.add_argument('--start', help='restart mode: warm or cold', type=str, choices=['warm', 'cold'], required=False, default='cold') - + subp.add_argument('--cdump', help='CDUMP to start the experiment', + type=str, required=False, default='gdas') + # --configdir is hidden from help + subp.add_argument('--configdir', help=SUPPRESS, type=str, required=False, default=os.path.join(_top, 'parm/config/gfs')) subp.add_argument('--yaml', help='Defaults to substitute from', type=str, - required=False, default=os.path.join(_top, 'parm/config/yaml/defaults.yaml')) - - ufs_apps = ['ATM', 'ATMA', 'ATMW', 'S2S', 'S2SW'] + required=False, default=os.path.join(_top, 'parm/config/gfs/yaml/defaults.yaml')) + + # ensemble-only arguments + for subp in [cycled, gefs]: + subp.add_argument('--resens', help='resolution of the ensemble model forecast', + type=int, required=False, default=192) + subp.add_argument('--nens', help='number of ensemble members', + type=int, required=False, default=20) + + # GFS/GEFS forecast-only additional arguments + for subp in [forecasts, gefs]: + subp.add_argument('--app', help='UFS application', type=str, + choices=ufs_apps + ['S2SWA'], required=False, default='ATM') + subp.add_argument('--gfs_cyc', help='Number of forecasts per day', type=int, + choices=[1, 2, 4], default=1, required=False) # cycled mode additional arguments cycled.add_argument('--icsdir', help='full path to initial condition directory', type=str, required=False, default=None) - cycled.add_argument('--resens', help='resolution of the ensemble model forecast', - type=int, required=False, default=192) - cycled.add_argument('--nens', help='number of ensemble members', - type=int, required=False, default=20) cycled.add_argument('--app', help='UFS application', type=str, choices=ufs_apps, required=False, default='ATM') - - # forecast only mode additional arguments - forecasts.add_argument('--app', help='UFS application', type=str, - choices=ufs_apps + ['S2SWA'], required=False, default='ATM') + cycled.add_argument('--gfs_cyc', help='cycles to run forecast', type=int, + choices=[0, 1, 2, 4], default=1, required=False) + + # GEFS-only arguments + # Create hidden mode argument since there is real option for GEFS + gefs.add_argument('--mode', help=SUPPRESS, type=str, required=False, default='forecast-only') + # Create hidden start argument since GEFS is always cold start + gefs.add_argument('--start', help=SUPPRESS, type=str, required=False, default='cold') + # Create hidden arguments for configdir and yaml + gefs.add_argument('--configdir', help=SUPPRESS, type=str, required=False, + default=os.path.join(_top, 'parm/config/gefs')) + gefs.add_argument('--yaml', help='Defaults to substitute from', type=str, required=False, + default=os.path.join(_top, 'parm/config/gefs/yaml/defaults.yaml')) args = parser.parse_args() @@ -413,11 +440,15 @@ def query_and_clean(dirname): def validate_user_request(host, inputs): - expt_res = f'C{inputs.resdet}' supp_res = host.info['SUPPORTED_RESOLUTIONS'] machine = host.machine - if expt_res not in supp_res: - raise NotImplementedError(f"Supported resolutions on {machine} are:\n{', '.join(supp_res)}") + for attr in ['resdet', 'ensres']: + try: + expt_res = f'C{getattr(inputs, attr)}' + except AttributeError: + continue + if expt_res not in supp_res: + raise NotImplementedError(f"Supported resolutions on {machine} are:\n{', '.join(supp_res)}") if __name__ == '__main__':