#!/bin/bash -fe # E3SMv2.1 Water Cycle run_e3sm script template. # # Configured to reproduce v2.LR.amip_0101 on chrysalis. # Modify as needed for other machines. # # Bash coding style inspired by: # http://kfirlavi.herokuapp.com/blog/2012/11/14/defensive-bash-programming main() { # For debugging, uncomment line below #set -x # --- Configuration flags ---- # Machine and project readonly MACHINE=BigRed200 readonly PROJECT="r00942" # Simulation readonly COMPSET="F2010" readonly RESOLUTION="ne30pg2_EC30to60E2r2" # Code and compilation #readonly CHECKOUT="20221102-maint-20" readonly BRANCH="maint-2.1" readonly CHERRY=( ) readonly DEBUG_COMPILE=false # BEFORE RUNNING : CHANGE the following CASE_NAME to desired value # For developmental simulations, recommended convention: #readonly CASE_NAME=${CHECKOUT}.amip_0101.${RESOLUTION}.${MACHINE} # For production simulations: readonly CASE_NAME="v2.1.LR.F2010_0101_20240923_resubmit_test" # If this is part of a simulation campaign, ask your group lead about using a case_group label # readonly CASE_GROUP="" # Run options readonly MODEL_START_TYPE="hybrid" # 'initial', 'continue', 'branch', 'hybrid' readonly START_DATE="2010-01-01" # Additional options for 'branch' and 'hybrid' readonly GET_REFCASE=TRUE #readonly RUN_REFDIR="/lcrc/group/e3sm/${USER}/E3SMv2_test/v2.LR.amip_0101/init" readonly RUN_REFDIR="/N/project/cascade/E3SM_data/www/WaterCycle/E3SMv2/LR/v2.LR.amip_0101/init" readonly RUN_REFCASE="v2.LR.historical_0101" readonly RUN_REFDATE="2010-01-01" # same as MODEL_START_DATE for 'branch', can be different for 'hybrid' # Set paths #readonly CODE_ROOT="${HOME}/E3SMv2_test/code/${CHECKOUT}" readonly CODE_ROOT="/N/project/MSB_Project/E3SMv2.1/E3SM" #readonly CASE_ROOT="/lcrc/group/e3sm/${USER}/E3SMv2_test/${CASE_NAME}" readonly CASE_ROOT="/N/project/MSB_Project/E3SMv2.0_scripts/${CASE_NAME}" # did not change to v2.1 8/26/24 readonly CASE_RUN_SCRATCH="/N/scratch/pgoddard/cime_scratch/E3SMv2.0/${CASE_NAME}" # did not change to v2.1 8/26/24 # Sub-directories readonly CASE_BUILD_DIR=${CASE_ROOT}/build # Don't put build in SCRATCH readonly CASE_ARCHIVE_DIR=${CASE_RUN_SCRATCH}/archive # Define type of run # short tests: 'XS_2x5_ndays', 'XS_1x10_ndays', 'S_1x10_ndays', # 'M_1x10_ndays', 'ML_1x10_ndays', 'L_1x10_ndays' # or 'production' for full simulation #readonly run='XS_1x10_ndays' readonly run='custom-4_1x10_ndays' #readonly run='custom-4_2x5_ndays' #readonly run='production' if [ "${run}" != "production" ]; then echo "setting up Short test simulations: ${run}" # Short test simulations tmp=($(echo $run | tr "_" " ")) layout=${tmp[0]} units=${tmp[2]} resubmit=$(( ${tmp[1]%%x*} -1 )) length=${tmp[1]##*x} readonly CASE_SCRIPTS_DIR=${CASE_ROOT}/tests/${run}/case_scripts readonly CASE_RUN_DIR=${CASE_RUN_SCRATCH}/tests/${run}/run readonly PELAYOUT=${layout} readonly WALLTIME="00:30:00" readonly STOP_OPTION=${units} readonly STOP_N=${length} readonly REST_OPTION=${STOP_OPTION} readonly REST_N=${STOP_N} readonly RESUBMIT=${resubmit} readonly DO_SHORT_TERM_ARCHIVING=false else echo "setting up ${run}" # Production simulation readonly CASE_SCRIPTS_DIR=${CASE_ROOT}/case_scripts readonly CASE_RUN_DIR=${CASE_RUN_SCRATCH}/run readonly PELAYOUT="custom-12" readonly WALLTIME="20:00:00" # maximum wall clock time requested for the batch jobs readonly STOP_OPTION="nyears" # see next line readonly STOP_N="5" # How often to stop the model, should be a multiple of REST_N. units (STOP_OPTION) and length of each segment (i.e., each batch job) readonly REST_OPTION="nyears" # see next line readonly REST_N="1" # units and frequency for writing restart files (make sure STOP_N is a multiple of REST_N, otherwise the model will stop without writing a restart fie at the end) readonly RESUBMIT="4" # Submissions after initial one. Total simulation length = initial STOP_N + STOP_N*RESUBMIT readonly DO_SHORT_TERM_ARCHIVING=false fi # Coupler history readonly HIST_OPTION="nyears" readonly HIST_N="1" # Leave empty (unless you understand what it does) readonly OLD_EXECUTABLE="" # --- Toggle flags for what to do ---- do_fetch_code=false do_create_newcase=true do_case_setup=true do_case_build=true do_case_submit=true # --- Now, do the work --- # Make directories created by this script world-readable umask 022 # Fetch code from Github fetch_code # Create case create_newcase # Custom PE layout custom_pelayout # Setup case_setup # Build case_build # Configure runtime options runtime_options # Copy script into case_script directory for provenance copy_script # Submit case_submit # All done echo $'\n----- All done -----\n' } # ======================= # Custom user_nl settings # ======================= user_nl() { cat << EOF >> user_nl_eam nhtfrq = 0,-24,-6,-6,-3,-24,0 mfilt = 1,30,120,120,240,30,1 avgflag_pertape = 'A','A','I','A','A','A','I' fexcl1 = 'CFAD_SR532_CAL', 'LINOZ_DO3', 'LINOZ_DO3_PSC', 'LINOZ_O3CLIM', 'LINOZ_O3COL', 'LINOZ_SSO3', 'hstobie_linoz' fincl1 = 'extinct_sw_inp','extinct_lw_bnd7','extinct_lw_inp','CLD_CAL', 'TREFMNAV', 'TREFMXAV' fincl2 = 'FLUT','PRECT','U200','V200','U850','V850','Z500','OMEGA500','UBOT','VBOT','TREFHT','TREFHTMN:M','TREFHTMX:X','QREFHT','TS','PS','TMQ','TUQ','TVQ','TOZ', 'FLDS', 'FLNS', 'FSDS', 'FSNS', 'SHFLX', 'LHFLX', 'TGCLDCWP', 'TGCLDIWP', 'TGCLDLWP', 'CLDTOT', 'T250', 'T200', 'T150', 'T100', 'T050', 'T025', 'T010', 'T005', 'T002', 'T001', 'TTOP', 'U250', 'U150', 'U100', 'U050', 'U025', 'U010', 'U005', 'U002', 'U001', 'UTOP', 'FSNT', 'FLNT' fincl3 = 'PSL','T200','T500','U850','V850','UBOT','VBOT','TREFHT', 'Z700', 'TBOT:M' fincl4 = 'FLUT','U200','U850','PRECT','OMEGA500' fincl5 = 'PRECT','PRECC','TUQ','TVQ','QFLX','SHFLX','U90M','V90M' fincl6 = 'CLDTOT_ISCCP','MEANCLDALB_ISCCP','MEANTAU_ISCCP','MEANPTOP_ISCCP','MEANTB_ISCCP','CLDTOT_CAL','CLDTOT_CAL_LIQ','CLDTOT_CAL_ICE','CLDTOT_CAL_UN','CLDHGH_CAL','CLDHGH_CAL_LIQ','CLDHGH_CAL_ICE','CLDHGH_CAL_UN','CLDMED_CAL','CLDMED_CAL_LIQ','CLDMED_CAL_ICE','CLDMED_CAL_UN','CLDLOW_CAL','CLDLOW_CAL_LIQ','CLDLOW_CAL_ICE','CLDLOW_CAL_UN' fincl7 = 'O3', 'PS', 'TROP_P' EOF cat << EOF >> user_nl_elm hist_dov2xy = .true.,.true. hist_fincl2 = 'H2OSNO', 'FSNO', 'QRUNOFF', 'QSNOMELT', 'FSNO_EFF', 'SNORDSL', 'SNOW', 'FSDS', 'FSR', 'FLDS', 'FIRE', 'FIRA' hist_mfilt = 1,365 hist_nhtfrq = 0,-24 hist_avgflag_pertape = 'A','A' ! Override check_finidat_fsurdat_consistency = .false. ! Override check_finidat_fsurdat_consistency = .false. EOF cat << EOF >> user_nl_mosart rtmhist_fincl2 = 'RIVER_DISCHARGE_OVER_LAND_LIQ' rtmhist_mfilt = 1,365 rtmhist_ndens = 2 rtmhist_nhtfrq = 0,-24 EOF } # ===================================== # Customize MPAS stream files if needed # ===================================== patch_mpas_streams() { echo } # ===================================================== # Custom PE layout: custom-N where N is number of nodes # ===================================================== custom_pelayout() { if [[ ${PELAYOUT} == custom-* ]]; then echo $'\n CUSTOMIZE PROCESSOR CONFIGURATION:' # Number of cores per node (machine specific) if [ "${MACHINE}" == "chrysalis" ]; then ncore=64 elif [ "${MACHINE}" == "BigRed200" ]; then ncore=32 else echo 'ERROR: MACHINE = '${MACHINE}' is not supported for custom PE layout.' exit 400 fi # Extract number of nodes tmp=($(echo ${PELAYOUT} | tr "-" " ")) nnodes=${tmp[1]} # Customize pushd ${CASE_SCRIPTS_DIR} ./xmlchange NTASKS=$(( $nnodes * $ncore )) ./xmlchange NTHRDS=1 ./xmlchange MAX_MPITASKS_PER_NODE=$ncore ./xmlchange MAX_TASKS_PER_NODE=$ncore # Layout-specific customization if [ "${nnodes}" == "1" ]; then echo Using custom 1 nodes layout with BR200 ./xmlchange CPL_NTASKS=$(( $ncore * 1)) ./xmlchange ATM_NTASKS=$(( $ncore * 1)) ./xmlchange OCN_NTASKS=$(( $ncore * 1)) ./xmlchange OCN_ROOTPE=0 ./xmlchange LND_NTASKS=$(( $ncore * 1)) ./xmlchange ROF_NTASKS=$(( $ncore * 1)) ./xmlchange ICE_NTASKS=$(( $ncore * 1)) ./xmlchange LND_ROOTPE=0 ./xmlchange ROF_ROOTPE=0 elif [ "${nnodes}" == "2" ]; then echo Using custom 2 nodes layout with BR200 ./xmlchange CPL_NTASKS=$(( $ncore * 2)) ./xmlchange ATM_NTASKS=$(( $ncore * 2)) ./xmlchange OCN_NTASKS=$(( $ncore * 2)) ./xmlchange OCN_ROOTPE=0 ./xmlchange LND_NTASKS=$(( $ncore * 2)) ./xmlchange ROF_NTASKS=$(( $ncore * 2)) ./xmlchange ICE_NTASKS=$(( $ncore * 2)) ./xmlchange LND_ROOTPE=0 ./xmlchange ROF_ROOTPE=0 elif [ "${nnodes}" == "4" ]; then echo Using custom 4 nodes layout with BR200 ./xmlchange CPL_NTASKS=$(( $ncore * 4)) ./xmlchange ATM_NTASKS=$(( $ncore * 4)) ./xmlchange OCN_NTASKS=$(( $ncore * 4)) ./xmlchange OCN_ROOTPE=0 ./xmlchange LND_NTASKS=$(( $ncore * 4)) ./xmlchange ROF_NTASKS=$(( $ncore * 4)) ./xmlchange ICE_NTASKS=$(( $ncore * 4)) ./xmlchange LND_ROOTPE=0 ./xmlchange ROF_ROOTPE=0 elif [ "${nnodes}" == "8" ]; then echo Using custom 8 nodes layout with BR200 ./xmlchange CPL_NTASKS=$(( $ncore * 8)) ./xmlchange ATM_NTASKS=$(( $ncore * 8)) ./xmlchange OCN_NTASKS=$(( $ncore * 8)) ./xmlchange OCN_ROOTPE=0 ./xmlchange LND_NTASKS=$(( $ncore * 8)) ./xmlchange ROF_NTASKS=$(( $ncore * 8)) ./xmlchange ICE_NTASKS=$(( $ncore * 8)) ./xmlchange LND_ROOTPE=0 ./xmlchange ROF_ROOTPE=0 elif [ "${nnodes}" == "12" ]; then echo Using custom 12 nodes layout with BR200 ./xmlchange CPL_NTASKS=$(( $ncore * 12)) ./xmlchange ATM_NTASKS=$(( $ncore * 12)) ./xmlchange OCN_NTASKS=$(( $ncore * 12)) ./xmlchange OCN_ROOTPE=0 ./xmlchange LND_NTASKS=$(( $ncore * 12)) ./xmlchange ROF_NTASKS=$(( $ncore * 12)) ./xmlchange ICE_NTASKS=$(( $ncore * 12)) ./xmlchange LND_ROOTPE=0 ./xmlchange ROF_ROOTPE=0 else echo 'ERROR: unsupported layout '${PELAYOUT} exit 401 fi popd fi } ###################################################### ### Most users won't need to change anything below ### ###################################################### #----------------------------------------------------- fetch_code() { if [ "${do_fetch_code,,}" != "true" ]; then echo $'\n----- Skipping fetch_code -----\n' return fi echo $'\n----- Starting fetch_code -----\n' local path=${CODE_ROOT} local repo=e3sm echo "Cloning $repo repository branch $BRANCH under $path" if [ -d "${path}" ]; then echo "ERROR: Directory already exists. Not overwriting" exit 20 fi mkdir -p ${path} pushd ${path} # This will put repository, with all code git clone git@github.com:E3SM-Project/${repo}.git . # Setup git hooks rm -rf .git/hooks git clone git@github.com:E3SM-Project/E3SM-Hooks.git .git/hooks git config commit.template .git/hooks/commit.template # Check out desired branch git checkout ${BRANCH} # Custom addition if [ "${CHERRY}" != "" ]; then echo ----- WARNING: adding git cherry-pick ----- for commit in "${CHERRY[@]}" do echo ${commit} git cherry-pick ${commit} done echo ------------------------------------------- fi # Bring in all submodule components git submodule update --init --recursive popd } #----------------------------------------------------- create_newcase() { if [ "${do_create_newcase,,}" != "true" ]; then echo $'\n----- Skipping create_newcase -----\n' return fi echo $'\n----- Starting create_newcase -----\n' if [[ ${PELAYOUT} == custom-* ]]; then layout="M" # temporary placeholder for create_newcase else layout=${PELAYOUT} fi # Base arguments args=" --case ${CASE_NAME} \ --output-root ${CASE_ROOT} \ --script-root ${CASE_SCRIPTS_DIR} \ --handle-preexisting-dirs u \ --compset ${COMPSET} \ --res ${RESOLUTION} \ --machine ${MACHINE} \ --walltime ${WALLTIME} \ --pecount ${layout}" # Optional arguments if [ ! -z "${PROJECT}" ]; then args="${args} --project ${PROJECT}" fi if [ ! -z "${CASE_GROUP}" ]; then args="${args} --case-group ${CASE_GROUP}" fi if [ ! -z "${QUEUE}" ]; then args="${args} --queue ${QUEUE}" fi ${CODE_ROOT}/cime/scripts/create_newcase ${args} if [ $? != 0 ]; then echo $'\nNote: if create_newcase failed because sub-directory already exists:' echo $' * delete old case_script sub-directory' echo $' * or set do_newcase=false\n' exit 35 fi } #----------------------------------------------------- case_setup() { if [ "${do_case_setup,,}" != "true" ]; then echo $'\n----- Skipping case_setup -----\n' return fi echo $'\n----- Starting case_setup -----\n' pushd ${CASE_SCRIPTS_DIR} # Setup some CIME directories ./xmlchange EXEROOT=${CASE_BUILD_DIR} ./xmlchange RUNDIR=${CASE_RUN_DIR} # Short term archiving ./xmlchange DOUT_S=${DO_SHORT_TERM_ARCHIVING^^} ./xmlchange DOUT_S_ROOT=${CASE_ARCHIVE_DIR} # Build with COSP, except for a data atmosphere (datm) if [ `./xmlquery --value COMP_ATM` == "datm" ]; then echo $'\nThe specified configuration uses a data atmosphere, so cannot activate COSP simulator\n' else echo $'\nConfiguring E3SM to use the COSP simulator\n' ./xmlchange --id CAM_CONFIG_OPTS --append --val='-cosp' fi # Extracts input_data_dir in case it is needed for user edits to the namelist later local input_data_dir=`./xmlquery DIN_LOC_ROOT --value` # Custom user_nl user_nl # Finally, run CIME case.setup ./case.setup --reset popd } #----------------------------------------------------- case_build() { pushd ${CASE_SCRIPTS_DIR} # do_case_build = false if [ "${do_case_build,,}" != "true" ]; then echo $'\n----- case_build -----\n' if [ "${OLD_EXECUTABLE}" == "" ]; then # Ues previously built executable, make sure it exists if [ -x ${CASE_BUILD_DIR}/e3sm.exe ]; then echo 'Skipping build because $do_case_build = '${do_case_build} else echo 'ERROR: $do_case_build = '${do_case_build}' but no executable exists for this case.' exit 297 fi else # If absolute pathname exists and is executable, reuse pre-exiting executable if [ -x ${OLD_EXECUTABLE} ]; then echo 'Using $OLD_EXECUTABLE = '${OLD_EXECUTABLE} cp -fp ${OLD_EXECUTABLE} ${CASE_BUILD_DIR}/ else echo 'ERROR: $OLD_EXECUTABLE = '$OLD_EXECUTABLE' does not exist or is not an executable file.' exit 297 fi fi echo 'WARNING: Setting BUILD_COMPLETE = TRUE. This is a little risky, but trusting the user.' ./xmlchange BUILD_COMPLETE=TRUE # do_case_build = true else echo $'\n----- Starting case_build -----\n' # Turn on debug compilation option if requested if [ "${DEBUG_COMPILE^^}" == "TRUE" ]; then ./xmlchange DEBUG=${DEBUG_COMPILE^^} fi # Run CIME case.build ./case.build # Some user_nl settings won't be updated to *_in files under the run directory # Call preview_namelists to make sure *_in and user_nl files are consistent. ./preview_namelists fi popd } #----------------------------------------------------- runtime_options() { echo $'\n----- Starting runtime_options -----\n' pushd ${CASE_SCRIPTS_DIR} # Set simulation start date ./xmlchange RUN_STARTDATE=${START_DATE} # Segment length ./xmlchange STOP_OPTION=${STOP_OPTION,,},STOP_N=${STOP_N} # Restart frequency ./xmlchange REST_OPTION=${REST_OPTION,,},REST_N=${REST_N} # Coupler history ./xmlchange HIST_OPTION=${HIST_OPTION,,},HIST_N=${HIST_N} # Coupler budgets (always on) ./xmlchange BUDGETS=TRUE # Set resubmissions if (( RESUBMIT > 0 )); then ./xmlchange RESUBMIT=${RESUBMIT} fi # Run type # Start from default of user-specified initial conditions if [ "${MODEL_START_TYPE,,}" == "initial" ]; then ./xmlchange RUN_TYPE="startup" ./xmlchange CONTINUE_RUN="FALSE" # Continue existing run elif [ "${MODEL_START_TYPE,,}" == "continue" ]; then ./xmlchange CONTINUE_RUN="TRUE" elif [ "${MODEL_START_TYPE,,}" == "branch" ] || [ "${MODEL_START_TYPE,,}" == "hybrid" ]; then ./xmlchange RUN_TYPE=${MODEL_START_TYPE,,} ./xmlchange GET_REFCASE=${GET_REFCASE} ./xmlchange RUN_REFDIR=${RUN_REFDIR} ./xmlchange RUN_REFCASE=${RUN_REFCASE} ./xmlchange RUN_REFDATE=${RUN_REFDATE} echo 'Warning: $MODEL_START_TYPE = '${MODEL_START_TYPE} echo '$RUN_REFDIR = '${RUN_REFDIR} echo '$RUN_REFCASE = '${RUN_REFCASE} echo '$RUN_REFDATE = '${START_DATE} else echo 'ERROR: $MODEL_START_TYPE = '${MODEL_START_TYPE}' is unrecognized. Exiting.' exit 380 fi # Patch mpas streams files patch_mpas_streams popd } #----------------------------------------------------- case_submit() { if [ "${do_case_submit,,}" != "true" ]; then echo $'\n----- Skipping case_submit -----\n' return fi echo $'\n----- Starting case_submit -----\n' pushd ${CASE_SCRIPTS_DIR} # Run CIME case.submit ./case.submit popd } #----------------------------------------------------- copy_script() { echo $'\n----- Saving run script for provenance -----\n' local script_provenance_dir=${CASE_SCRIPTS_DIR}/run_script_provenance mkdir -p ${script_provenance_dir} local this_script_name=`basename $0` local script_provenance_name=${this_script_name}.`date +%Y%m%d-%H%M%S` cp -vp ${this_script_name} ${script_provenance_dir}/${script_provenance_name} } #----------------------------------------------------- # Silent versions of popd and pushd pushd() { command pushd "$@" > /dev/null } popd() { command popd "$@" > /dev/null } # Now, actually run the script #----------------------------------------------------- main