diff --git a/conf/jobs-real-from-ideal.yaml b/conf/jobs-real-from-ideal.yaml index c7669488f0a23670032034c276fc34dcb7705229..a0a163c9c22974a22df773d0de04b90262172281 100644 --- a/conf/jobs-real-from-ideal.yaml +++ b/conf/jobs-real-from-ideal.yaml @@ -75,16 +75,29 @@ JOBS: FILE: templates/real-from-ideal/prepare_experiment.sh DEPENDENCIES: BUILD_ICON RUNNING: once - WALLCLOCK: 01:00 + WALLCLOCK: 00:10 + + PREPARE_IDEAL_DIRECTORY: + FILE: templates/real-from-ideal/prepare_ideal_directory.sh + DEPENDENCIES: PREPARE_EXPERIMENT + RUNNING: date + WALLCLOCK: 00:10 - PREPARE_DATE: - FILE: templates/real-from-ideal/prepare_date.sh + PREPARE_IDEAL_NAMELIST: + FILE: templates/real-from-ideal/prepare_ideal_namelist.sh + DEPENDENCIES: PREPARE_IDEAL_DIRECTORY + RUNNING: date + WALLCLOCK: 00:10 + + RUN_IDEAL: + FILE: templates/real-from-ideal/run_ideal.sh + DEPENDENCIES: PREPARE_IDEAL_NAMELIST RUNNING: date WALLCLOCK: 01:00 PREPARE_MEMBER: FILE: templates/real-from-ideal/prepare_member.sh - DEPENDENCIES: PREPARE_EXPERIMENT PREPARE_DATE + DEPENDENCIES: RUN_IDEAL RUNNING: member WALLCLOCK: 01:00 @@ -96,7 +109,6 @@ JOBS: TYPE: python EXECUTABLE: "%HPCROOTDIR%/%python_environment.folder_name%/bin/python3" - RUN_ICON: FILE: templates/run_icon.sh DEPENDENCIES: PREPARE_CHUNK diff --git a/templates/real-from-ideal/prepare_date.sh b/templates/real-from-ideal/prepare_date.sh deleted file mode 100644 index 4152601c3603607a80529ea090ab4529d7e4b1aa..0000000000000000000000000000000000000000 --- a/templates/real-from-ideal/prepare_date.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -l - -# Get some variables provided by autosubmit. -WORKDIR=%HPCROOTDIR% -STARTDATE=%SDATE% - -# Define date directory, create it and go there -COMMON_DATE_FOLDER=${WORKDIR}/${STARTDATE}/inidata -# Create member folder and go there -mkdir -p ${COMMON_DATE_FOLDER} -cd ${COMMON_DATE_FOLDER} || exit - -# some settings -AN_MEMBER=$(printf "%03d" %initial_conditions.member%) -INITIAL_CONDITIONS_PARENT_FOLDER=%initial_conditions.parent_folder% - -INITIAL_CONDITIONS_PATH=${INITIAL_CONDITIONS_PARENT_FOLDER}/${STARTDATE:0:6}/${STARTDATE:0:8}T00 - -AN_SOURCE=$(find ${INITIAL_CONDITIONS_PATH} -name "igaf*00.m${AN_MEMBER}.grb" | sort | tail -n 1) -FG_SOURCE=$(find ${INITIAL_CONDITIONS_PATH} -name "igfff00030000.m${AN_MEMBER}.grb" | sort | tail -n 1) - -if [ ! -f "${AN_SOURCE}" ]; then - echo "Analysis file for date ${STARTDATE} not found!" - exit 1 -fi - -if [ ! -f "${FG_SOURCE}" ]; then - echo "FG file for date ${STARTDATE} not found!" - exit 1 -fi - -AN_FILE=$(basename "${AN_SOURCE}") -FG_FILE=$(basename "${FG_SOURCE}") - -# Save filenames to be used later by other scripts. -echo "${AN_FILE}" > an_file.txt -echo "${FG_FILE}" > fg_file.txt - -# Copy the first-guess and analysis files. -cp "${FG_SOURCE}" "${FG_FILE}" -cp "${AN_SOURCE}" "${AN_FILE}" - -# Change permissions to read only. -chmod 440 ./* diff --git a/templates/real-from-ideal/prepare_experiment.sh b/templates/real-from-ideal/prepare_experiment.sh index 5d9b03dcf54d7cb2c3e32780033d78d6ca64d265..b25b40a9fa6eeca08222eb7fb8e40f15c7bf2901 100644 --- a/templates/real-from-ideal/prepare_experiment.sh +++ b/templates/real-from-ideal/prepare_experiment.sh @@ -4,8 +4,6 @@ WORKDIR=%HPCROOTDIR% DYNAMICS_GRID_FILENAME=%simulation.dynamics_grid_filename% RADIATION_GRID_FILE=%simulation.radiation_grid_filename% -EXTERNAL_PARAMETERS_FILE=%simulation.external_parameters_filename% - # Activate spack SPACK_ENV=${WORKDIR}/spack/share/spack/setup-env.sh @@ -33,13 +31,10 @@ function download_file() { BASEURL=http://icon-downloads.mpimet.mpg.de/grids/public/edzw download_file $BASEURL/${DYNAMICS_GRID_FILENAME} download_file $BASEURL/${RADIATION_GRID_FILE} -download_file $BASEURL/${EXTERNAL_PARAMETERS_FILE} # Link input for radiation ln -sf "${ICON_DATA_PATH}/rrtmg_lw.nc" . ln -sf "${ICON_DATA_PATH}/ECHAM6_CldOptProps.nc" . -ln -sf "${ICON_BASE_PATH}/run/ana_varnames_map_file.txt" . - # Change permissions to read only. -chmod 440 ./* \ No newline at end of file +chmod 440 ./* diff --git a/templates/real-from-ideal/prepare_ideal_directory.sh b/templates/real-from-ideal/prepare_ideal_directory.sh new file mode 100644 index 0000000000000000000000000000000000000000..38631ac7fbe75951734aafc22479d96eecef2de0 --- /dev/null +++ b/templates/real-from-ideal/prepare_ideal_directory.sh @@ -0,0 +1,18 @@ +#!/bin/bash -l + +# Get some variables provided by autosubmit. +WORKDIR=%HPCROOTDIR% +STARTDATE=%SDATE% + +# Common folder with data needed for all simulations +COMMON_INIDATA_FOLDER=${WORKDIR}/inidata + +# Ideal folder +IDEAL_DIR=${WORKDIR}/${STARTDATE}/ideal + +# Create member folder and go there +mkdir -p ${IDEAL_DIR} +cd ${IDEAL_DIR} || exit + +# Link all files from the common inidata folder and the common date folder +ln -sf ${COMMON_INIDATA_FOLDER}/* . diff --git a/templates/real-from-ideal/prepare_ideal_namelist.py b/templates/real-from-ideal/prepare_ideal_namelist.py new file mode 100644 index 0000000000000000000000000000000000000000..18714ccedf0010eaec38b0faa3d2e6d72bbe1f49 --- /dev/null +++ b/templates/real-from-ideal/prepare_ideal_namelist.py @@ -0,0 +1,86 @@ +import logging +import re +from datetime import datetime, timedelta +from pathlib import Path + +import f90nml + +logger = logging.getLogger("prepare_chunk") +logger.setLevel(logging.INFO) + +# Get some autosubmit variables +WORKDIR = "%HPCROOTDIR%" +STARTDATE = "%SDATE%" + +# Example of date format "2018-06-01T00:00:00Z" +date_format = "%simulation.date_format%" + +START_YEAR = "%Chunk_START_YEAR%" +START_MONTH = "%Chunk_START_MONTH%" +START_DAY = "%Chunk_START_DAY%" +START_HOUR = "%Chunk_START_HOUR%" + +END_YEAR = "%Chunk_END_YEAR%" +END_MONTH = "%Chunk_END_MONTH%" +END_DAY = "%Chunk_END_DAY%" +END_HOUR = "%Chunk_END_HOUR%" + +Chunk_START_DATE = datetime(year=int(START_YEAR), month=int(START_MONTH), day=int(START_DAY), hour=int(START_HOUR)) +Chunk_END_DATE = datetime(year=int(END_YEAR), month=int(END_MONTH), day=int(END_DAY), hour=int(END_HOUR)) + +# Compute difference in seconds +checkpoint_time = int((Chunk_END_DATE - Chunk_START_DATE).total_seconds()) + +# TODO: Is that really necessary? +# Add 10 minutes to allow the model to write the restarts +Chunk_END_DATE = Chunk_END_DATE + timedelta(minutes=10) +# Get run directory +RUNDIR = Path(f"{WORKDIR}/{STARTDATE}/ideal") + +# Get some variable replacements from the proj.yml file through autosubmit +variable_replacements = { + "dynamics_grid_filename": "%simulation.dynamics_grid_filename%", + "radiation_grid_filename": "%simulation.radiation_grid_filename%", + "external_parameters_filename": "%simulation.external_parameters_filename%", + "Chunk_START_DATE": Chunk_START_DATE.strftime(date_format), + "Chunk_END_DATE": Chunk_END_DATE.strftime(date_format), + "is_restart": False if "%CHUNK%" == "1" else True, + "checkpoint_time": checkpoint_time, +} + + +def adapt_namelist(input_namelist: str, output_namelist: str): + input_namelist = Path(input_namelist) + output_namelist = Path(output_namelist) + + namelist = f90nml.read(input_namelist.as_posix()) + group_keys = [gk for gk in namelist] + + for group in group_keys: + variable_keys = [vk for vk in namelist[group]] + for variable in variable_keys: + value = namelist[group][variable] + m = re.match(r"%(.*)%", str(value)) + if m: + key = m.group(1) + + if key not in variable_replacements: + raise AssertionError(f"The namelist {input_namelist.as_posix()!r} contains the variable {key!r} " + f"which is not in the list of provided replacements:\n" + f"{[v for v in variable_replacements]}") + logger.info(f"Replacing {group}>{variable}:{key} with {variable_replacements[key]!r}") + namelist[group][variable] = variable_replacements[key] + + f90nml.write(nml=namelist, nml_path=output_namelist.as_posix(), force=True) + + +if __name__ == '__main__': + atmosphere_namelist_path = "%simulation.namelist_paths.ideal.atmosphere%" + master_namelist_path = "%simulation.namelist_paths.master%" + + # Adapt atmosphere namelist + adapt_namelist(input_namelist=atmosphere_namelist_path, + output_namelist=(RUNDIR / "icon_atmosphere.namelist").as_posix()) + # Adapt master namelist + adapt_namelist(input_namelist=master_namelist_path, + output_namelist=(RUNDIR / "icon_master.namelist").as_posix()) diff --git a/templates/real-from-ideal/prepare_member.sh b/templates/real-from-ideal/prepare_member.sh index ff7ebc135904287721217e1666d5fcb85a20bfd4..ce40f48b60453135aa163439493822a29ddedca1 100644 --- a/templates/real-from-ideal/prepare_member.sh +++ b/templates/real-from-ideal/prepare_member.sh @@ -7,8 +7,6 @@ MEMBER=%MEMBER% # Common folder with data needed for all simulations COMMON_INIDATA_FOLDER=${WORKDIR}/inidata -# Common folder for the same start date -COMMON_DATE_FOLDER=${WORKDIR}/${STARTDATE}/inidata # Member folder MEMBER_DIR=${WORKDIR}/${STARTDATE}/${MEMBER} @@ -21,4 +19,3 @@ cd ${MEMBER_DIR} || exit # Link all files from the common inidata folder and the common date folder ln -sf ${COMMON_INIDATA_FOLDER}/* . -ln -sf ${COMMON_DATE_FOLDER}/* . diff --git a/templates/real-from-ideal/run_ideal.sh b/templates/real-from-ideal/run_ideal.sh new file mode 100644 index 0000000000000000000000000000000000000000..cec0251755487445e1b3a510023a5856d4912e88 --- /dev/null +++ b/templates/real-from-ideal/run_ideal.sh @@ -0,0 +1,23 @@ +# Get some variables provided by autosubmit. +WORKDIR=%HPCROOTDIR% +ICON_VERSION=%ICON_VERSION% + +STARTDATE=%SDATE% + +# Define rundir +RUNDIR=${WORKDIR}/${STARTDATE}/ideal + +# Go to the ideal rundir +cd ${RUNDIR} + +# Activate spack +SPACK_ENV=${WORKDIR}/spack/share/spack/setup-env.sh +source ${SPACK_ENV} +# Load icon module +spack load icon-nwp@%ICON_VERSION% + +# Set environment variable for eccodes-dwd definitions: +source ${WORKDIR}/eccodes_defs.env + +# Run icon +srun icon