Skip to content

Commit

Permalink
Switch snow DA to use 2DVar for deterministic and ensemble mean (#3163)
Browse files Browse the repository at this point in the history
This PR moves the snow DA from a LETKF-OI approach with a fake ensemble
to a 2DVar approach for the deterministic and the ensemble mean for
GDAS/GFS. This PR also adds support for JCB and refactoring of the jobs
to leverage the Jedi class in the workflow.

Resolves #3002 
---------

Co-authored-by: RussTreadon-NOAA <[email protected]>
Co-authored-by: Jiarui Dong <[email protected]>
Co-authored-by: DavidNew-NOAA <[email protected]>
Co-authored-by: Cory Martin <[email protected]>
Co-authored-by: Walter Kolczynski - NOAA <[email protected]>
  • Loading branch information
6 people authored Dec 20, 2024
1 parent 2007864 commit d479111
Show file tree
Hide file tree
Showing 35 changed files with 782 additions and 835 deletions.
10 changes: 6 additions & 4 deletions env/HERA.env
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,16 @@ elif [[ "${step}" = "snowanl" ]]; then
export APRUN_CALCFIMS="${launcher} -n 1"

export NTHREADS_SNOWANL=${NTHREADSmax}
export APRUN_SNOWANL="${APRUN_default} --cpus-per-task=${NTHREADS_SNOWANL}"
export APRUN_SNOWANL="${APRUN_default} --mem=0 --cpus-per-task=${NTHREADS_SNOWANL}"

export APRUN_APPLY_INCR="${launcher} -n 6"

elif [[ "${step}" = "esnowrecen" ]]; then
elif [[ "${step}" = "esnowanl" ]]; then

export NTHREADS_ESNOWRECEN=${NTHREADSmax}
export APRUN_ESNOWRECEN="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWRECEN}"
export APRUN_CALCFIMS="${launcher} -n 1"

export NTHREADS_ESNOWANL=${NTHREADSmax}
export APRUN_ESNOWANL="${APRUN_default} --mem=0 --cpus-per-task=${NTHREADS_ESNOWANL}"

export APRUN_APPLY_INCR="${launcher} -n 6"

Expand Down
8 changes: 5 additions & 3 deletions env/HERCULES.env
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,12 @@ case ${step} in

export APRUN_APPLY_INCR="${launcher} -n 6"
;;
"esnowrecen")
"esnowanl")

export NTHREADS_ESNOWRECEN=${NTHREADSmax}
export APRUN_ESNOWRECEN="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWRECEN}"
export APRUN_CALCFIMS="${launcher} -n 1"

export NTHREADS_ESNOWANL=${NTHREADSmax}
export APRUN_ESNOWANL="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWANL}"

export APRUN_APPLY_INCR="${launcher} -n 6"
;;
Expand Down
8 changes: 5 additions & 3 deletions env/JET.env
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ elif [[ "${step}" = "snowanl" ]]; then

export APRUN_APPLY_INCR="${launcher} -n 6"

elif [[ "${step}" = "esnowrecen" ]]; then
elif [[ "${step}" = "esnowanl" ]]; then

export NTHREADS_ESNOWRECEN=${NTHREADSmax}
export APRUN_ESNOWRECEN="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWRECEN}"
export APRUN_CALCFIMS="${launcher} -n 1"

export NTHREADS_ESNOWANL=${NTHREADSmax}
export APRUN_ESNOWANL="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWANL}"

export APRUN_APPLY_INCR="${launcher} -n 6"

Expand Down
8 changes: 5 additions & 3 deletions env/ORION.env
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,12 @@ elif [[ "${step}" = "snowanl" ]]; then

export APRUN_APPLY_INCR="${launcher} -n 6"

elif [[ "${step}" = "esnowrecen" ]]; then
elif [[ "${step}" = "esnowanl" ]]; then

export NTHREADS_ESNOWRECEN=${NTHREADSmax}
export APRUN_ESNOWRECEN="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWRECEN}"
export APRUN_CALCFIMS="${launcher} -n 1"

export NTHREADS_ESNOWANL=${NTHREADSmax}
export APRUN_ESNOWANL="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWANL}"

export APRUN_APPLY_INCR="${launcher} -n 6"

Expand Down
8 changes: 5 additions & 3 deletions env/S4.env
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ elif [[ "${step}" = "snowanl" ]]; then

export APRUN_APPLY_INCR="${launcher} -n 6"

elif [[ "${step}" = "esnowrecen" ]]; then
elif [[ "${step}" = "esnowanl" ]]; then

export NTHREADS_ESNOWRECEN=${NTHREADSmax}
export APRUN_ESNOWRECEN="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWRECEN}"
export APRUN_CALCFIMS="${launcher} -n 1"

export NTHREADS_ESNOWANL=${NTHREADSmax}
export APRUN_ESNOWANL="${APRUN_default} --cpus-per-task=${NTHREADS_ESNOWANL}"

export APRUN_APPLY_INCR="${launcher} -n 6"

Expand Down
8 changes: 5 additions & 3 deletions env/WCOSS2.env
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ elif [[ "${step}" = "snowanl" ]]; then

export APRUN_APPLY_INCR="${launcher} -n 6"

elif [[ "${step}" = "esnowrecen" ]]; then
elif [[ "${step}" = "esnowanl" ]]; then

export NTHREADS_ESNOWRECEN=${NTHREADSmax}
export APRUN_ESNOWRECEN="${APRUN_default}"
export APRUN_CALCFIMS="${launcher} -n 1"

export NTHREADS_ESNOWANL=${NTHREADSmax}
export APRUN_ESNOWANL="${APRUN_default}"

export APRUN_APPLY_INCR="${launcher} -n 6"

Expand Down
3 changes: 2 additions & 1 deletion jobs/JGDAS_ENKF_ARCHIVE
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ source "${HOMEgfs}/ush/jjob_header.sh" -e "earc" -c "base earc"
YMD=${PDY} HH=${cyc} declare_from_tmpl -rx COM_TOP
MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \
COMIN_ATMOS_ANALYSIS_ENSSTAT:COM_ATMOS_ANALYSIS_TMPL \
COMIN_ATMOS_HISTORY_ENSSTAT:COM_ATMOS_HISTORY_TMPL
COMIN_ATMOS_HISTORY_ENSSTAT:COM_ATMOS_HISTORY_TMPL \
COMIN_SNOW_ANALYSIS_ENSSTAT:COM_SNOW_ANALYSIS_TMPL

###############################################################
# Run archive script
Expand Down
18 changes: 11 additions & 7 deletions jobs/JGDAS_ENKF_SNOW_RECENTER → jobs/JGLOBAL_SNOWENS_ANALYSIS
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#! /usr/bin/env bash

source "${HOMEgfs}/ush/preamble.sh"
source "${HOMEgfs}/ush/jjob_header.sh" -e "esnowrecen" -c "base esnowrecen"
source "${HOMEgfs}/ush/jjob_header.sh" -e "esnowanl" -c "base esnowanl"

##############################################
# Set variables used in the script
Expand All @@ -10,19 +10,18 @@ source "${HOMEgfs}/ush/jjob_header.sh" -e "esnowrecen" -c "base esnowrecen"
# shellcheck disable=SC2153
GDUMP="gdas"
export GDUMP
CDUMP=${RUN/enkf}
export CDUMP

##############################################
# Begin JOB SPECIFIC work
##############################################
# Generate COM variables from templates
RUN=${CDUMP} YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \
COMIN_OBS:COM_OBS_TMPL
YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \
COMIN_OBS:COM_OBS_TMPL \
COMOUT_ATMOS_ANALYSIS:COM_ATMOS_ANALYSIS_TMPL \
COMOUT_CONF:COM_CONF_TMPL
MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl \
COMOUT_SNOW_ANALYSIS:COM_SNOW_ANALYSIS_TMPL

mkdir -p "${COMOUT_SNOW_ANALYSIS}" "${COMOUT_CONF}"

for imem in $(seq 1 "${NMEM_ENS}"); do
memchar="mem$(printf %03i "${imem}")"
Expand All @@ -31,10 +30,15 @@ for imem in $(seq 1 "${NMEM_ENS}"); do
mkdir -p "${COMOUT_SNOW_ANALYSIS}"
done

MEMDIR="ensstat" YMD=${PDY} HH=${cyc} declare_from_tmpl -x\
COMOUT_SNOW_ANALYSIS:COM_SNOW_ANALYSIS_TMPL

mkdir -p "${COMOUT_SNOW_ANALYSIS}" "${COMOUT_CONF}"

###############################################################
# Run relevant script

EXSCRIPT=${SNOWANLPY:-${SCRgfs}/exgdas_enkf_snow_recenter.py}
EXSCRIPT=${SNOWANLPY:-${SCRgfs}/exglobal_snowens_analysis.py}
${EXSCRIPT}
status=$?
(( status != 0 )) && exit "${status}"
Expand Down
10 changes: 6 additions & 4 deletions jobs/JGLOBAL_SNOW_ANALYSIS
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#! /usr/bin/env bash

source "${HOMEgfs}/ush/preamble.sh"
export DATA=${DATA:-${DATAROOT}/${RUN}snowanl_${cyc}}
source "${HOMEgfs}/ush/jjob_header.sh" -e "snowanl" -c "base snowanl"

##############################################
Expand All @@ -18,12 +17,15 @@ GDUMP="gdas"
# Begin JOB SPECIFIC work
##############################################
# Generate COM variables from templates
YMD=${PDY} HH=${cyc} declare_from_tmpl -rx COM_OBS COM_SNOW_ANALYSIS COM_CONF
YMD=${PDY} HH=${cyc} declare_from_tmpl -rx \
COMIN_OBS:COM_OBS_TMPL \
COMOUT_SNOW_ANALYSIS:COM_SNOW_ANALYSIS_TMPL \
COMOUT_CONF:COM_CONF_TMPL

RUN=${GDUMP} YMD=${gPDY} HH=${gcyc} declare_from_tmpl -rx \
COM_ATMOS_RESTART_PREV:COM_ATMOS_RESTART_TMPL
COMIN_ATMOS_RESTART_PREV:COM_ATMOS_RESTART_TMPL

mkdir -m 775 -p "${COM_SNOW_ANALYSIS}" "${COM_CONF}"
mkdir -m 775 -p "${COMOUT_SNOW_ANALYSIS}" "${COMOUT_CONF}"

###############################################################
# Run relevant script
Expand Down
26 changes: 26 additions & 0 deletions jobs/rocoto/esnowanl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#! /usr/bin/env bash

source "${HOMEgfs}/ush/preamble.sh"

###############################################################
# Source UFSDA workflow modules
. "${HOMEgfs}/ush/load_ufsda_modules.sh"
status=$?
[[ ${status} -ne 0 ]] && exit "${status}"

export job="esnowanl"
export jobid="${job}.$$"

###############################################################
# setup python path for ioda utilities
# shellcheck disable=SC2311
pyiodaPATH="${HOMEgfs}/sorc/gdas.cd/build/lib/python$(detect_py_ver)/"
gdasappPATH="${HOMEgfs}/sorc/gdas.cd/sorc/iodaconv/src:${pyiodaPATH}"
PYTHONPATH="${PYTHONPATH:+${PYTHONPATH}:}:${gdasappPATH}"
export PYTHONPATH

###############################################################
# Execute the JJOB
"${HOMEgfs}/jobs/JGLOBAL_SNOWENS_ANALYSIS"
status=$?
exit "${status}"
18 changes: 0 additions & 18 deletions jobs/rocoto/esnowrecen.sh

This file was deleted.

8 changes: 8 additions & 0 deletions parm/archive/enkf.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ enkf:
- "{{ COMIN_ATMOS_ANALYSIS_ENSSTAT | relpath(ROTDIR) }}/{{ head }}{{ file }}"
{% endfor %}

{% if DO_JEDISNOWDA %}
- "{{ COMIN_SNOW_ANALYSIS_ENSSTAT | relpath(ROTDIR) }}/{{ head }}snowstat.tgz"
{% for itile in range(1,7) %}
# Snow analysis is 3dvar
- "{{ COMIN_SNOW_ANALYSIS_ENSSTAT | relpath(ROTDIR) }}/snowinc.{{ cycle_YMD }}.{{ cycle_HH }}0000.sfc_data.tile{{ itile }}.nc"
{% endfor %}
{% endif %}

# Ensemble mean analyses/increments
# 6-hr analysis/increment
{% if do_calc_increment %}
Expand Down
2 changes: 1 addition & 1 deletion parm/archive/gdas_restarta.yaml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ gdas_restarta:

# Snow configuration yaml
{% if DO_JEDISNOWDA %}
- "{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}letkfoi.yaml"
- "{{ COMIN_CONF | relpath(ROTDIR) }}/{{ head }}snowanlvar.yaml"
{% endif %}

# Input BUFR files
Expand Down
38 changes: 38 additions & 0 deletions parm/config/gfs/config.esnowanl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#! /usr/bin/env bash

########## config.esnowanl ##########
# configuration common to snow ensemble analysis tasks

echo "BEGIN: config.esnowanl"

# Get task specific resources
source "${EXPDIR}/config.resources" esnowanl

export OBS_LIST="${PARMgfs}/gdas/snow/obs/lists/gdas_snow.yaml.j2"
export GTS_SNOW_STAGE_YAML="${PARMgfs}/gdas/snow/obs/config/bufr2ioda_mapping.yaml.j2"

export JCB_BASE_YAML="${PARMgfs}/gdas/snow/jcb-base.yaml.j2"
export JCB_ALGO_YAML_VAR="${PARMgfs}/gdas/snow/jcb-prototype_2dvar.yaml.j2"

# Process IMS snowcover into snow depth
export IMS_OBS_LIST="${PARMgfs}/gdas/snow/prep/prep_ims.yaml.j2"
export CALCFIMSEXE="${EXECgfs}/calcfIMS.exe"
export FIMS_NML_TMPL="${PARMgfs}/gdas/snow/prep/fims.nml.j2"
export IMS2IODACONV="${USHgfs}/imsfv3_scf2ioda.py"

export JEDI_FIX_YAML="${PARMgfs}/gdas/snow_jedi_fix.yaml.j2"
export BERROR_STAGING_YAML="${PARMgfs}/gdas/staging/snow_berror.yaml.j2"
export SNOW_ENS_STAGE_TMPL="${PARMgfs}/gdas/snow_stage_ens_update.yaml.j2"
export SNOW_OROG_STAGE_TMPL="${PARMgfs}/gdas/snow_stage_orog.yaml.j2"
export SNOW_ENS_FINALIZE_TMPL="${PARMgfs}/gdas/snow_finalize_ens_update.yaml.j2"

# Name of the executable that applies increment to bkg and its namelist template
export APPLY_INCR_EXE="${EXECgfs}/apply_incr.exe"
export ENS_APPLY_INCR_NML_TMPL="${PARMgfs}/gdas/snow/ens_apply_incr_nml.j2"

export JEDI_CONFIG_YAML="${PARMgfs}/gdas/esnowanl_jedi_config.yaml.j2"

export io_layout_x=@IO_LAYOUT_X@
export io_layout_y=@IO_LAYOUT_Y@

echo "END: config.esnowanl"
29 changes: 0 additions & 29 deletions parm/config/gfs/config.esnowrecen

This file was deleted.

12 changes: 6 additions & 6 deletions parm/config/gfs/config.resources
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if (( $# != 1 )); then
echo "prep prepatmiodaobs"
echo "atmanlinit atmanlvar atmanlfv3inc atmanlfinal"
echo "atmensanlinit atmensanlobs atmensanlsol atmensanlletkf atmensanlfv3inc atmensanlfinal"
echo "snowanl esnowrecen"
echo "snowanl esnowanl"
echo "prepobsaero aeroanlinit aeroanlvar aeroanlfinal aeroanlgenb"
echo "anal sfcanl analcalc analdiag fcst echgres"
echo "upp atmos_products"
Expand Down Expand Up @@ -346,11 +346,11 @@ case ${step} in

walltime="00:15:00"
ntasks=$(( layout_x * layout_y * 6 ))
threads_per_task=1
threads_per_task=2
tasks_per_node=$(( max_tasks_per_node / threads_per_task ))
;;

"esnowrecen")
"esnowanl")
# below lines are for creating JEDI YAML
case ${CASE} in
"C768")
Expand All @@ -373,9 +373,9 @@ case ${step} in
export layout_x
export layout_y

walltime="00:15:00"
walltime="00:30:00"
ntasks=$(( layout_x * layout_y * 6 ))
threads_per_task=1
threads_per_task=2
tasks_per_node=$(( max_tasks_per_node / threads_per_task ))
;;

Expand Down Expand Up @@ -1213,7 +1213,7 @@ case ${step} in
;;

"esfc")
walltime="00:15:00"
walltime="00:25:00"
ntasks=80
threads_per_task=1
tasks_per_node=$(( max_tasks_per_node / threads_per_task ))
Expand Down
Loading

0 comments on commit d479111

Please sign in to comment.