From 570ac4e43992938890df0677efe84ad0e5f0dbdb Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Fri, 30 Jun 2023 14:28:58 +0200 Subject: [PATCH 01/39] minor correction for issue #5 style, starting of how to use read.me for mn4 for issue 3 --- sources/data-coupler/how_to_run_mn4.ipynb | 152 +++++++++++++++++++++ sources/ece3-toy-model/launch_yaml_mn4.cmd | 1 - sources/ece3-toy-model/toy_model.py | 2 +- 3 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 sources/data-coupler/how_to_run_mn4.ipynb diff --git a/sources/data-coupler/how_to_run_mn4.ipynb b/sources/data-coupler/how_to_run_mn4.ipynb new file mode 100644 index 0000000..99e235c --- /dev/null +++ b/sources/data-coupler/how_to_run_mn4.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Introduction \n", + "The Data Coupler is being developed at the BSC to implement a CO2 box model for EC-Earth3 and to read and interpolate CO2 anthropogenic emissions (from e.g. CMIP6 input4MIPS) and CO2 surface fluxes (from e.g. vegetation+fire+ocean fluxes from SiB4). \n", + "\n", + "## Getting the model \n", + "The model can be cloned from (BSC-ES gitlab repository)[https://earth.bsc.es/gitlab/es/python-amip-reader] \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "git clone https://earth.bsc.es/gitlab/es/python-amip-reader.git\n", + "cd python-amip-reader\n", + "git checkout data-coupler" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setting up the model\n", + "First copy the datasets from Etienne's directory ```/gpfs/scratch/bsc32/bsc32051/git/python-amip-reader/tests/data/```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "datadir=/gpfs/scratch/bsc32/bsc32051/git/python-amip-reader/tests/data/\n", + "cd /python-amip-reader\n", + "cp $datadir/forcing/* tests/data/forcing\n", + "cp $datadir/co2/* tests/data/co2" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To build oasis and the optional fortran amip-forcing follow the instructions in https://earth.bsc.es/gitlab/es/python-amip-reader/-/blob/data-coupler/README.md#compile" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cd /sources/oasis3-mct/util/make_dir\n", + "cp make.templ.inc make.inc\n", + "# change this line\n", + "# include $(curr_path)/make.mn4\n", + "# to\n", + "# include $(curr_path)/make.hpc2020\n", + " \n", + "cd $HPCPERM/work/python-amip-reader/sources/amip-forcing/src/fortran\n", + " \n", + "module reset ; module load python3/3.10.10-01 prgenv/intel intel/2021.4.0 hpcx-openmpi/2.9.0 hdf5-parallel/1.12.2 netcdf4-parallel/4.9.1\n", + " \n", + "make realclean && make oasis && make" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Running the model\n", + "To run the model you need to edit file $HPCPERM/work/python-amip-reader/tests/launch-hpc2020.cmd and make sure the proper configuration is un-commented at the end, for example\n", + "\n", + "For a simple AMIP run using the classic fortran amip-forcing: \n", + "\n", + "bash ./run_example.sh fortran forcing 4 2005-01-01 2005-03-01 0 128 true false\n", + "\n", + "For the CO2 box model :\n", + "\n", + "bash ./run_example.sh co2box co2 4 2005-01-01 2005-05-01 0 128 true false\n", + "\n", + "The following lines hard-coded in run_example.sh control the options of the CO2 box model\n", + "\n", + " CO2_CMODE=true # set to false to disable co2 concentrations reading\n", + " CO2_EMODE=true # set to false to disable emissions reading\n", + "\n", + "\n", + "\n", + "There are 2 ways to run the model: \n", + "\n", + "1) run an interactive session and launch the job with bash (for short runs and debugging)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ecinteractive -c6 -t 12:00:00 -m 32GB\n", + "cd $HPCPERM/work/python-amip-reader/tests/\n", + "bash launch-hpc2020.cmd" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "2) launch the job with sbatch (for longer runs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cd $HPCPERM/work/python-amip-reader/tests/\n", + "sbatch launch-hpc2020.cmd" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If the run is successful, output will be present in a folder representing the run you made e.g. work_fortran_forcing_4_2005-01-01_2005-03-01_0_128_true\n", + "\n", + "Some files are post-processed with proper grid and time metadata applied." + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/sources/ece3-toy-model/launch_yaml_mn4.cmd b/sources/ece3-toy-model/launch_yaml_mn4.cmd index 764fe7e..195766f 100644 --- a/sources/ece3-toy-model/launch_yaml_mn4.cmd +++ b/sources/ece3-toy-model/launch_yaml_mn4.cmd @@ -35,7 +35,6 @@ done cp -f $datadir/rmp* $rundir cp -f $srcdir/*.py $rundir cp -f $srcdir/namcouple $rundir -cp -f $srcdir/*.yaml $rundir cd $rundir diff --git a/sources/ece3-toy-model/toy_model.py b/sources/ece3-toy-model/toy_model.py index 5eada78..38ba24e 100644 --- a/sources/ece3-toy-model/toy_model.py +++ b/sources/ece3-toy-model/toy_model.py @@ -46,7 +46,7 @@ if __name__ == '__main__': coupling = read_in_data.get("coupling") coupling_out_vars = coupling.get("out_vars") coupling_in_vars = coupling.get("in_vars") - restart_file = coupling.get("restart_file") + restart_file = coupling.get("restart_file") # This feature is not used for now. TODO ### Pass the values to original code -- GitLab From 896dcde8f8aaac702fb5085506d94779207768d6 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 4 Jul 2023 15:26:48 +0200 Subject: [PATCH 02/39] including the yaml function to read and write namelist for datacoupler. It will replace the method that is used to read and write namelists. small notebook to explain how to run Datacoupler on mn4 is also included --- .gitignore | 2 + sources/data-coupler/how_to_run_mn4.ipynb | 39 ++++++--- sources/data-coupler/launch_yaml_mn4.cmd | 24 ++++++ sources/data-coupler/namelist.amip_py.sh | 21 +++++ sources/data-coupler/yamlUtils.py | 98 +++++++++++++++++++++++ 5 files changed, 174 insertions(+), 10 deletions(-) create mode 100644 sources/data-coupler/launch_yaml_mn4.cmd create mode 100755 sources/data-coupler/namelist.amip_py.sh create mode 100644 sources/data-coupler/yamlUtils.py diff --git a/.gitignore b/.gitignore index f6561a6..dd87366 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ work_* sources/oasis3-mct/generated __pycache__ +tests/* +tests/data// tests/.coverage* tests/htmlcov sources/oasis3-mct/util/make_dir/make.inc diff --git a/sources/data-coupler/how_to_run_mn4.ipynb b/sources/data-coupler/how_to_run_mn4.ipynb index 99e235c..48b592b 100644 --- a/sources/data-coupler/how_to_run_mn4.ipynb +++ b/sources/data-coupler/how_to_run_mn4.ipynb @@ -41,8 +41,8 @@ "source": [ "datadir=/gpfs/scratch/bsc32/bsc32051/git/python-amip-reader/tests/data/\n", "cd /python-amip-reader\n", - "cp $datadir/forcing/* tests/data/forcing\n", - "cp $datadir/co2/* tests/data/co2" + "cp -r $datadir/forcing/* tests/data/forcing\n", + "cp -r $datadir/co2/* tests/data/co2" ] }, { @@ -60,16 +60,35 @@ "outputs": [], "source": [ "cd /sources/oasis3-mct/util/make_dir\n", - "cp make.templ.inc make.inc\n", - "# change this line\n", - "# include $(curr_path)/make.mn4\n", - "# to\n", - "# include $(curr_path)/make.hpc2020\n", - " \n", - "cd $HPCPERM/work/python-amip-reader/sources/amip-forcing/src/fortran\n", + "cp make.templ.inc make.inc" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Please chnage the path of the make file to include MN4, and then complie the as follows: " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "include $(curr_path)/make.mn4\n", + "\n", " \n", - "module reset ; module load python3/3.10.10-01 prgenv/intel intel/2021.4.0 hpcx-openmpi/2.9.0 hdf5-parallel/1.12.2 netcdf4-parallel/4.9.1\n", + "cd ../sources/amip-forcing/src/fortran\n", " \n", + "module load impi/2017.4\n", + "module load mkl/2017.4\n", + "module load intel/2021.4\n", + "module load python/3.6.1\n", + "module load netcdf/4.2\n", + "module load cdo/1.9.3\n", + "\n", "make realclean && make oasis && make" ] }, diff --git a/sources/data-coupler/launch_yaml_mn4.cmd b/sources/data-coupler/launch_yaml_mn4.cmd new file mode 100644 index 0000000..fcf86f7 --- /dev/null +++ b/sources/data-coupler/launch_yaml_mn4.cmd @@ -0,0 +1,24 @@ +#!/bin/bash + +# slurm specific options for Marenostrum4 +#SBATCH --qos=debug +#SBATCH -N 1 +#SBATCH -n 3 +#SBATCH -c 1 +#SBATCH -t 00:05:00 +#SBATCH --exclusive + +#load python and netcdf modules +export PYTHONPATH="" +module load python/3.6.1 +module load netcdf/4.2 + +set -xuve + + + +# run yaml script +chmod +x namelist.amip_py.sh +bash namelist.amip_py.sh +#python3 YAML_util.py +# --yaml_file_path ifs_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path nemo_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path runoff_toy_model.yaml diff --git a/sources/data-coupler/namelist.amip_py.sh b/sources/data-coupler/namelist.amip_py.sh new file mode 100755 index 0000000..79e8e9d --- /dev/null +++ b/sources/data-coupler/namelist.amip_py.sh @@ -0,0 +1,21 @@ +# flist_* can hold lists of files, separated by commas +#flist_sst=\'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc\' +#flist_sic=\'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc\' +#to generate VHR amip files for Edu... +#flist_sst=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sst_2010.nc\' +#flist_sic=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sic_2010.nc\' + +#!/bin/bash +mpirun -np 1 python3 yamlUtils.py \ + --file_name namelist.yaml \ + --leg_length_sec 5097600 \ + --cpl_freq_amip_sec 86400 \ + --leg_start_date_yyyy 2005 \ + --leg_start_date_mm 01 \ + --leg_start_date_dd 01 \ + --ifs_cmip_fixyear 0 \ + --flist_sst tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc \ + --flist_sic siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc \ + --LDebug False\ + --LInterpolate False + diff --git a/sources/data-coupler/yamlUtils.py b/sources/data-coupler/yamlUtils.py new file mode 100644 index 0000000..695391f --- /dev/null +++ b/sources/data-coupler/yamlUtils.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +# Copyright 2023 - Barcelona Supercomputing Center +# Authors: Amirpasha Mozaffari +# MIT License + +import yaml +from yaml.loader import SafeLoader +import os +import argparse + + +def argument_parse_namelist_amip(): + parser = argparse.ArgumentParser() + parser.add_argument("--file_name",default="value0", type=str, help='name of the YAML file that will be created') + parser.add_argument("--leg_length_sec",default="value1", type=str, help='TBD') + parser.add_argument("--cpl_freq_amip_sec",default="value2", type=str, help='TBD') + parser.add_argument("--leg_start_date_yyyy",default="value3", type=str, help='TBD') + parser.add_argument("--leg_start_date_mm",default="value4", type=str, help='TBD') + parser.add_argument("--leg_start_date_dd",default="value5", type=str, help='TBD') + parser.add_argument("--ifs_cmip_fixyear",default="value6", type=str, help='TBD') + parser.add_argument("--flist_sst",default="value7", type=str, help='TBD') + parser.add_argument("--flist_sic",default="value8", type=str, help='TBD') + parser.add_argument("--LDebug",default="value9", type=str, help='TBD') + parser.add_argument("--LInterpolate",default="value10", type=str, help='TBD') + input_argument = vars(parser.parse_args()) #convertargparseNameSpace to dict + print(type(input_argument)) + return input_argument + + +def read_yaml_file(file_name): + current_path = os.getcwd() + yamel_file_path = os.path.join(current_path,file_name) + if os.path.isfile(yamel_file_path) == False: + print("YAML file does not exist. Aborted") + raise NameError("YAML file does not exist.") + + #Open the file and load the file + with open(yamel_file_path) as file: + read_in_data = yaml.load(file, Loader=SafeLoader) + print(read_in_data) + file.close() + return read_in_data + + +def write_namelist_amip_yaml(input_arguments): + ''' + write down a yaml file, by using the input arguments that passed to it. + + ''' + + file_name = input_arguments.get("file_name") + leg_length_sec = input_arguments.get("leg_length_sec") + cpl_freq_amip_sec = input_arguments.get("cpl_freq_amip_sec") + leg_start_date_yyyy = input_arguments.get("leg_start_date_yyyy") + leg_start_date_mm = input_arguments.get("leg_start_date_mm") + leg_start_date_dd = input_arguments.get("leg_start_date_dd") + ifs_cmip_fixyear = input_arguments.get("ifs_cmip_fixyear") + flist_sst= input_arguments.get("flist_sst") + flist_sic= input_arguments.get("flist_sic") + LDebug = input_arguments.get("LDebug") + LInterpolate = input_arguments.get("LInterpolate") + + # yaml file path + current_path = os.getcwd() + yamel_file_path = os.path.join(current_path,file_name) + + + # remove if the YAML file exist + if os.path.isfile(yamel_file_path) == True: + os.remove(yamel_file_path) + print("file exists, older file is deleted.") + + yaml_write_doc = [{'RunLengthSec' : [leg_length_sec]}, + {'TimeStepSec' : [cpl_freq_amip_sec]}, + {'StartYear' : [leg_start_date_yyyy]}, + {'StartMonth' : [leg_start_date_mm]}, + {'StartDay' : [leg_start_date_dd]}, + {'FixYear' : [ifs_cmip_fixyear]}, + {'FileListSST' : [flist_sst]}, + {'FileListSIC' : [flist_sic]}, + {'LDebug' : [LDebug]}, + {'LInterpolate' : [LInterpolate]}] + + with open(yamel_file_path, 'w') as file: + file.write('# This is an input namelist file for DataCoupler tool\n') + documents = yaml.dump(yaml_write_doc, file, width=50, indent=1) + file.close + + return file_name + +if __name__ == '__main__': + + input_arguments = argument_parse_namelist_amip() + file_name = write_namelist_amip_yaml(input_arguments) + read_yaml_file(file_name) + + print("Run finished") + -- GitLab From 6f559454dfee8325171a377b6b207135b3e3c2bb Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 4 Jul 2023 17:06:29 +0200 Subject: [PATCH 03/39] replacing the namelist with yaml, using the bash. small test is created --- sources/data-coupler/namelist.amip | 15 ++++++++++++ sources/data-coupler/namelist.amip.sh | 24 ++++++++++++++++++++ sources/data-coupler/namelist.amip.yaml | 11 +++++++++ sources/data-coupler/namelist.amip_yaml.sh | 20 ++++++++++++++++ sources/data-coupler/namelist.yaml | 21 +++++++++++++++++ sources/data-coupler/namelist_toghether.yaml | 21 +++++++++++++++++ 6 files changed, 112 insertions(+) create mode 100644 sources/data-coupler/namelist.amip create mode 100755 sources/data-coupler/namelist.amip.sh create mode 100644 sources/data-coupler/namelist.amip.yaml create mode 100755 sources/data-coupler/namelist.amip_yaml.sh create mode 100644 sources/data-coupler/namelist.yaml create mode 100644 sources/data-coupler/namelist_toghether.yaml diff --git a/sources/data-coupler/namelist.amip b/sources/data-coupler/namelist.amip new file mode 100644 index 0000000..82cd99e --- /dev/null +++ b/sources/data-coupler/namelist.amip @@ -0,0 +1,15 @@ +!----------------------------------------------------------------------- +&NAMAMIP +!----------------------------------------------------------------------- + RunLengthSec = 31622400 + TimeStepSec = 86400 + StartYear = 2004 + StartMonth = 01 + StartDay = 01 + FixYear = 0 + FileListSST = 'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc' + FileListSIC = 'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc' + LDebug = false + LInterpolate = No +!----------------------------------------------------------------------- +/ diff --git a/sources/data-coupler/namelist.amip.sh b/sources/data-coupler/namelist.amip.sh new file mode 100755 index 0000000..c072ff4 --- /dev/null +++ b/sources/data-coupler/namelist.amip.sh @@ -0,0 +1,24 @@ +# flist_* can hold lists of files, separated by commas +flist_sst=\'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc\' +flist_sic=\'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc\' +#to generate VHR amip files for Edu... +#flist_sst=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sst_2010.nc\' +#flist_sic=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sic_2010.nc\' + +cat << EOF +!----------------------------------------------------------------------- +&NAMAMIP +!----------------------------------------------------------------------- + RunLengthSec = ${leg_length_sec} + TimeStepSec = ${cpl_freq_amip_sec} + StartYear = ${leg_start_date_yyyymmdd:0:4} + StartMonth = ${leg_start_date_yyyymmdd:4:2} + StartDay = ${leg_start_date_yyyymmdd:6:2} + FixYear = ${ifs_cmip_fixyear} + FileListSST = ${flist_sst} + FileListSIC = ${flist_sic} + LDebug = false + LInterpolate = ${amip_interpolate} +!----------------------------------------------------------------------- +/ +EOF diff --git a/sources/data-coupler/namelist.amip.yaml b/sources/data-coupler/namelist.amip.yaml new file mode 100644 index 0000000..df6b735 --- /dev/null +++ b/sources/data-coupler/namelist.amip.yaml @@ -0,0 +1,11 @@ +# YAML file input + RunLengthSec : - 31622400 + TimeStepSec : - 86400 + StartYear : - 2004 + StartMonth : - 01 + StartDay : - 01 + FixYear : - 0 + FileListSST : - tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc + FileListSIC : - siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc + LDebug : - false + LInterpolate : No diff --git a/sources/data-coupler/namelist.amip_yaml.sh b/sources/data-coupler/namelist.amip_yaml.sh new file mode 100755 index 0000000..3dcb1f6 --- /dev/null +++ b/sources/data-coupler/namelist.amip_yaml.sh @@ -0,0 +1,20 @@ +# flist_* can hold lists of files, separated by commas +flist_sst=tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc +flist_sic=siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc +#to generate VHR amip files for Edu... +#flist_sst=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sst_2010.nc\' +#flist_sic=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sic_2010.nc\' + +cat << EOF +# YAML file input + RunLengthSec : - ${leg_length_sec} + TimeStepSec : - ${cpl_freq_amip_sec} + StartYear : - ${leg_start_date_yyyymmdd:0:4} + StartMonth : - ${leg_start_date_yyyymmdd:4:2} + StartDay : - ${leg_start_date_yyyymmdd:6:2} + FixYear : - ${ifs_cmip_fixyear} + FileListSST : - ${flist_sst} + FileListSIC : - ${flist_sic} + LDebug : - false + LInterpolate : ${amip_interpolate} +EOF diff --git a/sources/data-coupler/namelist.yaml b/sources/data-coupler/namelist.yaml new file mode 100644 index 0000000..ee75c56 --- /dev/null +++ b/sources/data-coupler/namelist.yaml @@ -0,0 +1,21 @@ +# This is an input namelist file for DataCoupler tool +- RunLengthSec: + - '5097600' +- TimeStepSec: + - '86400' +- StartYear: + - '2005' +- StartMonth: + - '01' +- StartDay: + - '01' +- FixYear: + - '0' +- FileListSST: + - tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc +- FileListSIC: + - siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc +- LDebug: + - 'False' +- LInterpolate: + - 'False' diff --git a/sources/data-coupler/namelist_toghether.yaml b/sources/data-coupler/namelist_toghether.yaml new file mode 100644 index 0000000..370a780 --- /dev/null +++ b/sources/data-coupler/namelist_toghether.yaml @@ -0,0 +1,21 @@ +# This is an input namelist file for DataCoupler tool +- RunLengthSec: + - '31622400' +- TimeStepSec: + - '86400' +- StartYear: + - '2004' +- StartMonth: + - '01' +- StartDay: + - '01' +- FixYear: + - '0' +- FileListSST: + - '''tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc''' +- FileListSIC: + - '''siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc''' +- LDebug: + - 'No' +- LInterpolate: + - 'No' -- GitLab From 82a7b0a2461924bb2721a875ae54e32bd3ddbe16 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 4 Jul 2023 17:08:07 +0200 Subject: [PATCH 04/39] replace test case for namelist with yaml --- sources/data-coupler/test.sh | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 sources/data-coupler/test.sh diff --git a/sources/data-coupler/test.sh b/sources/data-coupler/test.sh new file mode 100644 index 0000000..b3ecde5 --- /dev/null +++ b/sources/data-coupler/test.sh @@ -0,0 +1,38 @@ +#!/bin/bash +## Usage + +# module load python/3.6.1 +# module load netcdf/4.2 + +leg_end_date=20050101 +leg_start_date=20040101 +model=fortran +amip_mode=forcing +amip_interpolate=No +ifs_cmip_fixyear=0 + +leg_length_sec=$(( $(date -u -d "${leg_end_date}" +%s) - $(date -u -d "${leg_start_date}" +%s) )) +cpl_freq_amip_sec=86400 # Always +leg_start_date_yyyymmdd=$(date -u -d "${leg_start_date}" +%Y%m%d) + +if [ $model = fortran ] || [ $model = pythoncompat ]; then + if [ $amip_mode = forcing ]; then + #how it is done + . ./namelist.amip.sh > ./namelist.amip + #how will be in YAML + . ./namelist.amip_yaml.sh > ./namelist.amip.yaml + #how will be python + # python3 yamlUtils.py \ + # --file_name namelist_toghether.yaml \ + # --leg_length_sec ${leg_length_sec} \ + # --cpl_freq_amip_sec ${cpl_freq_amip_sec} \ + # --leg_start_date_yyyy ${leg_start_date_yyyymmdd:0:4} \ + # --leg_start_date_mm ${leg_start_date_yyyymmdd:4:2} \ + # --leg_start_date_dd ${leg_start_date_yyyymmdd:6:2} \ + # --ifs_cmip_fixyear ${ifs_cmip_fixyear} \ + # --flist_sst ${flist_sst} \ + # --flist_sic ${flist_sic} \ + # --LDebug No\ + # --LInterpolate ${amip_interpolate} + fi +fi -- GitLab From e236fb28f4ea04b4d5a32d5e15318ac86ebf130a Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 5 Jul 2023 17:01:10 +0200 Subject: [PATCH 05/39] place holder for yaml creator in run-example --- .gitignore | 10 +++++- tests/data/namelist_python.amip_yaml.sh | 47 +++++++++++++++++++++++++ tests/launch-mn4.cmd | 3 +- tests/run_example.sh | 4 +++ 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100755 tests/data/namelist_python.amip_yaml.sh diff --git a/.gitignore b/.gitignore index dd87366..b61c0d1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,16 @@ work_* sources/oasis3-mct/generated __pycache__ -tests/* tests/data// tests/.coverage* tests/htmlcov +tests/.gitignore +tests/amip.yaml.sh +tests/data/areas-amip.nc +tests/data/bak/ +tests/data/ece3-toy-model/ +tests/data/grids-amip.nc +tests/data/masks-amip.nc +tests/data/test_word_break.sh +tests/data/tmp1.nc sources/oasis3-mct/util/make_dir/make.inc diff --git a/tests/data/namelist_python.amip_yaml.sh b/tests/data/namelist_python.amip_yaml.sh new file mode 100755 index 0000000..fb36694 --- /dev/null +++ b/tests/data/namelist_python.amip_yaml.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +echo $co2_conf_var +echo "$co2_conf_var" +echo '$co2_conf_var' + +temp1="" +lines="" +line_number=1 +IFS=' ' read -ra ADDR <<< $co2_conf_var +for i in "${ADDR[@]}"; do + SUB='FileInputVars' + if grep -q "$SUB" <<< "$i"; then + lines[line_number]=$temp1 + line_number=$line_number+1 + echo $temp1 + temp1="" + echo "Start of the new line" + + else + temp1="$temp1 $i" + echo "No match found" + fi + echo $i +done + +echo $lines + + +cat << EOF +# YAML file input + RunLengthSec : - ${leg_length_sec} + TimeStepSec : - ${cpl_freq_amip_sec} + StartYear : - ${leg_start_date_yyyymmdd:0:4} + StartMonth : - ${leg_start_date_yyyymmdd:4:2} + StartDay : - ${leg_start_date_yyyymmdd:6:2} + FixYear : - ${ifs_cmip_fixyear} + FileInputVars1 : - ${sst_conf_var:21:${#sst_conf_var}} + FileInputVars2 : - ${sic_conf_var:21:${#sic_conf_var}} + + + XXX3 : - ${co2_conf_var:21:${#co2_conf_var}} + + + XXX4 : - ${oasis_conf_var:21:${#oasis_conf_var}} + LDebug : - false +EOF diff --git a/tests/launch-mn4.cmd b/tests/launch-mn4.cmd index 95c5fd6..993ba6b 100644 --- a/tests/launch-mn4.cmd +++ b/tests/launch-mn4.cmd @@ -3,11 +3,12 @@ #SBATCH -N 1 #SBATCH -n 5 #SBATCH -c 1 -#SBATCH -t 1:00:00 +#SBATCH -t 0:05:00 #SBATCH --exclusive module load python/3.6.1 module load netcdf/4.2 +module load CDO/1.9.3 module list export MPIRUN="mpirun" diff --git a/tests/run_example.sh b/tests/run_example.sh index dcb068f..89e0821 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -124,8 +124,10 @@ leg_start_date_yyyymmdd=$(date -u -d "${leg_start_date}" +%Y%m%d) if [ $model = fortran ] || [ $model = pythoncompat ]; then if [ $amip_mode = forcing ]; then . ./namelist.amip.sh > ./namelist.amip + echo 'NOTE: model - fortran / Forcing' else . ./namelist_primavera.amip.sh > ./namelist.amip + echo 'NOTE: model - fortran / PRIMAVERA' fi else #if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then @@ -196,6 +198,8 @@ else oasis_conf_var="" fi . ./namelist_python.amip.sh > ./namelist.amip + echo 'NOTE: model - fortran / namelist_python.amip.sh' + . ./namelist_python.amip_yaml.sh > ./namelist.amip.yaml [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box fi if [ $amip_mode = forcing ]; then -- GitLab From 47aef8fb302a60e811b36d5f85275d3d44f74ca5 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Thu, 6 Jul 2023 16:38:00 +0200 Subject: [PATCH 06/39] it produce a yml output alongside the namelist, and able to read in the simple yml file, excluding the list of the vars for oasis --- sources/data-coupler/DataCoupler.py | 10 +++++ sources/data-coupler/DataCouplerUtils.py | 56 ++++++++++++++++++++++++ tests/data/namelist_python.amip_yaml.sh | 50 +++++---------------- tests/run_example.sh | 30 ++++++++++--- 4 files changed, 102 insertions(+), 44 deletions(-) diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 854e2a5..420bc8c 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -9,8 +9,10 @@ import numpy as np import os import logging import math +import sys from DataCouplerUtils import read_namelist, days_since_refyear, is_leap, earth_area +from DataCouplerUtils import read_ymllist from DataCouplerFileVar import FileInputVar from DataCouplerOasisVar import OasisOutputVar @@ -21,6 +23,14 @@ class DataCoupler: # Read RunLengthSec,TimeStepSec, config, etc. from namelist RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_namelist(NAMELIST_FILE_NAME, NAMELIST_SECTION) + + ### TODO for now it is feed in the middle of the function + YAML_NAMELIST_FILE_NAME = "namelist.amip.yaml" + RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, \ + StartDay_y, FixYear_y = read_ymllist(YAML_NAMELIST_FILE_NAME) + print("NEXT LINE IS PRODUCED BY YAML FILE READER", file=sys.stderr) + print(RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, StartDay_y, FixYear_y, file=sys.stderr) + if LDebug: logging.basicConfig(filename=LOG_FILE_NAME, format='%(message)s', level=logging.DEBUG) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index d84fdc8..1b8d158 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -5,6 +5,9 @@ from datetime import date import re import f90nml import numpy as np +import yaml +from yaml.loader import SafeLoader + # constants earth_area = 6371000.**2 @@ -219,3 +222,56 @@ def read_namelist(NAMELIST_FILE_NAME,NAMELIST_SECTION): return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config + + + +def read_ymllist(YAML_NAMELIST_FILE_NAME): + ''' + Reads the namelist. + ''' + yamel_file=YAML_NAMELIST_FILE_NAME + + with open(yamel_file) as f: + nmly = yaml.load(f, Loader=SafeLoader) + f.close() + + RunLengthSec = nmly['RunLengthSec'] + TimeStepSec = nmly['TimeStepSec'] + StartYear = nmly['StartYear'] + StartMonth = nmly['StartMonth'] + StartDay = nmly['StartDay'] + FixYear = nmly['FixYear'] + #LDebug = nmly['LDebug'] + + return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear + +# TODO will be deleted +# ### Read in YAML file +# current_path = os.getcwd() +# parser=argparse.ArgumentParser() +# parser.add_argument("--yaml_file_path",type=str) +# args = parser.parse_args() +# yamel_file_path = os.path.join(current_path,args.yaml_file_path) +# if os.path.isfile(yamel_file_path) == False: +# print("YAML file does not exist. Aborted") +# raise NameError("YAML file does not exist.") + +# # Open the file and load the file + + +# ### Read in file +# #read_yaml(read_in_data) +# model = read_in_data.get("model") +# model_name = model.get("model_name") + +# # Read in Simulation information +# simulation = read_in_data.get("simulation") +# simulation_coupling_interval = simulation.get("coupling_interval") +# simulation_run_length_sec = simulation.get("run_length_sec") +# simulation_nx = simulation.get("nx") + +# # Read in Coupling infomration +# coupling = read_in_data.get("coupling") +# coupling_out_vars = coupling.get("out_vars") +# coupling_in_vars = coupling.get("in_vars") +# restart_file = coupling.get("restart_file") # This feature is not used for now. TODO \ No newline at end of file diff --git a/tests/data/namelist_python.amip_yaml.sh b/tests/data/namelist_python.amip_yaml.sh index fb36694..8d8046e 100755 --- a/tests/data/namelist_python.amip_yaml.sh +++ b/tests/data/namelist_python.amip_yaml.sh @@ -1,47 +1,19 @@ #!/bin/bash -echo $co2_conf_var -echo "$co2_conf_var" -echo '$co2_conf_var' - -temp1="" -lines="" -line_number=1 -IFS=' ' read -ra ADDR <<< $co2_conf_var -for i in "${ADDR[@]}"; do - SUB='FileInputVars' - if grep -q "$SUB" <<< "$i"; then - lines[line_number]=$temp1 - line_number=$line_number+1 - echo $temp1 - temp1="" - echo "Start of the new line" - - else - temp1="$temp1 $i" - echo "No match found" - fi - echo $i -done - -echo $lines - cat << EOF # YAML file input - RunLengthSec : - ${leg_length_sec} - TimeStepSec : - ${cpl_freq_amip_sec} - StartYear : - ${leg_start_date_yyyymmdd:0:4} - StartMonth : - ${leg_start_date_yyyymmdd:4:2} - StartDay : - ${leg_start_date_yyyymmdd:6:2} - FixYear : - ${ifs_cmip_fixyear} - FileInputVars1 : - ${sst_conf_var:21:${#sst_conf_var}} - FileInputVars2 : - ${sic_conf_var:21:${#sic_conf_var}} - - - XXX3 : - ${co2_conf_var:21:${#co2_conf_var}} +RunLengthSec : ${leg_length_sec} +TimeStepSec : ${cpl_freq_amip_sec} +StartYear : ${leg_start_date_yyyymmdd:0:4} +StartMonth : ${leg_start_date_yyyymmdd:4:2} +StartDay : ${leg_start_date_yyyymmdd:6:2} +FixYear : ${ifs_cmip_fixyear} +$sst_conf_var_yml +$sic_conf_var_yml +$co2_conf_var_yml +$oasis_conf_var_yml +LDebug : false - XXX4 : - ${oasis_conf_var:21:${#oasis_conf_var}} - LDebug : - false EOF diff --git a/tests/run_example.sh b/tests/run_example.sh index 89e0821..1e02f7e 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -133,18 +133,26 @@ else #if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then i=1 + ii=1 if [ $model = co2box ] || [ $model = datacoupler ]; then var=FileInputVars else var=Vars fi sst_conf_var=${var}"("$((i++))",:) = 'AMIP_sst_monthly', 'AMIP', 'AMIP_sst', 'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc', 'tosbcs', 1870, 2016, 'monthly', ${amip_interpolate}, 1, 273.15, 271.38, ,true,true," + sst_conf_var_yml="${var}("$((ii++))"): AMIP_sst_monthly, AMIP', AMIP_sst, tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, tosbcs, 1870, 2016, monthly, ${amip_interpolate}, 1, 273.15, 271.38, , true, true" + sic_conf_var=${var}"("$((i++))",:) = 'AMIP_sic_monthly', 'AMIP', 'AMIP_sic', 'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc', 'siconcbcs', 1870, 2016, 'monthly', ${amip_interpolate}, 0.01, 0, 0, 1,true,true," + sic_conf_var_yml="${var}("$((ii++))"): AMIP_sic_monthly, AMIP, AMIP_sic, siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, siconcbcs, 1870, 2016, monthly, ${amip_interpolate}, 0.01, 0, 0, 1, true, true" j=1 + jj=1 + oasis_conf_var_yml="" oasis_conf_var="!OasisOutputVars(j,:) = , , , , , \n" oasis_conf_var=$'\n'"OasisOutputVars("$((j++))",:) = 'AMIP_sst', 'AMIP', 'daily', 1, 0, true," + oasis_conf_var_yml="OasisOutputVars("$((jj++))") : AMIP_sst, AMIP, daily, 1, 0, true"$'\n' oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = 'AMIP_sic', 'AMIP', 'daily', 1, 0, true," + oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : AMIP_sic, AMIP, daily, 1, 0, true"$'\n' if [ $amip_mode = co2 ]; then co2_conf_var="" co2_conf_var+="!FileInputVars(i,:) = "$'\n' @@ -172,11 +180,20 @@ else fi if [ ${CO2_EMODE} == true ] ; then # this is the 3D monthly emissions used for ECE4, the calendar fix mentionned below is probably required - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_em_monthly', 'CO2_emis', '"$mod"_CO2_emis', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 1, 0, , ,true,true,"$'\n' - # add land/ocean fluxes equal to 0.5/0.1 that of emissions, for demonstration purposes + co2_conf_var_yml="" + + + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_em_monthly', 'CO2_emis', '"$mod"_CO2_emis', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 1, 0, , ,true,true,"$'\n' + co2_conf_var_yml+="${var}("$((ii++))"): CO2_em_monthly, CO2_emis, "$mod"_CO2_emis, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 1, 0, , ,true,true"$'\n' + # add land/ocean fluxes equal to 0.5/0.1 that of emissions, for demonstration purposes co2_conf_var+=${var}"("$((i++))",:) = 'CO2_land_monthly', 'CO2_emis', '"$mod"_CO2_land', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.5, 0, , ,true,true,"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_ocean_monthly', 'CO2_emis', '"$mod"_CO2_ocean', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.1, 0, , ,true,true,"$'\n' - fi + co2_conf_var_yml+="${var}("$((ii++))"): CO2_land_monthly, CO2_emis, "$mod"_CO2_land, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 0.5, 0, , , true, true"$'\n' + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_ocean_monthly', 'CO2_emis', '"$mod"_CO2_ocean', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.1, 0, , ,true,true,"$'\n' + co2_conf_var_yml+="${var}("$((ii++))"): CO2_ocean_monthly, CO2_emis, "$mod"_CO2_ocean, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 0.1, 0, , ,true,true" + + + + fi #OasisOutputVars(i,:) = if [ ${CO2_CMODE} == true ] ; then oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_cconc', 'GLOBAL', 'daily', 1, 0, true," @@ -185,9 +202,12 @@ else if [ ${CO2_EMODE} == true ] ; then # this is the 3D monthly emissions used for ECE4 oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_emis', 'CO2_emis', 'daily', 1, 0, true," + oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_emis, CO2_emis, daily, 1, 0, true"$'\n' oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_land', 'CO2_emis', 'daily', 1, 0, true," + oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_land, CO2_emis, daily, 1, 0, true"$'\n' oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_ocean', 'CO2_emis', 'daily', 1, 0, true," - fi + oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_ocean, CO2_emis, daily, 1, 0, true" + fi else co2_conf_var="" fi -- GitLab From 5b19a90b50a0b1cc3837749b8e08a96a2598a003 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Mon, 10 Jul 2023 17:10:22 +0200 Subject: [PATCH 07/39] a python script genrate_yaml.py read in a template yaml file, fill in the varieble passed to it by the run_example (mock), and generate a exp yaml file --- tests/data/exp1_aimp.yaml | 124 +++++++++++++++++++++++++++++ tests/data/generate_yaml.py | 128 ++++++++++++++++++++++++++++++ tests/data/launch_generate_yml.sh | 23 ++++++ tests/data/template_amip.yaml | 27 +++++++ 4 files changed, 302 insertions(+) create mode 100644 tests/data/exp1_aimp.yaml create mode 100644 tests/data/generate_yaml.py create mode 100755 tests/data/launch_generate_yml.sh create mode 100644 tests/data/template_amip.yaml diff --git a/tests/data/exp1_aimp.yaml b/tests/data/exp1_aimp.yaml new file mode 100644 index 0000000..9b5c3f7 --- /dev/null +++ b/tests/data/exp1_aimp.yaml @@ -0,0 +1,124 @@ +RunLengthSec: '5097600' +TimeStepSec: '86400' +StartYear: '2005' +StartMonth: '01' +StartDay: '01' +FixYear: '0' +FileInputVars: + AMIP_sst_monthly: + id: AMIP_sst_monthly + grid_name: AMIP + oasis_name: AMIP_sst + file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc + netcdf_variable: tosbcs + yref_min: 1870 + yref_max: 2016 + timestep: monthly + interpolate: 'true' + scale_factor: 1 + offset: 273.15 + min: 271.38 + max: null + update: true + accum: true + AMIP_sic_monthly: + id: AMIP_sic_monthly + grid_name: AMIP + oasis_name: AMIP_sic + file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc + netcdf_variable: siconcbcs + yref_min: 1870 + yref_max: 2016 + timestep: monthly + interpolate: 'true' + scale_factor: 0.01 + offset: 0 + min: 1 + max: null + update: true + accum: true + CO2_em_monthly: + id: CO2_em_monthly + grid_name: CO2_emis + oasis_name: AMIP_CO2_emis + file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc + netcdf_variable: CO2_em_anthro + yref_min: 1750 + yref_max: 2018 + timestep: monthly + interpolate: 'false' + scale_factor: 0.01 + offset: 1 + min: 0 + max: null + update: true + accum: true + CO2_land_monthly: + id: CO2_land_monthly + grid_name: CO2_emis + oasis_name: AMIP_CO2_land + file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc + netcdf_variable: CO2_em_anthro + yref_min: 1750 + yref_max: 2018 + timestep: monthly + interpolate: 'false' + scale_factor: 0.01 + offset: 0.5 + min: 0 + max: null + update: true + accum: true + CO2_ocean_monthly: + id: CO2_ocean_monthly + grid_name: CO2_emis + oasis_name: AMIP_CO2_ocean + file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc + netcdf_variable: CO2_em_anthro + yref_min: 1750 + yref_max: 2018 + timestep: monthly + interpolate: 'false' + scale_factor: 0.01 + offset: 0.1 + min: 0 + max: null + update: true + accum: true +OasisOutputVars: +- AMIP_sst: + id: AMIP_sst + grid_name: AMIP + timestep: daily + scale_factor: 1 + offset: 0 + reset: true +- AMIP_sic: + id: AMIP_sic + grid_name: AMIP + timestep: daily + scale_factor: 1 + offset: 0 + reset: true +- AMIP_CO2_emis: + id: AMIP_CO2_emis + grid_name: CO2_emis + timestep: daily + scale_factor: 1 + offset: 0 + reset: true +- AMIP_CO2_land: + id: AMIP_CO2_land + grid_name: CO2_emis + timestep: daily + scale_factor: 1 + offset: 0 + reset: true +- AMIP_CO2_ocean: + id: AMIP_CO2_ocean + grid_name: CO2_emis + timestep: daily + scale_factor: 1 + offset: 0 + reset: true +LDebug: false diff --git a/tests/data/generate_yaml.py b/tests/data/generate_yaml.py new file mode 100644 index 0000000..e9434e9 --- /dev/null +++ b/tests/data/generate_yaml.py @@ -0,0 +1,128 @@ + +# Copyright 2022 - Barcelona Supercomputing Center +# Author: Etienne Tourigny, Rodrigo Martín Posada +# MIT License +from datetime import date +import numpy as np +import yaml +from yaml.loader import SafeLoader +import argparse +import os +import sys + +if __name__ == '__main__': + +### Read in YAML file + current_path = os.getcwd() + parser=argparse.ArgumentParser() + parser.add_argument("--model_name",type=str) + parser.add_argument("--template_name",type=str) + parser.add_argument("--file_name",type=str) + parser.add_argument("--leg_length_sec",type=str) + parser.add_argument("--cpl_freq_amip_sec",type=str) + parser.add_argument("--StartYear",type=str) + parser.add_argument("--StartMonth",type=str) + parser.add_argument("--StartDay",type=str) + parser.add_argument("--FixYear",type=str) + parser.add_argument("--amip_interpolate",type=str) + parser.add_argument("--co2_interpolate",type=str) + args = parser.parse_args() + ModelName = args.model_name + RunLengthSec = args.leg_length_sec + TimeStepSec = args.cpl_freq_amip_sec + StartYear = args.StartYear + StartMonth = args.StartMonth + StartDay = args.StartDay + FixYear = args.FixYear + AMIP_interpolate = args.amip_interpolate + CO2_interpolate = args.co2_interpolate + + template_name = args.template_name + file_name = args.file_name + # TODO add check to create a test here + + + yamel_file_path = "/home/bsc32/bsc32013/scrath_23013/ec_earth/amip/python-amip-reader/tests/data/template_amip.yaml" #os.path.join(current_path,args.template_name) + print(yamel_file_path) + + # if os.path.isfile(yamel_file_path) == False: + # print("YAML file does not exist. Aborted", file=sys.stderr) + # raise NameError("YAML file does not exist.") + + # Open the template file and load the file + read_in_data = {} + with open(yamel_file_path) as file: + read_in_data = yaml.load(file, Loader=SafeLoader) + file.close() + +## Modify the ReadInData based on the values passed by the RunExample + + +# Modify the fields from template files + read_in_data['RunLengthSec'] = RunLengthSec + read_in_data['TimeStepSec'] = TimeStepSec + read_in_data['StartYear'] = StartYear + read_in_data['StartMonth'] = StartMonth + read_in_data['StartDay'] = StartDay + read_in_data['FixYear'] = FixYear + + read_in_data['FileInputVars']['AMIP_sst_monthly']['interpolate'] = AMIP_interpolate + read_in_data['FileInputVars']['AMIP_sic_monthly']['interpolate'] = AMIP_interpolate + read_in_data['FileInputVars']['CO2_em_monthly']['interpolate'] = CO2_interpolate + read_in_data['FileInputVars']['CO2_land_monthly']['interpolate'] = CO2_interpolate + read_in_data['FileInputVars']['CO2_ocean_monthly']['interpolate'] = CO2_interpolate + + # Save it again +with open(file_name, 'w') as stream: + yaml.dump(read_in_data, stream, sort_keys=False) + + + + + + + + +### Read in template file + #read_yaml(read_in_data) + # RunLengthSec = read_in_data.get("RunLengthSec") + # TimeStepSec = read_in_data.get("TimeStepSec") + # StartYear = read_in_data.get("StartYear") + # StartMonth = read_in_data.get("StartMonth") + # StartDay = read_in_data.get("StartDay") + # FixYear = read_in_data.get("FixYear") + + # Read in FileInputVars information + # FileInputVars = read_in_data.get("FileInputVars") + # FileInputVars_AMIP_sst_monthly = FileInputVars.get("AMIP_sst_monthly") + # FileInputVars_AMIP_sst_monthly_id = FileInputVars_AMIP_sst_monthly.get("id") + # FileInputVars_AMIP_sic_monthly= FileInputVars.get("AMIP_sic_monthly") + # FileInputVars_CO2_em_monthly = FileInputVars.get("CO2_em_monthly") + # FileInputVars_CO2_land_monthly = FileInputVars.get("CO2_land_monthly") + + + # Read in OasisOutputVars information + # OasisOutputVars = read_in_data.get("OasisOutputVars") + # print(OasisOutputVars) + # OasisOutputVars_AMIP_sst_monthly = OasisOutputVars.get("AMIP_sst_monthly") + # OasisOutputVars_AMIP_sic= OasisOutputVars.get("AMIP_sic") + # OasisOutputVars_AMIP_CO2_emis = OasisOutputVars.get("AMIP_CO2_emis") + # OasisOutputVars_AMIP_CO2_land = OasisOutputVars.get("AMIP_CO2_land") + # OasisOutputVars_AMIP_CO2_ocean = OasisOutputVars.get("AMIP_CO2_ocean") + + # print(FileInputVars_AMIP_sst_monthly_id) + # LDebug = read_in_data.get("LDebug") + + # experiment_out_data = {} + # experiment_out_data = {RunLengthSec,TimeStepSec,StartYear, StartMonth, FixYear,FileInputVars} + + + + # print(experiment_out_data) + + + + # with open(r'store_file.yaml', 'w') as file: + # documents = yaml.dump(experiment_out_data, file) + + diff --git a/tests/data/launch_generate_yml.sh b/tests/data/launch_generate_yml.sh new file mode 100755 index 0000000..138026e --- /dev/null +++ b/tests/data/launch_generate_yml.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# slurm specific options for Marenostrum4 +#SBATCH --qos=debug +#SBATCH -N 1 +#SBATCH -n 3 +#SBATCH -c 1 +#SBATCH -t 1:00:00 +#SBATCH --exclusive + +#load python and netcdf modules +export PYTHONPATH="" +module load intel/2017.4 +module load intel/2017.4 +module load python/3.6.1 +module load netcdf/4.2 +module load CDO/1.9.3 +module list +export MPIRUN="mpirun" + + +# run IFS+NEMO+runoff toy model +mpirun -np 1 python3 generate_yaml.py --model_name datacoupler --template_name template_aimp.yaml --file_name exp1_aimp.yaml --leg_length_sec 5097600 --cpl_freq_amip_sec 86400 --StartYear 2005 --StartMonth 01 --StartDay 01 --FixYear 0 --amip_interpolate true --co2_interpolate false diff --git a/tests/data/template_amip.yaml b/tests/data/template_amip.yaml new file mode 100644 index 0000000..9f7437d --- /dev/null +++ b/tests/data/template_amip.yaml @@ -0,0 +1,27 @@ +# YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file + +RunLengthSec : [leg_length_sec] +TimeStepSec : [cpl_freq_amip_sec] +StartYear : [StartYear] +StartMonth : [StartMonth] +StartDay : [StartDay] +FixYear : [FixYear] + +FileInputVars: + AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : amip_interpolate, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} + AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : amip_interpolate, scale_factor: 0.01, offset: 0, min: 1, max: , update: true, accum: true} + CO2_em_monthly : { id : CO2_em_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_emis, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : amip_interpolate, scale_factor: 0.01, offset: 1, min: 0, max: , update: true, accum: true} + CO2_land_monthly: { id : CO2_land_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_land, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : amip_interpolate, scale_factor: 0.01, offset: 0.5, min: 0, max: , update: true, accum: true} + CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : amip_interpolate, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} + +OasisOutputVars: + - AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + - AMIP_sic : { id: AMIP_sic, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + - AMIP_CO2_emis : { id: AMIP_CO2_emis, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + - AMIP_CO2_land : { id: AMIP_CO2_land, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + - AMIP_CO2_ocean : { id: AMIP_CO2_ocean, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + +LDebug : false + + + -- GitLab From 53cc838fe136f4b0963b8ee7d264f719efbd4133 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 11 Jul 2023 09:05:54 +0200 Subject: [PATCH 08/39] small fix to the genrate_yaml.py to only modify the exp. detail --- tests/data/exp1_aimp.yaml | 10 ++-- tests/data/generate_yaml.py | 96 ++++++++----------------------- tests/data/launch_generate_yml.sh | 2 +- tests/data/template_amip.yaml | 15 ++--- 4 files changed, 37 insertions(+), 86 deletions(-) diff --git a/tests/data/exp1_aimp.yaml b/tests/data/exp1_aimp.yaml index 9b5c3f7..c89b192 100644 --- a/tests/data/exp1_aimp.yaml +++ b/tests/data/exp1_aimp.yaml @@ -14,7 +14,7 @@ FileInputVars: yref_min: 1870 yref_max: 2016 timestep: monthly - interpolate: 'true' + interpolate: true scale_factor: 1 offset: 273.15 min: 271.38 @@ -30,7 +30,7 @@ FileInputVars: yref_min: 1870 yref_max: 2016 timestep: monthly - interpolate: 'true' + interpolate: true scale_factor: 0.01 offset: 0 min: 1 @@ -46,7 +46,7 @@ FileInputVars: yref_min: 1750 yref_max: 2018 timestep: monthly - interpolate: 'false' + interpolate: false scale_factor: 0.01 offset: 1 min: 0 @@ -62,7 +62,7 @@ FileInputVars: yref_min: 1750 yref_max: 2018 timestep: monthly - interpolate: 'false' + interpolate: false scale_factor: 0.01 offset: 0.5 min: 0 @@ -78,7 +78,7 @@ FileInputVars: yref_min: 1750 yref_max: 2018 timestep: monthly - interpolate: 'false' + interpolate: false scale_factor: 0.01 offset: 0.1 min: 0 diff --git a/tests/data/generate_yaml.py b/tests/data/generate_yaml.py index e9434e9..a124f32 100644 --- a/tests/data/generate_yaml.py +++ b/tests/data/generate_yaml.py @@ -13,7 +13,6 @@ import sys if __name__ == '__main__': ### Read in YAML file - current_path = os.getcwd() parser=argparse.ArgumentParser() parser.add_argument("--model_name",type=str) parser.add_argument("--template_name",type=str) @@ -24,8 +23,6 @@ if __name__ == '__main__': parser.add_argument("--StartMonth",type=str) parser.add_argument("--StartDay",type=str) parser.add_argument("--FixYear",type=str) - parser.add_argument("--amip_interpolate",type=str) - parser.add_argument("--co2_interpolate",type=str) args = parser.parse_args() ModelName = args.model_name RunLengthSec = args.leg_length_sec @@ -34,30 +31,30 @@ if __name__ == '__main__': StartMonth = args.StartMonth StartDay = args.StartDay FixYear = args.FixYear - AMIP_interpolate = args.amip_interpolate - CO2_interpolate = args.co2_interpolate + # Check the existence of template file and experiment file. template_name = args.template_name - file_name = args.file_name - # TODO add check to create a test here - + output_file_name = args.file_name - yamel_file_path = "/home/bsc32/bsc32013/scrath_23013/ec_earth/amip/python-amip-reader/tests/data/template_amip.yaml" #os.path.join(current_path,args.template_name) - print(yamel_file_path) + current_path = os.getcwd() + yamel_input_file_path = os.path.join(current_path,template_name) + yamel_output_file_path = os.path.join(current_path,output_file_name) - # if os.path.isfile(yamel_file_path) == False: - # print("YAML file does not exist. Aborted", file=sys.stderr) - # raise NameError("YAML file does not exist.") - + if os.path.isfile(yamel_input_file_path) == False: + print("yaml template file does not exist. Aborted", file=sys.stderr) + raise NameError("YAML file does not exist.") + + if os.path.isfile(yamel_input_file_path) == True: + print("yaml output file exists. It will be deleted.", file=sys.stderr) + os.remove(yamel_output_file_path) + # Open the template file and load the file read_in_data = {} - with open(yamel_file_path) as file: + with open(yamel_input_file_path) as file: read_in_data = yaml.load(file, Loader=SafeLoader) file.close() -## Modify the ReadInData based on the values passed by the RunExample - - +# Modify the ReadInData based on the values passed by the RunExample # Modify the fields from template files read_in_data['RunLengthSec'] = RunLengthSec read_in_data['TimeStepSec'] = TimeStepSec @@ -66,63 +63,16 @@ if __name__ == '__main__': read_in_data['StartDay'] = StartDay read_in_data['FixYear'] = FixYear - read_in_data['FileInputVars']['AMIP_sst_monthly']['interpolate'] = AMIP_interpolate - read_in_data['FileInputVars']['AMIP_sic_monthly']['interpolate'] = AMIP_interpolate - read_in_data['FileInputVars']['CO2_em_monthly']['interpolate'] = CO2_interpolate - read_in_data['FileInputVars']['CO2_land_monthly']['interpolate'] = CO2_interpolate - read_in_data['FileInputVars']['CO2_ocean_monthly']['interpolate'] = CO2_interpolate + # ## TODO remove this part + # read_in_data['FileInputVars']['AMIP_sst_monthly']['interpolate'] = AMIP_interpolate + # read_in_data['FileInputVars']['AMIP_sic_monthly']['interpolate'] = AMIP_interpolate + # read_in_data['FileInputVars']['CO2_em_monthly']['interpolate'] = CO2_interpolate + # read_in_data['FileInputVars']['CO2_land_monthly']['interpolate'] = CO2_interpolate + # read_in_data['FileInputVars']['CO2_ocean_monthly']['interpolate'] = CO2_interpolate # Save it again -with open(file_name, 'w') as stream: +with open(output_file_name, 'w') as stream: yaml.dump(read_in_data, stream, sort_keys=False) - - - - - - - -### Read in template file - #read_yaml(read_in_data) - # RunLengthSec = read_in_data.get("RunLengthSec") - # TimeStepSec = read_in_data.get("TimeStepSec") - # StartYear = read_in_data.get("StartYear") - # StartMonth = read_in_data.get("StartMonth") - # StartDay = read_in_data.get("StartDay") - # FixYear = read_in_data.get("FixYear") - - # Read in FileInputVars information - # FileInputVars = read_in_data.get("FileInputVars") - # FileInputVars_AMIP_sst_monthly = FileInputVars.get("AMIP_sst_monthly") - # FileInputVars_AMIP_sst_monthly_id = FileInputVars_AMIP_sst_monthly.get("id") - # FileInputVars_AMIP_sic_monthly= FileInputVars.get("AMIP_sic_monthly") - # FileInputVars_CO2_em_monthly = FileInputVars.get("CO2_em_monthly") - # FileInputVars_CO2_land_monthly = FileInputVars.get("CO2_land_monthly") - - - # Read in OasisOutputVars information - # OasisOutputVars = read_in_data.get("OasisOutputVars") - # print(OasisOutputVars) - # OasisOutputVars_AMIP_sst_monthly = OasisOutputVars.get("AMIP_sst_monthly") - # OasisOutputVars_AMIP_sic= OasisOutputVars.get("AMIP_sic") - # OasisOutputVars_AMIP_CO2_emis = OasisOutputVars.get("AMIP_CO2_emis") - # OasisOutputVars_AMIP_CO2_land = OasisOutputVars.get("AMIP_CO2_land") - # OasisOutputVars_AMIP_CO2_ocean = OasisOutputVars.get("AMIP_CO2_ocean") - - # print(FileInputVars_AMIP_sst_monthly_id) - # LDebug = read_in_data.get("LDebug") - - # experiment_out_data = {} - # experiment_out_data = {RunLengthSec,TimeStepSec,StartYear, StartMonth, FixYear,FileInputVars} - - - - # print(experiment_out_data) - - - - # with open(r'store_file.yaml', 'w') as file: - # documents = yaml.dump(experiment_out_data, file) - +print("yaml output file created.", file=sys.stderr) diff --git a/tests/data/launch_generate_yml.sh b/tests/data/launch_generate_yml.sh index 138026e..a79780e 100755 --- a/tests/data/launch_generate_yml.sh +++ b/tests/data/launch_generate_yml.sh @@ -20,4 +20,4 @@ export MPIRUN="mpirun" # run IFS+NEMO+runoff toy model -mpirun -np 1 python3 generate_yaml.py --model_name datacoupler --template_name template_aimp.yaml --file_name exp1_aimp.yaml --leg_length_sec 5097600 --cpl_freq_amip_sec 86400 --StartYear 2005 --StartMonth 01 --StartDay 01 --FixYear 0 --amip_interpolate true --co2_interpolate false +mpirun -np 1 python3 generate_yaml.py --model_name datacoupler --template_name template_amip.yaml --file_name exp1_aimp.yaml --leg_length_sec 5097600 --cpl_freq_amip_sec 86400 --StartYear 2005 --StartMonth 01 --StartDay 01 --FixYear 0 diff --git a/tests/data/template_amip.yaml b/tests/data/template_amip.yaml index 9f7437d..3c5c406 100644 --- a/tests/data/template_amip.yaml +++ b/tests/data/template_amip.yaml @@ -1,18 +1,19 @@ # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file - -RunLengthSec : [leg_length_sec] +# This section will be filled automatically +RunLengthSec : [leg_length_sec] TimeStepSec : [cpl_freq_amip_sec] StartYear : [StartYear] StartMonth : [StartMonth] StartDay : [StartDay] FixYear : [FixYear] +# Only fill the folloing section: FileInputVars: - AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : amip_interpolate, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} - AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : amip_interpolate, scale_factor: 0.01, offset: 0, min: 1, max: , update: true, accum: true} - CO2_em_monthly : { id : CO2_em_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_emis, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : amip_interpolate, scale_factor: 0.01, offset: 1, min: 0, max: , update: true, accum: true} - CO2_land_monthly: { id : CO2_land_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_land, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : amip_interpolate, scale_factor: 0.01, offset: 0.5, min: 0, max: , update: true, accum: true} - CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : amip_interpolate, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} + AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} + AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 1, max: , update: true, accum: true} + CO2_em_monthly : { id : CO2_em_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_emis, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 1, min: 0, max: , update: true, accum: true} + CO2_land_monthly: { id : CO2_land_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_land, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.5, min: 0, max: , update: true, accum: true} + CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} OasisOutputVars: - AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } -- GitLab From 63e7cbbb9b54777e194bbc52de476b51927095f9 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 11 Jul 2023 16:09:12 +0200 Subject: [PATCH 09/39] replace python for bash for generate exp. yaml file --- sources/data-coupler/DataCoupler.py | 6 +- sources/data-coupler/DataCouplerUtils.py | 85 ++++++++-------- tests/data/exp1_aimp.yaml | 124 ----------------------- tests/data/output_file2.yaml | 28 +++++ tests/data/template_amip.yaml | 2 +- tests/data/yaml_parse.sh | 13 +++ tests/run_example.sh | 5 +- 7 files changed, 89 insertions(+), 174 deletions(-) delete mode 100644 tests/data/exp1_aimp.yaml create mode 100644 tests/data/output_file2.yaml create mode 100755 tests/data/yaml_parse.sh diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 420bc8c..acf4881 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -12,7 +12,7 @@ import math import sys from DataCouplerUtils import read_namelist, days_since_refyear, is_leap, earth_area -from DataCouplerUtils import read_ymllist +from DataCouplerUtils import read_exp_yaml from DataCouplerFileVar import FileInputVar from DataCouplerOasisVar import OasisOutputVar @@ -25,9 +25,9 @@ class DataCoupler: StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_namelist(NAMELIST_FILE_NAME, NAMELIST_SECTION) ### TODO for now it is feed in the middle of the function - YAML_NAMELIST_FILE_NAME = "namelist.amip.yaml" + YAML_NAMELIST_FILE_NAME = "exp1_amip.yaml" RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, \ - StartDay_y, FixYear_y = read_ymllist(YAML_NAMELIST_FILE_NAME) + StartDay_y, FixYear_y = read_exp_yaml(YAML_NAMELIST_FILE_NAME) print("NEXT LINE IS PRODUCED BY YAML FILE READER", file=sys.stderr) print(RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, StartDay_y, FixYear_y, file=sys.stderr) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 1b8d158..8167d3d 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -7,6 +7,8 @@ import f90nml import numpy as np import yaml from yaml.loader import SafeLoader +import sys +import os # constants @@ -219,59 +221,54 @@ def read_namelist(NAMELIST_FILE_NAME,NAMELIST_SECTION): raise Exception('DataCoupler: Invalid configuration ids, all ids must be unique') else: oasisOut_vars_config = None + + print("NOTE: fileIn_vars_config are {fileIn_vars_config}".format(fileIn_vars_config = fileIn_vars_config),file=sys.stderr) + print("NOTE: oasisOut_vars_config are {oasisOut_vars_config}".format(oasisOut_vars_config = oasisOut_vars_config),file=sys.stderr) - + return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config -def read_ymllist(YAML_NAMELIST_FILE_NAME): +def read_exp_yaml(experiment_yaml_input): ''' - Reads the namelist. + Reads the experiment yaml file ''' - yamel_file=YAML_NAMELIST_FILE_NAME + yamel_file=experiment_yaml_input - with open(yamel_file) as f: - nmly = yaml.load(f, Loader=SafeLoader) - f.close() + with open(yamel_file) as file: + read_in = yaml.load(file, Loader=SafeLoader) + file.close() - RunLengthSec = nmly['RunLengthSec'] - TimeStepSec = nmly['TimeStepSec'] - StartYear = nmly['StartYear'] - StartMonth = nmly['StartMonth'] - StartDay = nmly['StartDay'] - FixYear = nmly['FixYear'] - #LDebug = nmly['LDebug'] + # Experiment detail + + RunLengthSec = read_in.get('RunLengthSec') + TimeStepSec = read_in.get('TimeStepSec') + StartYear = read_in.get('StartYear') + StartMonth = read_in.get('StartMonth') + StartDay = read_in.get('StartDay') + FixYear = read_in.get('FixYear') + LDebug = read_in.get('LDebug') + + + if "FileInputVars" in read_in : + FileInputVars_out = {} + + FileInputVars_out = read_in.get('FileInputVars') + print("NOTE: File Input Vars are {FileInputVars_out}".format(FileInputVars_out = FileInputVars_out),file=sys.stderr) + + if "OasisOutputVars" in read_in : + OasisOutputVars_out = {} + print(type(OasisOutputVars_out), file=sys.stderr) + OasisOutputVars_out = read_in.get('OasisOutputVars') + print(type(OasisOutputVars_out), file=sys.stderr) + + # print(type(OasisOutputVars_out.keys()), file=sys.stderr) + + # print("NOTE: File OASIS Output Vars are {OasisOutputVars_out}".format(OasisOutputVars_out = OasisOutputVars_out),file=sys.stderr) + # print("NOTE: KEYS: File OASIS Output Vars are {keys}".format(keys = OasisOutputVars_out.keys),file=sys.stderr) + # print("NOTE: VALUES: File OASIS Output Vars are {values}".format(values = OasisOutputVars_out.values),file=sys.stderr) return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear -# TODO will be deleted -# ### Read in YAML file -# current_path = os.getcwd() -# parser=argparse.ArgumentParser() -# parser.add_argument("--yaml_file_path",type=str) -# args = parser.parse_args() -# yamel_file_path = os.path.join(current_path,args.yaml_file_path) -# if os.path.isfile(yamel_file_path) == False: -# print("YAML file does not exist. Aborted") -# raise NameError("YAML file does not exist.") - -# # Open the file and load the file - - -# ### Read in file -# #read_yaml(read_in_data) -# model = read_in_data.get("model") -# model_name = model.get("model_name") - -# # Read in Simulation information -# simulation = read_in_data.get("simulation") -# simulation_coupling_interval = simulation.get("coupling_interval") -# simulation_run_length_sec = simulation.get("run_length_sec") -# simulation_nx = simulation.get("nx") - -# # Read in Coupling infomration -# coupling = read_in_data.get("coupling") -# coupling_out_vars = coupling.get("out_vars") -# coupling_in_vars = coupling.get("in_vars") -# restart_file = coupling.get("restart_file") # This feature is not used for now. TODO \ No newline at end of file + diff --git a/tests/data/exp1_aimp.yaml b/tests/data/exp1_aimp.yaml deleted file mode 100644 index c89b192..0000000 --- a/tests/data/exp1_aimp.yaml +++ /dev/null @@ -1,124 +0,0 @@ -RunLengthSec: '5097600' -TimeStepSec: '86400' -StartYear: '2005' -StartMonth: '01' -StartDay: '01' -FixYear: '0' -FileInputVars: - AMIP_sst_monthly: - id: AMIP_sst_monthly - grid_name: AMIP - oasis_name: AMIP_sst - file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc - netcdf_variable: tosbcs - yref_min: 1870 - yref_max: 2016 - timestep: monthly - interpolate: true - scale_factor: 1 - offset: 273.15 - min: 271.38 - max: null - update: true - accum: true - AMIP_sic_monthly: - id: AMIP_sic_monthly - grid_name: AMIP - oasis_name: AMIP_sic - file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc - netcdf_variable: siconcbcs - yref_min: 1870 - yref_max: 2016 - timestep: monthly - interpolate: true - scale_factor: 0.01 - offset: 0 - min: 1 - max: null - update: true - accum: true - CO2_em_monthly: - id: CO2_em_monthly - grid_name: CO2_emis - oasis_name: AMIP_CO2_emis - file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc - netcdf_variable: CO2_em_anthro - yref_min: 1750 - yref_max: 2018 - timestep: monthly - interpolate: false - scale_factor: 0.01 - offset: 1 - min: 0 - max: null - update: true - accum: true - CO2_land_monthly: - id: CO2_land_monthly - grid_name: CO2_emis - oasis_name: AMIP_CO2_land - file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc - netcdf_variable: CO2_em_anthro - yref_min: 1750 - yref_max: 2018 - timestep: monthly - interpolate: false - scale_factor: 0.01 - offset: 0.5 - min: 0 - max: null - update: true - accum: true - CO2_ocean_monthly: - id: CO2_ocean_monthly - grid_name: CO2_emis - oasis_name: AMIP_CO2_ocean - file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc - netcdf_variable: CO2_em_anthro - yref_min: 1750 - yref_max: 2018 - timestep: monthly - interpolate: false - scale_factor: 0.01 - offset: 0.1 - min: 0 - max: null - update: true - accum: true -OasisOutputVars: -- AMIP_sst: - id: AMIP_sst - grid_name: AMIP - timestep: daily - scale_factor: 1 - offset: 0 - reset: true -- AMIP_sic: - id: AMIP_sic - grid_name: AMIP - timestep: daily - scale_factor: 1 - offset: 0 - reset: true -- AMIP_CO2_emis: - id: AMIP_CO2_emis - grid_name: CO2_emis - timestep: daily - scale_factor: 1 - offset: 0 - reset: true -- AMIP_CO2_land: - id: AMIP_CO2_land - grid_name: CO2_emis - timestep: daily - scale_factor: 1 - offset: 0 - reset: true -- AMIP_CO2_ocean: - id: AMIP_CO2_ocean - grid_name: CO2_emis - timestep: daily - scale_factor: 1 - offset: 0 - reset: true -LDebug: false diff --git a/tests/data/output_file2.yaml b/tests/data/output_file2.yaml new file mode 100644 index 0000000..bb8765e --- /dev/null +++ b/tests/data/output_file2.yaml @@ -0,0 +1,28 @@ +# YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file +# This section will be filled automatically +RunLengthSec : 5097600 +TimeStepSec : 86400 +StartYear : 2005 +StartMonth : 01 +StartDay : 01 +FixYear : 0 + +# Only fill the following section: +FileInputVars: + AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} + AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 1, max: , update: true, accum: true} + CO2_em_monthly : { id : CO2_em_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_emis, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 1, min: 0, max: , update: true, accum: true} + CO2_land_monthly: { id : CO2_land_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_land, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.5, min: 0, max: , update: true, accum: true} + CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} + +OasisOutputVars: + - AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + - AMIP_sic : { id: AMIP_sic, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + - AMIP_CO2_emis : { id: AMIP_CO2_emis, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + - AMIP_CO2_land : { id: AMIP_CO2_land, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + - AMIP_CO2_ocean : { id: AMIP_CO2_ocean, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + +LDebug : false + + + diff --git a/tests/data/template_amip.yaml b/tests/data/template_amip.yaml index 3c5c406..ad7f3ce 100644 --- a/tests/data/template_amip.yaml +++ b/tests/data/template_amip.yaml @@ -7,7 +7,7 @@ StartMonth : [StartMonth] StartDay : [StartDay] FixYear : [FixYear] -# Only fill the folloing section: +# Only fill the following section: FileInputVars: AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 1, max: , update: true, accum: true} diff --git a/tests/data/yaml_parse.sh b/tests/data/yaml_parse.sh new file mode 100755 index 0000000..2eb18dd --- /dev/null +++ b/tests/data/yaml_parse.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +RunLengthSec=${leg_length_sec} +TimeStepSec=${cpl_freq_amip_sec} +StartYear=${leg_start_date_yyyymmdd:0:4} +StartMonth=${leg_start_date_yyyymmdd:4:2} +StartDay=${leg_start_date_yyyymmdd:6:2} +FixYear=${ifs_cmip_fixyear} +Output_file_name=${exp_input_yaml_file} + +sed -e "s/\[leg_length_sec\]/$RunLengthSec/" -e "s/\[cpl_freq_amip_sec\]/$TimeStepSec/" -e "s/\[StartYear\]/$StartYear/" -e "s/\[StartMonth\]/$StartMonth/" \ + -e "s/\[StartMonth\]/$StartMonth/" -e "s/\[StartDay\]/$StartDay/" -e "s/\[StartDay\]/$StartDay/" \ + -e "s/\[FixYear\]/$FixYear/" template_amip.yaml > $Output_file_name diff --git a/tests/run_example.sh b/tests/run_example.sh index 1e02f7e..54c1c47 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -112,6 +112,7 @@ else cp -f $datadir/areas-noamip.nc $rundir/areas.nc fi cp -f $datadir/*.sh $rundir/. +cp -f $datadir/*.yaml $rundir/. cp -f $source_exe1 $rundir/. ln -sf $source_exe2 $rundir/. cd $rundir @@ -124,10 +125,8 @@ leg_start_date_yyyymmdd=$(date -u -d "${leg_start_date}" +%Y%m%d) if [ $model = fortran ] || [ $model = pythoncompat ]; then if [ $amip_mode = forcing ]; then . ./namelist.amip.sh > ./namelist.amip - echo 'NOTE: model - fortran / Forcing' else . ./namelist_primavera.amip.sh > ./namelist.amip - echo 'NOTE: model - fortran / PRIMAVERA' fi else #if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then @@ -220,6 +219,8 @@ else . ./namelist_python.amip.sh > ./namelist.amip echo 'NOTE: model - fortran / namelist_python.amip.sh' . ./namelist_python.amip_yaml.sh > ./namelist.amip.yaml + exp_input_yaml_file="exp1_amip.yaml" + . ./yaml_parse.sh [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box fi if [ $amip_mode = forcing ]; then -- GitLab From 1d60ae45bdd0c7dd8df5f6e871ac53b4a6c8ddb6 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 11 Jul 2023 16:20:20 +0200 Subject: [PATCH 10/39] removing unused files - repo clean up --- .../data-coupler}/generate_yaml.py | 0 sources/data-coupler/namelist.amip | 15 -------- sources/data-coupler/namelist.amip.sh | 24 ------------ sources/data-coupler/namelist.amip.yaml | 11 ------ sources/data-coupler/namelist.amip_py.sh | 21 ---------- sources/data-coupler/namelist.amip_yaml.sh | 20 ---------- sources/data-coupler/namelist.yaml | 21 ---------- sources/data-coupler/namelist_toghether.yaml | 21 ---------- sources/data-coupler/test.sh | 38 ------------------- 9 files changed, 171 deletions(-) rename {tests/data => sources/data-coupler}/generate_yaml.py (100%) delete mode 100644 sources/data-coupler/namelist.amip delete mode 100755 sources/data-coupler/namelist.amip.sh delete mode 100644 sources/data-coupler/namelist.amip.yaml delete mode 100755 sources/data-coupler/namelist.amip_py.sh delete mode 100755 sources/data-coupler/namelist.amip_yaml.sh delete mode 100644 sources/data-coupler/namelist.yaml delete mode 100644 sources/data-coupler/namelist_toghether.yaml delete mode 100644 sources/data-coupler/test.sh diff --git a/tests/data/generate_yaml.py b/sources/data-coupler/generate_yaml.py similarity index 100% rename from tests/data/generate_yaml.py rename to sources/data-coupler/generate_yaml.py diff --git a/sources/data-coupler/namelist.amip b/sources/data-coupler/namelist.amip deleted file mode 100644 index 82cd99e..0000000 --- a/sources/data-coupler/namelist.amip +++ /dev/null @@ -1,15 +0,0 @@ -!----------------------------------------------------------------------- -&NAMAMIP -!----------------------------------------------------------------------- - RunLengthSec = 31622400 - TimeStepSec = 86400 - StartYear = 2004 - StartMonth = 01 - StartDay = 01 - FixYear = 0 - FileListSST = 'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc' - FileListSIC = 'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc' - LDebug = false - LInterpolate = No -!----------------------------------------------------------------------- -/ diff --git a/sources/data-coupler/namelist.amip.sh b/sources/data-coupler/namelist.amip.sh deleted file mode 100755 index c072ff4..0000000 --- a/sources/data-coupler/namelist.amip.sh +++ /dev/null @@ -1,24 +0,0 @@ -# flist_* can hold lists of files, separated by commas -flist_sst=\'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc\' -flist_sic=\'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc\' -#to generate VHR amip files for Edu... -#flist_sst=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sst_2010.nc\' -#flist_sic=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sic_2010.nc\' - -cat << EOF -!----------------------------------------------------------------------- -&NAMAMIP -!----------------------------------------------------------------------- - RunLengthSec = ${leg_length_sec} - TimeStepSec = ${cpl_freq_amip_sec} - StartYear = ${leg_start_date_yyyymmdd:0:4} - StartMonth = ${leg_start_date_yyyymmdd:4:2} - StartDay = ${leg_start_date_yyyymmdd:6:2} - FixYear = ${ifs_cmip_fixyear} - FileListSST = ${flist_sst} - FileListSIC = ${flist_sic} - LDebug = false - LInterpolate = ${amip_interpolate} -!----------------------------------------------------------------------- -/ -EOF diff --git a/sources/data-coupler/namelist.amip.yaml b/sources/data-coupler/namelist.amip.yaml deleted file mode 100644 index df6b735..0000000 --- a/sources/data-coupler/namelist.amip.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# YAML file input - RunLengthSec : - 31622400 - TimeStepSec : - 86400 - StartYear : - 2004 - StartMonth : - 01 - StartDay : - 01 - FixYear : - 0 - FileListSST : - tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc - FileListSIC : - siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc - LDebug : - false - LInterpolate : No diff --git a/sources/data-coupler/namelist.amip_py.sh b/sources/data-coupler/namelist.amip_py.sh deleted file mode 100755 index 79e8e9d..0000000 --- a/sources/data-coupler/namelist.amip_py.sh +++ /dev/null @@ -1,21 +0,0 @@ -# flist_* can hold lists of files, separated by commas -#flist_sst=\'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc\' -#flist_sic=\'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc\' -#to generate VHR amip files for Edu... -#flist_sst=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sst_2010.nc\' -#flist_sic=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sic_2010.nc\' - -#!/bin/bash -mpirun -np 1 python3 yamlUtils.py \ - --file_name namelist.yaml \ - --leg_length_sec 5097600 \ - --cpl_freq_amip_sec 86400 \ - --leg_start_date_yyyy 2005 \ - --leg_start_date_mm 01 \ - --leg_start_date_dd 01 \ - --ifs_cmip_fixyear 0 \ - --flist_sst tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc \ - --flist_sic siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc \ - --LDebug False\ - --LInterpolate False - diff --git a/sources/data-coupler/namelist.amip_yaml.sh b/sources/data-coupler/namelist.amip_yaml.sh deleted file mode 100755 index 3dcb1f6..0000000 --- a/sources/data-coupler/namelist.amip_yaml.sh +++ /dev/null @@ -1,20 +0,0 @@ -# flist_* can hold lists of files, separated by commas -flist_sst=tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc -flist_sic=siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc -#to generate VHR amip files for Edu... -#flist_sst=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sst_2010.nc\' -#flist_sic=\'amip_EC-Earth3P-VHR_hist-1950_r1i1p1f1_19950101-20141231_sic_2010.nc\' - -cat << EOF -# YAML file input - RunLengthSec : - ${leg_length_sec} - TimeStepSec : - ${cpl_freq_amip_sec} - StartYear : - ${leg_start_date_yyyymmdd:0:4} - StartMonth : - ${leg_start_date_yyyymmdd:4:2} - StartDay : - ${leg_start_date_yyyymmdd:6:2} - FixYear : - ${ifs_cmip_fixyear} - FileListSST : - ${flist_sst} - FileListSIC : - ${flist_sic} - LDebug : - false - LInterpolate : ${amip_interpolate} -EOF diff --git a/sources/data-coupler/namelist.yaml b/sources/data-coupler/namelist.yaml deleted file mode 100644 index ee75c56..0000000 --- a/sources/data-coupler/namelist.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# This is an input namelist file for DataCoupler tool -- RunLengthSec: - - '5097600' -- TimeStepSec: - - '86400' -- StartYear: - - '2005' -- StartMonth: - - '01' -- StartDay: - - '01' -- FixYear: - - '0' -- FileListSST: - - tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc -- FileListSIC: - - siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc -- LDebug: - - 'False' -- LInterpolate: - - 'False' diff --git a/sources/data-coupler/namelist_toghether.yaml b/sources/data-coupler/namelist_toghether.yaml deleted file mode 100644 index 370a780..0000000 --- a/sources/data-coupler/namelist_toghether.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# This is an input namelist file for DataCoupler tool -- RunLengthSec: - - '31622400' -- TimeStepSec: - - '86400' -- StartYear: - - '2004' -- StartMonth: - - '01' -- StartDay: - - '01' -- FixYear: - - '0' -- FileListSST: - - '''tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc''' -- FileListSIC: - - '''siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc''' -- LDebug: - - 'No' -- LInterpolate: - - 'No' diff --git a/sources/data-coupler/test.sh b/sources/data-coupler/test.sh deleted file mode 100644 index b3ecde5..0000000 --- a/sources/data-coupler/test.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -## Usage - -# module load python/3.6.1 -# module load netcdf/4.2 - -leg_end_date=20050101 -leg_start_date=20040101 -model=fortran -amip_mode=forcing -amip_interpolate=No -ifs_cmip_fixyear=0 - -leg_length_sec=$(( $(date -u -d "${leg_end_date}" +%s) - $(date -u -d "${leg_start_date}" +%s) )) -cpl_freq_amip_sec=86400 # Always -leg_start_date_yyyymmdd=$(date -u -d "${leg_start_date}" +%Y%m%d) - -if [ $model = fortran ] || [ $model = pythoncompat ]; then - if [ $amip_mode = forcing ]; then - #how it is done - . ./namelist.amip.sh > ./namelist.amip - #how will be in YAML - . ./namelist.amip_yaml.sh > ./namelist.amip.yaml - #how will be python - # python3 yamlUtils.py \ - # --file_name namelist_toghether.yaml \ - # --leg_length_sec ${leg_length_sec} \ - # --cpl_freq_amip_sec ${cpl_freq_amip_sec} \ - # --leg_start_date_yyyy ${leg_start_date_yyyymmdd:0:4} \ - # --leg_start_date_mm ${leg_start_date_yyyymmdd:4:2} \ - # --leg_start_date_dd ${leg_start_date_yyyymmdd:6:2} \ - # --ifs_cmip_fixyear ${ifs_cmip_fixyear} \ - # --flist_sst ${flist_sst} \ - # --flist_sic ${flist_sic} \ - # --LDebug No\ - # --LInterpolate ${amip_interpolate} - fi -fi -- GitLab From 123cde48218a4322c88e5873c9ccae11ef66b24a Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 11 Jul 2023 17:23:12 +0200 Subject: [PATCH 11/39] ensure that nested yaml file read as nested dictionaries --- sources/data-coupler/DataCouplerUtils.py | 25 ++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 8167d3d..7263b9d 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -8,7 +8,8 @@ import numpy as np import yaml from yaml.loader import SafeLoader import sys -import os +import os +import collections # constants @@ -234,9 +235,8 @@ def read_exp_yaml(experiment_yaml_input): ''' Reads the experiment yaml file ''' - yamel_file=experiment_yaml_input - with open(yamel_file) as file: + with open(experiment_yaml_input) as file: read_in = yaml.load(file, Loader=SafeLoader) file.close() @@ -252,16 +252,25 @@ def read_exp_yaml(experiment_yaml_input): if "FileInputVars" in read_in : - FileInputVars_out = {} + FileInputVars_readin = {} + FileInputVars_readin_variables = FileInputVars_readin.keys + + FileInputVars_readin = read_in.get('FileInputVars') + print("NOTE: The type is: {}".format(type(FileInputVars_readin)),file=sys.stderr) + print("NOTE: The keys are: {}".format(FileInputVars_readin_variables),file=sys.stderr) + print("NOTE: The values are: {}".format(FileInputVars_readin.values),file=sys.stderr) + + + + + print("NOTE: Normal File Input Vars are {}".format(FileInputVars_readin),file=sys.stderr) - FileInputVars_out = read_in.get('FileInputVars') - print("NOTE: File Input Vars are {FileInputVars_out}".format(FileInputVars_out = FileInputVars_out),file=sys.stderr) if "OasisOutputVars" in read_in : OasisOutputVars_out = {} - print(type(OasisOutputVars_out), file=sys.stderr) + #print(type(OasisOutputVars_out), file=sys.stderr) OasisOutputVars_out = read_in.get('OasisOutputVars') - print(type(OasisOutputVars_out), file=sys.stderr) + #print(type(OasisOutputVars_out), file=sys.stderr) # print(type(OasisOutputVars_out.keys()), file=sys.stderr) -- GitLab From 5cc14927e83b6fdebf5c499ddbc784d652c98640 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 12 Jul 2023 09:33:08 +0200 Subject: [PATCH 12/39] the sed commond is replaced by executable yaml file, simplyfing the concat of the varieble to template yaml --- tests/data/output_file2.yaml | 28 ---------------------------- tests/data/template_amip.yaml | 14 ++++++++------ tests/run_example.sh | 3 ++- 3 files changed, 10 insertions(+), 35 deletions(-) delete mode 100644 tests/data/output_file2.yaml mode change 100644 => 100755 tests/data/template_amip.yaml diff --git a/tests/data/output_file2.yaml b/tests/data/output_file2.yaml deleted file mode 100644 index bb8765e..0000000 --- a/tests/data/output_file2.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file -# This section will be filled automatically -RunLengthSec : 5097600 -TimeStepSec : 86400 -StartYear : 2005 -StartMonth : 01 -StartDay : 01 -FixYear : 0 - -# Only fill the following section: -FileInputVars: - AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} - AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 1, max: , update: true, accum: true} - CO2_em_monthly : { id : CO2_em_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_emis, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 1, min: 0, max: , update: true, accum: true} - CO2_land_monthly: { id : CO2_land_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_land, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.5, min: 0, max: , update: true, accum: true} - CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} - -OasisOutputVars: - - AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - - AMIP_sic : { id: AMIP_sic, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - - AMIP_CO2_emis : { id: AMIP_CO2_emis, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - - AMIP_CO2_land : { id: AMIP_CO2_land, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - - AMIP_CO2_ocean : { id: AMIP_CO2_ocean, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - -LDebug : false - - - diff --git a/tests/data/template_amip.yaml b/tests/data/template_amip.yaml old mode 100644 new mode 100755 index ad7f3ce..57a70d4 --- a/tests/data/template_amip.yaml +++ b/tests/data/template_amip.yaml @@ -1,11 +1,12 @@ +cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file # This section will be filled automatically -RunLengthSec : [leg_length_sec] -TimeStepSec : [cpl_freq_amip_sec] -StartYear : [StartYear] -StartMonth : [StartMonth] -StartDay : [StartDay] -FixYear : [FixYear] +RunLengthSec : ${leg_length_sec} +TimeStepSec : ${cpl_freq_amip_sec} +StartYear : ${leg_start_date_yyyymmdd:0:4} +StartMonth : ${leg_start_date_yyyymmdd:4:2} +StartDay : ${leg_start_date_yyyymmdd:6:2} +FixYear : ${ifs_cmip_fixyear} # Only fill the following section: FileInputVars: @@ -23,6 +24,7 @@ OasisOutputVars: - AMIP_CO2_ocean : { id: AMIP_CO2_ocean, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } LDebug : false +EOF diff --git a/tests/run_example.sh b/tests/run_example.sh index 54c1c47..206c414 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -219,8 +219,9 @@ else . ./namelist_python.amip.sh > ./namelist.amip echo 'NOTE: model - fortran / namelist_python.amip.sh' . ./namelist_python.amip_yaml.sh > ./namelist.amip.yaml + # TODO the name of the file should be generated based on the experiment that is running exp_input_yaml_file="exp1_amip.yaml" - . ./yaml_parse.sh + . ./template_amip.yaml > $exp_input_yaml_file [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box fi if [ $amip_mode = forcing ]; then -- GitLab From 64f0d005119c03abb6520c6678a312dee55b2e55 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 12 Jul 2023 12:44:26 +0200 Subject: [PATCH 13/39] it reads in the YAML file, and replace the read in from namelist and it works, it needs cleanup --- sources/data-coupler/AMIPDataCoupler.py | 16 ++++++++++- sources/data-coupler/DataCoupler.py | 34 ++++++++++++++++++----- sources/data-coupler/DataCouplerUtils.py | 35 ++++++++---------------- tests/data/template_amip.yaml | 20 +++++++------- tests/data/yaml_parse.sh | 13 --------- tests/run_example.sh | 8 +++--- 6 files changed, 68 insertions(+), 58 deletions(-) delete mode 100755 tests/data/yaml_parse.sh diff --git a/sources/data-coupler/AMIPDataCoupler.py b/sources/data-coupler/AMIPDataCoupler.py index a456ff7..e5eb1ed 100644 --- a/sources/data-coupler/AMIPDataCoupler.py +++ b/sources/data-coupler/AMIPDataCoupler.py @@ -4,16 +4,30 @@ # MIT License from DataCoupler import DataCoupler +import argparse +import sys # Constants NAMELIST_FILE_NAME = 'namelist.amip' NAMELIST_SECTION = 'NAMAMIP' LOG_FILE_NAME = 'amip.log' CPLNG_COMP_NAME = 'AMIPFORC' +#YAML_INPUT_FILE_NAME = "namelist.amip_exp1.yaml" +YAML_INPUT_FILE_NAME = "blabla" if __name__ == '__main__': + try: + parser=argparse.ArgumentParser() + parser.add_argument("--yaml_experiment_input_file",type=str,default=YAML_INPUT_FILE_NAME) + args = parser.parse_args() + YAML_INPUT_FILE_NAME = args.yaml_experiment_input_file + except: + print("NOTE: Could note read in the input yaml file : {}".format(YAML_INPUT_FILE_NAME), file=sys.stderr) + else: + print("NOTE: input yaml file is : {}".format(YAML_INPUT_FILE_NAME), file=sys.stderr) + # Setup - amip = DataCoupler(NAMELIST_FILE_NAME, NAMELIST_SECTION, LOG_FILE_NAME) + amip = DataCoupler(NAMELIST_FILE_NAME, NAMELIST_SECTION, YAML_INPUT_FILE_NAME, LOG_FILE_NAME) amip.setup_data_coupler() amip.setup_oasis(CPLNG_COMP_NAME, write_grid=True, write_grid_mask=True, write_grid_corners= True, write_grid_areas = True) diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index acf4881..8f1ebac 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -18,19 +18,39 @@ from DataCouplerOasisVar import OasisOutputVar class DataCoupler: - def __init__(self, NAMELIST_FILE_NAME, NAMELIST_SECTION, LOG_FILE_NAME): + def __init__(self, NAMELIST_FILE_NAME, NAMELIST_SECTION,YAML_INPUT_FILE_NAME, LOG_FILE_NAME): # Read RunLengthSec,TimeStepSec, config, etc. from namelist RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_namelist(NAMELIST_FILE_NAME, NAMELIST_SECTION) - ### TODO for now it is feed in the middle of the function - YAML_NAMELIST_FILE_NAME = "exp1_amip.yaml" + + RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, \ - StartDay_y, FixYear_y = read_exp_yaml(YAML_NAMELIST_FILE_NAME) - print("NEXT LINE IS PRODUCED BY YAML FILE READER", file=sys.stderr) - print(RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, StartDay_y, FixYear_y, file=sys.stderr) - + StartDay_y, FixYear_y, LDebug_y, fileIn_vars_config_y, oasisOut_vars_config_y = read_exp_yaml(YAML_INPUT_FILE_NAME) + + + # TODO : just a test to show that YAML file and the namelist readin are identical (will be removed) + + print("NOTE: NEXT LINE IS PRODUCED BY Original FILE READER", file=sys.stderr) + print(RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear,\ + LDebug, fileIn_vars_config, oasisOut_vars_config, file=sys.stderr) + + print("NOTE: NEXT LINE IS PRODUCED BY YAML FILE READER", file=sys.stderr) + print(RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, StartDay_y, FixYear_y,\ + LDebug_y, fileIn_vars_config_y, oasisOut_vars_config_y, file=sys.stderr) + + # TODO : just a test that to show that it works with read-in from YAML file instead of the namelist (will be removed) + RunLengthSec = RunLengthSec_y + TimeStepSec = TimeStepSec_y + StartYear = StartYear_y + StartMonth = StartMonth_y + StartDay = StartDay_y + LDebug = LDebug_y + fileIn_vars_config = fileIn_vars_config_y + oasisOut_vars_config = oasisOut_vars_config_y + + if LDebug: logging.basicConfig(filename=LOG_FILE_NAME, format='%(message)s', level=logging.DEBUG) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 7263b9d..54b09e6 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -253,31 +253,20 @@ def read_exp_yaml(experiment_yaml_input): if "FileInputVars" in read_in : FileInputVars_readin = {} - FileInputVars_readin_variables = FileInputVars_readin.keys - FileInputVars_readin = read_in.get('FileInputVars') - print("NOTE: The type is: {}".format(type(FileInputVars_readin)),file=sys.stderr) - print("NOTE: The keys are: {}".format(FileInputVars_readin_variables),file=sys.stderr) - print("NOTE: The values are: {}".format(FileInputVars_readin.values),file=sys.stderr) - - - - - print("NOTE: Normal File Input Vars are {}".format(FileInputVars_readin),file=sys.stderr) - + # Name of the Variable for this experiment + FileInputVarNames = list(FileInputVars_readin.keys()) + # Variable configuration for this experiment + FileInputVarFields_conf = list(FileInputVars_readin.values()) if "OasisOutputVars" in read_in : - OasisOutputVars_out = {} - #print(type(OasisOutputVars_out), file=sys.stderr) - OasisOutputVars_out = read_in.get('OasisOutputVars') - #print(type(OasisOutputVars_out), file=sys.stderr) - - # print(type(OasisOutputVars_out.keys()), file=sys.stderr) - - # print("NOTE: File OASIS Output Vars are {OasisOutputVars_out}".format(OasisOutputVars_out = OasisOutputVars_out),file=sys.stderr) - # print("NOTE: KEYS: File OASIS Output Vars are {keys}".format(keys = OasisOutputVars_out.keys),file=sys.stderr) - # print("NOTE: VALUES: File OASIS Output Vars are {values}".format(values = OasisOutputVars_out.values),file=sys.stderr) - - return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear + OasisOutputVars_readin = {} + OasisOutputVars_readin = read_in.get('OasisOutputVars') + # Name of the Variable for this experiment + OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) + # Variable configuration for this experiment + OasisOutputVars_conf = list(OasisOutputVars_readin.values()) + + return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf diff --git a/tests/data/template_amip.yaml b/tests/data/template_amip.yaml index 57a70d4..770bcb5 100755 --- a/tests/data/template_amip.yaml +++ b/tests/data/template_amip.yaml @@ -10,18 +10,18 @@ FixYear : ${ifs_cmip_fixyear} # Only fill the following section: FileInputVars: - AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} - AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 1, max: , update: true, accum: true} - CO2_em_monthly : { id : CO2_em_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_emis, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 1, min: 0, max: , update: true, accum: true} - CO2_land_monthly: { id : CO2_land_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_land, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.5, min: 0, max: , update: true, accum: true} - CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} + AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} + AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 0, max: 1, update: true, accum: true} + CO2_em_monthly : { id : CO2_em_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_emis, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 1, min: 0, max: , update: true, accum: true} + CO2_land_monthly: { id : CO2_land_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_land, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.5, min: 0, max: , update: true, accum: true} + CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} OasisOutputVars: - - AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - - AMIP_sic : { id: AMIP_sic, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - - AMIP_CO2_emis : { id: AMIP_CO2_emis, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - - AMIP_CO2_land : { id: AMIP_CO2_land, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - - AMIP_CO2_ocean : { id: AMIP_CO2_ocean, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sic : { id: AMIP_sic, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_CO2_emis : { id: AMIP_CO2_emis, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_CO2_land : { id: AMIP_CO2_land, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_CO2_ocean : { id: AMIP_CO2_ocean, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } LDebug : false EOF diff --git a/tests/data/yaml_parse.sh b/tests/data/yaml_parse.sh deleted file mode 100755 index 2eb18dd..0000000 --- a/tests/data/yaml_parse.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -RunLengthSec=${leg_length_sec} -TimeStepSec=${cpl_freq_amip_sec} -StartYear=${leg_start_date_yyyymmdd:0:4} -StartMonth=${leg_start_date_yyyymmdd:4:2} -StartDay=${leg_start_date_yyyymmdd:6:2} -FixYear=${ifs_cmip_fixyear} -Output_file_name=${exp_input_yaml_file} - -sed -e "s/\[leg_length_sec\]/$RunLengthSec/" -e "s/\[cpl_freq_amip_sec\]/$TimeStepSec/" -e "s/\[StartYear\]/$StartYear/" -e "s/\[StartMonth\]/$StartMonth/" \ - -e "s/\[StartMonth\]/$StartMonth/" -e "s/\[StartDay\]/$StartDay/" -e "s/\[StartDay\]/$StartDay/" \ - -e "s/\[FixYear\]/$FixYear/" template_amip.yaml > $Output_file_name diff --git a/tests/run_example.sh b/tests/run_example.sh index 206c414..90695f0 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -217,11 +217,11 @@ else oasis_conf_var="" fi . ./namelist_python.amip.sh > ./namelist.amip - echo 'NOTE: model - fortran / namelist_python.amip.sh' - . ./namelist_python.amip_yaml.sh > ./namelist.amip.yaml + # TODO the name of the file should be generated based on the experiment that is running - exp_input_yaml_file="exp1_amip.yaml" + exp_input_yaml_file="namelist.amip_exp1.yaml" . ./template_amip.yaml > $exp_input_yaml_file + [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box fi if [ $amip_mode = forcing ]; then @@ -236,7 +236,7 @@ fi ### Definition of mpirun command and batch script echo 'Executing the model using mpirun : ${MPIRUN}' -${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 +${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 --yaml_experiment_input_file $exp_input_yaml_file # convert output . convert-ece4pyreader-grids.sh ${leg_start_date} -- GitLab From 829e39ba5d2e4b2165ee9b8a7504d6274fb3a3ab Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 12 Jul 2023 15:43:31 +0200 Subject: [PATCH 14/39] refactoring the yaml reader to be experiment --conf, integarte the AMIPDataCoupler to the DataCoupler itself, introducing model name in yaml --- sources/data-coupler/AMIPDataCoupler.py | 4 +-- sources/data-coupler/DataCoupler.py | 33 ++++++++++++++++++++++++ sources/data-coupler/DataCouplerUtils.py | 3 +++ tests/data/template_amip.yaml | 9 +++++-- tests/run_example.sh | 8 +++--- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/sources/data-coupler/AMIPDataCoupler.py b/sources/data-coupler/AMIPDataCoupler.py index e5eb1ed..13009f4 100644 --- a/sources/data-coupler/AMIPDataCoupler.py +++ b/sources/data-coupler/AMIPDataCoupler.py @@ -12,10 +12,10 @@ NAMELIST_FILE_NAME = 'namelist.amip' NAMELIST_SECTION = 'NAMAMIP' LOG_FILE_NAME = 'amip.log' CPLNG_COMP_NAME = 'AMIPFORC' -#YAML_INPUT_FILE_NAME = "namelist.amip_exp1.yaml" -YAML_INPUT_FILE_NAME = "blabla" +YAML_INPUT_FILE_NAME = "namelist.amip_exp1.yaml" if __name__ == '__main__': + # receive the yaml experiment input file is it exists , otherwise pass try: parser=argparse.ArgumentParser() parser.add_argument("--yaml_experiment_input_file",type=str,default=YAML_INPUT_FILE_NAME) diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 8f1ebac..a44d43c 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -290,3 +290,36 @@ class DataCoupler: 'T' if self.lleapfx2 else 'F')) logging.debug('UPDATED DataCoupler INIT - tnewyear: {}'.format(self.tnewyear)) logging.debug('DataCoupler INIT - tlastfeb: {}'.format(self.tlastfeb)) + + + + +## TODO this part needs refactoring and these values should be passed on , not be hard -coded here +# Constants +NAMELIST_FILE_NAME = 'namelist.amip' +NAMELIST_SECTION = 'NAMAMIP' +LOG_FILE_NAME = 'amip.log' +CPLNG_COMP_NAME = 'AMIPFORC' +YAML_INPUT_FILE_NAME = "namelist.amip_exp1.yaml" + +if __name__ == '__main__': + # receive the yaml experiment input file is it exists , otherwise pass + try: + parser=argparse.ArgumentParser() + parser.add_argument("--conf",type=str,default=YAML_INPUT_FILE_NAME) + args = parser.parse_args() + YAML_INPUT_FILE_NAME = args.yaml_experiment_input_file + except: + print("NOTE: Could note read in the input yaml file : {}".format(YAML_INPUT_FILE_NAME), file=sys.stderr) + else: + print("NOTE: input yaml file is : {}".format(YAML_INPUT_FILE_NAME), file=sys.stderr) + + # Setup + amip = DataCoupler(NAMELIST_FILE_NAME, NAMELIST_SECTION, YAML_INPUT_FILE_NAME, LOG_FILE_NAME) + amip.setup_data_coupler() + amip.setup_oasis(CPLNG_COMP_NAME, write_grid=True, write_grid_mask=True, + write_grid_corners= True, write_grid_areas = True) + # Time loop + amip.run_time_loop() + # Finalize + amip.finalise_data_coupler() \ No newline at end of file diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 54b09e6..4a983f9 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -242,6 +242,7 @@ def read_exp_yaml(experiment_yaml_input): # Experiment detail + ModelName = read_in.get('ModelName') RunLengthSec = read_in.get('RunLengthSec') TimeStepSec = read_in.get('TimeStepSec') StartYear = read_in.get('StartYear') @@ -250,7 +251,9 @@ def read_exp_yaml(experiment_yaml_input): FixYear = read_in.get('FixYear') LDebug = read_in.get('LDebug') + # Create the log_file name and sanity-check + # Check the type of input in yaml file if "FileInputVars" in read_in : FileInputVars_readin = {} FileInputVars_readin = read_in.get('FileInputVars') diff --git a/tests/data/template_amip.yaml b/tests/data/template_amip.yaml index 770bcb5..a59fc72 100755 --- a/tests/data/template_amip.yaml +++ b/tests/data/template_amip.yaml @@ -1,6 +1,11 @@ cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file -# This section will be filled automatically + +# Information about the model +## fill the following section: +ModelName : ModelName + +## This section will be filled automatically RunLengthSec : ${leg_length_sec} TimeStepSec : ${cpl_freq_amip_sec} StartYear : ${leg_start_date_yyyymmdd:0:4} @@ -8,7 +13,7 @@ StartMonth : ${leg_start_date_yyyymmdd:4:2} StartDay : ${leg_start_date_yyyymmdd:6:2} FixYear : ${ifs_cmip_fixyear} -# Only fill the following section: +## fill the following section: FileInputVars: AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 0, max: 1, update: true, accum: true} diff --git a/tests/run_example.sh b/tests/run_example.sh index 90695f0..9428c69 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -45,7 +45,9 @@ elif [ $model = python ] || [ $model = pythoncompat ]; then # exe2='python3 -m cProfile -s cumtime amip_forcing.py' source_exe2=$srcdir/../sources/amip-forcing/src/python/*.py elif [ $model = datacoupler ] ; then - exe2='python3 AMIPDataCoupler.py' + # TODO + #exe2='python3 AMIPDataCoupler.py' + exe2='python3 DataCoupler.py' # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' # exe2='python3 -m cProfile -s cumtime amip_forcing.py' source_exe2=$srcdir/../sources/data-coupler/*.py @@ -221,7 +223,7 @@ else # TODO the name of the file should be generated based on the experiment that is running exp_input_yaml_file="namelist.amip_exp1.yaml" . ./template_amip.yaml > $exp_input_yaml_file - + [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box fi if [ $amip_mode = forcing ]; then @@ -236,7 +238,7 @@ fi ### Definition of mpirun command and batch script echo 'Executing the model using mpirun : ${MPIRUN}' -${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 --yaml_experiment_input_file $exp_input_yaml_file +${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 --conf $exp_input_yaml_file # convert output . convert-ece4pyreader-grids.sh ${leg_start_date} -- GitLab From 2ab9bddcb53710d80d7a17c3a37dd687e0f9a702 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Thu, 13 Jul 2023 15:37:19 +0200 Subject: [PATCH 15/39] Refactored the script by removing all the legacy functions and hardcoded values related to the namelist. Additionally, modified the generation of the experiment configuration file name, which is now based on the ModelName specified in the template file. --- sources/data-coupler/DataCoupler.py | 74 ++++++------------- sources/data-coupler/DataCouplerUtils.py | 11 ++- ...{template_amip.yaml => template_conf.yaml} | 12 +-- tests/run_example.sh | 8 +- 4 files changed, 40 insertions(+), 65 deletions(-) rename tests/data/{template_amip.yaml => template_conf.yaml} (94%) diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index a44d43c..eaf43be 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -9,50 +9,24 @@ import numpy as np import os import logging import math -import sys +import sys +import argparse from DataCouplerUtils import read_namelist, days_since_refyear, is_leap, earth_area -from DataCouplerUtils import read_exp_yaml +from DataCouplerUtils import read_yaml_conf from DataCouplerFileVar import FileInputVar from DataCouplerOasisVar import OasisOutputVar class DataCoupler: - def __init__(self, NAMELIST_FILE_NAME, NAMELIST_SECTION,YAML_INPUT_FILE_NAME, LOG_FILE_NAME): + def __init__(self,yaml_conf_file): - # Read RunLengthSec,TimeStepSec, config, etc. from namelist - RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_namelist(NAMELIST_FILE_NAME, NAMELIST_SECTION) - - - RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, \ - StartDay_y, FixYear_y, LDebug_y, fileIn_vars_config_y, oasisOut_vars_config_y = read_exp_yaml(YAML_INPUT_FILE_NAME) + ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_yaml_conf(yaml_conf_file) - - # TODO : just a test to show that YAML file and the namelist readin are identical (will be removed) - - print("NOTE: NEXT LINE IS PRODUCED BY Original FILE READER", file=sys.stderr) - print(RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear,\ - LDebug, fileIn_vars_config, oasisOut_vars_config, file=sys.stderr) - - print("NOTE: NEXT LINE IS PRODUCED BY YAML FILE READER", file=sys.stderr) - print(RunLengthSec_y, TimeStepSec_y, StartYear_y, StartMonth_y, StartDay_y, FixYear_y,\ - LDebug_y, fileIn_vars_config_y, oasisOut_vars_config_y, file=sys.stderr) - - # TODO : just a test that to show that it works with read-in from YAML file instead of the namelist (will be removed) - RunLengthSec = RunLengthSec_y - TimeStepSec = TimeStepSec_y - StartYear = StartYear_y - StartMonth = StartMonth_y - StartDay = StartDay_y - LDebug = LDebug_y - fileIn_vars_config = fileIn_vars_config_y - oasisOut_vars_config = oasisOut_vars_config_y - - if LDebug: - logging.basicConfig(filename=LOG_FILE_NAME, format='%(message)s', level=logging.DEBUG) + logging.basicConfig(filename=LogFileName, format='%(message)s', level=logging.DEBUG) date_yref_min = max([conf['yref_min'] for conf in fileIn_vars_config]) date_yref_max = min([conf['yref_max'] for conf in fileIn_vars_config]) @@ -68,6 +42,9 @@ class DataCoupler: if ((StartYear < date_yref_min) and (RunLengthSec > (date_yref_min-StartYear+1)*3600*24*365)): raise Exception("RunLengthSec is too long for StartYear less than date_yref_min") + # Oasis Compiler description + self.OasisCPLNG = OasisCPLNG + # time axis unit = days self.delta_t = TimeStepSec/86400. self.fix_year = FixYear @@ -90,9 +67,9 @@ class DataCoupler: logging.debug('fileIn_vars: {}'.format(self.fileIn_vars.keys())) - def setup_oasis(self, CPLNG_COMP_NAME, write_grid=True, write_grid_mask=True, write_grid_corners= True, write_grid_areas = True): + def setup_oasis(self, write_grid=True, write_grid_mask=True, write_grid_corners= True, write_grid_areas = True): # OASIS init - self.oasis_comp = pyoasis.Component(CPLNG_COMP_NAME) + self.oasis_comp = pyoasis.Component(self.OasisCPLNG) self.oasisOut_vars = {} # Setup grids and write if requested @@ -293,33 +270,24 @@ class DataCoupler: - -## TODO this part needs refactoring and these values should be passed on , not be hard -coded here -# Constants -NAMELIST_FILE_NAME = 'namelist.amip' -NAMELIST_SECTION = 'NAMAMIP' -LOG_FILE_NAME = 'amip.log' -CPLNG_COMP_NAME = 'AMIPFORC' -YAML_INPUT_FILE_NAME = "namelist.amip_exp1.yaml" - if __name__ == '__main__': # receive the yaml experiment input file is it exists , otherwise pass try: parser=argparse.ArgumentParser() - parser.add_argument("--conf",type=str,default=YAML_INPUT_FILE_NAME) + parser.add_argument("--conf",type=str) args = parser.parse_args() - YAML_INPUT_FILE_NAME = args.yaml_experiment_input_file + yaml_conf_file = args.conf except: - print("NOTE: Could note read in the input yaml file : {}".format(YAML_INPUT_FILE_NAME), file=sys.stderr) + print("NOTE: Could note read in the input yaml file : {}".format(yaml_conf_file), file=sys.stderr) else: - print("NOTE: input yaml file is : {}".format(YAML_INPUT_FILE_NAME), file=sys.stderr) + print("NOTE: input yaml file is : {}".format(yaml_conf_file), file=sys.stderr) # Setup - amip = DataCoupler(NAMELIST_FILE_NAME, NAMELIST_SECTION, YAML_INPUT_FILE_NAME, LOG_FILE_NAME) - amip.setup_data_coupler() - amip.setup_oasis(CPLNG_COMP_NAME, write_grid=True, write_grid_mask=True, + datacoupler = DataCoupler(yaml_conf_file) + datacoupler.setup_data_coupler() + datacoupler.setup_oasis(write_grid=True, write_grid_mask=True, write_grid_corners= True, write_grid_areas = True) # Time loop - amip.run_time_loop() + datacoupler.run_time_loop() # Finalize - amip.finalise_data_coupler() \ No newline at end of file + datacoupler.finalise_data_coupler() \ No newline at end of file diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 4a983f9..8ae5827 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -231,7 +231,7 @@ def read_namelist(NAMELIST_FILE_NAME,NAMELIST_SECTION): -def read_exp_yaml(experiment_yaml_input): +def read_yaml_conf(experiment_yaml_input): ''' Reads the experiment yaml file ''' @@ -240,9 +240,14 @@ def read_exp_yaml(experiment_yaml_input): read_in = yaml.load(file, Loader=SafeLoader) file.close() - # Experiment detail + # Model Information ModelName = read_in.get('ModelName') + OasisCPLNG = read_in.get('OasisCPLNG') + LogFileName = read_in.get('LogFileName') + + ## Run Information + RunLengthSec = read_in.get('RunLengthSec') TimeStepSec = read_in.get('TimeStepSec') StartYear = read_in.get('StartYear') @@ -270,6 +275,6 @@ def read_exp_yaml(experiment_yaml_input): # Variable configuration for this experiment OasisOutputVars_conf = list(OasisOutputVars_readin.values()) - return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf + return ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf diff --git a/tests/data/template_amip.yaml b/tests/data/template_conf.yaml similarity index 94% rename from tests/data/template_amip.yaml rename to tests/data/template_conf.yaml index a59fc72..bfda97d 100755 --- a/tests/data/template_amip.yaml +++ b/tests/data/template_conf.yaml @@ -1,11 +1,13 @@ cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file -# Information about the model -## fill the following section: -ModelName : ModelName +## Model Information +ModelName : AMIP +OasisCPLNG : AMIPFORC +LogFileName : amip.log +YamlConfName : ${yaml_conf_name} -## This section will be filled automatically +## Run Information RunLengthSec : ${leg_length_sec} TimeStepSec : ${cpl_freq_amip_sec} StartYear : ${leg_start_date_yyyymmdd:0:4} @@ -13,7 +15,7 @@ StartMonth : ${leg_start_date_yyyymmdd:4:2} StartDay : ${leg_start_date_yyyymmdd:6:2} FixYear : ${ifs_cmip_fixyear} -## fill the following section: +## Coupling Information FileInputVars: AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 0, max: 1, update: true, accum: true} diff --git a/tests/run_example.sh b/tests/run_example.sh index 9428c69..580081a 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -220,9 +220,9 @@ else fi . ./namelist_python.amip.sh > ./namelist.amip - # TODO the name of the file should be generated based on the experiment that is running - exp_input_yaml_file="namelist.amip_exp1.yaml" - . ./template_amip.yaml > $exp_input_yaml_file + # Create the name of the experiment conf yaml based on the model name in template yaml + yaml_conf_name=$(grep -F "ModelName" "template_conf.yaml" | awk '{print $3}') + . ./template_conf.yaml > $yaml_conf_name [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box fi @@ -238,7 +238,7 @@ fi ### Definition of mpirun command and batch script echo 'Executing the model using mpirun : ${MPIRUN}' -${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 --conf $exp_input_yaml_file +${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 --conf $yaml_conf_name # convert output . convert-ece4pyreader-grids.sh ${leg_start_date} -- GitLab From 3bd4fafa80e934ec1af8672b92f26c253babead8 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Fri, 14 Jul 2023 15:44:42 +0200 Subject: [PATCH 16/39] including AMIP forcing to YAML support, in addition now yaml file is passed to run_example as argument from batch_script file --- sources/data-coupler/DataCoupler.py | 2 ++ ...aml => template_conf_datacoupler_co2.yaml} | 0 .../template_conf_datacoupler_forcing.yaml | 30 +++++++++++++++++++ tests/launch-mn4.cmd | 4 +-- tests/run_example.sh | 30 +++++++++++++------ 5 files changed, 55 insertions(+), 11 deletions(-) rename tests/data/{template_conf.yaml => template_conf_datacoupler_co2.yaml} (100%) create mode 100755 tests/data/template_conf_datacoupler_forcing.yaml diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index eaf43be..6859211 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -65,6 +65,8 @@ class DataCoupler: for conf in fileIn_vars_config: self.fileIn_vars[conf['id']] = FileInputVar(conf, self.fix_year, self.start_year) logging.debug('fileIn_vars: {}'.format(self.fileIn_vars.keys())) + print("NOTE: FileInputVar in original form {}".format(self._oasisOut_vars_config ),file=sys.stderr) + def setup_oasis(self, write_grid=True, write_grid_mask=True, write_grid_corners= True, write_grid_areas = True): diff --git a/tests/data/template_conf.yaml b/tests/data/template_conf_datacoupler_co2.yaml similarity index 100% rename from tests/data/template_conf.yaml rename to tests/data/template_conf_datacoupler_co2.yaml diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml new file mode 100755 index 0000000..24cb8b0 --- /dev/null +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -0,0 +1,30 @@ +cat << EOF +# YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file + +## Model Information +ModelName : AMIP +OasisCPLNG : AMIPFORC +LogFileName : amip.log +YamlConfName : ${yaml_conf_name} + +## Run Information +RunLengthSec : ${leg_length_sec} +TimeStepSec : ${cpl_freq_amip_sec} +StartYear : ${leg_start_date_yyyymmdd:0:4} +StartMonth : ${leg_start_date_yyyymmdd:4:2} +StartDay : ${leg_start_date_yyyymmdd:6:2} +FixYear : ${ifs_cmip_fixyear} + +## Coupling Information +FileInputVars: + AMIP_sst_monthly : { id : AMIP_sst_monthly, grid_name: AMIP, oasis_name: AMIP_sst, file_pattern: tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: tosbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 1, offset: 273.15, min: 271.38, max: , update: true, accum: true} + AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 0, max: 1, update: true, accum: true} + +OasisOutputVars: + AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sic : { id: AMIP_sic, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + + +LDebug : false +EOF + diff --git a/tests/launch-mn4.cmd b/tests/launch-mn4.cmd index 2a7bfd3..e5d6268 100644 --- a/tests/launch-mn4.cmd +++ b/tests/launch-mn4.cmd @@ -18,10 +18,10 @@ source ../sources/oasis3-mct/generated/python/init.sh #bash ./run_example.sh fortran forcing 4 2005-01-01 2005-03-01 0 128 true #bash ./run_example-t1279.sh python forcing 4 2010-01-01 2010-03-01 0 128 true -#bash ./run_example.sh datacoupler co2 4 2005-01-01 2005-03-01 0 128 true false +bash ./run_example.sh datacoupler co2 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_co2.yaml #bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true false -bash ./run_example.sh datacoupler forcing 4 2005-01-01 2005-03-01 0 128 true false +#bash ./run_example.sh datacoupler forcing 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_forcing.yaml #bash ./run_example.sh python co2 4 2005-01-01 2005-03-01 0 128 true #bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true #bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true false diff --git a/tests/run_example.sh b/tests/run_example.sh index 580081a..97cca97 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -1,11 +1,12 @@ #!/bin/bash ## Usage -if [ $# -ne 9 ]; then - echo 'Invalid args.' - echo 'Usage ./run_example.sh ' - echo 'Try ./run_example.sh python forcing 4 1990-01-01 1991-01-01 0 L128 true' - exit 1 -fi + +# if [ $# -ne 9 ]; then +# echo 'Invalid args.' +# echo 'Usage ./run_example.sh ' +# echo 'Try ./run_example.sh python forcing 4 1990-01-01 1991-01-01 0 L128 true' +# exit 1 +# fi set -xuve @@ -21,6 +22,7 @@ ifs_cmip_fixyear=$6 ifs_grid=$7 amip_interpolate=$8 co2_interpolate=$9 +yaml_conf_file=${10} host=`uname -n` user=`whoami` @@ -129,6 +131,7 @@ if [ $model = fortran ] || [ $model = pythoncompat ]; then . ./namelist.amip.sh > ./namelist.amip else . ./namelist_primavera.amip.sh > ./namelist.amip + fi else #if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then @@ -221,8 +224,8 @@ else . ./namelist_python.amip.sh > ./namelist.amip # Create the name of the experiment conf yaml based on the model name in template yaml - yaml_conf_name=$(grep -F "ModelName" "template_conf.yaml" | awk '{print $3}') - . ./template_conf.yaml > $yaml_conf_name + yaml_conf_name=$(grep -F "ModelName" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' + . ./$yaml_conf_file > $yaml_conf_name [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box fi @@ -238,7 +241,16 @@ fi ### Definition of mpirun command and batch script echo 'Executing the model using mpirun : ${MPIRUN}' -${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 --conf $yaml_conf_name + +# To seprate the DataCoupler with YAML input file from legecy codes +if [ $model = datacoupler ] ; then + if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then + ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 --conf $yaml_conf_name + fi +else + ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 +fi + # convert output . convert-ece4pyreader-grids.sh ${leg_start_date} -- GitLab From 9a483c417a5004c2b42841815d018620be81b4ac Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Mon, 17 Jul 2023 16:37:17 +0200 Subject: [PATCH 17/39] removing model name and replacing its use with OasisCPLNG, including send/rec-id and send/rec-grid-name in template and necessary changes --- sources/data-coupler/DataCoupler.py | 15 ++++++++++----- sources/data-coupler/DataCouplerOasisVar.py | 2 +- sources/data-coupler/DataCouplerUtils.py | 5 +++-- tests/data/template_conf_datacoupler_co2.yaml | 14 ++++++-------- tests/data/template_conf_datacoupler_forcing.yaml | 8 ++++---- tests/run_example.sh | 4 ++-- 6 files changed, 26 insertions(+), 22 deletions(-) diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 6859211..7c26ee5 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -22,7 +22,7 @@ class DataCoupler: def __init__(self,yaml_conf_file): - ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_yaml_conf(yaml_conf_file) if LDebug: @@ -65,7 +65,7 @@ class DataCoupler: for conf in fileIn_vars_config: self.fileIn_vars[conf['id']] = FileInputVar(conf, self.fix_year, self.start_year) logging.debug('fileIn_vars: {}'.format(self.fileIn_vars.keys())) - print("NOTE: FileInputVar in original form {}".format(self._oasisOut_vars_config ),file=sys.stderr) + @@ -122,23 +122,28 @@ class DataCoupler: for v in grid_vars: # look for this oasis var in OasisVars config configs = self._oasisOut_vars_config - config = list(filter(lambda configs: configs['id'] == v.oasis_name, configs)) + config = list(filter(lambda configs: configs['send_id'] == v.oasis_name, configs)) if len(config)!=1: raise Exception("oasis var {} not defined in OasisOutputVars".format(v.oasis_name)) if not v.oasis_name in self.oasisOut_vars: logging.debug('creating oasis var {} with grid {} and fileIn_var {}'.format(v.oasis_name, grid_name,v.id)) self.oasisOut_vars[v.oasis_name] = OasisOutputVar(config[0], partition, v.grid_lon.shape, {v.id:v}) + print('NOTE: creating oasis var {} with grid {} and fileIn_var {}'.format(v.oasis_name, grid_name,v.id),file=sys.stderr) + else: logging.debug('adding to oasis var {} with grid {} fileIn_var {}'.format(v.oasis_name, grid_name,v.id)) self.oasisOut_vars[v.oasis_name].add_file_input_var(v.id,v) + print('NOTE: adding to oasis var {} with grid {} fileIn_var {}'.format(v.oasis_name, grid_name,v.id),file=sys.stderr) + logging.debug('oasisOut_vars: {}'.format(str(self.oasisOut_vars.keys()))) for var_name, oasisOut_var in self.oasisOut_vars.items(): logging.debug('oasisOut_var {} is linked to fileIn vars {}'.format(var_name, oasisOut_var.file_input_vars() )) + print('oasisOut_var {} is linked to fileIn vars {}'.format(var_name, oasisOut_var.file_input_vars() ),file=sys.stderr) # check that all OasisVars are actually defined for config in self._oasisOut_vars_config: - if not config['id'] in self.oasisOut_vars: - raise Exception("oasis var {} in OasisOutputVars not defined in FileInputVars".format(config['id'])) + if not config['send_id'] in self.oasisOut_vars: + raise Exception("oasis var {} in OasisOutputVars not defined in FileInputVars".format(config['send_id'])) self.oasis_comp.enddef() diff --git a/sources/data-coupler/DataCouplerOasisVar.py b/sources/data-coupler/DataCouplerOasisVar.py index d7ff628..7b27d0b 100644 --- a/sources/data-coupler/DataCouplerOasisVar.py +++ b/sources/data-coupler/DataCouplerOasisVar.py @@ -12,7 +12,7 @@ from DataCouplerUtils import scale_factor_from_str class OasisOutputVar: def __init__(self, conf, partition, grid_shape, fileIn_vars ): self._conf = conf - self._id = conf['id'] + self._id = conf['send_id'] self._reset = conf['reset'] self._scale_factor = scale_factor_from_str(conf['scale_factor']) if type(conf['scale_factor']) == str else conf['scale_factor'] self._offset = np.float64(conf['offset']) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 8ae5827..b76e84d 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -242,7 +242,6 @@ def read_yaml_conf(experiment_yaml_input): # Model Information - ModelName = read_in.get('ModelName') OasisCPLNG = read_in.get('OasisCPLNG') LogFileName = read_in.get('LogFileName') @@ -254,6 +253,7 @@ def read_yaml_conf(experiment_yaml_input): StartMonth = read_in.get('StartMonth') StartDay = read_in.get('StartDay') FixYear = read_in.get('FixYear') + GridInfo = read_in.get('GridInfo') LDebug = read_in.get('LDebug') # Create the log_file name and sanity-check @@ -274,7 +274,8 @@ def read_yaml_conf(experiment_yaml_input): OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) # Variable configuration for this experiment OasisOutputVars_conf = list(OasisOutputVars_readin.values()) + print("Oasis OutPut Variables are {}".format(OasisOutputVars_conf),file=sys.stderr) - return ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf + return OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf diff --git a/tests/data/template_conf_datacoupler_co2.yaml b/tests/data/template_conf_datacoupler_co2.yaml index bfda97d..6920c18 100755 --- a/tests/data/template_conf_datacoupler_co2.yaml +++ b/tests/data/template_conf_datacoupler_co2.yaml @@ -2,7 +2,6 @@ cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file ## Model Information -ModelName : AMIP OasisCPLNG : AMIPFORC LogFileName : amip.log YamlConfName : ${yaml_conf_name} @@ -14,6 +13,7 @@ StartYear : ${leg_start_date_yyyymmdd:0:4} StartMonth : ${leg_start_date_yyyymmdd:4:2} StartDay : ${leg_start_date_yyyymmdd:6:2} FixYear : ${ifs_cmip_fixyear} +GridInfo : TBD_VALUE ## Coupling Information FileInputVars: @@ -24,14 +24,12 @@ FileInputVars: CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} OasisOutputVars: - AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - AMIP_sic : { id: AMIP_sic, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - AMIP_CO2_emis : { id: AMIP_CO2_emis, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - AMIP_CO2_land : { id: AMIP_CO2_land, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - AMIP_CO2_ocean : { id: AMIP_CO2_ocean, grid_name: 'CO2_emis', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sst : { send_id: AMIP_sst, receive_id: A_sst, send_grid_name: 'AMIP', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sic : { send_id: AMIP_sic, receive_id: A_sic, send_grid_name: 'AMIP', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_CO2_emis : { send_id: AMIP_CO2_emis, receive_id: A_CO2_emis, send_grid_name: 'CO2_emis', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_CO2_land : { send_id: AMIP_CO2_land, receive_id: A_CO2_land, send_grid_name: 'CO2_emis', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_CO2_ocean : { send_id: AMIP_CO2_ocean, receive_id: A_CO2_ocean, send_grid_name: 'CO2_emis', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } LDebug : false EOF - - diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml index 24cb8b0..2632357 100755 --- a/tests/data/template_conf_datacoupler_forcing.yaml +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -2,7 +2,6 @@ cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file ## Model Information -ModelName : AMIP OasisCPLNG : AMIPFORC LogFileName : amip.log YamlConfName : ${yaml_conf_name} @@ -14,6 +13,8 @@ StartYear : ${leg_start_date_yyyymmdd:0:4} StartMonth : ${leg_start_date_yyyymmdd:4:2} StartDay : ${leg_start_date_yyyymmdd:6:2} FixYear : ${ifs_cmip_fixyear} +GridInfo : TBD_VALUE + ## Coupling Information FileInputVars: @@ -21,9 +22,8 @@ FileInputVars: AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 0, max: 1, update: true, accum: true} OasisOutputVars: - AMIP_sst : { id: AMIP_sst, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - AMIP_sic : { id: AMIP_sic, grid_name: 'AMIP', timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - + AMIP_sst : { send_id: AMIP_sst, receive_id: A_sst, send_grid_name: 'AMIP', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sic : { send_id: AMIP_sic, receive_id: A_sic, send_grid_name: 'AMIP', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } LDebug : false EOF diff --git a/tests/run_example.sh b/tests/run_example.sh index 97cca97..ad2479f 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -223,8 +223,8 @@ else fi . ./namelist_python.amip.sh > ./namelist.amip - # Create the name of the experiment conf yaml based on the model name in template yaml - yaml_conf_name=$(grep -F "ModelName" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' + # Create the name of the experiment conf yaml based on the OasisCPLNG name in template yaml + yaml_conf_name=$(grep -F "OasisCPLNG" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' . ./$yaml_conf_file > $yaml_conf_name [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box -- GitLab From 96f81f98e2c75a50c62528f025c3bf22a8d84fca Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 18 Jul 2023 11:06:06 +0200 Subject: [PATCH 18/39] replacing the namelist usage in IFS_toy with the YAML_cong file, reintroducing OasisModel var to yaml conf to be used in general toy model --- sources/data-coupler/DataCoupler.py | 2 +- sources/data-coupler/DataCouplerUtils.py | 7 +- sources/data-coupler/generate_yaml.py | 78 ------- sources/data-coupler/launch_yaml_mn4.cmd | 24 --- sources/ece3-toy-model/toy_model.py | 1 - tests/data/template_conf_datacoupler_co2.yaml | 1 + .../template_conf_datacoupler_forcing.yaml | 1 + tests/general_toy_model.py | 195 ++++++++++++++++++ tests/run_example.sh | 6 +- 9 files changed, 203 insertions(+), 112 deletions(-) delete mode 100644 sources/data-coupler/generate_yaml.py delete mode 100644 sources/data-coupler/launch_yaml_mn4.cmd create mode 100755 tests/general_toy_model.py diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 7c26ee5..0e7a198 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -22,7 +22,7 @@ class DataCoupler: def __init__(self,yaml_conf_file): - OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_yaml_conf(yaml_conf_file) if LDebug: diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index b76e84d..5fa7b20 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -223,10 +223,6 @@ def read_namelist(NAMELIST_FILE_NAME,NAMELIST_SECTION): else: oasisOut_vars_config = None - print("NOTE: fileIn_vars_config are {fileIn_vars_config}".format(fileIn_vars_config = fileIn_vars_config),file=sys.stderr) - print("NOTE: oasisOut_vars_config are {oasisOut_vars_config}".format(oasisOut_vars_config = oasisOut_vars_config),file=sys.stderr) - - return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config @@ -242,6 +238,7 @@ def read_yaml_conf(experiment_yaml_input): # Model Information + OasisModel = read_in.get('OasisModel') OasisCPLNG = read_in.get('OasisCPLNG') LogFileName = read_in.get('LogFileName') @@ -276,6 +273,6 @@ def read_yaml_conf(experiment_yaml_input): OasisOutputVars_conf = list(OasisOutputVars_readin.values()) print("Oasis OutPut Variables are {}".format(OasisOutputVars_conf),file=sys.stderr) - return OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf + return OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf diff --git a/sources/data-coupler/generate_yaml.py b/sources/data-coupler/generate_yaml.py deleted file mode 100644 index a124f32..0000000 --- a/sources/data-coupler/generate_yaml.py +++ /dev/null @@ -1,78 +0,0 @@ - -# Copyright 2022 - Barcelona Supercomputing Center -# Author: Etienne Tourigny, Rodrigo Martín Posada -# MIT License -from datetime import date -import numpy as np -import yaml -from yaml.loader import SafeLoader -import argparse -import os -import sys - -if __name__ == '__main__': - -### Read in YAML file - parser=argparse.ArgumentParser() - parser.add_argument("--model_name",type=str) - parser.add_argument("--template_name",type=str) - parser.add_argument("--file_name",type=str) - parser.add_argument("--leg_length_sec",type=str) - parser.add_argument("--cpl_freq_amip_sec",type=str) - parser.add_argument("--StartYear",type=str) - parser.add_argument("--StartMonth",type=str) - parser.add_argument("--StartDay",type=str) - parser.add_argument("--FixYear",type=str) - args = parser.parse_args() - ModelName = args.model_name - RunLengthSec = args.leg_length_sec - TimeStepSec = args.cpl_freq_amip_sec - StartYear = args.StartYear - StartMonth = args.StartMonth - StartDay = args.StartDay - FixYear = args.FixYear - - # Check the existence of template file and experiment file. - template_name = args.template_name - output_file_name = args.file_name - - current_path = os.getcwd() - yamel_input_file_path = os.path.join(current_path,template_name) - yamel_output_file_path = os.path.join(current_path,output_file_name) - - if os.path.isfile(yamel_input_file_path) == False: - print("yaml template file does not exist. Aborted", file=sys.stderr) - raise NameError("YAML file does not exist.") - - if os.path.isfile(yamel_input_file_path) == True: - print("yaml output file exists. It will be deleted.", file=sys.stderr) - os.remove(yamel_output_file_path) - - # Open the template file and load the file - read_in_data = {} - with open(yamel_input_file_path) as file: - read_in_data = yaml.load(file, Loader=SafeLoader) - file.close() - -# Modify the ReadInData based on the values passed by the RunExample -# Modify the fields from template files - read_in_data['RunLengthSec'] = RunLengthSec - read_in_data['TimeStepSec'] = TimeStepSec - read_in_data['StartYear'] = StartYear - read_in_data['StartMonth'] = StartMonth - read_in_data['StartDay'] = StartDay - read_in_data['FixYear'] = FixYear - - # ## TODO remove this part - # read_in_data['FileInputVars']['AMIP_sst_monthly']['interpolate'] = AMIP_interpolate - # read_in_data['FileInputVars']['AMIP_sic_monthly']['interpolate'] = AMIP_interpolate - # read_in_data['FileInputVars']['CO2_em_monthly']['interpolate'] = CO2_interpolate - # read_in_data['FileInputVars']['CO2_land_monthly']['interpolate'] = CO2_interpolate - # read_in_data['FileInputVars']['CO2_ocean_monthly']['interpolate'] = CO2_interpolate - - # Save it again -with open(output_file_name, 'w') as stream: - yaml.dump(read_in_data, stream, sort_keys=False) - -print("yaml output file created.", file=sys.stderr) - diff --git a/sources/data-coupler/launch_yaml_mn4.cmd b/sources/data-coupler/launch_yaml_mn4.cmd deleted file mode 100644 index fcf86f7..0000000 --- a/sources/data-coupler/launch_yaml_mn4.cmd +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# slurm specific options for Marenostrum4 -#SBATCH --qos=debug -#SBATCH -N 1 -#SBATCH -n 3 -#SBATCH -c 1 -#SBATCH -t 00:05:00 -#SBATCH --exclusive - -#load python and netcdf modules -export PYTHONPATH="" -module load python/3.6.1 -module load netcdf/4.2 - -set -xuve - - - -# run yaml script -chmod +x namelist.amip_py.sh -bash namelist.amip_py.sh -#python3 YAML_util.py -# --yaml_file_path ifs_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path nemo_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path runoff_toy_model.yaml diff --git a/sources/ece3-toy-model/toy_model.py b/sources/ece3-toy-model/toy_model.py index 38ba24e..c359096 100644 --- a/sources/ece3-toy-model/toy_model.py +++ b/sources/ece3-toy-model/toy_model.py @@ -9,7 +9,6 @@ import logging import argparse import os -import f90nml import pyoasis from pyoasis import OASIS # pylint: disable=no-name-in-module import numpy as np diff --git a/tests/data/template_conf_datacoupler_co2.yaml b/tests/data/template_conf_datacoupler_co2.yaml index 6920c18..e3f6981 100755 --- a/tests/data/template_conf_datacoupler_co2.yaml +++ b/tests/data/template_conf_datacoupler_co2.yaml @@ -2,6 +2,7 @@ cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file ## Model Information +OasisModel : IFS_TOY OasisCPLNG : AMIPFORC LogFileName : amip.log YamlConfName : ${yaml_conf_name} diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml index 2632357..4fbe79c 100755 --- a/tests/data/template_conf_datacoupler_forcing.yaml +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -2,6 +2,7 @@ cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file ## Model Information +OasisModel : IFS_TOY OasisCPLNG : AMIPFORC LogFileName : amip.log YamlConfName : ${yaml_conf_name} diff --git a/tests/general_toy_model.py b/tests/general_toy_model.py new file mode 100755 index 0000000..5a34527 --- /dev/null +++ b/tests/general_toy_model.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python3 +# Copyright 2021 - Barcelona Supercomputing Center +# Author: Rodrigo Martín Posada +# MIT License + +import f90nml +import pyoasis +from pyoasis import OASIS # pylint: disable=no-name-in-module +import numpy as np +import logging + +import yaml +from yaml.loader import SafeLoader +import logging +import argparse +import os +import sys +from DataCouplerUtils import read_yaml_conf + + +# TODO +# It will read in the YAML file instead of the namelist. It will receive the name of the YAMl file as argparse value +# it should turn to class in next step round of refactoring + + +L080_NX = 35718 # number of grid cells at T159 resolution +L128_NX = 88838 # number of grid cells at T255 resolution +L256_NX = 348528 # number of grid cells at T511 resolution +CO2_CMODE = False # is CO2 concentration-mode active? +CO2_EMODE = False # is CO2 emission-mode active? + + +def def_local_partition(nx, npes, mype): + il_size = nx // npes + il_offset = mype * il_size + if (npes-mype) <= nx % npes: + il_size += 1 + il_offset += (nx % npes) - (npes-mype) + return il_size, il_offset + +if __name__ == '__main__': + + try: + parser=argparse.ArgumentParser() + parser.add_argument("--conf",type=str) + args = parser.parse_args() + yaml_conf_file = args.conf + except: + print("NOTE:TOY Could note read in the input yaml file : {}".format(yaml_conf_file), file=sys.stderr) + else: + print("NOTE:TOY input yaml file is : {}".format(yaml_conf_file), file=sys.stderr) + + OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_yaml_conf(yaml_conf_file) + + + print("NOTE:OASIS MODEL is : {}".format(OasisModel), file=sys.stderr) + + # Constants from namelist + + COUPLING_INTERVAL = TimeStepSec + RUN_LENGTH_SEC = RunLengthSec + + # Init OASIS + comp = pyoasis.Component(OasisModel) + + # Get rank in local communicator + mype = comp.localcomm.rank + npes = comp.localcomm.size + value = str(100+mype) # ? Not sure what this means , same was in toy_model + # Unit for output messages + out_ifs = ("{OasisModel}.out_{value}").format(OasisModel=OasisModel,value=value) + logging.basicConfig(filename=out_ifs, format='%(message)s', level=logging.DEBUG) + logging.debug('-----------------------------------------------------------') + logging.debug('I am IFS-toy process with rank : {}'.format(mype)) + logging.debug('in my local communicator gathering {} processes'.format(npes)) + logging.debug('----------------------------------------------------------') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # PARTITION DEFINITION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + with open('namcouple', 'r') as f: + #contents = f.read() + contents = "" + for line in f: + li=line.strip() + if not li.startswith("#"): + contents += line + # TODOD find a better way to detect CO2_CMODE + if 'GLOBAL GLOBAL' in contents: + CO2_CMODE = True + if 'A_CO2_emis ' in contents: + CO2_EMODE = True + if 'L080' in contents: + nx = L080_NX + elif 'L128' in contents: + nx = L128_NX + elif 'L256' in contents: + nx = L256_NX + else: + raise Exception('Invalid IFS grid in namcouple') + # Definition of the local partition + il_size, il_offset = def_local_partition(nx, npes, mype) + logging.debug('Local partition definition') + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + partition = pyoasis.ApplePartition(il_offset, il_size) + if CO2_CMODE or CO2_EMODE: + #nx_co2 = 2 # for 2 hemisphere box model + nx_co2 = 1 + if mype == 0: + logging.debug('Local serial partition') + logging.debug('nx_co2 = {} mype = {}'.format(nx_co2, mype)) + partition2 = pyoasis.SerialPartition(nx_co2) + else: + nx_co2 = 0 + partition2 = None + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # DECLARATION OF THE COUPLING FIELDS + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + A_SST = pyoasis.Var("A_SST", partition, OASIS.IN) + A_Ice_frac = pyoasis.Var("A_Ice_frac", partition, OASIS.IN) + logging.debug('var_id A_SST, var_id A_Ice_frac {} {}'.format(A_SST._id, A_Ice_frac._id)) + if CO2_CMODE: + if mype == 0: + A_CO2_cconc = pyoasis.Var("A_CO2_cconc", partition2, OASIS.IN) + logging.debug('var_id A_CO2_cconc {}'.format(A_CO2_cconc._id)) + A_CO2_econc = pyoasis.Var("A_CO2_econc", partition2, OASIS.IN) + logging.debug('var_id A_CO2_econc {}'.format(A_CO2_cconc._id)) + if CO2_EMODE: + A_CO2_emis = pyoasis.Var("A_CO2_emis", partition, OASIS.IN) + logging.debug('var_id A_CO2_emis {}'.format(A_CO2_emis._id)) + A_CO2_land = pyoasis.Var("A_CO2_land", partition, OASIS.IN) + logging.debug('var_id A_CO2_land {}'.format(A_CO2_land._id)) + A_CO2_ocean = pyoasis.Var("A_CO2_ocean", partition, OASIS.IN) + logging.debug('var_id A_CO2_ocean {}'.format(A_CO2_ocean._id)) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION OF DEFINITION PHASE + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of initialisation phase') + + comp.enddef() + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TIME STEP LOOP + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('Timestep, field min, mean and max value') + + field_recv_A_SST = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_Ice_frac = pyoasis.asarray(np.full(il_size, -1.0)) + if CO2_CMODE and mype == 0: + field_recv_A_CO2_cconc = pyoasis.asarray(np.full(nx_co2, -1.0)) + field_recv_A_CO2_econc = pyoasis.asarray(np.full(nx_co2, -1.0)) + if CO2_EMODE: + field_recv_A_CO2_emis = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_CO2_land = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_CO2_ocean = pyoasis.asarray(np.full(il_size, -1.0)) + + for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): + A_SST.get(itap_sec, field_recv_A_SST) + A_Ice_frac.get(itap_sec, field_recv_A_Ice_frac) + + logging.debug('ITAP_SEC: {}'.format(itap_sec)) + logging.debug('A_SST -> {:.3e} {:.3e} {:.3e}'.format( + np.min(field_recv_A_SST), + np.mean(field_recv_A_SST), + np.max(field_recv_A_SST))) + logging.debug('A_Ice_frac -> {:.3e} {:.3e} {:.3e}'.format( + np.min(field_recv_A_Ice_frac), + np.mean(field_recv_A_Ice_frac), + np.max(field_recv_A_Ice_frac))) + if CO2_CMODE: + if mype == 0: + A_CO2_cconc.get(itap_sec, field_recv_A_CO2_cconc) + logging.debug('A_CO2_cconc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_cconc), np.mean(field_recv_A_CO2_cconc), np.max(field_recv_A_CO2_cconc))) + A_CO2_econc.get(itap_sec, field_recv_A_CO2_econc) + logging.debug('A_CO2_econc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_econc), np.mean(field_recv_A_CO2_econc), np.max(field_recv_A_CO2_econc))) + if CO2_EMODE: + A_CO2_emis.get(itap_sec, field_recv_A_CO2_emis) + logging.debug('A_CO2_emis -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_emis), np.mean(field_recv_A_CO2_emis), np.max(field_recv_A_CO2_emis))) + A_CO2_land.get(itap_sec, field_recv_A_CO2_land) + logging.debug('A_CO2_land -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_land), np.mean(field_recv_A_CO2_land), np.max(field_recv_A_CO2_land))) + A_CO2_ocean.get(itap_sec, field_recv_A_CO2_ocean) + logging.debug('A_CO2_ocean -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_ocean), np.mean(field_recv_A_CO2_ocean), np.max(field_recv_A_CO2_ocean))) + logging.debug('--------------------------------------\n') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of the program') + + del comp diff --git a/tests/run_example.sh b/tests/run_example.sh index ad2479f..ce98a62 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -31,8 +31,8 @@ srcdir=`pwd` datadir=$srcdir/data -exe1='python3 IFS_toy.py' -source_exe1=$srcdir/IFS_toy.py +exe1='python3 general_toy_model.py' +source_exe1=$srcdir/general_toy_model.py if [ $model = fortran ]; then exe2='./amip-forcing' @@ -245,7 +245,7 @@ echo 'Executing the model using mpirun : ${MPIRUN}' # To seprate the DataCoupler with YAML input file from legecy codes if [ $model = datacoupler ] ; then if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then - ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 --conf $yaml_conf_name + ${MPIRUN} -np $nproc_exe1 $exe1 --conf $yaml_conf_name : -np $nproc_exe2 $exe2 --conf $yaml_conf_name fi else ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 -- GitLab From 2d6e2cff716a71cc86020b20aef9ee24744b134b Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 19 Jul 2023 18:28:38 +0200 Subject: [PATCH 19/39] WIP: works by reading send/recieve-id for forcing with no hard-coded segment, next namecouple --- sources/data-coupler/DataCoupler.py | 4 +- sources/data-coupler/DataCouplerUtils.py | 5 +- tests/data/template_conf_datacoupler_co2.yaml | 4 +- .../template_conf_datacoupler_forcing.yaml | 4 +- tests/general_toy_model.py | 97 +++----- tests/general_toy_model_backup.py | 207 ++++++++++++++++++ tests/launch-mn4.cmd | 4 +- 7 files changed, 251 insertions(+), 74 deletions(-) create mode 100755 tests/general_toy_model_backup.py diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 0e7a198..62c417f 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -23,7 +23,7 @@ class DataCoupler: OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_yaml_conf(yaml_conf_file) + StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars = read_yaml_conf(yaml_conf_file) if LDebug: logging.basicConfig(filename=LogFileName, format='%(message)s', level=logging.DEBUG) @@ -128,12 +128,10 @@ class DataCoupler: if not v.oasis_name in self.oasisOut_vars: logging.debug('creating oasis var {} with grid {} and fileIn_var {}'.format(v.oasis_name, grid_name,v.id)) self.oasisOut_vars[v.oasis_name] = OasisOutputVar(config[0], partition, v.grid_lon.shape, {v.id:v}) - print('NOTE: creating oasis var {} with grid {} and fileIn_var {}'.format(v.oasis_name, grid_name,v.id),file=sys.stderr) else: logging.debug('adding to oasis var {} with grid {} fileIn_var {}'.format(v.oasis_name, grid_name,v.id)) self.oasisOut_vars[v.oasis_name].add_file_input_var(v.id,v) - print('NOTE: adding to oasis var {} with grid {} fileIn_var {}'.format(v.oasis_name, grid_name,v.id),file=sys.stderr) logging.debug('oasisOut_vars: {}'.format(str(self.oasisOut_vars.keys()))) for var_name, oasisOut_var in self.oasisOut_vars.items(): diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 5fa7b20..ef6a905 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -267,12 +267,13 @@ def read_yaml_conf(experiment_yaml_input): if "OasisOutputVars" in read_in : OasisOutputVars_readin = {} OasisOutputVars_readin = read_in.get('OasisOutputVars') + print("NOTE: OasisOutputVars_readin : {}".format(OasisOutputVars_readin), file=sys.stderr) # Name of the Variable for this experiment OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) + # Variable configuration for this experiment OasisOutputVars_conf = list(OasisOutputVars_readin.values()) - print("Oasis OutPut Variables are {}".format(OasisOutputVars_conf),file=sys.stderr) - return OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf + return OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin diff --git a/tests/data/template_conf_datacoupler_co2.yaml b/tests/data/template_conf_datacoupler_co2.yaml index e3f6981..4f0ec37 100755 --- a/tests/data/template_conf_datacoupler_co2.yaml +++ b/tests/data/template_conf_datacoupler_co2.yaml @@ -25,8 +25,8 @@ FileInputVars: CO2_ocean_monthly: { id : CO2_ocean_monthly, grid_name: CO2_emis, oasis_name: AMIP_CO2_ocean, file_pattern: CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, netcdf_variable: CO2_em_anthro, yref_min : 1750, yref_max: 2018, timestep: monthly, interpolate : false, scale_factor: 0.01, offset: 0.1, min: 0, max: , update: true, accum: true} OasisOutputVars: - AMIP_sst : { send_id: AMIP_sst, receive_id: A_sst, send_grid_name: 'AMIP', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - AMIP_sic : { send_id: AMIP_sic, receive_id: A_sic, send_grid_name: 'AMIP', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sst : { send_id: AMIP_sst, receive_id: A_SST, send_grid_name: 'AMIP', receive_grid_name: L128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sic : { send_id: AMIP_sic, receive_id: A_Ice_frac, send_grid_name: 'AMIP', receive_grid_name: L128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } AMIP_CO2_emis : { send_id: AMIP_CO2_emis, receive_id: A_CO2_emis, send_grid_name: 'CO2_emis', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } AMIP_CO2_land : { send_id: AMIP_CO2_land, receive_id: A_CO2_land, send_grid_name: 'CO2_emis', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } AMIP_CO2_ocean : { send_id: AMIP_CO2_ocean, receive_id: A_CO2_ocean, send_grid_name: 'CO2_emis', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml index 4fbe79c..06c1fea 100755 --- a/tests/data/template_conf_datacoupler_forcing.yaml +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -23,8 +23,8 @@ FileInputVars: AMIP_sic_monthly : { id : AMIP_sic_monthly, grid_name: AMIP, oasis_name: AMIP_sic, file_pattern: siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, netcdf_variable: siconcbcs, yref_min : 1870, yref_max: 2016, timestep: monthly, interpolate : true, scale_factor: 0.01, offset: 0, min: 0, max: 1, update: true, accum: true} OasisOutputVars: - AMIP_sst : { send_id: AMIP_sst, receive_id: A_sst, send_grid_name: 'AMIP', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } - AMIP_sic : { send_id: AMIP_sic, receive_id: A_sic, send_grid_name: 'AMIP', receive_grid_name: B128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sst : { send_id: AMIP_sst, receive_id: A_SST, send_grid_name: 'AMIP', receive_grid_name: L128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } + AMIP_sic : { send_id: AMIP_sic, receive_id: A_Ice_frac, send_grid_name: 'AMIP', receive_grid_name: L128, timestep: 'daily', scale_factor: 1, offset: 0, reset: true } LDebug : false EOF diff --git a/tests/general_toy_model.py b/tests/general_toy_model.py index 5a34527..d4f1538 100755 --- a/tests/general_toy_model.py +++ b/tests/general_toy_model.py @@ -51,11 +51,9 @@ if __name__ == '__main__': print("NOTE:TOY input yaml file is : {}".format(yaml_conf_file), file=sys.stderr) OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config = read_yaml_conf(yaml_conf_file) + StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars_readin = read_yaml_conf(yaml_conf_file) - print("NOTE:OASIS MODEL is : {}".format(OasisModel), file=sys.stderr) - # Constants from namelist COUPLING_INTERVAL = TimeStepSec @@ -116,76 +114,49 @@ if __name__ == '__main__': nx_co2 = 0 partition2 = None + + # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. + OasisOutputVars = [] + Oasis_receive_id = [] + for v in OasisOutputVars_readin.keys() : + OasisOutputVars.append([OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']]) + Oasis_receive_id.append(OasisOutputVars_readin[v]['receive_id']) + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # DECLARATION OF THE COUPLING FIELDS # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - A_SST = pyoasis.Var("A_SST", partition, OASIS.IN) - A_Ice_frac = pyoasis.Var("A_Ice_frac", partition, OASIS.IN) - logging.debug('var_id A_SST, var_id A_Ice_frac {} {}'.format(A_SST._id, A_Ice_frac._id)) - if CO2_CMODE: - if mype == 0: - A_CO2_cconc = pyoasis.Var("A_CO2_cconc", partition2, OASIS.IN) - logging.debug('var_id A_CO2_cconc {}'.format(A_CO2_cconc._id)) - A_CO2_econc = pyoasis.Var("A_CO2_econc", partition2, OASIS.IN) - logging.debug('var_id A_CO2_econc {}'.format(A_CO2_cconc._id)) - if CO2_EMODE: - A_CO2_emis = pyoasis.Var("A_CO2_emis", partition, OASIS.IN) - logging.debug('var_id A_CO2_emis {}'.format(A_CO2_emis._id)) - A_CO2_land = pyoasis.Var("A_CO2_land", partition, OASIS.IN) - logging.debug('var_id A_CO2_land {}'.format(A_CO2_land._id)) - A_CO2_ocean = pyoasis.Var("A_CO2_ocean", partition, OASIS.IN) - logging.debug('var_id A_CO2_ocean {}'.format(A_CO2_ocean._id)) + variables = {} # Create a dictionary to store the variables - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION OF DEFINITION PHASE - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of initialisation phase') + for name in Oasis_receive_id: + var = pyoasis.Var(name, partition, OASIS.IN) + variables[name] = var + print("NOTE:OASIS {name}: {pyoasis_output}".format(name=name, pyoasis_output=var), file=sys.stderr) + + logging.debug('var_id {}: {}'.format(name, var._id)) + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# TERMINATION OF DEFINITION PHASE +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of initialization phase') comp.enddef() - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TIME STEP LOOP - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('Timestep, field min, mean and max value') - - field_recv_A_SST = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_Ice_frac = pyoasis.asarray(np.full(il_size, -1.0)) - if CO2_CMODE and mype == 0: - field_recv_A_CO2_cconc = pyoasis.asarray(np.full(nx_co2, -1.0)) - field_recv_A_CO2_econc = pyoasis.asarray(np.full(nx_co2, -1.0)) - if CO2_EMODE: - field_recv_A_CO2_emis = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_CO2_land = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_CO2_ocean = pyoasis.asarray(np.full(il_size, -1.0)) +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# TIME STEP LOOP +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('Timestep, field min, mean, and max value') + + fields = {} + + for name in Oasis_receive_id: + fields[name] = pyoasis.asarray(np.full(il_size, -1.0)) for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): - A_SST.get(itap_sec, field_recv_A_SST) - A_Ice_frac.get(itap_sec, field_recv_A_Ice_frac) - - logging.debug('ITAP_SEC: {}'.format(itap_sec)) - logging.debug('A_SST -> {:.3e} {:.3e} {:.3e}'.format( - np.min(field_recv_A_SST), - np.mean(field_recv_A_SST), - np.max(field_recv_A_SST))) - logging.debug('A_Ice_frac -> {:.3e} {:.3e} {:.3e}'.format( - np.min(field_recv_A_Ice_frac), - np.mean(field_recv_A_Ice_frac), - np.max(field_recv_A_Ice_frac))) - if CO2_CMODE: - if mype == 0: - A_CO2_cconc.get(itap_sec, field_recv_A_CO2_cconc) - logging.debug('A_CO2_cconc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_cconc), np.mean(field_recv_A_CO2_cconc), np.max(field_recv_A_CO2_cconc))) - A_CO2_econc.get(itap_sec, field_recv_A_CO2_econc) - logging.debug('A_CO2_econc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_econc), np.mean(field_recv_A_CO2_econc), np.max(field_recv_A_CO2_econc))) - if CO2_EMODE: - A_CO2_emis.get(itap_sec, field_recv_A_CO2_emis) - logging.debug('A_CO2_emis -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_emis), np.mean(field_recv_A_CO2_emis), np.max(field_recv_A_CO2_emis))) - A_CO2_land.get(itap_sec, field_recv_A_CO2_land) - logging.debug('A_CO2_land -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_land), np.mean(field_recv_A_CO2_land), np.max(field_recv_A_CO2_land))) - A_CO2_ocean.get(itap_sec, field_recv_A_CO2_ocean) - logging.debug('A_CO2_ocean -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_ocean), np.mean(field_recv_A_CO2_ocean), np.max(field_recv_A_CO2_ocean))) - logging.debug('--------------------------------------\n') + for name in Oasis_receive_id: + variables[name].get(itap_sec, fields[name]) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # TERMINATION diff --git a/tests/general_toy_model_backup.py b/tests/general_toy_model_backup.py new file mode 100755 index 0000000..ce1a467 --- /dev/null +++ b/tests/general_toy_model_backup.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +# Copyright 2021 - Barcelona Supercomputing Center +# Author: Rodrigo Martín Posada +# MIT License + +import f90nml +import pyoasis +from pyoasis import OASIS # pylint: disable=no-name-in-module +import numpy as np +import logging + +import yaml +from yaml.loader import SafeLoader +import logging +import argparse +import os +import sys +from DataCouplerUtils import read_yaml_conf + + +# TODO +# It will read in the YAML file instead of the namelist. It will receive the name of the YAMl file as argparse value +# it should turn to class in next step round of refactoring + + +L080_NX = 35718 # number of grid cells at T159 resolution +L128_NX = 88838 # number of grid cells at T255 resolution +L256_NX = 348528 # number of grid cells at T511 resolution +CO2_CMODE = False # is CO2 concentration-mode active? +CO2_EMODE = False # is CO2 emission-mode active? + + +def def_local_partition(nx, npes, mype): + il_size = nx // npes + il_offset = mype * il_size + if (npes-mype) <= nx % npes: + il_size += 1 + il_offset += (nx % npes) - (npes-mype) + return il_size, il_offset + +if __name__ == '__main__': + + try: + parser=argparse.ArgumentParser() + parser.add_argument("--conf",type=str) + args = parser.parse_args() + yaml_conf_file = args.conf + except: + print("NOTE:TOY Could note read in the input yaml file : {}".format(yaml_conf_file), file=sys.stderr) + else: + print("NOTE:TOY input yaml file is : {}".format(yaml_conf_file), file=sys.stderr) + + OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars_readin = read_yaml_conf(yaml_conf_file) + + + # Constants from namelist + + COUPLING_INTERVAL = TimeStepSec + RUN_LENGTH_SEC = RunLengthSec + + # Init OASIS + comp = pyoasis.Component(OasisModel) + + # Get rank in local communicator + mype = comp.localcomm.rank + npes = comp.localcomm.size + value = str(100+mype) # ? Not sure what this means , same was in toy_model + # Unit for output messages + out_ifs = ("{OasisModel}.out_{value}").format(OasisModel=OasisModel,value=value) + logging.basicConfig(filename=out_ifs, format='%(message)s', level=logging.DEBUG) + logging.debug('-----------------------------------------------------------') + logging.debug('I am IFS-toy process with rank : {}'.format(mype)) + logging.debug('in my local communicator gathering {} processes'.format(npes)) + logging.debug('----------------------------------------------------------') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # PARTITION DEFINITION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + with open('namcouple', 'r') as f: + #contents = f.read() + contents = "" + for line in f: + li=line.strip() + if not li.startswith("#"): + contents += line + # TODOD find a better way to detect CO2_CMODE + if 'GLOBAL GLOBAL' in contents: + CO2_CMODE = True + if 'A_CO2_emis ' in contents: + CO2_EMODE = True + if 'L080' in contents: + nx = L080_NX + elif 'L128' in contents: + nx = L128_NX + elif 'L256' in contents: + nx = L256_NX + else: + raise Exception('Invalid IFS grid in namcouple') + # Definition of the local partition + il_size, il_offset = def_local_partition(nx, npes, mype) + logging.debug('Local partition definition') + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + partition = pyoasis.ApplePartition(il_offset, il_size) + if CO2_CMODE or CO2_EMODE: + #nx_co2 = 2 # for 2 hemisphere box model + nx_co2 = 1 + if mype == 0: + logging.debug('Local serial partition') + logging.debug('nx_co2 = {} mype = {}'.format(nx_co2, mype)) + partition2 = pyoasis.SerialPartition(nx_co2) + else: + nx_co2 = 0 + partition2 = None + + + # Prepare the list that is necessary for + OasisOutputVars = [] + for v in OasisOutputVars_readin.keys() : + OasisOutputVars.append([OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']]) + variable = OasisOutputVars_readin[v]['receive_id'] + #variable = pyoasis.Var(OasisOutputVars_readin[v]['receive_id'], partition, OASIS.IN) + # print("NOTE: {variable_name} : {pyoasis_output}".format(variable_name =v, pyoasis_output=variable), file=sys.stderr) + print("NOTE:OASIS VARIABLE NAME : {pyoasis_output}".format( pyoasis_output= variable), file=sys.stderr) + + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # DECLARATION OF THE COUPLING FIELDS + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + A_SST = pyoasis.Var("A_SST", partition, OASIS.IN) + print("NOTE:OASIS ASST : {pyoasis_output}".format( pyoasis_output=A_SST), file=sys.stderr) + A_Ice_frac = pyoasis.Var("A_Ice_frac", partition, OASIS.IN) + print("NOTE:OASIS A_Ice_frac : {pyoasis_output}".format( pyoasis_output=A_Ice_frac), file=sys.stderr) + logging.debug('var_id A_SST, var_id A_Ice_frac {} {}'.format(A_SST._id, A_Ice_frac._id)) + + if CO2_CMODE: + if mype == 0: + A_CO2_cconc = pyoasis.Var("A_CO2_cconc", partition2, OASIS.IN) + logging.debug('var_id A_CO2_cconc {}'.format(A_CO2_cconc._id)) + A_CO2_econc = pyoasis.Var("A_CO2_econc", partition2, OASIS.IN) + logging.debug('var_id A_CO2_econc {}'.format(A_CO2_cconc._id)) + if CO2_EMODE: + A_CO2_emis = pyoasis.Var("A_CO2_emis", partition, OASIS.IN) + logging.debug('var_id A_CO2_emis {}'.format(A_CO2_emis._id)) + A_CO2_land = pyoasis.Var("A_CO2_land", partition, OASIS.IN) + logging.debug('var_id A_CO2_land {}'.format(A_CO2_land._id)) + A_CO2_ocean = pyoasis.Var("A_CO2_ocean", partition, OASIS.IN) + logging.debug('var_id A_CO2_ocean {}'.format(A_CO2_ocean._id)) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION OF DEFINITION PHASE + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of initialisation phase') + + comp.enddef() + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TIME STEP LOOP + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('Timestep, field min, mean and max value') + + field_recv_A_SST = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_Ice_frac = pyoasis.asarray(np.full(il_size, -1.0)) + if CO2_CMODE and mype == 0: + field_recv_A_CO2_cconc = pyoasis.asarray(np.full(nx_co2, -1.0)) + field_recv_A_CO2_econc = pyoasis.asarray(np.full(nx_co2, -1.0)) + if CO2_EMODE: + field_recv_A_CO2_emis = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_CO2_land = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_CO2_ocean = pyoasis.asarray(np.full(il_size, -1.0)) + + for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): + A_SST.get(itap_sec, field_recv_A_SST) + A_Ice_frac.get(itap_sec, field_recv_A_Ice_frac) + + logging.debug('ITAP_SEC: {}'.format(itap_sec)) + logging.debug('A_SST -> {:.3e} {:.3e} {:.3e}'.format( + np.min(field_recv_A_SST), + np.mean(field_recv_A_SST), + np.max(field_recv_A_SST))) + logging.debug('A_Ice_frac -> {:.3e} {:.3e} {:.3e}'.format( + np.min(field_recv_A_Ice_frac), + np.mean(field_recv_A_Ice_frac), + np.max(field_recv_A_Ice_frac))) + if CO2_CMODE: + if mype == 0: + A_CO2_cconc.get(itap_sec, field_recv_A_CO2_cconc) + logging.debug('A_CO2_cconc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_cconc), np.mean(field_recv_A_CO2_cconc), np.max(field_recv_A_CO2_cconc))) + A_CO2_econc.get(itap_sec, field_recv_A_CO2_econc) + logging.debug('A_CO2_econc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_econc), np.mean(field_recv_A_CO2_econc), np.max(field_recv_A_CO2_econc))) + if CO2_EMODE: + A_CO2_emis.get(itap_sec, field_recv_A_CO2_emis) + logging.debug('A_CO2_emis -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_emis), np.mean(field_recv_A_CO2_emis), np.max(field_recv_A_CO2_emis))) + A_CO2_land.get(itap_sec, field_recv_A_CO2_land) + logging.debug('A_CO2_land -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_land), np.mean(field_recv_A_CO2_land), np.max(field_recv_A_CO2_land))) + A_CO2_ocean.get(itap_sec, field_recv_A_CO2_ocean) + logging.debug('A_CO2_ocean -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_ocean), np.mean(field_recv_A_CO2_ocean), np.max(field_recv_A_CO2_ocean))) + logging.debug('--------------------------------------\n') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of the program') + + del comp diff --git a/tests/launch-mn4.cmd b/tests/launch-mn4.cmd index e5d6268..58fd6d9 100644 --- a/tests/launch-mn4.cmd +++ b/tests/launch-mn4.cmd @@ -18,10 +18,10 @@ source ../sources/oasis3-mct/generated/python/init.sh #bash ./run_example.sh fortran forcing 4 2005-01-01 2005-03-01 0 128 true #bash ./run_example-t1279.sh python forcing 4 2010-01-01 2010-03-01 0 128 true -bash ./run_example.sh datacoupler co2 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_co2.yaml +#bash ./run_example.sh datacoupler co2 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_co2.yaml #bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true false -#bash ./run_example.sh datacoupler forcing 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_forcing.yaml +bash ./run_example.sh datacoupler forcing 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_forcing.yaml #bash ./run_example.sh python co2 4 2005-01-01 2005-03-01 0 128 true #bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true #bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true false -- GitLab From a28f78c767f2183de73722b1bce3ec6d681637d1 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Fri, 21 Jul 2023 13:11:10 +0200 Subject: [PATCH 20/39] WIP: harmonizing the general_toy_model.py with toy_model.py, still needs more adjustment. Extracting functions from DataCoupler to a seperate YAMLb script --- sources/data-coupler/DataCouplerUtils.py | 40 +++++ sources/data-coupler/YAMLlUtils.py | 106 +++++++++++ sources/data-coupler/yamlUtils.py | 98 ----------- sources/ece3-toy-model/nemo_toy_model.yaml | 6 +- .../template_conf_datacoupler_forcing.yaml | 5 +- tests/general_toy_model.py | 164 +++++++++++------- 6 files changed, 261 insertions(+), 158 deletions(-) create mode 100644 sources/data-coupler/YAMLlUtils.py delete mode 100644 sources/data-coupler/yamlUtils.py diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index ef6a905..0b71a29 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -277,3 +277,43 @@ def read_yaml_conf(experiment_yaml_input): return OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin +def read_yaml_meta(experiment_yaml_input): + ''' + Reads the experiment yaml file + ''' + + with open(experiment_yaml_input) as file: + read_in = yaml.load(file, Loader=SafeLoader) + file.close() + + + # Model Information + yaml_type = read_in.get('type') + + return yaml_type + + + +def read_yaml_conf_toy(experiment_yaml_input): + +# Open the file and load the file + with open(experiment_yaml_input) as f: + read_in_data = yaml.load(f, Loader=SafeLoader) + f.close() + +### Read in file + #read_yaml(read_in_data) + model = read_in_data.get("model") + model_name = model.get("model_name") + + # Read in Simulation information + simulation = read_in_data.get("simulation") + simulation_coupling_interval = simulation.get("coupling_interval") + simulation_run_length_sec = simulation.get("run_length_sec") + simulation_nx = simulation.get("nx") + + # Read in Coupling infomration + coupling = read_in_data.get("coupling") + coupling_out_vars = coupling.get("out_vars") + coupling_in_vars = coupling.get("in_vars") + restart_file = coupling.get("restart_file") # This feature is not used for now. TODO \ No newline at end of file diff --git a/sources/data-coupler/YAMLlUtils.py b/sources/data-coupler/YAMLlUtils.py new file mode 100644 index 0000000..d4e5641 --- /dev/null +++ b/sources/data-coupler/YAMLlUtils.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# Copyright 2023 - Barcelona Supercomputing Center +# Authors: Amirpasha Mozaffari +# MIT License + +import yaml +from yaml.loader import SafeLoader +import os +import argparse +import sys + + + +# class yaml_file: + + +def read_yaml_meta(yaml_file): + ''' + Reads the metadata of the yaml file + it includes type which could be: + type 1 : NAMELIST + type 2 : NEMO / IFS / RUNOFF toy model + ''' + with open(yaml_file) as file: + read_in = yaml.load(file, Loader=SafeLoader) + file.close() + + # Model Information + yaml_type = read_in.get('type') + return yaml_type + + +def read_yaml_conf_type1(yaml_file): + ''' + Reads the experiment yaml file + ''' + + with open(yaml_file) as file: + read_in = yaml.load(file, Loader=SafeLoader) + file.close() + + # Model Information + ModelName = read_in.get('ModelName') + OasisCPLNG = read_in.get('OasisCPLNG') + LogFileName = read_in.get('LogFileName') + + ## Run Information + + RunLengthSec = read_in.get('RunLengthSec') + TimeStepSec = read_in.get('TimeStepSec') + StartYear = read_in.get('StartYear') + StartMonth = read_in.get('StartMonth') + StartDay = read_in.get('StartDay') + FixYear = read_in.get('FixYear') + GridInfo = read_in.get('GridInfo') + LDebug = read_in.get('LDebug') + + # Create the log_file name and sanity-check + + # Check the type of input in yaml file + if "FileInputVars" in read_in : + FileInputVars_readin = {} + FileInputVars_readin = read_in.get('FileInputVars') + # Name of the Variable for this experiment + FileInputVarNames = list(FileInputVars_readin.keys()) + # Variable configuration for this experiment + FileInputVarFields_conf = list(FileInputVars_readin.values()) + + if "OasisOutputVars" in read_in : + OasisOutputVars_readin = {} + OasisOutputVars_readin = read_in.get('OasisOutputVars') + print("NOTE: OasisOutputVars_readin : {}".format(OasisOutputVars_readin), file=sys.stderr) + # Name of the Variable for this experiment + OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) + + # Variable configuration for this experiment + OasisOutputVars_conf = list(OasisOutputVars_readin.values()) + + return ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin + + +def read_yaml_conf_type2(yaml_file): + +# Open the file and load the file + with open(yaml_file) as f: + read_in_data = yaml.load(f, Loader=SafeLoader) + f.close() + +### Read in file + #read_yaml(read_in_data) + model = read_in_data.get("model") + model_name = model.get("ModelName") + + # Read in Simulation information + simulation = read_in_data.get("simulation") + simulation_coupling_interval = simulation.get("coupling_interval") + simulation_run_length_sec = simulation.get("run_length_sec") + simulation_nx = simulation.get("nx") + + # Read in Coupling infomration + coupling = read_in_data.get("coupling") + coupling_out_vars = coupling.get("out_vars") + coupling_in_vars = coupling.get("in_vars") + restart_file = coupling.get("restart_file") # This feature is not used for now. TODO + + return model, model_name, simulation_coupling_interval, simulation_run_length_sec, simulation_nx, coupling_out_vars, coupling_in_vars, restart_file diff --git a/sources/data-coupler/yamlUtils.py b/sources/data-coupler/yamlUtils.py deleted file mode 100644 index 695391f..0000000 --- a/sources/data-coupler/yamlUtils.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2023 - Barcelona Supercomputing Center -# Authors: Amirpasha Mozaffari -# MIT License - -import yaml -from yaml.loader import SafeLoader -import os -import argparse - - -def argument_parse_namelist_amip(): - parser = argparse.ArgumentParser() - parser.add_argument("--file_name",default="value0", type=str, help='name of the YAML file that will be created') - parser.add_argument("--leg_length_sec",default="value1", type=str, help='TBD') - parser.add_argument("--cpl_freq_amip_sec",default="value2", type=str, help='TBD') - parser.add_argument("--leg_start_date_yyyy",default="value3", type=str, help='TBD') - parser.add_argument("--leg_start_date_mm",default="value4", type=str, help='TBD') - parser.add_argument("--leg_start_date_dd",default="value5", type=str, help='TBD') - parser.add_argument("--ifs_cmip_fixyear",default="value6", type=str, help='TBD') - parser.add_argument("--flist_sst",default="value7", type=str, help='TBD') - parser.add_argument("--flist_sic",default="value8", type=str, help='TBD') - parser.add_argument("--LDebug",default="value9", type=str, help='TBD') - parser.add_argument("--LInterpolate",default="value10", type=str, help='TBD') - input_argument = vars(parser.parse_args()) #convertargparseNameSpace to dict - print(type(input_argument)) - return input_argument - - -def read_yaml_file(file_name): - current_path = os.getcwd() - yamel_file_path = os.path.join(current_path,file_name) - if os.path.isfile(yamel_file_path) == False: - print("YAML file does not exist. Aborted") - raise NameError("YAML file does not exist.") - - #Open the file and load the file - with open(yamel_file_path) as file: - read_in_data = yaml.load(file, Loader=SafeLoader) - print(read_in_data) - file.close() - return read_in_data - - -def write_namelist_amip_yaml(input_arguments): - ''' - write down a yaml file, by using the input arguments that passed to it. - - ''' - - file_name = input_arguments.get("file_name") - leg_length_sec = input_arguments.get("leg_length_sec") - cpl_freq_amip_sec = input_arguments.get("cpl_freq_amip_sec") - leg_start_date_yyyy = input_arguments.get("leg_start_date_yyyy") - leg_start_date_mm = input_arguments.get("leg_start_date_mm") - leg_start_date_dd = input_arguments.get("leg_start_date_dd") - ifs_cmip_fixyear = input_arguments.get("ifs_cmip_fixyear") - flist_sst= input_arguments.get("flist_sst") - flist_sic= input_arguments.get("flist_sic") - LDebug = input_arguments.get("LDebug") - LInterpolate = input_arguments.get("LInterpolate") - - # yaml file path - current_path = os.getcwd() - yamel_file_path = os.path.join(current_path,file_name) - - - # remove if the YAML file exist - if os.path.isfile(yamel_file_path) == True: - os.remove(yamel_file_path) - print("file exists, older file is deleted.") - - yaml_write_doc = [{'RunLengthSec' : [leg_length_sec]}, - {'TimeStepSec' : [cpl_freq_amip_sec]}, - {'StartYear' : [leg_start_date_yyyy]}, - {'StartMonth' : [leg_start_date_mm]}, - {'StartDay' : [leg_start_date_dd]}, - {'FixYear' : [ifs_cmip_fixyear]}, - {'FileListSST' : [flist_sst]}, - {'FileListSIC' : [flist_sic]}, - {'LDebug' : [LDebug]}, - {'LInterpolate' : [LInterpolate]}] - - with open(yamel_file_path, 'w') as file: - file.write('# This is an input namelist file for DataCoupler tool\n') - documents = yaml.dump(yaml_write_doc, file, width=50, indent=1) - file.close - - return file_name - -if __name__ == '__main__': - - input_arguments = argument_parse_namelist_amip() - file_name = write_namelist_amip_yaml(input_arguments) - read_yaml_file(file_name) - - print("Run finished") - diff --git a/sources/ece3-toy-model/nemo_toy_model.yaml b/sources/ece3-toy-model/nemo_toy_model.yaml index 22aa850..393ef37 100644 --- a/sources/ece3-toy-model/nemo_toy_model.yaml +++ b/sources/ece3-toy-model/nemo_toy_model.yaml @@ -3,8 +3,12 @@ # TBD --- +# yaml metadata +type : 2 + + model: - model_name: NEMO_TOY + ModelName: NEMO_TOY simulation: coupling_interval : 2700 diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml index 06c1fea..7ef7fef 100755 --- a/tests/data/template_conf_datacoupler_forcing.yaml +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -1,8 +1,11 @@ cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file +# yaml metadata +type : 1 + ## Model Information -OasisModel : IFS_TOY +ModelName : IFS_TOY OasisCPLNG : AMIPFORC LogFileName : amip.log YamlConfName : ${yaml_conf_name} diff --git a/tests/general_toy_model.py b/tests/general_toy_model.py index d4f1538..8cbcd83 100755 --- a/tests/general_toy_model.py +++ b/tests/general_toy_model.py @@ -15,8 +15,8 @@ import logging import argparse import os import sys -from DataCouplerUtils import read_yaml_conf - +#from DataCouplerUtils import read_yaml_conf , read_yaml_meta +from YAMLlUtils import read_yaml_meta, read_yaml_conf_type1, read_yaml_conf_type2 # TODO # It will read in the YAML file instead of the namelist. It will receive the name of the YAMl file as argparse value @@ -38,6 +38,34 @@ def def_local_partition(nx, npes, mype): il_offset += (nx % npes) - (npes-mype) return il_size, il_offset +## will be replaced with YAML version in step 5 +def read_name_couple(namcouple): + with open(namcouple, 'r') as f: + contents = "" + CO2_CMODE = None + CO2_EMODE = None + + for line in f: + li=line.strip() + if not li.startswith("#"): + contents += line + # TODOD find a better way to detect CO2_CMODE + if 'GLOBAL GLOBAL' in contents: + CO2_CMODE = True + if 'A_CO2_emis ' in contents: + CO2_EMODE = True + if 'L080' in contents: + nx = L080_NX + elif 'L128' in contents: + nx = L128_NX + elif 'L256' in contents: + nx = L256_NX + else: + raise Exception('Invalid IFS grid in namcouple') + return nx + + + if __name__ == '__main__': try: @@ -50,77 +78,100 @@ if __name__ == '__main__': else: print("NOTE:TOY input yaml file is : {}".format(yaml_conf_file), file=sys.stderr) - OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars_readin = read_yaml_conf(yaml_conf_file) + # Determine the type of yaml file + yaml_type = read_yaml_meta(yaml_conf_file) + + # - # Constants from namelist + if yaml_type == 1 : + ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + + COUPLING_INTERVAL = TimeStepSec + RUN_LENGTH_SEC = RunLengthSec + #nx = GridInfo + + + elif yaml_type == 2: + model, model_name, simulation_coupling_interval, simulation_run_length_sec, \ + simulation_nx, coupling_out_vars, coupling_in_vars, restart_file = read_yaml_conf_type2(yaml_conf_file) + ModelName = model_name + COUPLING_INTERVAL = simulation_coupling_interval + - COUPLING_INTERVAL = TimeStepSec - RUN_LENGTH_SEC = RunLengthSec # Init OASIS - comp = pyoasis.Component(OasisModel) + comp = pyoasis.Component(ModelName) # Get rank in local communicator mype = comp.localcomm.rank npes = comp.localcomm.size - value = str(100+mype) # ? Not sure what this means , same was in toy_model - # Unit for output messages - out_ifs = ("{OasisModel}.out_{value}").format(OasisModel=OasisModel,value=value) - logging.basicConfig(filename=out_ifs, format='%(message)s', level=logging.DEBUG) + + + # BUG : shouldnt it be the npes and not mpye (?) + mype_value = str(100+mype) + out_model = '{ModelName}.out_{mype_value}'.format(ModelName = ModelName, mype_value = mype_value) + + logging.basicConfig(filename=out_model, format='%(message)s', level=logging.DEBUG) logging.debug('-----------------------------------------------------------') - logging.debug('I am IFS-toy process with rank : {}'.format(mype)) + logging.info('I am {ModelName} process with rank : {mype}'.format(ModelName = ModelName, + mype = mype_value)) + #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) logging.debug('in my local communicator gathering {} processes'.format(npes)) logging.debug('----------------------------------------------------------') + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # PARTITION DEFINITION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + if yaml_type == 1 : + + namcouple = 'namcouple' + nx = read_name_couple(namcouple) + + # with open('namcouple', 'r') as f: + # #contents = f.read() + # contents = "" + # for line in f: + # li=line.strip() + # if not li.startswith("#"): + # contents += line + # # TODOD find a better way to detect CO2_CMODE + # if 'GLOBAL GLOBAL' in contents: + # CO2_CMODE = True + # if 'A_CO2_emis ' in contents: + # CO2_EMODE = True + # if 'L080' in contents: + # nx = L080_NX + # elif 'L128' in contents: + # nx = L128_NX + # elif 'L256' in contents: + # nx = L256_NX + # else: + # raise Exception('Invalid IFS grid in namcouple') + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # PARTITION DEFINITION # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # Definition of the local partition + il_size, il_offset = def_local_partition(nx, npes, mype) + logging.debug('Local partition definition') + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + partition = pyoasis.ApplePartition(il_offset, il_size) + + else : - with open('namcouple', 'r') as f: - #contents = f.read() - contents = "" - for line in f: - li=line.strip() - if not li.startswith("#"): - contents += line - # TODOD find a better way to detect CO2_CMODE - if 'GLOBAL GLOBAL' in contents: - CO2_CMODE = True - if 'A_CO2_emis ' in contents: - CO2_EMODE = True - if 'L080' in contents: - nx = L080_NX - elif 'L128' in contents: - nx = L128_NX - elif 'L256' in contents: - nx = L256_NX - else: - raise Exception('Invalid IFS grid in namcouple') - # Definition of the local partition - il_size, il_offset = def_local_partition(nx, npes, mype) - logging.debug('Local partition definition') - logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) - partition = pyoasis.ApplePartition(il_offset, il_size) - if CO2_CMODE or CO2_EMODE: - #nx_co2 = 2 # for 2 hemisphere box model - nx_co2 = 1 - if mype == 0: - logging.debug('Local serial partition') - logging.debug('nx_co2 = {} mype = {}'.format(nx_co2, mype)) - partition2 = pyoasis.SerialPartition(nx_co2) - else: - nx_co2 = 0 - partition2 = None + # Definition of the local partition for toy model + partition = pyoasis.SerialPartition(simulation_nx) - # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. - OasisOutputVars = [] - Oasis_receive_id = [] - for v in OasisOutputVars_readin.keys() : - OasisOutputVars.append([OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']]) - Oasis_receive_id.append(OasisOutputVars_readin[v]['receive_id']) + # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. + OasisOutputVars = [] + Oasis_receive_id = [] + for v in OasisOutputVars_readin.keys() : + OasisOutputVars.append([OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']]) + Oasis_receive_id.append(OasisOutputVars_readin[v]['receive_id']) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # DECLARATION OF THE COUPLING FIELDS @@ -130,9 +181,7 @@ if __name__ == '__main__': for name in Oasis_receive_id: var = pyoasis.Var(name, partition, OASIS.IN) - variables[name] = var - print("NOTE:OASIS {name}: {pyoasis_output}".format(name=name, pyoasis_output=var), file=sys.stderr) - + variables[name] = var logging.debug('var_id {}: {}'.format(name, var._id)) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -156,7 +205,6 @@ if __name__ == '__main__': for name in Oasis_receive_id: variables[name].get(itap_sec, fields[name]) - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # TERMINATION -- GitLab From dd69b9cede25b99641cfc1d2021e296c85b0c791 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Mon, 24 Jul 2023 11:24:05 +0200 Subject: [PATCH 21/39] WIP: developing tools that is needed for generating namcouple, they will all move to a single script to generate namcouple before toy_model and datacoupler --- sources/data-coupler/DataCoupler.py | 42 ++++++++++++++++++-- sources/data-coupler/DataCouplerUtils.py | 49 +++++++++++++++++++++++- sources/data-coupler/YAMLlUtils.py | 3 ++ tests/data/namcouple | 28 ++++++++++++++ tests/data/namecouple_empty.yaml | 20 ++++++++++ tests/data/namecouple_filled.yaml | 36 +++++++++++++++++ tests/general_toy_model.py | 24 ------------ 7 files changed, 174 insertions(+), 28 deletions(-) create mode 100644 tests/data/namcouple create mode 100644 tests/data/namecouple_empty.yaml create mode 100644 tests/data/namecouple_filled.yaml diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 62c417f..e8936b7 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -13,7 +13,8 @@ import sys import argparse from DataCouplerUtils import read_namelist, days_since_refyear, is_leap, earth_area -from DataCouplerUtils import read_yaml_conf +from DataCouplerUtils import read_yaml_conf, replace_strings_in_file , replace_string_in_file, append_multiple_lines_to_file, add_field_to_namcouple, add_end_to_namecouple +from YAMLlUtils import read_yaml_conf_type1 from DataCouplerFileVar import FileInputVar from DataCouplerOasisVar import OasisOutputVar @@ -22,15 +23,50 @@ class DataCoupler: def __init__(self,yaml_conf_file): - OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars = read_yaml_conf(yaml_conf_file) + # OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + # StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars = read_yaml_conf(yaml_conf_file) + ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + + + if LDebug: logging.basicConfig(filename=LogFileName, format='%(message)s', level=logging.DEBUG) date_yref_min = max([conf['yref_min'] for conf in fileIn_vars_config]) date_yref_max = min([conf['yref_max'] for conf in fileIn_vars_config]) + # Creating namcouple + + # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. + + input_file_path = "namecouple_empty.yaml" + replacements_dict = { + "(nfileds)": "1", + "(runtime)": str(RunLengthSec), + } + + output_file_path = "namecouple_filled_by_python.yaml" + replace_strings_in_file(input_file_path, replacements_dict, output_file_path) + + for v in OasisOutputVars_readin.keys() : + + lines = add_field_to_namcouple(OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], \ + TimeStepSec,OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']) + + append_multiple_lines_to_file(output_file_path, lines) + + lines = add_end_to_namecouple() + append_multiple_lines_to_file(output_file_path, lines) + + + + # OasisOutputVars.append([OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']]) + # Oasis_receive_id.append(OasisOutputVars_readin[v]['receive_id']) + + + # valid FixYear to get a seasonal cycle, or set one if none and running outside time window if (FixYear > 0): FixYear = min(date_yref_max, max(date_yref_min, FixYear)) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 0b71a29..8d0bf7f 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -316,4 +316,51 @@ def read_yaml_conf_toy(experiment_yaml_input): coupling = read_in_data.get("coupling") coupling_out_vars = coupling.get("out_vars") coupling_in_vars = coupling.get("in_vars") - restart_file = coupling.get("restart_file") # This feature is not used for now. TODO \ No newline at end of file + restart_file = coupling.get("restart_file") # This feature is not used for now. TODO + + + +def replace_string_in_file(input_file_path, target_string, new_string, output_file_path): + with open(input_file_path, 'r') as input_file: + content = input_file.read() + + updated_content = content.replace(target_string, new_string) + + with open(output_file_path, 'w') as output_file: + output_file.write(updated_content) + + + +def replace_strings_in_file(input_file_path, replacements_dict, output_file_path): + with open(input_file_path, 'r') as input_file: + content = input_file.read() + + for target_string, new_string in replacements_dict.items(): + content = content.replace(target_string, new_string) + + with open(output_file_path, 'w') as output_file: + output_file.write(content) + +def append_multiple_lines_to_file(file_path, lines_to_append): + with open(file_path, 'a') as file: + # for line in lines_to_append: + file.write(lines_to_append + '\n') + + +def add_field_to_namcouple(send_id, receive_id, timestepsec,send_grid_name, receive_grid): + lines_to_append = "\n" + \ + str(send_id) + " " + str(receive_id) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ + str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ + "P 0 P 0\n" + \ + "SCRIPR \n" + \ + "GAUSWGT LR SCALAR LATITUDE 1 9 2.0 \n" + + return lines_to_append + +def add_end_to_namecouple(): + lines_to_append = "\n" + \ + "# =================================================================================================\n" + \ + "$END\n" + \ + "# =================================================================================================\n" + + return lines_to_append \ No newline at end of file diff --git a/sources/data-coupler/YAMLlUtils.py b/sources/data-coupler/YAMLlUtils.py index d4e5641..e3c636e 100644 --- a/sources/data-coupler/YAMLlUtils.py +++ b/sources/data-coupler/YAMLlUtils.py @@ -104,3 +104,6 @@ def read_yaml_conf_type2(yaml_file): restart_file = coupling.get("restart_file") # This feature is not used for now. TODO return model, model_name, simulation_coupling_interval, simulation_run_length_sec, simulation_nx, coupling_out_vars, coupling_in_vars, restart_file + + + diff --git a/tests/data/namcouple b/tests/data/namcouple new file mode 100644 index 0000000..b3f68b7 --- /dev/null +++ b/tests/data/namcouple @@ -0,0 +1,28 @@ +# ================================================================================================= +# General OASIS configuration +# ================================================================================================= + $NFIELDS + 1 + $END +# ------------------------------------------------------------------------------------------------- + $RUNTIME + 5097600 + $END +# ------------------------------------------------------------------------------------------------- + $NLOGPRT + 0 0 + $END +# ------------------------------------------------------------------------------------------------- + $STRINGS +# ================================================================================================= +# Fields send from AMIP to IFS +# ================================================================================================= +# --- AMIP forcing data --- [ifs amip] + AMIP_sst:AMIP_sic A_SST:A_Ice_frac 1 86400 1 rstas.nc EXPOUT + AMIP L128 LAG=0 + P 0 P 0 + SCRIPR + GAUSWGT LR SCALAR LATITUDE 1 9 2.0 +# ------------------------------------------------------------------------------------------------- + $END +# ================================================================================================= diff --git a/tests/data/namecouple_empty.yaml b/tests/data/namecouple_empty.yaml new file mode 100644 index 0000000..4a9f2c6 --- /dev/null +++ b/tests/data/namecouple_empty.yaml @@ -0,0 +1,20 @@ + +# ================================================================================================= +# General OASIS configuration +# ================================================================================================= + $NFIELDS + (nfileds) + $END +# ------------------------------------------------------------------------------------------------- + $RUNTIME + (runtime) + $END +# ------------------------------------------------------------------------------------------------- + $NLOGPRT + 0 0 + $END +# ------------------------------------------------------------------------------------------------- + $STRINGS +# ================================================================================================= +# Fields send from AMIP to IFS +# ================================================================================================= diff --git a/tests/data/namecouple_filled.yaml b/tests/data/namecouple_filled.yaml new file mode 100644 index 0000000..bc8a455 --- /dev/null +++ b/tests/data/namecouple_filled.yaml @@ -0,0 +1,36 @@ + +# ================================================================================================= +# General OASIS configuration +# ================================================================================================= + $NFIELDS + 1 + $END +# ------------------------------------------------------------------------------------------------- + $RUNTIME + 5097600 + $END +# ------------------------------------------------------------------------------------------------- + $NLOGPRT + 0 0 + $END +# ------------------------------------------------------------------------------------------------- + $STRINGS +# ================================================================================================= +# Fields send from AMIP to IFS +# ================================================================================================= + + AMIP_sst A_SST 1 86400 1 rstas.nc EXPOUT + AMIP L128 LAG=0 + P 0 P 0 + SCRIPR + GAUSWGT LR SCALAR LATITUDE 1 9 2.0 + + AMIP_sic A_Ice_frac 1 86400 1 rstas.nc EXPOUT + AMIP L128 LAG=0 + P 0 P 0 + SCRIPR + GAUSWGT LR SCALAR LATITUDE 1 9 2.0 + +# ------------------------------------------------------------------------------------------------- + $END +# ================================================================================================= \ No newline at end of file diff --git a/tests/general_toy_model.py b/tests/general_toy_model.py index 8cbcd83..b4b2e9a 100755 --- a/tests/general_toy_model.py +++ b/tests/general_toy_model.py @@ -65,7 +65,6 @@ def read_name_couple(namcouple): return nx - if __name__ == '__main__': try: @@ -100,7 +99,6 @@ if __name__ == '__main__': COUPLING_INTERVAL = simulation_coupling_interval - # Init OASIS comp = pyoasis.Component(ModelName) @@ -129,28 +127,6 @@ if __name__ == '__main__': namcouple = 'namcouple' nx = read_name_couple(namcouple) - # with open('namcouple', 'r') as f: - # #contents = f.read() - # contents = "" - # for line in f: - # li=line.strip() - # if not li.startswith("#"): - # contents += line - # # TODOD find a better way to detect CO2_CMODE - # if 'GLOBAL GLOBAL' in contents: - # CO2_CMODE = True - # if 'A_CO2_emis ' in contents: - # CO2_EMODE = True - # if 'L080' in contents: - # nx = L080_NX - # elif 'L128' in contents: - # nx = L128_NX - # elif 'L256' in contents: - # nx = L256_NX - # else: - # raise Exception('Invalid IFS grid in namcouple') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # PARTITION DEFINITION # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- GitLab From ade21477d8e0d710d3f31b344a52aac5376af635 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 25 Jul 2023 14:54:59 +0200 Subject: [PATCH 22/39] namcouple script is generating the namecouple in the style that was discussed (for each variable in a seperate parag.), eventhough it is not working with Oasis, it will follow up in next step --- sources/data-coupler/DataCoupler.py | 31 +---- sources/data-coupler/DataCouplerUtils.py | 62 ++++----- sources/data-coupler/namcoupler_creator.py | 122 ++++++++++++++++++ tests/data/namcouple_2line.sh | 36 ++++++ ...couple_empty.yaml => namcouple_empty.yaml} | 2 +- ...uple_filled.yaml => namcouple_filled.yaml} | 0 tests/run_example.sh | 13 ++ 7 files changed, 204 insertions(+), 62 deletions(-) create mode 100644 sources/data-coupler/namcoupler_creator.py create mode 100755 tests/data/namcouple_2line.sh rename tests/data/{namecouple_empty.yaml => namcouple_empty.yaml} (95%) rename tests/data/{namecouple_filled.yaml => namcouple_filled.yaml} (100%) diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index e8936b7..a232350 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -13,7 +13,7 @@ import sys import argparse from DataCouplerUtils import read_namelist, days_since_refyear, is_leap, earth_area -from DataCouplerUtils import read_yaml_conf, replace_strings_in_file , replace_string_in_file, append_multiple_lines_to_file, add_field_to_namcouple, add_end_to_namecouple +from DataCouplerUtils import read_yaml_conf #, replace_strings_in_file , replace_string_in_file, append_multiple_lines_to_file, add_field_to_namcouple, add_end_to_namecouple from YAMLlUtils import read_yaml_conf_type1 from DataCouplerFileVar import FileInputVar from DataCouplerOasisVar import OasisOutputVar @@ -37,35 +37,6 @@ class DataCoupler: date_yref_min = max([conf['yref_min'] for conf in fileIn_vars_config]) date_yref_max = min([conf['yref_max'] for conf in fileIn_vars_config]) - # Creating namcouple - - # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. - - input_file_path = "namecouple_empty.yaml" - replacements_dict = { - "(nfileds)": "1", - "(runtime)": str(RunLengthSec), - } - - output_file_path = "namecouple_filled_by_python.yaml" - replace_strings_in_file(input_file_path, replacements_dict, output_file_path) - - for v in OasisOutputVars_readin.keys() : - - lines = add_field_to_namcouple(OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], \ - TimeStepSec,OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']) - - append_multiple_lines_to_file(output_file_path, lines) - - lines = add_end_to_namecouple() - append_multiple_lines_to_file(output_file_path, lines) - - - - # OasisOutputVars.append([OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']]) - # Oasis_receive_id.append(OasisOutputVars_readin[v]['receive_id']) - - # valid FixYear to get a seasonal cycle, or set one if none and running outside time window if (FixYear > 0): diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 8d0bf7f..74d7938 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -320,47 +320,47 @@ def read_yaml_conf_toy(experiment_yaml_input): -def replace_string_in_file(input_file_path, target_string, new_string, output_file_path): - with open(input_file_path, 'r') as input_file: - content = input_file.read() +# def replace_string_in_file(input_file_path, target_string, new_string, output_file_path): +# with open(input_file_path, 'r') as input_file: +# content = input_file.read() - updated_content = content.replace(target_string, new_string) +# updated_content = content.replace(target_string, new_string) - with open(output_file_path, 'w') as output_file: - output_file.write(updated_content) +# with open(output_file_path, 'w') as output_file: +# output_file.write(updated_content) -def replace_strings_in_file(input_file_path, replacements_dict, output_file_path): - with open(input_file_path, 'r') as input_file: - content = input_file.read() +# def replace_strings_in_file(input_file_path, replacements_dict, output_file_path): +# with open(input_file_path, 'r') as input_file: +# content = input_file.read() - for target_string, new_string in replacements_dict.items(): - content = content.replace(target_string, new_string) +# for target_string, new_string in replacements_dict.items(): +# content = content.replace(target_string, new_string) - with open(output_file_path, 'w') as output_file: - output_file.write(content) +# with open(output_file_path, 'w') as output_file: +# output_file.write(content) -def append_multiple_lines_to_file(file_path, lines_to_append): - with open(file_path, 'a') as file: - # for line in lines_to_append: - file.write(lines_to_append + '\n') +# def append_multiple_lines_to_file(file_path, lines_to_append): +# with open(file_path, 'a') as file: +# # for line in lines_to_append: +# file.write(lines_to_append + '\n') -def add_field_to_namcouple(send_id, receive_id, timestepsec,send_grid_name, receive_grid): - lines_to_append = "\n" + \ - str(send_id) + " " + str(receive_id) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ - str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ - "P 0 P 0\n" + \ - "SCRIPR \n" + \ - "GAUSWGT LR SCALAR LATITUDE 1 9 2.0 \n" +# def add_field_to_namcouple(send_id, receive_id, timestepsec,send_grid_name, receive_grid): +# lines_to_append = "\n" + \ +# str(send_id) + " " + str(receive_id) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ +# str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ +# "P 0 P 0\n" + \ +# "SCRIPR \n" + \ +# "GAUSWGT LR SCALAR LATITUDE 1 9 2.0 \n" - return lines_to_append +# return lines_to_append -def add_end_to_namecouple(): - lines_to_append = "\n" + \ - "# =================================================================================================\n" + \ - "$END\n" + \ - "# =================================================================================================\n" +# def add_end_to_namecouple(): +# lines_to_append = "\n" + \ +# "# =================================================================================================\n" + \ +# "$END\n" + \ +# "# =================================================================================================\n" - return lines_to_append \ No newline at end of file +# return lines_to_append \ No newline at end of file diff --git a/sources/data-coupler/namcoupler_creator.py b/sources/data-coupler/namcoupler_creator.py new file mode 100644 index 0000000..1fcbf4c --- /dev/null +++ b/sources/data-coupler/namcoupler_creator.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 +# Copyright 2023 - Barcelona Supercomputing Center +# Authors: Amirpasha Mozaffari +# MIT License + +import yaml +from yaml.loader import SafeLoader +import os +import argparse +import sys +from YAMLlUtils import read_yaml_conf_type1 +import f90nml + +# It will readin the YAML file that is generated by the RunExample and generate a namcouple list before + + + +def replace_string_in_file(input_file_path, target_string, new_string, output_file_path): + with open(input_file_path, 'r') as input_file: + content = input_file.read() + + updated_content = content.replace(target_string, new_string) + + with open(output_file_path, 'w') as output_file: + output_file.write(updated_content) + + + +def replace_strings_in_file(input_file_path, replacements_dict, output_file_path): + with open(input_file_path, 'r') as input_file: + content = input_file.read() + + for target_string, new_string in replacements_dict.items(): + content = content.replace(target_string, new_string) + + with open(output_file_path, 'w') as output_file: + output_file.write(content) + +def append_multiple_lines_to_file(file_path, lines_to_append): + with open(file_path, 'a') as file: + # for line in lines_to_append: + file.write(lines_to_append + '\n') + + +def add_field_to_namcouple(send_id, receive_id, timestepsec,send_grid_name, receive_grid): + lines_to_append = str(send_id) + " " + str(receive_id) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ + str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ + "P 0 P 0\n" + \ + "SCRIPR \n" + \ + "GAUSWGT LR SCALAR LATITUDE 1 9 2.0" + + return lines_to_append + +def add_end_to_namecouple(): + lines_to_append = "# -------------------------------------------------------------------------------------------------\n" + \ + "$END\n" + \ + "# =================================================================================================\n" + + return lines_to_append + + +def text_to_f90nml(input_file, output_file): + with open(input_file, 'r') as infile: + lines = infile.readlines() + + data = {} + for line in lines: + key, value = line.strip().split() + data[key] = value + + nml_data = f90nml.Namelist(data) + nml_data.write(output_file) + + + +# def yaml_to_f90nml(yaml_file, f90nml_file): +# # Read YAML file +# with open(yaml_file, 'r') as file: +# data = yaml.safe_load(file) + + # # Write to Fortran namelist file + # with open(f90nml_file, 'w') as file: + # nml = f90nml.Namelist(data) + # nml.write(file) + + +if __name__ == '__main__': + # receive the yaml experiment input file is it exists , otherwise pass + + parser=argparse.ArgumentParser() + parser.add_argument("--conf",type=str) + parser.add_argument("--input",type=str) + parser.add_argument("--output",type=str) + args = parser.parse_args() + yaml_conf_file = args.conf + input_file_path = args.input + intermediate_file = args.output + + ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + + + replacements_dict = { + "(nfileds)": "1", + "(runtime)": str(RunLengthSec), + } + + replace_strings_in_file(input_file_path, replacements_dict, intermediate_file) + + for v in OasisOutputVars_readin.keys() : + + lines = add_field_to_namcouple(OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], \ + TimeStepSec,OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']) + + append_multiple_lines_to_file(intermediate_file, lines) + + lines = add_end_to_namecouple() + append_multiple_lines_to_file(intermediate_file, lines) + + # f90nml_file = "namcouple_python" + # text_to_f90nml(intermediate_file, f90nml_file) + # # yaml_to_f90nml(intermediate_file, f90nml_file) \ No newline at end of file diff --git a/tests/data/namcouple_2line.sh b/tests/data/namcouple_2line.sh new file mode 100755 index 0000000..6150ed3 --- /dev/null +++ b/tests/data/namcouple_2line.sh @@ -0,0 +1,36 @@ +cat << EOF +# ================================================================================================= +# General OASIS configuration +# ================================================================================================= + \$NFIELDS + 1 + \$END +# ------------------------------------------------------------------------------------------------- + \$RUNTIME + ${leg_length_sec} + \$END +# ------------------------------------------------------------------------------------------------- + \$NLOGPRT + 0 0 + \$END +# ------------------------------------------------------------------------------------------------- + \$STRINGS +# ================================================================================================= +# Fields send from AMIP to IFS +# ================================================================================================= +# --- AMIP forcing data --- [ifs amip] + AMIP_sst A_SST 1 86400 1 rstas.nc EXPOUT + AMIP L${ifs_grid} LAG=0 + P 0 P 0 + SCRIPR + GAUSWGT LR SCALAR LATITUDE 1 9 2.0 + + AMIP_sic A_Ice_frac 1 86400 1 rstas.nc EXPOUT + AMIP L${ifs_grid} LAG=0 + P 0 P 0 + SCRIPR + GAUSWGT LR SCALAR LATITUDE 1 9 2.0 +# ------------------------------------------------------------------------------------------------- + \$END +# ================================================================================================= +EOF diff --git a/tests/data/namecouple_empty.yaml b/tests/data/namcouple_empty.yaml similarity index 95% rename from tests/data/namecouple_empty.yaml rename to tests/data/namcouple_empty.yaml index 4a9f2c6..8a1360f 100644 --- a/tests/data/namecouple_empty.yaml +++ b/tests/data/namcouple_empty.yaml @@ -1,4 +1,3 @@ - # ================================================================================================= # General OASIS configuration # ================================================================================================= @@ -18,3 +17,4 @@ # ================================================================================================= # Fields send from AMIP to IFS # ================================================================================================= +# --- AMIP forcing data --- [ifs amip] diff --git a/tests/data/namecouple_filled.yaml b/tests/data/namcouple_filled.yaml similarity index 100% rename from tests/data/namecouple_filled.yaml rename to tests/data/namcouple_filled.yaml diff --git a/tests/run_example.sh b/tests/run_example.sh index ce98a62..0ab6c58 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -33,6 +33,8 @@ datadir=$srcdir/data exe1='python3 general_toy_model.py' source_exe1=$srcdir/general_toy_model.py +py_script='python3 namcoupler_creator.py' + if [ $model = fortran ]; then exe2='./amip-forcing' @@ -231,12 +233,23 @@ else fi if [ $amip_mode = forcing ]; then . ./namcouple.sh > ./namcouple + . ./namcouple_2line.sh > ./namcouple1 + + input="namcouple_empty.yaml" + output="namcouple2" + py_nproc=1 + ${MPIRUN} -np $py_nproc $py_script --conf $yaml_conf_name --input $input --output $output + elif [ $amip_mode = co2 ]; then [ $model = co2box ] && . ./namcouple_co2box.sh > ./namcouple || . ./namcouple_co2.sh > ./namcouple else . ./namcouple_primavera.sh > ./namcouple fi +# Creating namcouple with python + + + ###################################################################### ### Definition of mpirun command and batch script -- GitLab From c13ff3985172a3f72233dd1851ca5cbbb95dae12 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 25 Jul 2023 15:36:24 +0200 Subject: [PATCH 23/39] namcouple is generated by puscript before the call of Toy_model and Datacoupler. problem with commit-id:dd69b9ce is fixed --- sources/data-coupler/namcoupler_creator.py | 36 +++++++++++++++++----- tests/data/namcouple_filled.yaml | 36 ---------------------- tests/run_example.sh | 4 +-- 3 files changed, 29 insertions(+), 47 deletions(-) delete mode 100644 tests/data/namcouple_filled.yaml diff --git a/sources/data-coupler/namcoupler_creator.py b/sources/data-coupler/namcoupler_creator.py index 1fcbf4c..b189e4d 100644 --- a/sources/data-coupler/namcoupler_creator.py +++ b/sources/data-coupler/namcoupler_creator.py @@ -48,8 +48,30 @@ def add_field_to_namcouple(send_id, receive_id, timestepsec,send_grid_name, rece "P 0 P 0\n" + \ "SCRIPR \n" + \ "GAUSWGT LR SCALAR LATITUDE 1 9 2.0" - - return lines_to_append + + return lines_to_append + + + +# def get_values_as_string(data_dict): +# if not isinstance(data_dict, dict): +# raise ValueError("Input must be a dictionary.") + +# send_id_values = data_dict.get('send_id', []) +# if not isinstance(send_id_values, list): +# raise ValueError("The value associated with 'send_id' key must be a list.") +# return ":".join(str(value) for value in send_id_values) + + +# def add_field_to_namcouple_single_para(keys_string, values_string, timestepsec,send_grid_name, receive_grid): +# lines_to_append = str(keys_string) + " " + str(values_string) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ +# str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ +# "P 0 P 0\n" + \ +# "SCRIPR \n" + \ +# "GAUSWGT LR SCALAR LATITUDE 1 9 2.0" +# return lines_to_append + + def add_end_to_namecouple(): lines_to_append = "# -------------------------------------------------------------------------------------------------\n" + \ @@ -99,9 +121,10 @@ if __name__ == '__main__': ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + number_of_fields = len(OasisOutputVars_readin) replacements_dict = { - "(nfileds)": "1", + "(nfileds)": str(number_of_fields), "(runtime)": str(RunLengthSec), } @@ -114,9 +137,6 @@ if __name__ == '__main__': append_multiple_lines_to_file(intermediate_file, lines) + lines = add_end_to_namecouple() - append_multiple_lines_to_file(intermediate_file, lines) - - # f90nml_file = "namcouple_python" - # text_to_f90nml(intermediate_file, f90nml_file) - # # yaml_to_f90nml(intermediate_file, f90nml_file) \ No newline at end of file + append_multiple_lines_to_file(intermediate_file, lines) \ No newline at end of file diff --git a/tests/data/namcouple_filled.yaml b/tests/data/namcouple_filled.yaml deleted file mode 100644 index bc8a455..0000000 --- a/tests/data/namcouple_filled.yaml +++ /dev/null @@ -1,36 +0,0 @@ - -# ================================================================================================= -# General OASIS configuration -# ================================================================================================= - $NFIELDS - 1 - $END -# ------------------------------------------------------------------------------------------------- - $RUNTIME - 5097600 - $END -# ------------------------------------------------------------------------------------------------- - $NLOGPRT - 0 0 - $END -# ------------------------------------------------------------------------------------------------- - $STRINGS -# ================================================================================================= -# Fields send from AMIP to IFS -# ================================================================================================= - - AMIP_sst A_SST 1 86400 1 rstas.nc EXPOUT - AMIP L128 LAG=0 - P 0 P 0 - SCRIPR - GAUSWGT LR SCALAR LATITUDE 1 9 2.0 - - AMIP_sic A_Ice_frac 1 86400 1 rstas.nc EXPOUT - AMIP L128 LAG=0 - P 0 P 0 - SCRIPR - GAUSWGT LR SCALAR LATITUDE 1 9 2.0 - -# ------------------------------------------------------------------------------------------------- - $END -# ================================================================================================= \ No newline at end of file diff --git a/tests/run_example.sh b/tests/run_example.sh index 0ab6c58..981333d 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -232,11 +232,9 @@ else [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box fi if [ $amip_mode = forcing ]; then - . ./namcouple.sh > ./namcouple - . ./namcouple_2line.sh > ./namcouple1 input="namcouple_empty.yaml" - output="namcouple2" + output="namcouple" py_nproc=1 ${MPIRUN} -np $py_nproc $py_script --conf $yaml_conf_name --input $input --output $output -- GitLab From 0982f6e009ea7f67e7c435d4941b6c979cb42f53 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 26 Jul 2023 09:57:03 +0200 Subject: [PATCH 24/39] fixing issue with misisng YAML file for toy model and mismatch in naming convention --- sources/ece3-toy-model/ifs_toy_model.yaml | 2 +- sources/ece3-toy-model/launch_yaml_mn4.cmd | 3 ++- sources/ece3-toy-model/nemo_toy_model.yaml | 2 +- sources/ece3-toy-model/runoff_toy_model.yaml | 2 +- sources/ece3-toy-model/toy_model.py | 5 +++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sources/ece3-toy-model/ifs_toy_model.yaml b/sources/ece3-toy-model/ifs_toy_model.yaml index fcf56ff..3fe900d 100644 --- a/sources/ece3-toy-model/ifs_toy_model.yaml +++ b/sources/ece3-toy-model/ifs_toy_model.yaml @@ -4,7 +4,7 @@ --- model: - model_name: IFS_TOY + ModelName: IFS_TOY simulation: coupling_interval : 2700 diff --git a/sources/ece3-toy-model/launch_yaml_mn4.cmd b/sources/ece3-toy-model/launch_yaml_mn4.cmd index 195766f..b04d4d8 100644 --- a/sources/ece3-toy-model/launch_yaml_mn4.cmd +++ b/sources/ece3-toy-model/launch_yaml_mn4.cmd @@ -35,9 +35,10 @@ done cp -f $datadir/rmp* $rundir cp -f $srcdir/*.py $rundir cp -f $srcdir/namcouple $rundir +cp -f $srcdir/*.yaml $rundir cd $rundir # run IFS+NEMO+runoff toy model -mpirun -np 1 python3 $srcdir/toy_model.py --yaml_file_path ifs_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path nemo_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path runoff_toy_model.yaml +mpirun -np 1 python3 $srcdir/toy_model.py --yaml_file_path ifs_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path nemo_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path runoff_toy_model.yaml diff --git a/sources/ece3-toy-model/nemo_toy_model.yaml b/sources/ece3-toy-model/nemo_toy_model.yaml index 393ef37..6e986c1 100644 --- a/sources/ece3-toy-model/nemo_toy_model.yaml +++ b/sources/ece3-toy-model/nemo_toy_model.yaml @@ -4,7 +4,7 @@ --- # yaml metadata -type : 2 +#type : 2 model: diff --git a/sources/ece3-toy-model/runoff_toy_model.yaml b/sources/ece3-toy-model/runoff_toy_model.yaml index 308d160..5bf52e8 100644 --- a/sources/ece3-toy-model/runoff_toy_model.yaml +++ b/sources/ece3-toy-model/runoff_toy_model.yaml @@ -4,7 +4,7 @@ --- model: - model_name: RUNOFF_TOY + ModelName: RUNOFF_TOY simulation: coupling_interval : 2700 diff --git a/sources/ece3-toy-model/toy_model.py b/sources/ece3-toy-model/toy_model.py index c359096..e31c6b9 100644 --- a/sources/ece3-toy-model/toy_model.py +++ b/sources/ece3-toy-model/toy_model.py @@ -18,8 +18,9 @@ if __name__ == '__main__': ### Read in YAML file current_path = os.getcwd() parser=argparse.ArgumentParser() + parser.add_argument("--run_dir",type=str) parser.add_argument("--yaml_file_path",type=str) - args = parser.parse_args() + args = parser.parse_args() yamel_file_path = os.path.join(current_path,args.yaml_file_path) if os.path.isfile(yamel_file_path) == False: print("YAML file does not exist. Aborted") @@ -33,7 +34,7 @@ if __name__ == '__main__': ### Read in file #read_yaml(read_in_data) model = read_in_data.get("model") - model_name = model.get("model_name") + model_name = model.get("ModelName") # Read in Simulation information simulation = read_in_data.get("simulation") -- GitLab From 0e31d89da50ed8d328c38d8c44321a377fe4eda7 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 26 Jul 2023 16:42:00 +0200 Subject: [PATCH 25/39] Merge both toy model types into a single general toy model with support for both toy model and datacoupler yaml --- sources/data-coupler/DataCoupler.py | 8 +- sources/data-coupler/YAMLlUtils.py | 14 +- sources/data-coupler/namcoupler_creator.py | 2 +- sources/ece3-toy-model/YAMLlUtils.py | 113 +++++++++++ sources/ece3-toy-model/general_toy_model.py | 185 ++++++++++++++++++ sources/ece3-toy-model/ifs_toy_model.yaml | 6 +- sources/ece3-toy-model/launch_yaml_mn4.cmd | 5 +- sources/ece3-toy-model/nemo_toy_model.yaml | 5 +- sources/ece3-toy-model/runoff_toy_model.yaml | 6 +- tests/data/template_conf_datacoupler_co2.yaml | 1 + .../template_conf_datacoupler_forcing.yaml | 15 +- tests/general_toy_model.py | 157 +++++++-------- tests/run_example.sh | 6 +- 13 files changed, 416 insertions(+), 107 deletions(-) create mode 100644 sources/ece3-toy-model/YAMLlUtils.py create mode 100755 sources/ece3-toy-model/general_toy_model.py diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index a232350..ce293ee 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -26,18 +26,16 @@ class DataCoupler: # OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ # StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars = read_yaml_conf(yaml_conf_file) - ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + + ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) - - if LDebug: logging.basicConfig(filename=LogFileName, format='%(message)s', level=logging.DEBUG) date_yref_min = max([conf['yref_min'] for conf in fileIn_vars_config]) date_yref_max = min([conf['yref_max'] for conf in fileIn_vars_config]) - # valid FixYear to get a seasonal cycle, or set one if none and running outside time window if (FixYear > 0): FixYear = min(date_yref_max, max(date_yref_min, FixYear)) @@ -50,7 +48,7 @@ class DataCoupler: raise Exception("RunLengthSec is too long for StartYear less than date_yref_min") # Oasis Compiler description - self.OasisCPLNG = OasisCPLNG + self.OasisCPLNG = ModelNameReceive # time axis unit = days self.delta_t = TimeStepSec/86400. diff --git a/sources/data-coupler/YAMLlUtils.py b/sources/data-coupler/YAMLlUtils.py index e3c636e..d529ef4 100644 --- a/sources/data-coupler/YAMLlUtils.py +++ b/sources/data-coupler/YAMLlUtils.py @@ -18,7 +18,7 @@ def read_yaml_meta(yaml_file): ''' Reads the metadata of the yaml file it includes type which could be: - type 1 : NAMELIST + type 1 : DataCoupler type 2 : NEMO / IFS / RUNOFF toy model ''' with open(yaml_file) as file: @@ -40,9 +40,10 @@ def read_yaml_conf_type1(yaml_file): file.close() # Model Information - ModelName = read_in.get('ModelName') - OasisCPLNG = read_in.get('OasisCPLNG') + ModelNameSend = read_in.get('ModelNameSend') + ModelNameReceive = read_in.get('ModelNameReceive') LogFileName = read_in.get('LogFileName') + PartitionType = read_in.get('PartitionType') ## Run Information @@ -76,7 +77,8 @@ def read_yaml_conf_type1(yaml_file): # Variable configuration for this experiment OasisOutputVars_conf = list(OasisOutputVars_readin.values()) - return ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin + return ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ + StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin def read_yaml_conf_type2(yaml_file): @@ -90,6 +92,7 @@ def read_yaml_conf_type2(yaml_file): #read_yaml(read_in_data) model = read_in_data.get("model") model_name = model.get("ModelName") + PartitionType = model.get("PartitionType") # Read in Simulation information simulation = read_in_data.get("simulation") @@ -103,7 +106,8 @@ def read_yaml_conf_type2(yaml_file): coupling_in_vars = coupling.get("in_vars") restart_file = coupling.get("restart_file") # This feature is not used for now. TODO - return model, model_name, simulation_coupling_interval, simulation_run_length_sec, simulation_nx, coupling_out_vars, coupling_in_vars, restart_file + return model, model_name, PartitionType, simulation_coupling_interval, simulation_run_length_sec,\ + simulation_nx, coupling_out_vars, coupling_in_vars, restart_file diff --git a/sources/data-coupler/namcoupler_creator.py b/sources/data-coupler/namcoupler_creator.py index b189e4d..dbcfd17 100644 --- a/sources/data-coupler/namcoupler_creator.py +++ b/sources/data-coupler/namcoupler_creator.py @@ -118,7 +118,7 @@ if __name__ == '__main__': input_file_path = args.input intermediate_file = args.output - ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) number_of_fields = len(OasisOutputVars_readin) diff --git a/sources/ece3-toy-model/YAMLlUtils.py b/sources/ece3-toy-model/YAMLlUtils.py new file mode 100644 index 0000000..d529ef4 --- /dev/null +++ b/sources/ece3-toy-model/YAMLlUtils.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +# Copyright 2023 - Barcelona Supercomputing Center +# Authors: Amirpasha Mozaffari +# MIT License + +import yaml +from yaml.loader import SafeLoader +import os +import argparse +import sys + + + +# class yaml_file: + + +def read_yaml_meta(yaml_file): + ''' + Reads the metadata of the yaml file + it includes type which could be: + type 1 : DataCoupler + type 2 : NEMO / IFS / RUNOFF toy model + ''' + with open(yaml_file) as file: + read_in = yaml.load(file, Loader=SafeLoader) + file.close() + + # Model Information + yaml_type = read_in.get('type') + return yaml_type + + +def read_yaml_conf_type1(yaml_file): + ''' + Reads the experiment yaml file + ''' + + with open(yaml_file) as file: + read_in = yaml.load(file, Loader=SafeLoader) + file.close() + + # Model Information + ModelNameSend = read_in.get('ModelNameSend') + ModelNameReceive = read_in.get('ModelNameReceive') + LogFileName = read_in.get('LogFileName') + PartitionType = read_in.get('PartitionType') + + ## Run Information + + RunLengthSec = read_in.get('RunLengthSec') + TimeStepSec = read_in.get('TimeStepSec') + StartYear = read_in.get('StartYear') + StartMonth = read_in.get('StartMonth') + StartDay = read_in.get('StartDay') + FixYear = read_in.get('FixYear') + GridInfo = read_in.get('GridInfo') + LDebug = read_in.get('LDebug') + + # Create the log_file name and sanity-check + + # Check the type of input in yaml file + if "FileInputVars" in read_in : + FileInputVars_readin = {} + FileInputVars_readin = read_in.get('FileInputVars') + # Name of the Variable for this experiment + FileInputVarNames = list(FileInputVars_readin.keys()) + # Variable configuration for this experiment + FileInputVarFields_conf = list(FileInputVars_readin.values()) + + if "OasisOutputVars" in read_in : + OasisOutputVars_readin = {} + OasisOutputVars_readin = read_in.get('OasisOutputVars') + print("NOTE: OasisOutputVars_readin : {}".format(OasisOutputVars_readin), file=sys.stderr) + # Name of the Variable for this experiment + OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) + + # Variable configuration for this experiment + OasisOutputVars_conf = list(OasisOutputVars_readin.values()) + + return ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ + StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin + + +def read_yaml_conf_type2(yaml_file): + +# Open the file and load the file + with open(yaml_file) as f: + read_in_data = yaml.load(f, Loader=SafeLoader) + f.close() + +### Read in file + #read_yaml(read_in_data) + model = read_in_data.get("model") + model_name = model.get("ModelName") + PartitionType = model.get("PartitionType") + + # Read in Simulation information + simulation = read_in_data.get("simulation") + simulation_coupling_interval = simulation.get("coupling_interval") + simulation_run_length_sec = simulation.get("run_length_sec") + simulation_nx = simulation.get("nx") + + # Read in Coupling infomration + coupling = read_in_data.get("coupling") + coupling_out_vars = coupling.get("out_vars") + coupling_in_vars = coupling.get("in_vars") + restart_file = coupling.get("restart_file") # This feature is not used for now. TODO + + return model, model_name, PartitionType, simulation_coupling_interval, simulation_run_length_sec,\ + simulation_nx, coupling_out_vars, coupling_in_vars, restart_file + + + diff --git a/sources/ece3-toy-model/general_toy_model.py b/sources/ece3-toy-model/general_toy_model.py new file mode 100755 index 0000000..95b42de --- /dev/null +++ b/sources/ece3-toy-model/general_toy_model.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python3 +# Copyright 2021 - Barcelona Supercomputing Center +# Author: Rodrigo Martín Posada +# MIT License + +import f90nml +import pyoasis +from pyoasis import OASIS # pylint: disable=no-name-in-module +import numpy as np +import logging + +import yaml +from yaml.loader import SafeLoader +import logging +import argparse +import os +import sys +from YAMLlUtils import read_yaml_meta, read_yaml_conf_type1, read_yaml_conf_type2 + +# TODO +# It will read in the YAML file instead of the namelist. It will receive the name of the YAMl file as argparse value +# it should turn to class in next step round of refactoring + + +def def_local_partition(nx, npes, mype): + il_size = nx // npes + il_offset = mype * il_size + if (npes-mype) <= nx % npes: + il_size += 1 + il_offset += (nx % npes) - (npes-mype) + return il_size, il_offset + + +def variable_exists(var_name): + return var_name in globals() + + +if __name__ == '__main__': + + + parser=argparse.ArgumentParser() + parser.add_argument("--conf",type=str) + # parser.add_argument("--namcouple",type=str) + args = parser.parse_args() + yaml_conf_file = args.conf + if os.path.isfile(yaml_conf_file) == False: + print("YAML file does not exist. Aborted") + raise NameError("YAML file does not exist.") + + # Determine the type of yaml file + yaml_type = read_yaml_meta(yaml_conf_file) + + # Read in DataCoupler YAML file type + + if yaml_type == 1 : + + ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ + StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + + ModelName = ModelNameSend + COUPLING_INTERVAL = TimeStepSec + RUN_LENGTH_SEC = RunLengthSec + nx = GridInfo + + # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. + coupling_in_vars = [] + for v in OasisOutputVars_readin.keys() : + coupling_in_vars.append(OasisOutputVars_readin[v]['receive_id']) + + # Read in ToModel Yaml file type + elif yaml_type == 2: + model, model_name, PartitionType, simulation_coupling_interval, simulation_run_length_sec, \ + simulation_nx, coupling_out_vars, coupling_in_vars, restart_file = read_yaml_conf_type2(yaml_conf_file) + + ModelName = model_name + COUPLING_INTERVAL = simulation_coupling_interval + RUN_LENGTH_SEC = simulation_run_length_sec + nx = simulation_nx + + + # Init OASIS + comp = pyoasis.Component(ModelName) + + # Get rank in local communicator + mype = comp.localcomm.rank + npes = comp.localcomm.size + + + # BUG : shouldnt it be the npes and not mpye (?) + mype_value = str(100+mype) + out_model = '{ModelName}.out_{mype_value}'.format(ModelName = ModelName, mype_value = mype_value) + + logging.basicConfig(filename=out_model, format='%(message)s', level=logging.DEBUG) + logging.debug('-----------------------------------------------------------') + logging.info('I am {ModelName} process with rank : {mype}'.format(ModelName = ModelName, + mype = mype_value)) + #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) + logging.debug('in my local communicator gathering {} processes'.format(npes)) + logging.debug('----------------------------------------------------------') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # PARTITION DEFINITION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # Definition of the local partition + + if yaml_type == 1 : #and PartitionType == "ApplePartition": + il_size, il_offset = def_local_partition(nx, npes, mype) + logging.debug('Local partition definition') + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + partition = pyoasis.ApplePartition(il_offset, il_size) + + elif yaml_type == 2 : #and PartitionType == "SerialPartition": + partition = pyoasis.SerialPartition(nx) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # DECLARATION OF THE COUPLING FIELDS + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + out_coupling_fields={} + + for v in coupling_out_vars: + out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) + logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) + + + in_coupling_fields = {} # Create a dictionary to store the variables + + for name in coupling_in_vars: + var = pyoasis.Var(name, partition, OASIS.IN) + in_coupling_fields[name] = var + logging.debug('var_id {}: {}'.format(name, var._id)) + + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# TERMINATION OF DEFINITION PHASE +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of initialization phase') + + comp.enddef() + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# TIME STEP LOOP +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('Timestep, field min, mean, and max value') + + if yaml_type == 1 : + fields = {} + + for name in coupling_in_vars: + fields[name] = pyoasis.asarray(np.full(il_size, -1.0)) + + for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): + for name in coupling_in_vars: + in_coupling_fields[name].get(itap_sec, fields[name]) + + elif yaml_type == 2 : + + field_data = pyoasis.asarray(np.full(nx, -1.0)) + + for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): + + for id, field in in_coupling_fields.items(): + field.get(itap_sec, field_data) + + for id, field in out_coupling_fields.items(): + sigma=1 + mu=1 + # send dummy data (100 for runoff, random for other variables) + #TODO send dummy data read from oasis restart file + if id == "A_Runoff": + field_data[:]=1.4658e-06 + field_data[:]=100 + else: + field_data[:]=sigma * np.random.randn(nx) + mu + field.put(itap_sec, field_data) + + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of the program') + + print('Model {} is finished successfully.'.format(ModelName)) + + del comp diff --git a/sources/ece3-toy-model/ifs_toy_model.yaml b/sources/ece3-toy-model/ifs_toy_model.yaml index 3fe900d..be0a920 100644 --- a/sources/ece3-toy-model/ifs_toy_model.yaml +++ b/sources/ece3-toy-model/ifs_toy_model.yaml @@ -3,8 +3,12 @@ # TBD --- +# yaml metadata +type : 2 + model: - ModelName: IFS_TOY + ModelName : IFS_TOY + PartitionType : SerialPartition simulation: coupling_interval : 2700 diff --git a/sources/ece3-toy-model/launch_yaml_mn4.cmd b/sources/ece3-toy-model/launch_yaml_mn4.cmd index b04d4d8..4c6963e 100644 --- a/sources/ece3-toy-model/launch_yaml_mn4.cmd +++ b/sources/ece3-toy-model/launch_yaml_mn4.cmd @@ -36,9 +36,10 @@ cp -f $datadir/rmp* $rundir cp -f $srcdir/*.py $rundir cp -f $srcdir/namcouple $rundir cp -f $srcdir/*.yaml $rundir - +#toy_model="toy_model.py" +toy_model="general_toy_model.py" cd $rundir # run IFS+NEMO+runoff toy model -mpirun -np 1 python3 $srcdir/toy_model.py --yaml_file_path ifs_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path nemo_toy_model.yaml : -np 1 python3 $srcdir/toy_model.py --yaml_file_path runoff_toy_model.yaml +mpirun -np 1 python3 $srcdir/$toy_model --conf ifs_toy_model.yaml : -np 1 python3 $srcdir/$toy_model --conf nemo_toy_model.yaml : -np 1 python3 $srcdir/$toy_model --conf runoff_toy_model.yaml diff --git a/sources/ece3-toy-model/nemo_toy_model.yaml b/sources/ece3-toy-model/nemo_toy_model.yaml index 6e986c1..434e09f 100644 --- a/sources/ece3-toy-model/nemo_toy_model.yaml +++ b/sources/ece3-toy-model/nemo_toy_model.yaml @@ -4,11 +4,12 @@ --- # yaml metadata -#type : 2 +type : 2 model: - ModelName: NEMO_TOY + ModelName : NEMO_TOY + PartitionType : SerialPartition simulation: coupling_interval : 2700 diff --git a/sources/ece3-toy-model/runoff_toy_model.yaml b/sources/ece3-toy-model/runoff_toy_model.yaml index 5bf52e8..78a41e6 100644 --- a/sources/ece3-toy-model/runoff_toy_model.yaml +++ b/sources/ece3-toy-model/runoff_toy_model.yaml @@ -3,8 +3,12 @@ # TBD --- +# yaml metadata +type : 2 + model: - ModelName: RUNOFF_TOY + ModelName : RUNOFF_TOY + PartitionType : SerialPartition simulation: coupling_interval : 2700 diff --git a/tests/data/template_conf_datacoupler_co2.yaml b/tests/data/template_conf_datacoupler_co2.yaml index 4f0ec37..750011d 100755 --- a/tests/data/template_conf_datacoupler_co2.yaml +++ b/tests/data/template_conf_datacoupler_co2.yaml @@ -6,6 +6,7 @@ OasisModel : IFS_TOY OasisCPLNG : AMIPFORC LogFileName : amip.log YamlConfName : ${yaml_conf_name} +PartitionType : ApplePartition ## Run Information RunLengthSec : ${leg_length_sec} diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml index 7ef7fef..c533647 100755 --- a/tests/data/template_conf_datacoupler_forcing.yaml +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -2,13 +2,14 @@ cat << EOF # YAML input file for DataCoupler, It will be ingested and turn to Experiment YAML file # yaml metadata -type : 1 +type : 1 # DataCoupler is 1, ToyModel is 2 ## Model Information -ModelName : IFS_TOY -OasisCPLNG : AMIPFORC -LogFileName : amip.log -YamlConfName : ${yaml_conf_name} +ModelNameSend : IFS_TOY +ModelNameReceive : AMIPFORC +LogFileName : amip.log +YamlConfName : ${yaml_conf_name} +PartitionType : ApplePartition ## Run Information RunLengthSec : ${leg_length_sec} @@ -17,7 +18,9 @@ StartYear : ${leg_start_date_yyyymmdd:0:4} StartMonth : ${leg_start_date_yyyymmdd:4:2} StartDay : ${leg_start_date_yyyymmdd:6:2} FixYear : ${ifs_cmip_fixyear} -GridInfo : TBD_VALUE +GridInfo : 88838 # number of grid cells : L080_NX = 35718 @ T159 resolution / L128_NX = 88838 @ T255 resolution / L256_NX = 348528 @ T511 resolution + + ## Coupling Information diff --git a/tests/general_toy_model.py b/tests/general_toy_model.py index b4b2e9a..95b42de 100755 --- a/tests/general_toy_model.py +++ b/tests/general_toy_model.py @@ -15,7 +15,6 @@ import logging import argparse import os import sys -#from DataCouplerUtils import read_yaml_conf , read_yaml_meta from YAMLlUtils import read_yaml_meta, read_yaml_conf_type1, read_yaml_conf_type2 # TODO @@ -23,13 +22,6 @@ from YAMLlUtils import read_yaml_meta, read_yaml_conf_type1, read_yaml_conf_type # it should turn to class in next step round of refactoring -L080_NX = 35718 # number of grid cells at T159 resolution -L128_NX = 88838 # number of grid cells at T255 resolution -L256_NX = 348528 # number of grid cells at T511 resolution -CO2_CMODE = False # is CO2 concentration-mode active? -CO2_EMODE = False # is CO2 emission-mode active? - - def def_local_partition(nx, npes, mype): il_size = nx // npes il_offset = mype * il_size @@ -38,65 +30,52 @@ def def_local_partition(nx, npes, mype): il_offset += (nx % npes) - (npes-mype) return il_size, il_offset -## will be replaced with YAML version in step 5 -def read_name_couple(namcouple): - with open(namcouple, 'r') as f: - contents = "" - CO2_CMODE = None - CO2_EMODE = None - - for line in f: - li=line.strip() - if not li.startswith("#"): - contents += line - # TODOD find a better way to detect CO2_CMODE - if 'GLOBAL GLOBAL' in contents: - CO2_CMODE = True - if 'A_CO2_emis ' in contents: - CO2_EMODE = True - if 'L080' in contents: - nx = L080_NX - elif 'L128' in contents: - nx = L128_NX - elif 'L256' in contents: - nx = L256_NX - else: - raise Exception('Invalid IFS grid in namcouple') - return nx +def variable_exists(var_name): + return var_name in globals() -if __name__ == '__main__': - try: - parser=argparse.ArgumentParser() - parser.add_argument("--conf",type=str) - args = parser.parse_args() - yaml_conf_file = args.conf - except: - print("NOTE:TOY Could note read in the input yaml file : {}".format(yaml_conf_file), file=sys.stderr) - else: - print("NOTE:TOY input yaml file is : {}".format(yaml_conf_file), file=sys.stderr) +if __name__ == '__main__': + + parser=argparse.ArgumentParser() + parser.add_argument("--conf",type=str) + # parser.add_argument("--namcouple",type=str) + args = parser.parse_args() + yaml_conf_file = args.conf + if os.path.isfile(yaml_conf_file) == False: + print("YAML file does not exist. Aborted") + raise NameError("YAML file does not exist.") # Determine the type of yaml file yaml_type = read_yaml_meta(yaml_conf_file) - # + # Read in DataCoupler YAML file type - if yaml_type == 1 : - ModelName, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + if yaml_type == 1 : + + ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ + StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + ModelName = ModelNameSend COUPLING_INTERVAL = TimeStepSec RUN_LENGTH_SEC = RunLengthSec - #nx = GridInfo + nx = GridInfo + + # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. + coupling_in_vars = [] + for v in OasisOutputVars_readin.keys() : + coupling_in_vars.append(OasisOutputVars_readin[v]['receive_id']) - + # Read in ToModel Yaml file type elif yaml_type == 2: - model, model_name, simulation_coupling_interval, simulation_run_length_sec, \ + model, model_name, PartitionType, simulation_coupling_interval, simulation_run_length_sec, \ simulation_nx, coupling_out_vars, coupling_in_vars, restart_file = read_yaml_conf_type2(yaml_conf_file) + ModelName = model_name - COUPLING_INTERVAL = simulation_coupling_interval + COUPLING_INTERVAL = simulation_coupling_interval + RUN_LENGTH_SEC = simulation_run_length_sec + nx = simulation_nx # Init OASIS @@ -118,48 +97,40 @@ if __name__ == '__main__': #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) logging.debug('in my local communicator gathering {} processes'.format(npes)) logging.debug('----------------------------------------------------------') - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # PARTITION DEFINITION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - if yaml_type == 1 : - - namcouple = 'namcouple' - nx = read_name_couple(namcouple) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # PARTITION DEFINITION # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Definition of the local partition + + if yaml_type == 1 : #and PartitionType == "ApplePartition": il_size, il_offset = def_local_partition(nx, npes, mype) logging.debug('Local partition definition') - logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) partition = pyoasis.ApplePartition(il_offset, il_size) - - else : - - # Definition of the local partition for toy model - partition = pyoasis.SerialPartition(simulation_nx) - - # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. - OasisOutputVars = [] - Oasis_receive_id = [] - for v in OasisOutputVars_readin.keys() : - OasisOutputVars.append([OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']]) - Oasis_receive_id.append(OasisOutputVars_readin[v]['receive_id']) + elif yaml_type == 2 : #and PartitionType == "SerialPartition": + partition = pyoasis.SerialPartition(nx) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # DECLARATION OF THE COUPLING FIELDS # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - variables = {} # Create a dictionary to store the variables + out_coupling_fields={} - for name in Oasis_receive_id: + for v in coupling_out_vars: + out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) + logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) + + + in_coupling_fields = {} # Create a dictionary to store the variables + + for name in coupling_in_vars: var = pyoasis.Var(name, partition, OASIS.IN) - variables[name] = var + in_coupling_fields[name] = var logging.debug('var_id {}: {}'.format(name, var._id)) + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # TERMINATION OF DEFINITION PHASE # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -172,14 +143,36 @@ if __name__ == '__main__': # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.debug('Timestep, field min, mean, and max value') - fields = {} + if yaml_type == 1 : + fields = {} + + for name in coupling_in_vars: + fields[name] = pyoasis.asarray(np.full(il_size, -1.0)) + + for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): + for name in coupling_in_vars: + in_coupling_fields[name].get(itap_sec, fields[name]) + + elif yaml_type == 2 : - for name in Oasis_receive_id: - fields[name] = pyoasis.asarray(np.full(il_size, -1.0)) + field_data = pyoasis.asarray(np.full(nx, -1.0)) - for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): - for name in Oasis_receive_id: - variables[name].get(itap_sec, fields[name]) + for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): + + for id, field in in_coupling_fields.items(): + field.get(itap_sec, field_data) + + for id, field in out_coupling_fields.items(): + sigma=1 + mu=1 + # send dummy data (100 for runoff, random for other variables) + #TODO send dummy data read from oasis restart file + if id == "A_Runoff": + field_data[:]=1.4658e-06 + field_data[:]=100 + else: + field_data[:]=sigma * np.random.randn(nx) + mu + field.put(itap_sec, field_data) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -187,4 +180,6 @@ if __name__ == '__main__': # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.debug('End of the program') + print('Model {} is finished successfully.'.format(ModelName)) + del comp diff --git a/tests/run_example.sh b/tests/run_example.sh index 981333d..33a70c7 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -234,9 +234,9 @@ fi if [ $amip_mode = forcing ]; then input="namcouple_empty.yaml" - output="namcouple" + namcouple_output="namcouple" py_nproc=1 - ${MPIRUN} -np $py_nproc $py_script --conf $yaml_conf_name --input $input --output $output + ${MPIRUN} -np $py_nproc $py_script --conf $yaml_conf_name --input $input --output $namcouple_output elif [ $amip_mode = co2 ]; then [ $model = co2box ] && . ./namcouple_co2box.sh > ./namcouple || . ./namcouple_co2.sh > ./namcouple @@ -256,7 +256,7 @@ echo 'Executing the model using mpirun : ${MPIRUN}' # To seprate the DataCoupler with YAML input file from legecy codes if [ $model = datacoupler ] ; then if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then - ${MPIRUN} -np $nproc_exe1 $exe1 --conf $yaml_conf_name : -np $nproc_exe2 $exe2 --conf $yaml_conf_name + ${MPIRUN} -np $nproc_exe1 $exe1 --conf $yaml_conf_name : -np $nproc_exe2 $exe2 --conf $yaml_conf_name fi else ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 -- GitLab From 7e5bf1cbbbc19d4a1e3a1cb8883f827ffb193d20 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Thu, 27 Jul 2023 10:17:33 +0200 Subject: [PATCH 26/39] Unifying execution of toy_model and datacoupler via /test/ directory with automated directory preparation and time stamping. --- sources/ece3-toy-model/general_toy_model.py | 185 ------------------ .../ece3-toy-model => tests}/YAMLlUtils.py | 0 .../launch_ece3_toy_model_mn4.cmd | 24 ++- 3 files changed, 19 insertions(+), 190 deletions(-) delete mode 100755 sources/ece3-toy-model/general_toy_model.py rename {sources/ece3-toy-model => tests}/YAMLlUtils.py (100%) rename sources/ece3-toy-model/launch_yaml_mn4.cmd => tests/launch_ece3_toy_model_mn4.cmd (66%) mode change 100644 => 100755 diff --git a/sources/ece3-toy-model/general_toy_model.py b/sources/ece3-toy-model/general_toy_model.py deleted file mode 100755 index 95b42de..0000000 --- a/sources/ece3-toy-model/general_toy_model.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 - Barcelona Supercomputing Center -# Author: Rodrigo Martín Posada -# MIT License - -import f90nml -import pyoasis -from pyoasis import OASIS # pylint: disable=no-name-in-module -import numpy as np -import logging - -import yaml -from yaml.loader import SafeLoader -import logging -import argparse -import os -import sys -from YAMLlUtils import read_yaml_meta, read_yaml_conf_type1, read_yaml_conf_type2 - -# TODO -# It will read in the YAML file instead of the namelist. It will receive the name of the YAMl file as argparse value -# it should turn to class in next step round of refactoring - - -def def_local_partition(nx, npes, mype): - il_size = nx // npes - il_offset = mype * il_size - if (npes-mype) <= nx % npes: - il_size += 1 - il_offset += (nx % npes) - (npes-mype) - return il_size, il_offset - - -def variable_exists(var_name): - return var_name in globals() - - -if __name__ == '__main__': - - - parser=argparse.ArgumentParser() - parser.add_argument("--conf",type=str) - # parser.add_argument("--namcouple",type=str) - args = parser.parse_args() - yaml_conf_file = args.conf - if os.path.isfile(yaml_conf_file) == False: - print("YAML file does not exist. Aborted") - raise NameError("YAML file does not exist.") - - # Determine the type of yaml file - yaml_type = read_yaml_meta(yaml_conf_file) - - # Read in DataCoupler YAML file type - - if yaml_type == 1 : - - ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ - StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) - - ModelName = ModelNameSend - COUPLING_INTERVAL = TimeStepSec - RUN_LENGTH_SEC = RunLengthSec - nx = GridInfo - - # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. - coupling_in_vars = [] - for v in OasisOutputVars_readin.keys() : - coupling_in_vars.append(OasisOutputVars_readin[v]['receive_id']) - - # Read in ToModel Yaml file type - elif yaml_type == 2: - model, model_name, PartitionType, simulation_coupling_interval, simulation_run_length_sec, \ - simulation_nx, coupling_out_vars, coupling_in_vars, restart_file = read_yaml_conf_type2(yaml_conf_file) - - ModelName = model_name - COUPLING_INTERVAL = simulation_coupling_interval - RUN_LENGTH_SEC = simulation_run_length_sec - nx = simulation_nx - - - # Init OASIS - comp = pyoasis.Component(ModelName) - - # Get rank in local communicator - mype = comp.localcomm.rank - npes = comp.localcomm.size - - - # BUG : shouldnt it be the npes and not mpye (?) - mype_value = str(100+mype) - out_model = '{ModelName}.out_{mype_value}'.format(ModelName = ModelName, mype_value = mype_value) - - logging.basicConfig(filename=out_model, format='%(message)s', level=logging.DEBUG) - logging.debug('-----------------------------------------------------------') - logging.info('I am {ModelName} process with rank : {mype}'.format(ModelName = ModelName, - mype = mype_value)) - #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) - logging.debug('in my local communicator gathering {} processes'.format(npes)) - logging.debug('----------------------------------------------------------') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # PARTITION DEFINITION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # Definition of the local partition - - if yaml_type == 1 : #and PartitionType == "ApplePartition": - il_size, il_offset = def_local_partition(nx, npes, mype) - logging.debug('Local partition definition') - logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) - partition = pyoasis.ApplePartition(il_offset, il_size) - - elif yaml_type == 2 : #and PartitionType == "SerialPartition": - partition = pyoasis.SerialPartition(nx) - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # DECLARATION OF THE COUPLING FIELDS - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - out_coupling_fields={} - - for v in coupling_out_vars: - out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) - logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) - - - in_coupling_fields = {} # Create a dictionary to store the variables - - for name in coupling_in_vars: - var = pyoasis.Var(name, partition, OASIS.IN) - in_coupling_fields[name] = var - logging.debug('var_id {}: {}'.format(name, var._id)) - - -# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -# TERMINATION OF DEFINITION PHASE -# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of initialization phase') - - comp.enddef() - -# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -# TIME STEP LOOP -# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('Timestep, field min, mean, and max value') - - if yaml_type == 1 : - fields = {} - - for name in coupling_in_vars: - fields[name] = pyoasis.asarray(np.full(il_size, -1.0)) - - for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): - for name in coupling_in_vars: - in_coupling_fields[name].get(itap_sec, fields[name]) - - elif yaml_type == 2 : - - field_data = pyoasis.asarray(np.full(nx, -1.0)) - - for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): - - for id, field in in_coupling_fields.items(): - field.get(itap_sec, field_data) - - for id, field in out_coupling_fields.items(): - sigma=1 - mu=1 - # send dummy data (100 for runoff, random for other variables) - #TODO send dummy data read from oasis restart file - if id == "A_Runoff": - field_data[:]=1.4658e-06 - field_data[:]=100 - else: - field_data[:]=sigma * np.random.randn(nx) + mu - field.put(itap_sec, field_data) - - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of the program') - - print('Model {} is finished successfully.'.format(ModelName)) - - del comp diff --git a/sources/ece3-toy-model/YAMLlUtils.py b/tests/YAMLlUtils.py similarity index 100% rename from sources/ece3-toy-model/YAMLlUtils.py rename to tests/YAMLlUtils.py diff --git a/sources/ece3-toy-model/launch_yaml_mn4.cmd b/tests/launch_ece3_toy_model_mn4.cmd old mode 100644 new mode 100755 similarity index 66% rename from sources/ece3-toy-model/launch_yaml_mn4.cmd rename to tests/launch_ece3_toy_model_mn4.cmd index 4c6963e..7b08908 --- a/sources/ece3-toy-model/launch_yaml_mn4.cmd +++ b/tests/launch_ece3_toy_model_mn4.cmd @@ -13,7 +13,7 @@ export PYTHONPATH="" module load python/3.6.1 module load netcdf/4.2 -set -xuve +#set -xuve # setup pyOasis environment export PYOASIS_ROOT=/gpfs/scratch/bsc32/bsc32051/git/python-amip-reader/sources/oasis3-mct/generated @@ -21,12 +21,19 @@ export LD_LIBRARY_PATH=${PYOASIS_ROOT}/lib:${LD_LIBRARY_PATH} export PYTHONPATH=${PYOASIS_ROOT}/python:${PYTHONPATH} export MPIRUN4PY="mpirun" + +## +timestamp=$(date +%Y%m%d_%H%M%S) + + # prepare rundir -rundir=run/ -srcdir=`pwd` datadir=/gpfs/scratch/bsc32/bsc32051/git/python-amip-reader/tests/data/ece3-toy-model +testdir=`pwd` +srcdir=$testdir/../sources/ece3-toy-model + +rundir=${testdir}/work_ece3_toy_model_${timestamp} -rm -rf $rundir +#rm -rf $rundir mkdir -p $rundir for f in masks.nc grids.nc areas.nc rstas.nc rstos.nc; do @@ -36,10 +43,17 @@ cp -f $datadir/rmp* $rundir cp -f $srcdir/*.py $rundir cp -f $srcdir/namcouple $rundir cp -f $srcdir/*.yaml $rundir + +cp -f $testdir/general_toy_model.py $rundir +cp -f $testdir/YAMLlUtils.py $rundir + #toy_model="toy_model.py" toy_model="general_toy_model.py" +echo "prep is finished" + cd $rundir # run IFS+NEMO+runoff toy model -mpirun -np 1 python3 $srcdir/$toy_model --conf ifs_toy_model.yaml : -np 1 python3 $srcdir/$toy_model --conf nemo_toy_model.yaml : -np 1 python3 $srcdir/$toy_model --conf runoff_toy_model.yaml +mpirun -np 1 python3 $testdir/$toy_model --conf ifs_toy_model.yaml : -np 1 python3 $testdir/$toy_model --conf nemo_toy_model.yaml : -np 1 python3 $testdir/$toy_model --conf runoff_toy_model.yaml + -- GitLab From cb39ab053bc3585b3bf3d9d6dd7e5e08047937c2 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 16 Aug 2023 12:05:46 +0200 Subject: [PATCH 27/39] minor chnages to fix the issues to use same general_toy_model for both datacoupler and toy_model --- sources/data-coupler/YAMLlUtils.py | 113 -------------- tests/general_toy_model_backup.py | 207 ------------------------- tests/launch_ece3_data_coupler_mn4.cmd | 31 ++++ tests/run_example.sh | 1 + 4 files changed, 32 insertions(+), 320 deletions(-) delete mode 100644 sources/data-coupler/YAMLlUtils.py delete mode 100755 tests/general_toy_model_backup.py create mode 100644 tests/launch_ece3_data_coupler_mn4.cmd diff --git a/sources/data-coupler/YAMLlUtils.py b/sources/data-coupler/YAMLlUtils.py deleted file mode 100644 index d529ef4..0000000 --- a/sources/data-coupler/YAMLlUtils.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2023 - Barcelona Supercomputing Center -# Authors: Amirpasha Mozaffari -# MIT License - -import yaml -from yaml.loader import SafeLoader -import os -import argparse -import sys - - - -# class yaml_file: - - -def read_yaml_meta(yaml_file): - ''' - Reads the metadata of the yaml file - it includes type which could be: - type 1 : DataCoupler - type 2 : NEMO / IFS / RUNOFF toy model - ''' - with open(yaml_file) as file: - read_in = yaml.load(file, Loader=SafeLoader) - file.close() - - # Model Information - yaml_type = read_in.get('type') - return yaml_type - - -def read_yaml_conf_type1(yaml_file): - ''' - Reads the experiment yaml file - ''' - - with open(yaml_file) as file: - read_in = yaml.load(file, Loader=SafeLoader) - file.close() - - # Model Information - ModelNameSend = read_in.get('ModelNameSend') - ModelNameReceive = read_in.get('ModelNameReceive') - LogFileName = read_in.get('LogFileName') - PartitionType = read_in.get('PartitionType') - - ## Run Information - - RunLengthSec = read_in.get('RunLengthSec') - TimeStepSec = read_in.get('TimeStepSec') - StartYear = read_in.get('StartYear') - StartMonth = read_in.get('StartMonth') - StartDay = read_in.get('StartDay') - FixYear = read_in.get('FixYear') - GridInfo = read_in.get('GridInfo') - LDebug = read_in.get('LDebug') - - # Create the log_file name and sanity-check - - # Check the type of input in yaml file - if "FileInputVars" in read_in : - FileInputVars_readin = {} - FileInputVars_readin = read_in.get('FileInputVars') - # Name of the Variable for this experiment - FileInputVarNames = list(FileInputVars_readin.keys()) - # Variable configuration for this experiment - FileInputVarFields_conf = list(FileInputVars_readin.values()) - - if "OasisOutputVars" in read_in : - OasisOutputVars_readin = {} - OasisOutputVars_readin = read_in.get('OasisOutputVars') - print("NOTE: OasisOutputVars_readin : {}".format(OasisOutputVars_readin), file=sys.stderr) - # Name of the Variable for this experiment - OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) - - # Variable configuration for this experiment - OasisOutputVars_conf = list(OasisOutputVars_readin.values()) - - return ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ - StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin - - -def read_yaml_conf_type2(yaml_file): - -# Open the file and load the file - with open(yaml_file) as f: - read_in_data = yaml.load(f, Loader=SafeLoader) - f.close() - -### Read in file - #read_yaml(read_in_data) - model = read_in_data.get("model") - model_name = model.get("ModelName") - PartitionType = model.get("PartitionType") - - # Read in Simulation information - simulation = read_in_data.get("simulation") - simulation_coupling_interval = simulation.get("coupling_interval") - simulation_run_length_sec = simulation.get("run_length_sec") - simulation_nx = simulation.get("nx") - - # Read in Coupling infomration - coupling = read_in_data.get("coupling") - coupling_out_vars = coupling.get("out_vars") - coupling_in_vars = coupling.get("in_vars") - restart_file = coupling.get("restart_file") # This feature is not used for now. TODO - - return model, model_name, PartitionType, simulation_coupling_interval, simulation_run_length_sec,\ - simulation_nx, coupling_out_vars, coupling_in_vars, restart_file - - - diff --git a/tests/general_toy_model_backup.py b/tests/general_toy_model_backup.py deleted file mode 100755 index ce1a467..0000000 --- a/tests/general_toy_model_backup.py +++ /dev/null @@ -1,207 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 - Barcelona Supercomputing Center -# Author: Rodrigo Martín Posada -# MIT License - -import f90nml -import pyoasis -from pyoasis import OASIS # pylint: disable=no-name-in-module -import numpy as np -import logging - -import yaml -from yaml.loader import SafeLoader -import logging -import argparse -import os -import sys -from DataCouplerUtils import read_yaml_conf - - -# TODO -# It will read in the YAML file instead of the namelist. It will receive the name of the YAMl file as argparse value -# it should turn to class in next step round of refactoring - - -L080_NX = 35718 # number of grid cells at T159 resolution -L128_NX = 88838 # number of grid cells at T255 resolution -L256_NX = 348528 # number of grid cells at T511 resolution -CO2_CMODE = False # is CO2 concentration-mode active? -CO2_EMODE = False # is CO2 emission-mode active? - - -def def_local_partition(nx, npes, mype): - il_size = nx // npes - il_offset = mype * il_size - if (npes-mype) <= nx % npes: - il_size += 1 - il_offset += (nx % npes) - (npes-mype) - return il_size, il_offset - -if __name__ == '__main__': - - try: - parser=argparse.ArgumentParser() - parser.add_argument("--conf",type=str) - args = parser.parse_args() - yaml_conf_file = args.conf - except: - print("NOTE:TOY Could note read in the input yaml file : {}".format(yaml_conf_file), file=sys.stderr) - else: - print("NOTE:TOY input yaml file is : {}".format(yaml_conf_file), file=sys.stderr) - - OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars_readin = read_yaml_conf(yaml_conf_file) - - - # Constants from namelist - - COUPLING_INTERVAL = TimeStepSec - RUN_LENGTH_SEC = RunLengthSec - - # Init OASIS - comp = pyoasis.Component(OasisModel) - - # Get rank in local communicator - mype = comp.localcomm.rank - npes = comp.localcomm.size - value = str(100+mype) # ? Not sure what this means , same was in toy_model - # Unit for output messages - out_ifs = ("{OasisModel}.out_{value}").format(OasisModel=OasisModel,value=value) - logging.basicConfig(filename=out_ifs, format='%(message)s', level=logging.DEBUG) - logging.debug('-----------------------------------------------------------') - logging.debug('I am IFS-toy process with rank : {}'.format(mype)) - logging.debug('in my local communicator gathering {} processes'.format(npes)) - logging.debug('----------------------------------------------------------') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # PARTITION DEFINITION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - with open('namcouple', 'r') as f: - #contents = f.read() - contents = "" - for line in f: - li=line.strip() - if not li.startswith("#"): - contents += line - # TODOD find a better way to detect CO2_CMODE - if 'GLOBAL GLOBAL' in contents: - CO2_CMODE = True - if 'A_CO2_emis ' in contents: - CO2_EMODE = True - if 'L080' in contents: - nx = L080_NX - elif 'L128' in contents: - nx = L128_NX - elif 'L256' in contents: - nx = L256_NX - else: - raise Exception('Invalid IFS grid in namcouple') - # Definition of the local partition - il_size, il_offset = def_local_partition(nx, npes, mype) - logging.debug('Local partition definition') - logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) - partition = pyoasis.ApplePartition(il_offset, il_size) - if CO2_CMODE or CO2_EMODE: - #nx_co2 = 2 # for 2 hemisphere box model - nx_co2 = 1 - if mype == 0: - logging.debug('Local serial partition') - logging.debug('nx_co2 = {} mype = {}'.format(nx_co2, mype)) - partition2 = pyoasis.SerialPartition(nx_co2) - else: - nx_co2 = 0 - partition2 = None - - - # Prepare the list that is necessary for - OasisOutputVars = [] - for v in OasisOutputVars_readin.keys() : - OasisOutputVars.append([OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']]) - variable = OasisOutputVars_readin[v]['receive_id'] - #variable = pyoasis.Var(OasisOutputVars_readin[v]['receive_id'], partition, OASIS.IN) - # print("NOTE: {variable_name} : {pyoasis_output}".format(variable_name =v, pyoasis_output=variable), file=sys.stderr) - print("NOTE:OASIS VARIABLE NAME : {pyoasis_output}".format( pyoasis_output= variable), file=sys.stderr) - - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # DECLARATION OF THE COUPLING FIELDS - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - A_SST = pyoasis.Var("A_SST", partition, OASIS.IN) - print("NOTE:OASIS ASST : {pyoasis_output}".format( pyoasis_output=A_SST), file=sys.stderr) - A_Ice_frac = pyoasis.Var("A_Ice_frac", partition, OASIS.IN) - print("NOTE:OASIS A_Ice_frac : {pyoasis_output}".format( pyoasis_output=A_Ice_frac), file=sys.stderr) - logging.debug('var_id A_SST, var_id A_Ice_frac {} {}'.format(A_SST._id, A_Ice_frac._id)) - - if CO2_CMODE: - if mype == 0: - A_CO2_cconc = pyoasis.Var("A_CO2_cconc", partition2, OASIS.IN) - logging.debug('var_id A_CO2_cconc {}'.format(A_CO2_cconc._id)) - A_CO2_econc = pyoasis.Var("A_CO2_econc", partition2, OASIS.IN) - logging.debug('var_id A_CO2_econc {}'.format(A_CO2_cconc._id)) - if CO2_EMODE: - A_CO2_emis = pyoasis.Var("A_CO2_emis", partition, OASIS.IN) - logging.debug('var_id A_CO2_emis {}'.format(A_CO2_emis._id)) - A_CO2_land = pyoasis.Var("A_CO2_land", partition, OASIS.IN) - logging.debug('var_id A_CO2_land {}'.format(A_CO2_land._id)) - A_CO2_ocean = pyoasis.Var("A_CO2_ocean", partition, OASIS.IN) - logging.debug('var_id A_CO2_ocean {}'.format(A_CO2_ocean._id)) - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION OF DEFINITION PHASE - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of initialisation phase') - - comp.enddef() - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TIME STEP LOOP - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('Timestep, field min, mean and max value') - - field_recv_A_SST = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_Ice_frac = pyoasis.asarray(np.full(il_size, -1.0)) - if CO2_CMODE and mype == 0: - field_recv_A_CO2_cconc = pyoasis.asarray(np.full(nx_co2, -1.0)) - field_recv_A_CO2_econc = pyoasis.asarray(np.full(nx_co2, -1.0)) - if CO2_EMODE: - field_recv_A_CO2_emis = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_CO2_land = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_CO2_ocean = pyoasis.asarray(np.full(il_size, -1.0)) - - for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): - A_SST.get(itap_sec, field_recv_A_SST) - A_Ice_frac.get(itap_sec, field_recv_A_Ice_frac) - - logging.debug('ITAP_SEC: {}'.format(itap_sec)) - logging.debug('A_SST -> {:.3e} {:.3e} {:.3e}'.format( - np.min(field_recv_A_SST), - np.mean(field_recv_A_SST), - np.max(field_recv_A_SST))) - logging.debug('A_Ice_frac -> {:.3e} {:.3e} {:.3e}'.format( - np.min(field_recv_A_Ice_frac), - np.mean(field_recv_A_Ice_frac), - np.max(field_recv_A_Ice_frac))) - if CO2_CMODE: - if mype == 0: - A_CO2_cconc.get(itap_sec, field_recv_A_CO2_cconc) - logging.debug('A_CO2_cconc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_cconc), np.mean(field_recv_A_CO2_cconc), np.max(field_recv_A_CO2_cconc))) - A_CO2_econc.get(itap_sec, field_recv_A_CO2_econc) - logging.debug('A_CO2_econc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_econc), np.mean(field_recv_A_CO2_econc), np.max(field_recv_A_CO2_econc))) - if CO2_EMODE: - A_CO2_emis.get(itap_sec, field_recv_A_CO2_emis) - logging.debug('A_CO2_emis -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_emis), np.mean(field_recv_A_CO2_emis), np.max(field_recv_A_CO2_emis))) - A_CO2_land.get(itap_sec, field_recv_A_CO2_land) - logging.debug('A_CO2_land -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_land), np.mean(field_recv_A_CO2_land), np.max(field_recv_A_CO2_land))) - A_CO2_ocean.get(itap_sec, field_recv_A_CO2_ocean) - logging.debug('A_CO2_ocean -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_ocean), np.mean(field_recv_A_CO2_ocean), np.max(field_recv_A_CO2_ocean))) - logging.debug('--------------------------------------\n') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of the program') - - del comp diff --git a/tests/launch_ece3_data_coupler_mn4.cmd b/tests/launch_ece3_data_coupler_mn4.cmd new file mode 100644 index 0000000..834c568 --- /dev/null +++ b/tests/launch_ece3_data_coupler_mn4.cmd @@ -0,0 +1,31 @@ +#!/bin/bash + +# slurm specific options for Marenostrum4 +#SBATCH --qos=debug +#SBATCH -N 1 +#SBATCH -n 5 +#SBATCH -c 1 +#SBATCH -t 0:05:00 +#SBATCH --exclusive + +#load python and netcdf modules +module load python/3.6.1 +module load netcdf/4.2 +module load CDO/1.9.3 +module list +export MPIRUN="mpirun" + +source ../sources/oasis3-mct/generated/python/init.sh + +#bash ./run_example.sh pythoncompat forcing 4 2005-01-01 2005-03-01 0 128 true +#bash ./run_example.sh fortran forcing 4 2005-01-01 2005-03-01 0 128 true +#bash ./run_example-t1279.sh python forcing 4 2010-01-01 2010-03-01 0 128 true + +#bash ./run_example.sh datacoupler co2 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_co2.yaml +#bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true false + +bash ./run_example.sh datacoupler forcing 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_forcing.yaml +#bash ./run_example.sh python co2 4 2005-01-01 2005-03-01 0 128 true +#bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true +#bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true false +#bash ./run_example.sh co2box co2 4 2005-01-01 2005-05-01 0 128 true false diff --git a/tests/run_example.sh b/tests/run_example.sh index 33a70c7..cced1dd 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -121,6 +121,7 @@ cp -f $datadir/*.sh $rundir/. cp -f $datadir/*.yaml $rundir/. cp -f $source_exe1 $rundir/. ln -sf $source_exe2 $rundir/. +cp -f $srcdir/*.py $rundir/. cd $rundir ### Generate namelist -- GitLab From 13a80468ea0ca23b9b0313783dc24c6bcc74c57b Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 29 Aug 2023 15:54:26 +0200 Subject: [PATCH 28/39] WIP: cam couple is produced by the preprocessing script in a cleaner and more straightforward manner, prep work to remove type from YAMLUtils --- .../data-coupler/DataCouplerPreprocessor.py | 101 +++++++++++ sources/data-coupler/namcoupler_creator.py | 142 --------------- tests/IFS_toy.py | 166 ------------------ tests/data/namcouple_empty.yaml | 20 --- tests/run_example.sh | 11 +- 5 files changed, 108 insertions(+), 332 deletions(-) create mode 100644 sources/data-coupler/DataCouplerPreprocessor.py delete mode 100644 sources/data-coupler/namcoupler_creator.py delete mode 100755 tests/IFS_toy.py delete mode 100644 tests/data/namcouple_empty.yaml diff --git a/sources/data-coupler/DataCouplerPreprocessor.py b/sources/data-coupler/DataCouplerPreprocessor.py new file mode 100644 index 0000000..83cdd8c --- /dev/null +++ b/sources/data-coupler/DataCouplerPreprocessor.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +# Copyright 2023 - Barcelona Supercomputing Center +# Authors: Amirpasha Mozaffari +# MIT License + +import yaml +from yaml.loader import SafeLoader +import os +import argparse +import sys +from YAMLlUtils import read_yaml_conf_type1 +import f90nml + +# It will readin the YAML file that is generated by the RunExample and generate a namcouple list before + + +def append_multiple_lines_to_file(file_path, lines_to_append): + with open(file_path, 'a') as file: + # for line in lines_to_append: + file.write(lines_to_append + '\n') + + +def add_field_to_namcouple(send_id, receive_id, timestepsec,send_grid_name, receive_grid): + lines_to_append = str(send_id) + " " + str(receive_id) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ + str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ + "P 0 P 0\n" + \ + "SCRIPR \n" + \ + "GAUSWGT LR SCALAR LATITUDE 1 9 2.0" + + return lines_to_append + + + +def create_empty_file(filename): + try: + with open(filename, 'w') as file: + pass # The file is created but remains empty + print(f"Empty file '{filename}' created successfully.") + except Exception as e: + print(f"An error occurred: {e}") + + +def add_begin_to_namecouple(nfields,runtime): + lines_to_append = """# ================================================================================================= +# General OASIS configuration +# ================================================================================================= + $NFIELDS + {nfields} + $END +# ------------------------------------------------------------------------------------------------- + $RUNTIME + {runtime} + $END +# ------------------------------------------------------------------------------------------------- + $NLOGPRT + 0 0 + $END +# ------------------------------------------------------------------------------------------------- + $STRINGS +# ================================================================================================= +# Fields send from AMIP to IFS +# ================================================================================================= +# --- AMIP forcing data --- [ifs amip]""" + + return(lines_to_append.format(nfields=nfields,runtime=runtime)) + + +def add_end_to_namecouple(): + lines_to_append = """# ------------------------------------------------------------------------------------------------- +$END +# =================================================================================================""" + + return lines_to_append + + +if __name__ == '__main__': + + parser=argparse.ArgumentParser() + parser.add_argument("--conf",type=str) + parser.add_argument("--output",type=str) + args = parser.parse_args() + yaml_conf_file = args.conf + output_file = args.output + + ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + + number_of_fields = len(OasisOutputVars_readin) + + # Creating the namcouple file amd insert the read-in data from YAML file + create_empty_file(output_file) + lines=add_begin_to_namecouple(number_of_fields,RunLengthSec) + append_multiple_lines_to_file(output_file, lines) + + for v in OasisOutputVars_readin.keys() : + lines = add_field_to_namcouple(OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], \ + TimeStepSec,OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']) + append_multiple_lines_to_file(output_file, lines) + + lines = add_end_to_namecouple() + append_multiple_lines_to_file(output_file, lines) \ No newline at end of file diff --git a/sources/data-coupler/namcoupler_creator.py b/sources/data-coupler/namcoupler_creator.py deleted file mode 100644 index dbcfd17..0000000 --- a/sources/data-coupler/namcoupler_creator.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2023 - Barcelona Supercomputing Center -# Authors: Amirpasha Mozaffari -# MIT License - -import yaml -from yaml.loader import SafeLoader -import os -import argparse -import sys -from YAMLlUtils import read_yaml_conf_type1 -import f90nml - -# It will readin the YAML file that is generated by the RunExample and generate a namcouple list before - - - -def replace_string_in_file(input_file_path, target_string, new_string, output_file_path): - with open(input_file_path, 'r') as input_file: - content = input_file.read() - - updated_content = content.replace(target_string, new_string) - - with open(output_file_path, 'w') as output_file: - output_file.write(updated_content) - - - -def replace_strings_in_file(input_file_path, replacements_dict, output_file_path): - with open(input_file_path, 'r') as input_file: - content = input_file.read() - - for target_string, new_string in replacements_dict.items(): - content = content.replace(target_string, new_string) - - with open(output_file_path, 'w') as output_file: - output_file.write(content) - -def append_multiple_lines_to_file(file_path, lines_to_append): - with open(file_path, 'a') as file: - # for line in lines_to_append: - file.write(lines_to_append + '\n') - - -def add_field_to_namcouple(send_id, receive_id, timestepsec,send_grid_name, receive_grid): - lines_to_append = str(send_id) + " " + str(receive_id) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ - str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ - "P 0 P 0\n" + \ - "SCRIPR \n" + \ - "GAUSWGT LR SCALAR LATITUDE 1 9 2.0" - - return lines_to_append - - - -# def get_values_as_string(data_dict): -# if not isinstance(data_dict, dict): -# raise ValueError("Input must be a dictionary.") - -# send_id_values = data_dict.get('send_id', []) -# if not isinstance(send_id_values, list): -# raise ValueError("The value associated with 'send_id' key must be a list.") -# return ":".join(str(value) for value in send_id_values) - - -# def add_field_to_namcouple_single_para(keys_string, values_string, timestepsec,send_grid_name, receive_grid): -# lines_to_append = str(keys_string) + " " + str(values_string) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ -# str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ -# "P 0 P 0\n" + \ -# "SCRIPR \n" + \ -# "GAUSWGT LR SCALAR LATITUDE 1 9 2.0" -# return lines_to_append - - - -def add_end_to_namecouple(): - lines_to_append = "# -------------------------------------------------------------------------------------------------\n" + \ - "$END\n" + \ - "# =================================================================================================\n" - - return lines_to_append - - -def text_to_f90nml(input_file, output_file): - with open(input_file, 'r') as infile: - lines = infile.readlines() - - data = {} - for line in lines: - key, value = line.strip().split() - data[key] = value - - nml_data = f90nml.Namelist(data) - nml_data.write(output_file) - - - -# def yaml_to_f90nml(yaml_file, f90nml_file): -# # Read YAML file -# with open(yaml_file, 'r') as file: -# data = yaml.safe_load(file) - - # # Write to Fortran namelist file - # with open(f90nml_file, 'w') as file: - # nml = f90nml.Namelist(data) - # nml.write(file) - - -if __name__ == '__main__': - # receive the yaml experiment input file is it exists , otherwise pass - - parser=argparse.ArgumentParser() - parser.add_argument("--conf",type=str) - parser.add_argument("--input",type=str) - parser.add_argument("--output",type=str) - args = parser.parse_args() - yaml_conf_file = args.conf - input_file_path = args.input - intermediate_file = args.output - - ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) - - number_of_fields = len(OasisOutputVars_readin) - - replacements_dict = { - "(nfileds)": str(number_of_fields), - "(runtime)": str(RunLengthSec), - } - - replace_strings_in_file(input_file_path, replacements_dict, intermediate_file) - - for v in OasisOutputVars_readin.keys() : - - lines = add_field_to_namcouple(OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], \ - TimeStepSec,OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']) - - append_multiple_lines_to_file(intermediate_file, lines) - - - lines = add_end_to_namecouple() - append_multiple_lines_to_file(intermediate_file, lines) \ No newline at end of file diff --git a/tests/IFS_toy.py b/tests/IFS_toy.py deleted file mode 100755 index 85f03b6..0000000 --- a/tests/IFS_toy.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 - Barcelona Supercomputing Center -# Author: Rodrigo Martín Posada -# MIT License - -import f90nml -import pyoasis -from pyoasis import OASIS # pylint: disable=no-name-in-module -import numpy as np -import logging - -NAMELIST_FILE_NAME = 'namelist.amip' -L080_NX = 35718 # number of grid cells at T159 resolution -L128_NX = 88838 # number of grid cells at T255 resolution -L256_NX = 348528 # number of grid cells at T511 resolution -CO2_CMODE = False # is CO2 concentration-mode active? -CO2_EMODE = False # is CO2 emission-mode active? - - -def def_local_partition(nx, npes, mype): - il_size = nx // npes - il_offset = mype * il_size - if (npes-mype) <= nx % npes: - il_size += 1 - il_offset += (nx % npes) - (npes-mype) - return il_size, il_offset - - -if __name__ == '__main__': - # Constants from namelist - nml = f90nml.read(NAMELIST_FILE_NAME) - COUPLING_INTERVAL = nml['NAMAMIP']['TimeStepSec'] - RUN_LENGTH_SEC = nml['NAMAMIP']['RunLengthSec'] - - # Init OASIS - comp = pyoasis.Component("IFS_TOY") - local_comm = comp.localcomm - # Get rank in local communicator - mype = comp.localcomm.rank - npes = comp.localcomm.size - - # Unit for output messages - out_ifs = 'IFS_toy.out_'+str(100+mype) - logging.basicConfig(filename=out_ifs, format='%(message)s', level=logging.DEBUG) - logging.debug('-----------------------------------------------------------') - logging.debug('I am IFS-toy process with rank : {}'.format(mype)) - logging.debug('in my local communicator gathering {} processes'.format(npes)) - logging.debug('----------------------------------------------------------') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # PARTITION DEFINITION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - with open('namcouple', 'r') as f: - #contents = f.read() - contents = "" - for line in f: - li=line.strip() - if not li.startswith("#"): - contents += line - # TODOD find a better way to detect CO2_CMODE - if 'GLOBAL GLOBAL' in contents: - CO2_CMODE = True - if 'A_CO2_emis ' in contents: - CO2_EMODE = True - if 'L080' in contents: - nx = L080_NX - elif 'L128' in contents: - nx = L128_NX - elif 'L256' in contents: - nx = L256_NX - else: - raise Exception('Invalid IFS grid in namcouple') - # Definition of the local partition - il_size, il_offset = def_local_partition(nx, npes, mype) - logging.debug('Local partition definition') - logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) - partition = pyoasis.ApplePartition(il_offset, il_size) - if CO2_CMODE or CO2_EMODE: - #nx_co2 = 2 # for 2 hemisphere box model - nx_co2 = 1 - if mype == 0: - logging.debug('Local serial partition') - logging.debug('nx_co2 = {} mype = {}'.format(nx_co2, mype)) - partition2 = pyoasis.SerialPartition(nx_co2) - else: - nx_co2 = 0 - partition2 = None - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # DECLARATION OF THE COUPLING FIELDS - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - A_SST = pyoasis.Var("A_SST", partition, OASIS.IN) - A_Ice_frac = pyoasis.Var("A_Ice_frac", partition, OASIS.IN) - logging.debug('var_id A_SST, var_id A_Ice_frac {} {}'.format(A_SST._id, A_Ice_frac._id)) - if CO2_CMODE: - if mype == 0: - A_CO2_cconc = pyoasis.Var("A_CO2_cconc", partition2, OASIS.IN) - logging.debug('var_id A_CO2_cconc {}'.format(A_CO2_cconc._id)) - A_CO2_econc = pyoasis.Var("A_CO2_econc", partition2, OASIS.IN) - logging.debug('var_id A_CO2_econc {}'.format(A_CO2_cconc._id)) - if CO2_EMODE: - A_CO2_emis = pyoasis.Var("A_CO2_emis", partition, OASIS.IN) - logging.debug('var_id A_CO2_emis {}'.format(A_CO2_emis._id)) - A_CO2_land = pyoasis.Var("A_CO2_land", partition, OASIS.IN) - logging.debug('var_id A_CO2_land {}'.format(A_CO2_land._id)) - A_CO2_ocean = pyoasis.Var("A_CO2_ocean", partition, OASIS.IN) - logging.debug('var_id A_CO2_ocean {}'.format(A_CO2_ocean._id)) - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION OF DEFINITION PHASE - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of initialisation phase') - - comp.enddef() - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TIME STEP LOOP - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('Timestep, field min, mean and max value') - - field_recv_A_SST = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_Ice_frac = pyoasis.asarray(np.full(il_size, -1.0)) - if CO2_CMODE and mype == 0: - field_recv_A_CO2_cconc = pyoasis.asarray(np.full(nx_co2, -1.0)) - field_recv_A_CO2_econc = pyoasis.asarray(np.full(nx_co2, -1.0)) - if CO2_EMODE: - field_recv_A_CO2_emis = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_CO2_land = pyoasis.asarray(np.full(il_size, -1.0)) - field_recv_A_CO2_ocean = pyoasis.asarray(np.full(il_size, -1.0)) - - for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): - A_SST.get(itap_sec, field_recv_A_SST) - A_Ice_frac.get(itap_sec, field_recv_A_Ice_frac) - - logging.debug('ITAP_SEC: {}'.format(itap_sec)) - logging.debug('A_SST -> {:.3e} {:.3e} {:.3e}'.format( - np.min(field_recv_A_SST), - np.mean(field_recv_A_SST), - np.max(field_recv_A_SST))) - logging.debug('A_Ice_frac -> {:.3e} {:.3e} {:.3e}'.format( - np.min(field_recv_A_Ice_frac), - np.mean(field_recv_A_Ice_frac), - np.max(field_recv_A_Ice_frac))) - if CO2_CMODE: - if mype == 0: - A_CO2_cconc.get(itap_sec, field_recv_A_CO2_cconc) - logging.debug('A_CO2_cconc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_cconc), np.mean(field_recv_A_CO2_cconc), np.max(field_recv_A_CO2_cconc))) - A_CO2_econc.get(itap_sec, field_recv_A_CO2_econc) - logging.debug('A_CO2_econc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_econc), np.mean(field_recv_A_CO2_econc), np.max(field_recv_A_CO2_econc))) - if CO2_EMODE: - A_CO2_emis.get(itap_sec, field_recv_A_CO2_emis) - logging.debug('A_CO2_emis -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_emis), np.mean(field_recv_A_CO2_emis), np.max(field_recv_A_CO2_emis))) - A_CO2_land.get(itap_sec, field_recv_A_CO2_land) - logging.debug('A_CO2_land -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_land), np.mean(field_recv_A_CO2_land), np.max(field_recv_A_CO2_land))) - A_CO2_ocean.get(itap_sec, field_recv_A_CO2_ocean) - logging.debug('A_CO2_ocean -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_ocean), np.mean(field_recv_A_CO2_ocean), np.max(field_recv_A_CO2_ocean))) - logging.debug('--------------------------------------\n') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of the program') - - del comp diff --git a/tests/data/namcouple_empty.yaml b/tests/data/namcouple_empty.yaml deleted file mode 100644 index 8a1360f..0000000 --- a/tests/data/namcouple_empty.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# ================================================================================================= -# General OASIS configuration -# ================================================================================================= - $NFIELDS - (nfileds) - $END -# ------------------------------------------------------------------------------------------------- - $RUNTIME - (runtime) - $END -# ------------------------------------------------------------------------------------------------- - $NLOGPRT - 0 0 - $END -# ------------------------------------------------------------------------------------------------- - $STRINGS -# ================================================================================================= -# Fields send from AMIP to IFS -# ================================================================================================= -# --- AMIP forcing data --- [ifs amip] diff --git a/tests/run_example.sh b/tests/run_example.sh index cced1dd..baccde5 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -33,7 +33,7 @@ datadir=$srcdir/data exe1='python3 general_toy_model.py' source_exe1=$srcdir/general_toy_model.py -py_script='python3 namcoupler_creator.py' +py_script='python3 DataCouplerPreprocessor.py' if [ $model = fortran ]; then @@ -227,7 +227,7 @@ else . ./namelist_python.amip.sh > ./namelist.amip # Create the name of the experiment conf yaml based on the OasisCPLNG name in template yaml - yaml_conf_name=$(grep -F "OasisCPLNG" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' + yaml_conf_name=$(grep -F "ModelNameReceive" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' . ./$yaml_conf_file > $yaml_conf_name [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box @@ -236,8 +236,10 @@ if [ $amip_mode = forcing ]; then input="namcouple_empty.yaml" namcouple_output="namcouple" - py_nproc=1 - ${MPIRUN} -np $py_nproc $py_script --conf $yaml_conf_name --input $input --output $namcouple_output + + # Run the py namcouple creator + $py_script --conf $yaml_conf_name --output $namcouple_output + elif [ $amip_mode = co2 ]; then [ $model = co2box ] && . ./namcouple_co2box.sh > ./namcouple || . ./namcouple_co2.sh > ./namcouple @@ -269,5 +271,6 @@ fi #echo $casename 'is executed or submitted to queue.' echo 'Results are found in rundir : '$rundir +echo 'Run Example is successfully executed' ###################################################################### -- GitLab From 38af9efecbce871250ab05896b1fe543ab0ae071 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 29 Aug 2023 17:03:50 +0200 Subject: [PATCH 29/39] WIP: ece3_toy_model reverted with small changes to launch script --- sources/data-coupler/toy_model.py | 146 +++++++++++++++++++ sources/ece3-toy-model/ifs_toy_model.yaml | 1 - sources/ece3-toy-model/nemo_toy_model.yaml | 2 - sources/ece3-toy-model/runoff_toy_model.yaml | 1 - tests/launch_ece3_toy_model_mn4.cmd | 5 +- 5 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 sources/data-coupler/toy_model.py diff --git a/sources/data-coupler/toy_model.py b/sources/data-coupler/toy_model.py new file mode 100644 index 0000000..5eada78 --- /dev/null +++ b/sources/data-coupler/toy_model.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +# Copyright 2023 - Barcelona Supercomputing Center +# Author: Rodrigo Martín Posada (2021), updated by : Amirpasha Mozaffari (2023) +# TBD + +import yaml +from yaml.loader import SafeLoader +import logging +import argparse +import os + +import f90nml +import pyoasis +from pyoasis import OASIS # pylint: disable=no-name-in-module +import numpy as np + +if __name__ == '__main__': + +### Read in YAML file + current_path = os.getcwd() + parser=argparse.ArgumentParser() + parser.add_argument("--yaml_file_path",type=str) + args = parser.parse_args() + yamel_file_path = os.path.join(current_path,args.yaml_file_path) + if os.path.isfile(yamel_file_path) == False: + print("YAML file does not exist. Aborted") + raise NameError("YAML file does not exist.") + + # Open the file and load the file + with open(yamel_file_path) as f: + read_in_data = yaml.load(f, Loader=SafeLoader) + f.close() + +### Read in file + #read_yaml(read_in_data) + model = read_in_data.get("model") + model_name = model.get("model_name") + + # Read in Simulation information + simulation = read_in_data.get("simulation") + simulation_coupling_interval = simulation.get("coupling_interval") + simulation_run_length_sec = simulation.get("run_length_sec") + simulation_nx = simulation.get("nx") + + # Read in Coupling infomration + coupling = read_in_data.get("coupling") + coupling_out_vars = coupling.get("out_vars") + coupling_in_vars = coupling.get("in_vars") + restart_file = coupling.get("restart_file") + +### Pass the values to original code + + # Init OASIS + comp = pyoasis.Component(model_name) + local_comm = comp.localcomm + # Get rank in local communicator + mype = comp.localcomm.rank + npes = comp.localcomm.size + + # BUG : shouldnt it be the npes and not mpye (?) + mype_value = str(100+mype) + out_model = '{model_name}.out_{mype_value}'.format(model_name = model_name, mype_value = mype_value) + + logging.basicConfig(filename=out_model, format='%(message)s', level=logging.DEBUG) + logging.debug('-----------------------------------------------------------') + logging.info('I am {model_name} process with rank : {mype}'.format(model_name = model_name, + mype = mype)) + #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) + logging.debug('in my local communicator gathering {} processes'.format(npes)) + logging.debug('----------------------------------------------------------') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # PARTITION DEFINITION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + # Definition of the local partition + partition = pyoasis.SerialPartition(simulation_nx) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # DECLARATION OF THE COUPLING FIELDS + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + out_coupling_fields={} + + for v in coupling_out_vars: + out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) + logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) + + + in_coupling_fields={} + + for v in coupling_in_vars: + in_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.IN) + logging.info('var_id {}, added as OASIS_IN var'.format(v)) + + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION OF DEFINITION PHASE + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of initialisation phase') + + comp.enddef() + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TIME STEP LOOP + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('Timestep, field min, mean and max value') + + field_data = pyoasis.asarray(np.full(simulation_nx, -1.0)) + + for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): + + logging.debug('ITAP_SEC: {} receiving fields'.format(itap_sec)) + logging.debug(str(in_coupling_fields.keys())) + for id, field in in_coupling_fields.items(): + field.get(itap_sec, field_data) + logging.debug('{} -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(field_data), np.mean(field_data), np.max(field_data))) + logging.debug('--------------------------------------\n') + + logging.debug('ITAP_SEC: {} sending fields'.format(itap_sec)) + logging.debug(str(out_coupling_fields.keys())) + for id, field in out_coupling_fields.items(): + sigma=1 + mu=1 + # send dummy data (100 for runoff, random for other variables) + #TODO send dummy data read from oasis restart file + if id == "A_Runoff": + field_data[:]=1.4658e-06 + field_data[:]=100 + else: + field_data[:]=sigma * np.random.randn(simulation_nx) + mu + field.put(itap_sec, field_data) + logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(field_data), np.mean(field_data), np.max(field_data))) + logging.debug('--------------------------------------\n') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of the program') + + print('Model {} is finished successfully.'.format(model_name)) + + del comp + + + diff --git a/sources/ece3-toy-model/ifs_toy_model.yaml b/sources/ece3-toy-model/ifs_toy_model.yaml index be0a920..8ef5c82 100644 --- a/sources/ece3-toy-model/ifs_toy_model.yaml +++ b/sources/ece3-toy-model/ifs_toy_model.yaml @@ -4,7 +4,6 @@ --- # yaml metadata -type : 2 model: ModelName : IFS_TOY diff --git a/sources/ece3-toy-model/nemo_toy_model.yaml b/sources/ece3-toy-model/nemo_toy_model.yaml index 434e09f..d346675 100644 --- a/sources/ece3-toy-model/nemo_toy_model.yaml +++ b/sources/ece3-toy-model/nemo_toy_model.yaml @@ -4,8 +4,6 @@ --- # yaml metadata -type : 2 - model: ModelName : NEMO_TOY diff --git a/sources/ece3-toy-model/runoff_toy_model.yaml b/sources/ece3-toy-model/runoff_toy_model.yaml index 78a41e6..47d9126 100644 --- a/sources/ece3-toy-model/runoff_toy_model.yaml +++ b/sources/ece3-toy-model/runoff_toy_model.yaml @@ -4,7 +4,6 @@ --- # yaml metadata -type : 2 model: ModelName : RUNOFF_TOY diff --git a/tests/launch_ece3_toy_model_mn4.cmd b/tests/launch_ece3_toy_model_mn4.cmd index 7b08908..608c694 100755 --- a/tests/launch_ece3_toy_model_mn4.cmd +++ b/tests/launch_ece3_toy_model_mn4.cmd @@ -47,13 +47,12 @@ cp -f $srcdir/*.yaml $rundir cp -f $testdir/general_toy_model.py $rundir cp -f $testdir/YAMLlUtils.py $rundir -#toy_model="toy_model.py" -toy_model="general_toy_model.py" +toy_model="toy_model.py" echo "prep is finished" cd $rundir # run IFS+NEMO+runoff toy model -mpirun -np 1 python3 $testdir/$toy_model --conf ifs_toy_model.yaml : -np 1 python3 $testdir/$toy_model --conf nemo_toy_model.yaml : -np 1 python3 $testdir/$toy_model --conf runoff_toy_model.yaml +mpirun -np 1 python3 $rundir/$toy_model --yaml_file_path ifs_toy_model.yaml : -np 1 python3 $rundir/$toy_model --yaml_file_path nemo_toy_model.yaml : -np 1 python3 $rundir/$toy_model --yaml_file_path runoff_toy_model.yaml -- GitLab From 8266f90750ddfad9ec1726ef0610dfe9eef3c15f Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 30 Aug 2023 16:26:50 +0200 Subject: [PATCH 30/39] WIP: DataCouplerPreprocessor.py is generating yaml_conf_ifs_toy_model.yaml that will be used be ifs_toy_model --- .../data-coupler/DataCouplerPreprocessor.py | 113 +++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/sources/data-coupler/DataCouplerPreprocessor.py b/sources/data-coupler/DataCouplerPreprocessor.py index 83cdd8c..3891ea4 100644 --- a/sources/data-coupler/DataCouplerPreprocessor.py +++ b/sources/data-coupler/DataCouplerPreprocessor.py @@ -8,8 +8,8 @@ from yaml.loader import SafeLoader import os import argparse import sys -from YAMLlUtils import read_yaml_conf_type1 -import f90nml +#from YAMLlUtils import read_yaml_conf_type1 +#import f90nml # It will readin the YAML file that is generated by the RunExample and generate a namcouple list before @@ -73,6 +73,104 @@ $END return lines_to_append + + +# Read the DataCoupler YAML + +def read_DataCoupler_yaml_input(yaml_file): + ''' + Reads the experiment yaml file + ''' + + with open(yaml_file) as file: + read_in = yaml.load(file, Loader=SafeLoader) + file.close() + + # Model Information + ModelNameSend = read_in.get('ModelNameSend') + ModelNameReceive = read_in.get('ModelNameReceive') + LogFileName = read_in.get('LogFileName') + PartitionType = read_in.get('PartitionType') + + ## Run Information + + RunLengthSec = read_in.get('RunLengthSec') + TimeStepSec = read_in.get('TimeStepSec') + StartYear = read_in.get('StartYear') + StartMonth = read_in.get('StartMonth') + StartDay = read_in.get('StartDay') + FixYear = read_in.get('FixYear') + GridInfo = read_in.get('GridInfo') + LDebug = read_in.get('LDebug') + + # Create the log_file name and sanity-check + + # Check the type of input in yaml file + if "FileInputVars" in read_in : + FileInputVars_readin = {} + FileInputVars_readin = read_in.get('FileInputVars') + # Name of the Variable for this experiment + FileInputVarNames = list(FileInputVars_readin.keys()) + # Variable configuration for this experiment + FileInputVarFields_conf = list(FileInputVars_readin.values()) + + if "OasisOutputVars" in read_in : + OasisOutputVars_readin = {} + OasisOutputVars_readin = read_in.get('OasisOutputVars') + print("NOTE: OasisOutputVars_readin : {}".format(OasisOutputVars_readin), file=sys.stderr) + # Name of the Variable for this experiment + OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) + + # Variable configuration for this experiment + OasisOutputVars_conf = list(OasisOutputVars_readin.values()) + + return ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ + StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin + + +# Create yaml_conf_name_ifs_toy_model + + +def create_yaml_conf_name_ifs_toy_model(filename,ModelName,PartitionTypeReceive,run_length_sec,coupling_interval,nx,OasisOutputVars_readin): + + coupling_out_vars=[] + + coupling_in_vars = [] + for v in OasisOutputVars_readin.keys() : + coupling_in_vars.append(OasisOutputVars_readin[v]['receive_id']) + + create_empty_file(filename) + lines_to_append =""" # Copyright 2023 - Barcelona Supercomputing Center +# Author: Amirpasha Mozaffari +# TBD +--- + +# yaml metadata +model: + ModelName : {ModelName} + #PartitionTypeSend : SerialPartition + PartitionTypeReceive : {PartitionTypeReceive} + +simulation: + coupling_interval : {coupling_interval} + run_length_sec : {run_length_sec} + # Definition of the local partition grid cell + # L080_NX = 35718 # number of LAND grid cells at T159 resolution + # L128_NX = 88838 # number of LAND grid cells at T255 resolution + # L256_NX = 348528 # number of LAND grid cells at T511 resolution + nx : {nx} + +coupling: + out_vars : {out_vars} + in_vars : {in_vars} + restart_file : /path/ + """ + append_multiple_lines_to_file(filename, lines_to_append.format(ModelName=ModelName,PartitionType=PartitionType,coupling_interval=coupling_interval,run_length_sec=run_length_sec,nx=nx,out_vars=coupling_out_vars,in_vars=coupling_in_vars )) + + + + + if __name__ == '__main__': parser=argparse.ArgumentParser() @@ -82,8 +180,10 @@ if __name__ == '__main__': yaml_conf_file = args.conf output_file = args.output + # Read the yaml file + ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_DataCoupler_yaml_input(yaml_conf_file) number_of_fields = len(OasisOutputVars_readin) @@ -98,4 +198,9 @@ if __name__ == '__main__': append_multiple_lines_to_file(output_file, lines) lines = add_end_to_namecouple() - append_multiple_lines_to_file(output_file, lines) \ No newline at end of file + append_multiple_lines_to_file(output_file, lines) + + # Creating the yaml_conf_name_ifs_toy_model + + ifs_conf_yaml = "yaml_conf_name_ifs_toy_model.yaml" + create_yaml_conf_name_ifs_toy_model(ifs_conf_yaml,ModelNameSend,PartitionType, RunLengthSec, TimeStepSec,GridInfo,OasisOutputVars_readin) -- GitLab From 8580fb4a41a244b0af89e0009d03ce90f6bd0bbf Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Thu, 31 Aug 2023 09:56:12 +0200 Subject: [PATCH 31/39] FIX: the model name mixup is fixed for datacoupler --- sources/data-coupler/DataCoupler.py | 2 +- sources/data-coupler/DataCouplerPreprocessor.py | 7 ++----- tests/data/template_conf_datacoupler_forcing.yaml | 4 ++-- tests/general_toy_model.py | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index ce293ee..923ae6b 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -48,7 +48,7 @@ class DataCoupler: raise Exception("RunLengthSec is too long for StartYear less than date_yref_min") # Oasis Compiler description - self.OasisCPLNG = ModelNameReceive + self.OasisCPLNG = ModelNameSend # time axis unit = days self.delta_t = TimeStepSec/86400. diff --git a/sources/data-coupler/DataCouplerPreprocessor.py b/sources/data-coupler/DataCouplerPreprocessor.py index 3891ea4..7bbe1fe 100644 --- a/sources/data-coupler/DataCouplerPreprocessor.py +++ b/sources/data-coupler/DataCouplerPreprocessor.py @@ -149,7 +149,7 @@ def create_yaml_conf_name_ifs_toy_model(filename,ModelName,PartitionTypeReceive, model: ModelName : {ModelName} #PartitionTypeSend : SerialPartition - PartitionTypeReceive : {PartitionTypeReceive} + PartitionTypeReceive : {PartitionType} simulation: coupling_interval : {coupling_interval} @@ -165,10 +165,7 @@ coupling: in_vars : {in_vars} restart_file : /path/ """ - append_multiple_lines_to_file(filename, lines_to_append.format(ModelName=ModelName,PartitionType=PartitionType,coupling_interval=coupling_interval,run_length_sec=run_length_sec,nx=nx,out_vars=coupling_out_vars,in_vars=coupling_in_vars )) - - - + append_multiple_lines_to_file(filename, lines_to_append.format(ModelName=ModelName,PartitionType=PartitionTypeReceive,coupling_interval=coupling_interval,run_length_sec=run_length_sec,nx=nx,out_vars=coupling_out_vars,in_vars=coupling_in_vars )) if __name__ == '__main__': diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml index c533647..3a6cfc9 100755 --- a/tests/data/template_conf_datacoupler_forcing.yaml +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -5,8 +5,8 @@ cat << EOF type : 1 # DataCoupler is 1, ToyModel is 2 ## Model Information -ModelNameSend : IFS_TOY -ModelNameReceive : AMIPFORC +ModelNameSend : AMIPFORC +ModelNameReceive : IFS_TOY LogFileName : amip.log YamlConfName : ${yaml_conf_name} PartitionType : ApplePartition diff --git a/tests/general_toy_model.py b/tests/general_toy_model.py index 95b42de..6c7bcd3 100755 --- a/tests/general_toy_model.py +++ b/tests/general_toy_model.py @@ -57,7 +57,7 @@ if __name__ == '__main__': ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) - ModelName = ModelNameSend + ModelName = ModelNameReceive COUPLING_INTERVAL = TimeStepSec RUN_LENGTH_SEC = RunLengthSec nx = GridInfo -- GitLab From c4e7ce7c3a961a8fe91a52fea095d0d6de362703 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Thu, 31 Aug 2023 17:04:14 +0200 Subject: [PATCH 32/39] WIP:( Does not work) - clean up up the datacoupler , toy_model_2.py needs some work --- sources/data-coupler/DataCoupler.py | 13 +- .../data-coupler/DataCouplerPreprocessor.py | 83 +----- sources/data-coupler/DataCouplerUtils.py | 109 +------ tests/launch_ece3_toy_model_mn4.cmd | 2 - tests/run_example.sh | 18 +- tests/run_example_working.sh | 279 ++++++++++++++++++ .../toy_model.py => tests/toy_model_2.py | 71 ++++- 7 files changed, 378 insertions(+), 197 deletions(-) create mode 100755 tests/run_example_working.sh rename sources/data-coupler/toy_model.py => tests/toy_model_2.py (70%) diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 923ae6b..f9052e1 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -13,22 +13,17 @@ import sys import argparse from DataCouplerUtils import read_namelist, days_since_refyear, is_leap, earth_area -from DataCouplerUtils import read_yaml_conf #, replace_strings_in_file , replace_string_in_file, append_multiple_lines_to_file, add_field_to_namcouple, add_end_to_namecouple -from YAMLlUtils import read_yaml_conf_type1 +from DataCouplerUtils import read_DataCoupler_yaml_input + from DataCouplerFileVar import FileInputVar from DataCouplerOasisVar import OasisOutputVar class DataCoupler: - def __init__(self,yaml_conf_file): - - - # OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - # StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config , OasisOutputVars = read_yaml_conf(yaml_conf_file) - + def __init__(self,yaml_conf_file): ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) + StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_DataCoupler_yaml_input(yaml_conf_file) if LDebug: logging.basicConfig(filename=LogFileName, format='%(message)s', level=logging.DEBUG) diff --git a/sources/data-coupler/DataCouplerPreprocessor.py b/sources/data-coupler/DataCouplerPreprocessor.py index 7bbe1fe..f65033a 100644 --- a/sources/data-coupler/DataCouplerPreprocessor.py +++ b/sources/data-coupler/DataCouplerPreprocessor.py @@ -7,10 +7,10 @@ import yaml from yaml.loader import SafeLoader import os import argparse -import sys -#from YAMLlUtils import read_yaml_conf_type1 -#import f90nml +import sys +from DataCouplerUtils import read_DataCoupler_yaml_input + # It will readin the YAML file that is generated by the RunExample and generate a namcouple list before @@ -73,64 +73,6 @@ $END return lines_to_append - - -# Read the DataCoupler YAML - -def read_DataCoupler_yaml_input(yaml_file): - ''' - Reads the experiment yaml file - ''' - - with open(yaml_file) as file: - read_in = yaml.load(file, Loader=SafeLoader) - file.close() - - # Model Information - ModelNameSend = read_in.get('ModelNameSend') - ModelNameReceive = read_in.get('ModelNameReceive') - LogFileName = read_in.get('LogFileName') - PartitionType = read_in.get('PartitionType') - - ## Run Information - - RunLengthSec = read_in.get('RunLengthSec') - TimeStepSec = read_in.get('TimeStepSec') - StartYear = read_in.get('StartYear') - StartMonth = read_in.get('StartMonth') - StartDay = read_in.get('StartDay') - FixYear = read_in.get('FixYear') - GridInfo = read_in.get('GridInfo') - LDebug = read_in.get('LDebug') - - # Create the log_file name and sanity-check - - # Check the type of input in yaml file - if "FileInputVars" in read_in : - FileInputVars_readin = {} - FileInputVars_readin = read_in.get('FileInputVars') - # Name of the Variable for this experiment - FileInputVarNames = list(FileInputVars_readin.keys()) - # Variable configuration for this experiment - FileInputVarFields_conf = list(FileInputVars_readin.values()) - - if "OasisOutputVars" in read_in : - OasisOutputVars_readin = {} - OasisOutputVars_readin = read_in.get('OasisOutputVars') - print("NOTE: OasisOutputVars_readin : {}".format(OasisOutputVars_readin), file=sys.stderr) - # Name of the Variable for this experiment - OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) - - # Variable configuration for this experiment - OasisOutputVars_conf = list(OasisOutputVars_readin.values()) - - return ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ - StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin - - -# Create yaml_conf_name_ifs_toy_model - - def create_yaml_conf_name_ifs_toy_model(filename,ModelName,PartitionTypeReceive,run_length_sec,coupling_interval,nx,OasisOutputVars_readin): coupling_out_vars=[] @@ -172,10 +114,13 @@ if __name__ == '__main__': parser=argparse.ArgumentParser() parser.add_argument("--conf",type=str) - parser.add_argument("--output",type=str) + parser.add_argument("--namcouple_output",type=str) + parser.add_argument("--toy_model_yaml_conf_output",type=str) args = parser.parse_args() yaml_conf_file = args.conf - output_file = args.output + namcouple_output = args.namcouple_output + toy_model_yaml_conf_output = args.toy_model_yaml_conf_output + # Read the yaml file @@ -185,19 +130,19 @@ if __name__ == '__main__': number_of_fields = len(OasisOutputVars_readin) # Creating the namcouple file amd insert the read-in data from YAML file - create_empty_file(output_file) + create_empty_file(namcouple_output) lines=add_begin_to_namecouple(number_of_fields,RunLengthSec) - append_multiple_lines_to_file(output_file, lines) + append_multiple_lines_to_file(namcouple_output, lines) for v in OasisOutputVars_readin.keys() : lines = add_field_to_namcouple(OasisOutputVars_readin[v]['send_id'], OasisOutputVars_readin[v]['receive_id'], \ TimeStepSec,OasisOutputVars_readin[v]['send_grid_name'], OasisOutputVars_readin[v]['receive_grid_name']) - append_multiple_lines_to_file(output_file, lines) + append_multiple_lines_to_file(namcouple_output, lines) lines = add_end_to_namecouple() - append_multiple_lines_to_file(output_file, lines) + append_multiple_lines_to_file(namcouple_output, lines) # Creating the yaml_conf_name_ifs_toy_model - ifs_conf_yaml = "yaml_conf_name_ifs_toy_model.yaml" - create_yaml_conf_name_ifs_toy_model(ifs_conf_yaml,ModelNameSend,PartitionType, RunLengthSec, TimeStepSec,GridInfo,OasisOutputVars_readin) + ifs_conf_yaml = toy_model_yaml_conf_output + create_yaml_conf_name_ifs_toy_model(ifs_conf_yaml,ModelNameReceive,PartitionType, RunLengthSec, TimeStepSec,GridInfo,OasisOutputVars_readin) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 74d7938..99fd148 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -226,24 +226,28 @@ def read_namelist(NAMELIST_FILE_NAME,NAMELIST_SECTION): return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config +## YAMLUtil -def read_yaml_conf(experiment_yaml_input): + +# Read the DataCoupler YAML + +def read_DataCoupler_yaml_input(yaml_file): ''' Reads the experiment yaml file ''' - with open(experiment_yaml_input) as file: + with open(yaml_file) as file: read_in = yaml.load(file, Loader=SafeLoader) file.close() - # Model Information - OasisModel = read_in.get('OasisModel') - OasisCPLNG = read_in.get('OasisCPLNG') + ModelNameSend = read_in.get('ModelNameSend') + ModelNameReceive = read_in.get('ModelNameReceive') LogFileName = read_in.get('LogFileName') + PartitionType = read_in.get('PartitionType') ## Run Information - + RunLengthSec = read_in.get('RunLengthSec') TimeStepSec = read_in.get('TimeStepSec') StartYear = read_in.get('StartYear') @@ -274,93 +278,6 @@ def read_yaml_conf(experiment_yaml_input): # Variable configuration for this experiment OasisOutputVars_conf = list(OasisOutputVars_readin.values()) - return OasisModel, OasisCPLNG, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin - - -def read_yaml_meta(experiment_yaml_input): - ''' - Reads the experiment yaml file - ''' - - with open(experiment_yaml_input) as file: - read_in = yaml.load(file, Loader=SafeLoader) - file.close() - - - # Model Information - yaml_type = read_in.get('type') - - return yaml_type - - - -def read_yaml_conf_toy(experiment_yaml_input): - -# Open the file and load the file - with open(experiment_yaml_input) as f: - read_in_data = yaml.load(f, Loader=SafeLoader) - f.close() - -### Read in file - #read_yaml(read_in_data) - model = read_in_data.get("model") - model_name = model.get("model_name") - - # Read in Simulation information - simulation = read_in_data.get("simulation") - simulation_coupling_interval = simulation.get("coupling_interval") - simulation_run_length_sec = simulation.get("run_length_sec") - simulation_nx = simulation.get("nx") - - # Read in Coupling infomration - coupling = read_in_data.get("coupling") - coupling_out_vars = coupling.get("out_vars") - coupling_in_vars = coupling.get("in_vars") - restart_file = coupling.get("restart_file") # This feature is not used for now. TODO - - - -# def replace_string_in_file(input_file_path, target_string, new_string, output_file_path): -# with open(input_file_path, 'r') as input_file: -# content = input_file.read() - -# updated_content = content.replace(target_string, new_string) - -# with open(output_file_path, 'w') as output_file: -# output_file.write(updated_content) - - - -# def replace_strings_in_file(input_file_path, replacements_dict, output_file_path): -# with open(input_file_path, 'r') as input_file: -# content = input_file.read() - -# for target_string, new_string in replacements_dict.items(): -# content = content.replace(target_string, new_string) - -# with open(output_file_path, 'w') as output_file: -# output_file.write(content) - -# def append_multiple_lines_to_file(file_path, lines_to_append): -# with open(file_path, 'a') as file: -# # for line in lines_to_append: -# file.write(lines_to_append + '\n') - - -# def add_field_to_namcouple(send_id, receive_id, timestepsec,send_grid_name, receive_grid): -# lines_to_append = "\n" + \ -# str(send_id) + " " + str(receive_id) + " 1 " + str(timestepsec) + " 1 rstas.nc EXPOUT \n" + \ -# str(send_grid_name) + " " + str(receive_grid) + " LAG=0 \n" + \ -# "P 0 P 0\n" + \ -# "SCRIPR \n" + \ -# "GAUSWGT LR SCALAR LATITUDE 1 9 2.0 \n" - -# return lines_to_append - -# def add_end_to_namecouple(): -# lines_to_append = "\n" + \ -# "# =================================================================================================\n" + \ -# "$END\n" + \ -# "# =================================================================================================\n" - -# return lines_to_append \ No newline at end of file + return ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ + StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin + diff --git a/tests/launch_ece3_toy_model_mn4.cmd b/tests/launch_ece3_toy_model_mn4.cmd index 608c694..b1632ba 100755 --- a/tests/launch_ece3_toy_model_mn4.cmd +++ b/tests/launch_ece3_toy_model_mn4.cmd @@ -44,8 +44,6 @@ cp -f $srcdir/*.py $rundir cp -f $srcdir/namcouple $rundir cp -f $srcdir/*.yaml $rundir -cp -f $testdir/general_toy_model.py $rundir -cp -f $testdir/YAMLlUtils.py $rundir toy_model="toy_model.py" diff --git a/tests/run_example.sh b/tests/run_example.sh index baccde5..d2a533e 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -31,8 +31,11 @@ srcdir=`pwd` datadir=$srcdir/data -exe1='python3 general_toy_model.py' -source_exe1=$srcdir/general_toy_model.py +#exe1='python3 general_toy_model.py' +#source_exe1=$srcdir/general_toy_model.py + +exe1='python3 toy_model_2.py' +source_exe1=$srcdir/toy_model_2.py py_script='python3 DataCouplerPreprocessor.py' @@ -227,7 +230,9 @@ else . ./namelist_python.amip.sh > ./namelist.amip # Create the name of the experiment conf yaml based on the OasisCPLNG name in template yaml - yaml_conf_name=$(grep -F "ModelNameReceive" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' + #yaml_conf_name=$(grep -F "ModelNameReceive" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' + yaml_conf_name='DataCoupler_exp_conf.yaml' + . ./$yaml_conf_file > $yaml_conf_name [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box @@ -236,9 +241,10 @@ if [ $amip_mode = forcing ]; then input="namcouple_empty.yaml" namcouple_output="namcouple" + toy_model_yaml_conf_output="yaml_conf_name_ifs_toy_model.yaml" # Run the py namcouple creator - $py_script --conf $yaml_conf_name --output $namcouple_output + $py_script --conf $yaml_conf_name --namcouple_output $namcouple_output --toy_model_yaml_conf_output $toy_model_yaml_conf_output elif [ $amip_mode = co2 ]; then @@ -259,7 +265,9 @@ echo 'Executing the model using mpirun : ${MPIRUN}' # To seprate the DataCoupler with YAML input file from legecy codes if [ $model = datacoupler ] ; then if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then - ${MPIRUN} -np $nproc_exe1 $exe1 --conf $yaml_conf_name : -np $nproc_exe2 $exe2 --conf $yaml_conf_name + + + ${MPIRUN} -np $nproc_exe1 $exe1 --conf $toy_model_yaml_conf_output : -np $nproc_exe2 $exe2 --conf $yaml_conf_name fi else ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 diff --git a/tests/run_example_working.sh b/tests/run_example_working.sh new file mode 100755 index 0000000..5564e85 --- /dev/null +++ b/tests/run_example_working.sh @@ -0,0 +1,279 @@ +#!/bin/bash +## Usage + +# if [ $# -ne 9 ]; then +# echo 'Invalid args.' +# echo 'Usage ./run_example.sh ' +# echo 'Try ./run_example.sh python forcing 4 1990-01-01 1991-01-01 0 L128 true' +# exit 1 +# fi + +set -xuve + +model=$1 +amip_mode=$2 # forcing or primavera +# - Define number of processes to run each executable +nproc_exe1=$3 +nproc_exe2=1 # AMIP is always one process + +leg_start_date=$4 +leg_end_date=$5 +ifs_cmip_fixyear=$6 +ifs_grid=$7 +amip_interpolate=$8 +co2_interpolate=$9 +yaml_conf_file=${10} +host=`uname -n` +user=`whoami` + +## - Define paths +srcdir=`pwd` +datadir=$srcdir/data + + +exe1='python3 general_toy_model.py' +source_exe1=$srcdir/general_toy_model.py +py_script='python3 DataCouplerPreprocessor.py' + + +if [ $model = fortran ]; then + exe2='./amip-forcing' + if [ $amip_mode = forcing ]; then + source_exe2=$srcdir/../sources/amip-forcing/bin/amip-forcing + else + source_exe2=$srcdir/../sources/amip-primavera/bin/amip-forcing + fi +elif [ $model = python ] || [ $model = pythoncompat ]; then + exe2='python3 amip_forcing.py' + # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' + # exe2='python3 -m cProfile -s cumtime amip_forcing.py' + source_exe2=$srcdir/../sources/amip-forcing/src/python/*.py +elif [ $model = datacoupler ] ; then + # TODO + #exe2='python3 AMIPDataCoupler.py' + exe2='python3 DataCoupler.py' + # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' + # exe2='python3 -m cProfile -s cumtime amip_forcing.py' + source_exe2=$srcdir/../sources/data-coupler/*.py +elif [ $model = co2box ] ; then + exe2='python3 CO2BoxDataCoupler.py' + # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' + # exe2='python3 -m cProfile -s cumtime amip_forcing.py' + source_exe2=$srcdir/../sources/data-coupler/*.py +else + echo 'Invalid args. You must specify a language for the AMIP reader: | ' + exit 1 +fi + +CO2_CMODE=false +CO2_EMODE=false + +# - Define rundir +rundir=${srcdir}/work_${model}_${amip_mode}_${nproc_exe1}_${leg_start_date}_${leg_end_date}_${ifs_cmip_fixyear}_${ifs_grid}_${amip_interpolate} +# export COVERAGE_FILE=${rundir}/../.coverage + +echo '*****************************************************************' +#echo '*** '$casename' : '$run +echo '' +echo 'Rundir :' $rundir +#echo 'Architecture :' $arch +echo 'Host : '$host +echo 'User : '$user +echo '' +echo $exe1' runs on '$nproc_exe1 'processes' +echo $exe2' runs on '$nproc_exe2 'processes' +echo '' +###################################################################### +### Create rundir and copy everything needed + +\rm -fr $rundir +mkdir -p $rundir +ln -sf $datadir/ICMGGa22e+000000 $rundir/. +ln -sf $datadir/*.txt $rundir/. +# Get SST and SIC +#if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then +if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then + ln -sf $datadir/forcing/siconcbcs*.nc $rundir/. + ln -sf $datadir/forcing/tosbcs*.nc $rundir/. + ln -sf $datadir/forcing/rmp_AMIP_to_L${ifs_grid}_GAUSWGT*.nc $rundir/. + if [ $amip_mode = co2 ]; then + ln -sf $datadir/co2/CO2-em-anthro_*.nc $rundir/. + ln -sf $datadir/co2/CO2-em-AIR-anthro_*.nc $rundir/. + ln -sf $datadir/co2/mole-fraction-of-carbon-dioxide-in-air_*.nc* $rundir/. + ln -sf $datadir/co2/rmp_CO2_emis_to_B${ifs_grid}_GAUSWGT*.nc $rundir/. + fi +else + ln -sf $datadir/$amip_mode/HadI*.nc $rundir/. + ln -sf $datadir/$amip_mode/rmp_PSIC_to_${ifs_grid}_GAUSWGT.nc $rundir/. + ln -sf $datadir/$amip_mode/rmp_PSST_to_${ifs_grid}_GAUSWGT.nc $rundir/. +fi +# Get grids and masks +if [ $model = fortran ] || [ $model = pythoncompat ]; then + cp -f $datadir/$amip_mode/masks.nc $rundir/. + cp -f $datadir/$amip_mode/grids.nc $rundir/. + cp -f $datadir/$amip_mode/areas.nc $rundir/. +else + cp -f $datadir/grids-noamip.nc $rundir/grids.nc + cp -f $datadir/masks-noamip.nc $rundir/masks.nc + cp -f $datadir/areas-noamip.nc $rundir/areas.nc +fi +cp -f $datadir/*.sh $rundir/. +cp -f $datadir/*.yaml $rundir/. +cp -f $source_exe1 $rundir/. +ln -sf $source_exe2 $rundir/. +cp -f $srcdir/*.py $rundir/. +cd $rundir + +### Generate namelist +leg_length_sec=$(( $(date -u -d "${leg_end_date}" +%s) - $(date -u -d "${leg_start_date}" +%s) )) +cpl_freq_amip_sec=86400 # Always +leg_start_date_yyyymmdd=$(date -u -d "${leg_start_date}" +%Y%m%d) + +if [ $model = fortran ] || [ $model = pythoncompat ]; then + if [ $amip_mode = forcing ]; then + . ./namelist.amip.sh > ./namelist.amip + else + . ./namelist_primavera.amip.sh > ./namelist.amip + + fi +else + #if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then + if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then + i=1 + ii=1 + if [ $model = co2box ] || [ $model = datacoupler ]; then + var=FileInputVars + else + var=Vars + fi + sst_conf_var=${var}"("$((i++))",:) = 'AMIP_sst_monthly', 'AMIP', 'AMIP_sst', 'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc', 'tosbcs', 1870, 2016, 'monthly', ${amip_interpolate}, 1, 273.15, 271.38, ,true,true," + sst_conf_var_yml="${var}("$((ii++))"): AMIP_sst_monthly, AMIP', AMIP_sst, tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, tosbcs, 1870, 2016, monthly, ${amip_interpolate}, 1, 273.15, 271.38, , true, true" + + sic_conf_var=${var}"("$((i++))",:) = 'AMIP_sic_monthly', 'AMIP', 'AMIP_sic', 'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc', 'siconcbcs', 1870, 2016, 'monthly', ${amip_interpolate}, 0.01, 0, 0, 1,true,true," + sic_conf_var_yml="${var}("$((ii++))"): AMIP_sic_monthly, AMIP, AMIP_sic, siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, siconcbcs, 1870, 2016, monthly, ${amip_interpolate}, 0.01, 0, 0, 1, true, true" + + j=1 + jj=1 + oasis_conf_var_yml="" + oasis_conf_var="!OasisOutputVars(j,:) = , , , , , \n" + oasis_conf_var=$'\n'"OasisOutputVars("$((j++))",:) = 'AMIP_sst', 'AMIP', 'daily', 1, 0, true," + oasis_conf_var_yml="OasisOutputVars("$((jj++))") : AMIP_sst, AMIP, daily, 1, 0, true"$'\n' + oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = 'AMIP_sic', 'AMIP', 'daily', 1, 0, true," + oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : AMIP_sic, AMIP, daily, 1, 0, true"$'\n' + if [ $amip_mode = co2 ]; then + co2_conf_var="" + co2_conf_var+="!FileInputVars(i,:) = "$'\n' + #[ $model = co2box ] && mod=CO2BOX || mod=AMIP + if [ $model = co2box ] ; then + mod=CO2BOX + CO2_CMODE=true # set to false to disable co2 concentrations reading + CO2_EMODE=true # set to false to disable emissions reading + else + mod=AMIP + CO2_CMODE=false # don't change this! + CO2_EMODE=true # don't change this! + fi + #this fix is required to correctly read the co2 files which havereftime 0-1-1, which isn't supported by python netcdf4 + #cdo -R -setreftime,1849-01-01,00:00 mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod + #this fix is required to correctly read the CO2_em_monthly files which have a 365day calendar and also to convert from a grid point/sectors fields to a global one + #cdo -L -setcalendar,gregorian -fldsum -vertsum -mul CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc co2-area.nc CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc + if [ ${CO2_CMODE} == true ] ; then + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_cconc_monthly', 'GLOBAL', '"$mod"_CO2_cconc', 'mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod', 'mole_fraction_of_carbon_dioxide_in_air', 1849, 2014, 'monthly', ${co2_interpolate}, 1, 0, , ,true,true,"$'\n' + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_econc_monthly', 'GLOBAL', '"$mod"_CO2_econc', 'mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod', 'mole_fraction_of_carbon_dioxide_in_air', 1849, 2014, 'monthly', ${co2_interpolate}, 'co2_ppm_to_mass', 0, , ,false,false,"$'\n' + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_em_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 86400, 0, , ,true,true,"$'\n' + # add land/ocean fluxes equal to 0.5/0.1 that of emissions, for demonstration purposes + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_land_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 43200, 0, , ,true,true,"$'\n' + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_ocean_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 8640, 0, , ,true,true,"$'\n' + fi + if [ ${CO2_EMODE} == true ] ; then + # this is the 3D monthly emissions used for ECE4, the calendar fix mentionned below is probably required + co2_conf_var_yml="" + + + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_em_monthly', 'CO2_emis', '"$mod"_CO2_emis', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 1, 0, , ,true,true,"$'\n' + co2_conf_var_yml+="${var}("$((ii++))"): CO2_em_monthly, CO2_emis, "$mod"_CO2_emis, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 1, 0, , ,true,true"$'\n' + # add land/ocean fluxes equal to 0.5/0.1 that of emissions, for demonstration purposes + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_land_monthly', 'CO2_emis', '"$mod"_CO2_land', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.5, 0, , ,true,true,"$'\n' + co2_conf_var_yml+="${var}("$((ii++))"): CO2_land_monthly, CO2_emis, "$mod"_CO2_land, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 0.5, 0, , , true, true"$'\n' + co2_conf_var+=${var}"("$((i++))",:) = 'CO2_ocean_monthly', 'CO2_emis', '"$mod"_CO2_ocean', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.1, 0, , ,true,true,"$'\n' + co2_conf_var_yml+="${var}("$((ii++))"): CO2_ocean_monthly, CO2_emis, "$mod"_CO2_ocean, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 0.1, 0, , ,true,true" + + + + fi + #OasisOutputVars(i,:) = + if [ ${CO2_CMODE} == true ] ; then + oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_cconc', 'GLOBAL', 'daily', 1, 0, true," + oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_econc', 'GLOBAL', 'daily', 'co2_mass_to_ppm', 0, false," + fi + if [ ${CO2_EMODE} == true ] ; then + # this is the 3D monthly emissions used for ECE4 + oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_emis', 'CO2_emis', 'daily', 1, 0, true," + oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_emis, CO2_emis, daily, 1, 0, true"$'\n' + oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_land', 'CO2_emis', 'daily', 1, 0, true," + oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_land, CO2_emis, daily, 1, 0, true"$'\n' + oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_ocean', 'CO2_emis', 'daily', 1, 0, true," + oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_ocean, CO2_emis, daily, 1, 0, true" + fi + else + co2_conf_var="" + fi + else + sst_conf_var="Vars(1,:) = 'AMIP_sst_daily', 'PSST', 'AMIP_sst', 'HadISST2_prelim_0to360_alldays_sst_[year].nc', 'sst', 1850, 2016, 'daily', false, 1, 0, , ," + sic_conf_var="Vars(2,:) = 'AMIP_sic_daily', 'PSIC', 'AMIP_sic', 'HadISST2_prelim_0to360_alldays_sic_[year].nc', 'sic', 1850, 2016, 'daily', false, 1, 0, , ," + co2_conf_var="" + oasis_conf_var="" + fi + . ./namelist_python.amip.sh > ./namelist.amip + + # Create the name of the experiment conf yaml based on the OasisCPLNG name in template yaml + #yaml_conf_name=$(grep -F "ModelNameReceive" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' + yaml_conf_name='DataCoupler_exp_conf.yaml' + + . ./$yaml_conf_file > $yaml_conf_name + + [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box +fi +if [ $amip_mode = forcing ]; then + + input="namcouple_empty.yaml" + namcouple_output="namcouple" + toy_model_yaml_conf_output="yaml_conf_name_ifs_toy_model.yaml" + + # Run the py namcouple creator + $py_script --conf $yaml_conf_name --namcouple_output $namcouple_output --toy_model_yaml_conf_output $toy_model_yaml_conf_output + + +elif [ $amip_mode = co2 ]; then + [ $model = co2box ] && . ./namcouple_co2box.sh > ./namcouple || . ./namcouple_co2.sh > ./namcouple +else + . ./namcouple_primavera.sh > ./namcouple +fi + +# Creating namcouple with python + + + +###################################################################### +### Definition of mpirun command and batch script + +echo 'Executing the model using mpirun : ${MPIRUN}' + +# To seprate the DataCoupler with YAML input file from legecy codes +if [ $model = datacoupler ] ; then + if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then + ${MPIRUN} -np $nproc_exe1 $exe1 --conf $yaml_conf_name : -np $nproc_exe2 $exe2 --conf $yaml_conf_name + fi +else + ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 +fi + + +# convert output +. convert-ece4pyreader-grids.sh ${leg_start_date} + +#echo $casename 'is executed or submitted to queue.' +echo 'Results are found in rundir : '$rundir +echo 'Run Example is successfully executed' + +###################################################################### diff --git a/sources/data-coupler/toy_model.py b/tests/toy_model_2.py similarity index 70% rename from sources/data-coupler/toy_model.py rename to tests/toy_model_2.py index 5eada78..0c10ff3 100644 --- a/sources/data-coupler/toy_model.py +++ b/tests/toy_model_2.py @@ -9,19 +9,39 @@ import logging import argparse import os -import f90nml import pyoasis from pyoasis import OASIS # pylint: disable=no-name-in-module import numpy as np -if __name__ == '__main__': + +def def_local_partition(nx, npes, mype): + il_size = nx // npes + il_offset = mype * il_size + if (npes-mype) <= nx % npes: + il_size += 1 + il_offset += (nx % npes) - (npes-mype) + return il_size, il_offset + + +def variable_exists(var_name): + return var_name in globals() + + + + + + +if __name__ == '__main__': + ### Read in YAML file current_path = os.getcwd() parser=argparse.ArgumentParser() - parser.add_argument("--yaml_file_path",type=str) - args = parser.parse_args() - yamel_file_path = os.path.join(current_path,args.yaml_file_path) + #parser.add_argument("--run_dir",type=str) + parser.add_argument("--conf",type=str) + args = parser.parse_args() + yamel_file_path = os.path.join(current_path,args.conf) + if os.path.isfile(yamel_file_path) == False: print("YAML file does not exist. Aborted") raise NameError("YAML file does not exist.") @@ -34,7 +54,7 @@ if __name__ == '__main__': ### Read in file #read_yaml(read_in_data) model = read_in_data.get("model") - model_name = model.get("model_name") + model_name = model.get("ModelName") # Read in Simulation information simulation = read_in_data.get("simulation") @@ -46,7 +66,7 @@ if __name__ == '__main__': coupling = read_in_data.get("coupling") coupling_out_vars = coupling.get("out_vars") coupling_in_vars = coupling.get("in_vars") - restart_file = coupling.get("restart_file") + restart_file = coupling.get("restart_file") # This feature is not used for now. TODO ### Pass the values to original code @@ -74,24 +94,43 @@ if __name__ == '__main__': # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Definition of the local partition - partition = pyoasis.SerialPartition(simulation_nx) + il_size, il_offset = def_local_partition(simulation_nx, npes, mype) + logging.debug('Local partition definition') + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + partition = pyoasis.ApplePartition(il_offset, il_size) + #partition = pyoasis.SerialPartition(simulation_nx) + # if npes > 1: + # il_size, il_offset = def_local_partition(nx, npes, mype) + # logging.debug('Local partition definition') + # logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + # partition = pyoasis.ApplePartition(il_offset, il_size) + # else: + # partition = pyoasis.SerialPartition(nx) + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # DECLARATION OF THE COUPLING FIELDS # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - out_coupling_fields={} + # out_coupling_fields={} + + # for v in coupling_out_vars: + # out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) + # logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) - for v in coupling_out_vars: - out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) - logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) + in_coupling_fields = {} # Create a dictionary to store the variables + for name in coupling_in_vars: + var = pyoasis.Var(name, partition, OASIS.IN) + in_coupling_fields[name] = var + logging.debug('var_id {}: {}'.format(name, var._id)) - in_coupling_fields={} + # in_coupling_fields={} - for v in coupling_in_vars: - in_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.IN) - logging.info('var_id {}, added as OASIS_IN var'.format(v)) + # for v in coupling_in_vars: + # in_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.IN) + # logging.debug('var_id {}: {}'.format(name, var._id)) + # logging.info('var_id {}, added as OASIS_IN var'.format(v)) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- GitLab From f08c0c94c850bd18a69a0d0d7ec5b406acf3b2d0 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Fri, 1 Sep 2023 15:43:17 +0200 Subject: [PATCH 33/39] both datacoupler and ece3-toy-model are using the same /ece3-toy-model/toy_model.py, plus some clean up --- sources/ece3-toy-model/toy_model.py | 119 +++++++----- tests/YAMLlUtils.py | 113 ----------- tests/general_toy_model.py | 185 ------------------ tests/launch_ece3_toy_model_mn4.cmd | 3 +- tests/run_example.sh | 8 +- tests/run_example_working.sh | 279 ---------------------------- tests/toy_model_2.py | 185 ------------------ 7 files changed, 81 insertions(+), 811 deletions(-) delete mode 100644 tests/YAMLlUtils.py delete mode 100755 tests/general_toy_model.py delete mode 100755 tests/run_example_working.sh delete mode 100644 tests/toy_model_2.py diff --git a/sources/ece3-toy-model/toy_model.py b/sources/ece3-toy-model/toy_model.py index e31c6b9..ff89349 100644 --- a/sources/ece3-toy-model/toy_model.py +++ b/sources/ece3-toy-model/toy_model.py @@ -2,26 +2,41 @@ # Copyright 2023 - Barcelona Supercomputing Center # Author: Rodrigo Martín Posada (2021), updated by : Amirpasha Mozaffari (2023) # TBD +# note: merged for both datacoupler and toy-model import yaml from yaml.loader import SafeLoader import logging import argparse import os - import pyoasis from pyoasis import OASIS # pylint: disable=no-name-in-module import numpy as np -if __name__ == '__main__': +def def_local_partition(nx, npes, mype): + il_size = nx // npes + il_offset = mype * il_size + if (npes-mype) <= nx % npes: + il_size += 1 + il_offset += (nx % npes) - (npes-mype) + return il_size, il_offset + + +def variable_exists(var_name): + return var_name in globals() + + +if __name__ == '__main__': + ### Read in YAML file current_path = os.getcwd() parser=argparse.ArgumentParser() - parser.add_argument("--run_dir",type=str) - parser.add_argument("--yaml_file_path",type=str) + #parser.add_argument("--run_dir",type=str) + parser.add_argument("--conf",type=str) args = parser.parse_args() - yamel_file_path = os.path.join(current_path,args.yaml_file_path) + yamel_file_path = os.path.join(current_path,args.conf) + if os.path.isfile(yamel_file_path) == False: print("YAML file does not exist. Aborted") raise NameError("YAML file does not exist.") @@ -73,25 +88,34 @@ if __name__ == '__main__': # PARTITION DEFINITION # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # Definition of the local partition - partition = pyoasis.SerialPartition(simulation_nx) - + if npes > 1: + il_size, il_offset = def_local_partition(simulation_nx, npes, mype) + logging.debug('Local partition definition') + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + partition = pyoasis.ApplePartition(il_offset, il_size) + par_type="Apple" + else: + partition = pyoasis.SerialPartition(simulation_nx) + par_type="Serial" + + out_coupling_fields={} + + for v in coupling_out_vars: + out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) + logging.debug('var_id {}, added as OASIS_OUT var'.format(v)) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # DECLARATION OF THE COUPLING FIELDS # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - out_coupling_fields={} - - for v in coupling_out_vars: - out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) - logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) - - in_coupling_fields={} + in_coupling_fields = {} # Create a dictionary to store the variables - for v in coupling_in_vars: - in_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.IN) - logging.info('var_id {}, added as OASIS_IN var'.format(v)) + for name in coupling_in_vars: + var = pyoasis.Var(name, partition, OASIS.IN) + in_coupling_fields[name] = var + logging.debug('var_id {}: {}'.format(name, var._id)) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -106,32 +130,39 @@ if __name__ == '__main__': # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.debug('Timestep, field min, mean and max value') - field_data = pyoasis.asarray(np.full(simulation_nx, -1.0)) - - for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): - - logging.debug('ITAP_SEC: {} receiving fields'.format(itap_sec)) - logging.debug(str(in_coupling_fields.keys())) - for id, field in in_coupling_fields.items(): - field.get(itap_sec, field_data) - logging.debug('{} -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(field_data), np.mean(field_data), np.max(field_data))) - logging.debug('--------------------------------------\n') - - logging.debug('ITAP_SEC: {} sending fields'.format(itap_sec)) - logging.debug(str(out_coupling_fields.keys())) - for id, field in out_coupling_fields.items(): - sigma=1 - mu=1 - # send dummy data (100 for runoff, random for other variables) - #TODO send dummy data read from oasis restart file - if id == "A_Runoff": - field_data[:]=1.4658e-06 - field_data[:]=100 - else: - field_data[:]=sigma * np.random.randn(simulation_nx) + mu - field.put(itap_sec, field_data) - logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(field_data), np.mean(field_data), np.max(field_data))) - logging.debug('--------------------------------------\n') + + if npes > 1: + fields = {} + + for name in coupling_in_vars: + fields[name] = pyoasis.asarray(np.full(il_size, -1.0)) + + for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): + for name in coupling_in_vars: + in_coupling_fields[name].get(itap_sec, fields[name]) + + else: + + fields = {} + fields = pyoasis.asarray(np.full(simulation_nx, -1.0)) + + for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): + + for id, field in in_coupling_fields.items(): + field.get(itap_sec, fields) + + for id, field in out_coupling_fields.items(): + sigma=1 + mu=1 + # send dummy data (100 for runoff, random for other variables) + #TODO send dummy data read from oasis restart file + if id == "A_Runoff": + fields[:]=1.4658e-06 + fields[:]=100 + else: + fields[:]=sigma * np.random.randn(simulation_nx) + mu + field.put(itap_sec, fields) + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # TERMINATION diff --git a/tests/YAMLlUtils.py b/tests/YAMLlUtils.py deleted file mode 100644 index d529ef4..0000000 --- a/tests/YAMLlUtils.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2023 - Barcelona Supercomputing Center -# Authors: Amirpasha Mozaffari -# MIT License - -import yaml -from yaml.loader import SafeLoader -import os -import argparse -import sys - - - -# class yaml_file: - - -def read_yaml_meta(yaml_file): - ''' - Reads the metadata of the yaml file - it includes type which could be: - type 1 : DataCoupler - type 2 : NEMO / IFS / RUNOFF toy model - ''' - with open(yaml_file) as file: - read_in = yaml.load(file, Loader=SafeLoader) - file.close() - - # Model Information - yaml_type = read_in.get('type') - return yaml_type - - -def read_yaml_conf_type1(yaml_file): - ''' - Reads the experiment yaml file - ''' - - with open(yaml_file) as file: - read_in = yaml.load(file, Loader=SafeLoader) - file.close() - - # Model Information - ModelNameSend = read_in.get('ModelNameSend') - ModelNameReceive = read_in.get('ModelNameReceive') - LogFileName = read_in.get('LogFileName') - PartitionType = read_in.get('PartitionType') - - ## Run Information - - RunLengthSec = read_in.get('RunLengthSec') - TimeStepSec = read_in.get('TimeStepSec') - StartYear = read_in.get('StartYear') - StartMonth = read_in.get('StartMonth') - StartDay = read_in.get('StartDay') - FixYear = read_in.get('FixYear') - GridInfo = read_in.get('GridInfo') - LDebug = read_in.get('LDebug') - - # Create the log_file name and sanity-check - - # Check the type of input in yaml file - if "FileInputVars" in read_in : - FileInputVars_readin = {} - FileInputVars_readin = read_in.get('FileInputVars') - # Name of the Variable for this experiment - FileInputVarNames = list(FileInputVars_readin.keys()) - # Variable configuration for this experiment - FileInputVarFields_conf = list(FileInputVars_readin.values()) - - if "OasisOutputVars" in read_in : - OasisOutputVars_readin = {} - OasisOutputVars_readin = read_in.get('OasisOutputVars') - print("NOTE: OasisOutputVars_readin : {}".format(OasisOutputVars_readin), file=sys.stderr) - # Name of the Variable for this experiment - OasisOutputVarsNames = list(OasisOutputVars_readin.keys()) - - # Variable configuration for this experiment - OasisOutputVars_conf = list(OasisOutputVars_readin.values()) - - return ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ - StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin - - -def read_yaml_conf_type2(yaml_file): - -# Open the file and load the file - with open(yaml_file) as f: - read_in_data = yaml.load(f, Loader=SafeLoader) - f.close() - -### Read in file - #read_yaml(read_in_data) - model = read_in_data.get("model") - model_name = model.get("ModelName") - PartitionType = model.get("PartitionType") - - # Read in Simulation information - simulation = read_in_data.get("simulation") - simulation_coupling_interval = simulation.get("coupling_interval") - simulation_run_length_sec = simulation.get("run_length_sec") - simulation_nx = simulation.get("nx") - - # Read in Coupling infomration - coupling = read_in_data.get("coupling") - coupling_out_vars = coupling.get("out_vars") - coupling_in_vars = coupling.get("in_vars") - restart_file = coupling.get("restart_file") # This feature is not used for now. TODO - - return model, model_name, PartitionType, simulation_coupling_interval, simulation_run_length_sec,\ - simulation_nx, coupling_out_vars, coupling_in_vars, restart_file - - - diff --git a/tests/general_toy_model.py b/tests/general_toy_model.py deleted file mode 100755 index 6c7bcd3..0000000 --- a/tests/general_toy_model.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2021 - Barcelona Supercomputing Center -# Author: Rodrigo Martín Posada -# MIT License - -import f90nml -import pyoasis -from pyoasis import OASIS # pylint: disable=no-name-in-module -import numpy as np -import logging - -import yaml -from yaml.loader import SafeLoader -import logging -import argparse -import os -import sys -from YAMLlUtils import read_yaml_meta, read_yaml_conf_type1, read_yaml_conf_type2 - -# TODO -# It will read in the YAML file instead of the namelist. It will receive the name of the YAMl file as argparse value -# it should turn to class in next step round of refactoring - - -def def_local_partition(nx, npes, mype): - il_size = nx // npes - il_offset = mype * il_size - if (npes-mype) <= nx % npes: - il_size += 1 - il_offset += (nx % npes) - (npes-mype) - return il_size, il_offset - - -def variable_exists(var_name): - return var_name in globals() - - -if __name__ == '__main__': - - - parser=argparse.ArgumentParser() - parser.add_argument("--conf",type=str) - # parser.add_argument("--namcouple",type=str) - args = parser.parse_args() - yaml_conf_file = args.conf - if os.path.isfile(yaml_conf_file) == False: - print("YAML file does not exist. Aborted") - raise NameError("YAML file does not exist.") - - # Determine the type of yaml file - yaml_type = read_yaml_meta(yaml_conf_file) - - # Read in DataCoupler YAML file type - - if yaml_type == 1 : - - ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ - StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin = read_yaml_conf_type1(yaml_conf_file) - - ModelName = ModelNameReceive - COUPLING_INTERVAL = TimeStepSec - RUN_LENGTH_SEC = RunLengthSec - nx = GridInfo - - # Extract the send_id, receive_id, send_grid_name, receive_grid_name from the OasisConf. - coupling_in_vars = [] - for v in OasisOutputVars_readin.keys() : - coupling_in_vars.append(OasisOutputVars_readin[v]['receive_id']) - - # Read in ToModel Yaml file type - elif yaml_type == 2: - model, model_name, PartitionType, simulation_coupling_interval, simulation_run_length_sec, \ - simulation_nx, coupling_out_vars, coupling_in_vars, restart_file = read_yaml_conf_type2(yaml_conf_file) - - ModelName = model_name - COUPLING_INTERVAL = simulation_coupling_interval - RUN_LENGTH_SEC = simulation_run_length_sec - nx = simulation_nx - - - # Init OASIS - comp = pyoasis.Component(ModelName) - - # Get rank in local communicator - mype = comp.localcomm.rank - npes = comp.localcomm.size - - - # BUG : shouldnt it be the npes and not mpye (?) - mype_value = str(100+mype) - out_model = '{ModelName}.out_{mype_value}'.format(ModelName = ModelName, mype_value = mype_value) - - logging.basicConfig(filename=out_model, format='%(message)s', level=logging.DEBUG) - logging.debug('-----------------------------------------------------------') - logging.info('I am {ModelName} process with rank : {mype}'.format(ModelName = ModelName, - mype = mype_value)) - #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) - logging.debug('in my local communicator gathering {} processes'.format(npes)) - logging.debug('----------------------------------------------------------') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # PARTITION DEFINITION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # Definition of the local partition - - if yaml_type == 1 : #and PartitionType == "ApplePartition": - il_size, il_offset = def_local_partition(nx, npes, mype) - logging.debug('Local partition definition') - logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) - partition = pyoasis.ApplePartition(il_offset, il_size) - - elif yaml_type == 2 : #and PartitionType == "SerialPartition": - partition = pyoasis.SerialPartition(nx) - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # DECLARATION OF THE COUPLING FIELDS - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - out_coupling_fields={} - - for v in coupling_out_vars: - out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) - logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) - - - in_coupling_fields = {} # Create a dictionary to store the variables - - for name in coupling_in_vars: - var = pyoasis.Var(name, partition, OASIS.IN) - in_coupling_fields[name] = var - logging.debug('var_id {}: {}'.format(name, var._id)) - - -# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -# TERMINATION OF DEFINITION PHASE -# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of initialization phase') - - comp.enddef() - -# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -# TIME STEP LOOP -# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('Timestep, field min, mean, and max value') - - if yaml_type == 1 : - fields = {} - - for name in coupling_in_vars: - fields[name] = pyoasis.asarray(np.full(il_size, -1.0)) - - for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): - for name in coupling_in_vars: - in_coupling_fields[name].get(itap_sec, fields[name]) - - elif yaml_type == 2 : - - field_data = pyoasis.asarray(np.full(nx, -1.0)) - - for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): - - for id, field in in_coupling_fields.items(): - field.get(itap_sec, field_data) - - for id, field in out_coupling_fields.items(): - sigma=1 - mu=1 - # send dummy data (100 for runoff, random for other variables) - #TODO send dummy data read from oasis restart file - if id == "A_Runoff": - field_data[:]=1.4658e-06 - field_data[:]=100 - else: - field_data[:]=sigma * np.random.randn(nx) + mu - field.put(itap_sec, field_data) - - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of the program') - - print('Model {} is finished successfully.'.format(ModelName)) - - del comp diff --git a/tests/launch_ece3_toy_model_mn4.cmd b/tests/launch_ece3_toy_model_mn4.cmd index b1632ba..bba5b19 100755 --- a/tests/launch_ece3_toy_model_mn4.cmd +++ b/tests/launch_ece3_toy_model_mn4.cmd @@ -44,7 +44,6 @@ cp -f $srcdir/*.py $rundir cp -f $srcdir/namcouple $rundir cp -f $srcdir/*.yaml $rundir - toy_model="toy_model.py" echo "prep is finished" @@ -52,5 +51,5 @@ echo "prep is finished" cd $rundir # run IFS+NEMO+runoff toy model -mpirun -np 1 python3 $rundir/$toy_model --yaml_file_path ifs_toy_model.yaml : -np 1 python3 $rundir/$toy_model --yaml_file_path nemo_toy_model.yaml : -np 1 python3 $rundir/$toy_model --yaml_file_path runoff_toy_model.yaml +mpirun -np 1 python3 $rundir/$toy_model --conf ifs_toy_model.yaml : -np 1 python3 $rundir/$toy_model --conf nemo_toy_model.yaml : -np 1 python3 $rundir/$toy_model --conf runoff_toy_model.yaml diff --git a/tests/run_example.sh b/tests/run_example.sh index d2a533e..95e278d 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -30,12 +30,14 @@ user=`whoami` srcdir=`pwd` datadir=$srcdir/data - #exe1='python3 general_toy_model.py' #source_exe1=$srcdir/general_toy_model.py -exe1='python3 toy_model_2.py' -source_exe1=$srcdir/toy_model_2.py +exe1='python3 toy_model.py' +toy_model_dir=$srcdir/../sources/ece3-toy-model +cp -f $toy_model_dir/*.py $srcdir + +source_exe1=$srcdir/toy_model.py py_script='python3 DataCouplerPreprocessor.py' diff --git a/tests/run_example_working.sh b/tests/run_example_working.sh deleted file mode 100755 index 5564e85..0000000 --- a/tests/run_example_working.sh +++ /dev/null @@ -1,279 +0,0 @@ -#!/bin/bash -## Usage - -# if [ $# -ne 9 ]; then -# echo 'Invalid args.' -# echo 'Usage ./run_example.sh ' -# echo 'Try ./run_example.sh python forcing 4 1990-01-01 1991-01-01 0 L128 true' -# exit 1 -# fi - -set -xuve - -model=$1 -amip_mode=$2 # forcing or primavera -# - Define number of processes to run each executable -nproc_exe1=$3 -nproc_exe2=1 # AMIP is always one process - -leg_start_date=$4 -leg_end_date=$5 -ifs_cmip_fixyear=$6 -ifs_grid=$7 -amip_interpolate=$8 -co2_interpolate=$9 -yaml_conf_file=${10} -host=`uname -n` -user=`whoami` - -## - Define paths -srcdir=`pwd` -datadir=$srcdir/data - - -exe1='python3 general_toy_model.py' -source_exe1=$srcdir/general_toy_model.py -py_script='python3 DataCouplerPreprocessor.py' - - -if [ $model = fortran ]; then - exe2='./amip-forcing' - if [ $amip_mode = forcing ]; then - source_exe2=$srcdir/../sources/amip-forcing/bin/amip-forcing - else - source_exe2=$srcdir/../sources/amip-primavera/bin/amip-forcing - fi -elif [ $model = python ] || [ $model = pythoncompat ]; then - exe2='python3 amip_forcing.py' - # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' - # exe2='python3 -m cProfile -s cumtime amip_forcing.py' - source_exe2=$srcdir/../sources/amip-forcing/src/python/*.py -elif [ $model = datacoupler ] ; then - # TODO - #exe2='python3 AMIPDataCoupler.py' - exe2='python3 DataCoupler.py' - # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' - # exe2='python3 -m cProfile -s cumtime amip_forcing.py' - source_exe2=$srcdir/../sources/data-coupler/*.py -elif [ $model = co2box ] ; then - exe2='python3 CO2BoxDataCoupler.py' - # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' - # exe2='python3 -m cProfile -s cumtime amip_forcing.py' - source_exe2=$srcdir/../sources/data-coupler/*.py -else - echo 'Invalid args. You must specify a language for the AMIP reader: | ' - exit 1 -fi - -CO2_CMODE=false -CO2_EMODE=false - -# - Define rundir -rundir=${srcdir}/work_${model}_${amip_mode}_${nproc_exe1}_${leg_start_date}_${leg_end_date}_${ifs_cmip_fixyear}_${ifs_grid}_${amip_interpolate} -# export COVERAGE_FILE=${rundir}/../.coverage - -echo '*****************************************************************' -#echo '*** '$casename' : '$run -echo '' -echo 'Rundir :' $rundir -#echo 'Architecture :' $arch -echo 'Host : '$host -echo 'User : '$user -echo '' -echo $exe1' runs on '$nproc_exe1 'processes' -echo $exe2' runs on '$nproc_exe2 'processes' -echo '' -###################################################################### -### Create rundir and copy everything needed - -\rm -fr $rundir -mkdir -p $rundir -ln -sf $datadir/ICMGGa22e+000000 $rundir/. -ln -sf $datadir/*.txt $rundir/. -# Get SST and SIC -#if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then -if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then - ln -sf $datadir/forcing/siconcbcs*.nc $rundir/. - ln -sf $datadir/forcing/tosbcs*.nc $rundir/. - ln -sf $datadir/forcing/rmp_AMIP_to_L${ifs_grid}_GAUSWGT*.nc $rundir/. - if [ $amip_mode = co2 ]; then - ln -sf $datadir/co2/CO2-em-anthro_*.nc $rundir/. - ln -sf $datadir/co2/CO2-em-AIR-anthro_*.nc $rundir/. - ln -sf $datadir/co2/mole-fraction-of-carbon-dioxide-in-air_*.nc* $rundir/. - ln -sf $datadir/co2/rmp_CO2_emis_to_B${ifs_grid}_GAUSWGT*.nc $rundir/. - fi -else - ln -sf $datadir/$amip_mode/HadI*.nc $rundir/. - ln -sf $datadir/$amip_mode/rmp_PSIC_to_${ifs_grid}_GAUSWGT.nc $rundir/. - ln -sf $datadir/$amip_mode/rmp_PSST_to_${ifs_grid}_GAUSWGT.nc $rundir/. -fi -# Get grids and masks -if [ $model = fortran ] || [ $model = pythoncompat ]; then - cp -f $datadir/$amip_mode/masks.nc $rundir/. - cp -f $datadir/$amip_mode/grids.nc $rundir/. - cp -f $datadir/$amip_mode/areas.nc $rundir/. -else - cp -f $datadir/grids-noamip.nc $rundir/grids.nc - cp -f $datadir/masks-noamip.nc $rundir/masks.nc - cp -f $datadir/areas-noamip.nc $rundir/areas.nc -fi -cp -f $datadir/*.sh $rundir/. -cp -f $datadir/*.yaml $rundir/. -cp -f $source_exe1 $rundir/. -ln -sf $source_exe2 $rundir/. -cp -f $srcdir/*.py $rundir/. -cd $rundir - -### Generate namelist -leg_length_sec=$(( $(date -u -d "${leg_end_date}" +%s) - $(date -u -d "${leg_start_date}" +%s) )) -cpl_freq_amip_sec=86400 # Always -leg_start_date_yyyymmdd=$(date -u -d "${leg_start_date}" +%Y%m%d) - -if [ $model = fortran ] || [ $model = pythoncompat ]; then - if [ $amip_mode = forcing ]; then - . ./namelist.amip.sh > ./namelist.amip - else - . ./namelist_primavera.amip.sh > ./namelist.amip - - fi -else - #if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then - if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then - i=1 - ii=1 - if [ $model = co2box ] || [ $model = datacoupler ]; then - var=FileInputVars - else - var=Vars - fi - sst_conf_var=${var}"("$((i++))",:) = 'AMIP_sst_monthly', 'AMIP', 'AMIP_sst', 'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc', 'tosbcs', 1870, 2016, 'monthly', ${amip_interpolate}, 1, 273.15, 271.38, ,true,true," - sst_conf_var_yml="${var}("$((ii++))"): AMIP_sst_monthly, AMIP', AMIP_sst, tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, tosbcs, 1870, 2016, monthly, ${amip_interpolate}, 1, 273.15, 271.38, , true, true" - - sic_conf_var=${var}"("$((i++))",:) = 'AMIP_sic_monthly', 'AMIP', 'AMIP_sic', 'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc', 'siconcbcs', 1870, 2016, 'monthly', ${amip_interpolate}, 0.01, 0, 0, 1,true,true," - sic_conf_var_yml="${var}("$((ii++))"): AMIP_sic_monthly, AMIP, AMIP_sic, siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, siconcbcs, 1870, 2016, monthly, ${amip_interpolate}, 0.01, 0, 0, 1, true, true" - - j=1 - jj=1 - oasis_conf_var_yml="" - oasis_conf_var="!OasisOutputVars(j,:) = , , , , , \n" - oasis_conf_var=$'\n'"OasisOutputVars("$((j++))",:) = 'AMIP_sst', 'AMIP', 'daily', 1, 0, true," - oasis_conf_var_yml="OasisOutputVars("$((jj++))") : AMIP_sst, AMIP, daily, 1, 0, true"$'\n' - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = 'AMIP_sic', 'AMIP', 'daily', 1, 0, true," - oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : AMIP_sic, AMIP, daily, 1, 0, true"$'\n' - if [ $amip_mode = co2 ]; then - co2_conf_var="" - co2_conf_var+="!FileInputVars(i,:) = "$'\n' - #[ $model = co2box ] && mod=CO2BOX || mod=AMIP - if [ $model = co2box ] ; then - mod=CO2BOX - CO2_CMODE=true # set to false to disable co2 concentrations reading - CO2_EMODE=true # set to false to disable emissions reading - else - mod=AMIP - CO2_CMODE=false # don't change this! - CO2_EMODE=true # don't change this! - fi - #this fix is required to correctly read the co2 files which havereftime 0-1-1, which isn't supported by python netcdf4 - #cdo -R -setreftime,1849-01-01,00:00 mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod - #this fix is required to correctly read the CO2_em_monthly files which have a 365day calendar and also to convert from a grid point/sectors fields to a global one - #cdo -L -setcalendar,gregorian -fldsum -vertsum -mul CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc co2-area.nc CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc - if [ ${CO2_CMODE} == true ] ; then - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_cconc_monthly', 'GLOBAL', '"$mod"_CO2_cconc', 'mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod', 'mole_fraction_of_carbon_dioxide_in_air', 1849, 2014, 'monthly', ${co2_interpolate}, 1, 0, , ,true,true,"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_econc_monthly', 'GLOBAL', '"$mod"_CO2_econc', 'mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod', 'mole_fraction_of_carbon_dioxide_in_air', 1849, 2014, 'monthly', ${co2_interpolate}, 'co2_ppm_to_mass', 0, , ,false,false,"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_em_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 86400, 0, , ,true,true,"$'\n' - # add land/ocean fluxes equal to 0.5/0.1 that of emissions, for demonstration purposes - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_land_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 43200, 0, , ,true,true,"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_ocean_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 8640, 0, , ,true,true,"$'\n' - fi - if [ ${CO2_EMODE} == true ] ; then - # this is the 3D monthly emissions used for ECE4, the calendar fix mentionned below is probably required - co2_conf_var_yml="" - - - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_em_monthly', 'CO2_emis', '"$mod"_CO2_emis', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 1, 0, , ,true,true,"$'\n' - co2_conf_var_yml+="${var}("$((ii++))"): CO2_em_monthly, CO2_emis, "$mod"_CO2_emis, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 1, 0, , ,true,true"$'\n' - # add land/ocean fluxes equal to 0.5/0.1 that of emissions, for demonstration purposes - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_land_monthly', 'CO2_emis', '"$mod"_CO2_land', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.5, 0, , ,true,true,"$'\n' - co2_conf_var_yml+="${var}("$((ii++))"): CO2_land_monthly, CO2_emis, "$mod"_CO2_land, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 0.5, 0, , , true, true"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_ocean_monthly', 'CO2_emis', '"$mod"_CO2_ocean', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.1, 0, , ,true,true,"$'\n' - co2_conf_var_yml+="${var}("$((ii++))"): CO2_ocean_monthly, CO2_emis, "$mod"_CO2_ocean, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 0.1, 0, , ,true,true" - - - - fi - #OasisOutputVars(i,:) = - if [ ${CO2_CMODE} == true ] ; then - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_cconc', 'GLOBAL', 'daily', 1, 0, true," - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_econc', 'GLOBAL', 'daily', 'co2_mass_to_ppm', 0, false," - fi - if [ ${CO2_EMODE} == true ] ; then - # this is the 3D monthly emissions used for ECE4 - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_emis', 'CO2_emis', 'daily', 1, 0, true," - oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_emis, CO2_emis, daily, 1, 0, true"$'\n' - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_land', 'CO2_emis', 'daily', 1, 0, true," - oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_land, CO2_emis, daily, 1, 0, true"$'\n' - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_ocean', 'CO2_emis', 'daily', 1, 0, true," - oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_ocean, CO2_emis, daily, 1, 0, true" - fi - else - co2_conf_var="" - fi - else - sst_conf_var="Vars(1,:) = 'AMIP_sst_daily', 'PSST', 'AMIP_sst', 'HadISST2_prelim_0to360_alldays_sst_[year].nc', 'sst', 1850, 2016, 'daily', false, 1, 0, , ," - sic_conf_var="Vars(2,:) = 'AMIP_sic_daily', 'PSIC', 'AMIP_sic', 'HadISST2_prelim_0to360_alldays_sic_[year].nc', 'sic', 1850, 2016, 'daily', false, 1, 0, , ," - co2_conf_var="" - oasis_conf_var="" - fi - . ./namelist_python.amip.sh > ./namelist.amip - - # Create the name of the experiment conf yaml based on the OasisCPLNG name in template yaml - #yaml_conf_name=$(grep -F "ModelNameReceive" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' - yaml_conf_name='DataCoupler_exp_conf.yaml' - - . ./$yaml_conf_file > $yaml_conf_name - - [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box -fi -if [ $amip_mode = forcing ]; then - - input="namcouple_empty.yaml" - namcouple_output="namcouple" - toy_model_yaml_conf_output="yaml_conf_name_ifs_toy_model.yaml" - - # Run the py namcouple creator - $py_script --conf $yaml_conf_name --namcouple_output $namcouple_output --toy_model_yaml_conf_output $toy_model_yaml_conf_output - - -elif [ $amip_mode = co2 ]; then - [ $model = co2box ] && . ./namcouple_co2box.sh > ./namcouple || . ./namcouple_co2.sh > ./namcouple -else - . ./namcouple_primavera.sh > ./namcouple -fi - -# Creating namcouple with python - - - -###################################################################### -### Definition of mpirun command and batch script - -echo 'Executing the model using mpirun : ${MPIRUN}' - -# To seprate the DataCoupler with YAML input file from legecy codes -if [ $model = datacoupler ] ; then - if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then - ${MPIRUN} -np $nproc_exe1 $exe1 --conf $yaml_conf_name : -np $nproc_exe2 $exe2 --conf $yaml_conf_name - fi -else - ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 -fi - - -# convert output -. convert-ece4pyreader-grids.sh ${leg_start_date} - -#echo $casename 'is executed or submitted to queue.' -echo 'Results are found in rundir : '$rundir -echo 'Run Example is successfully executed' - -###################################################################### diff --git a/tests/toy_model_2.py b/tests/toy_model_2.py deleted file mode 100644 index 0c10ff3..0000000 --- a/tests/toy_model_2.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2023 - Barcelona Supercomputing Center -# Author: Rodrigo Martín Posada (2021), updated by : Amirpasha Mozaffari (2023) -# TBD - -import yaml -from yaml.loader import SafeLoader -import logging -import argparse -import os - -import pyoasis -from pyoasis import OASIS # pylint: disable=no-name-in-module -import numpy as np - - - -def def_local_partition(nx, npes, mype): - il_size = nx // npes - il_offset = mype * il_size - if (npes-mype) <= nx % npes: - il_size += 1 - il_offset += (nx % npes) - (npes-mype) - return il_size, il_offset - - -def variable_exists(var_name): - return var_name in globals() - - - - - - -if __name__ == '__main__': - -### Read in YAML file - current_path = os.getcwd() - parser=argparse.ArgumentParser() - #parser.add_argument("--run_dir",type=str) - parser.add_argument("--conf",type=str) - args = parser.parse_args() - yamel_file_path = os.path.join(current_path,args.conf) - - if os.path.isfile(yamel_file_path) == False: - print("YAML file does not exist. Aborted") - raise NameError("YAML file does not exist.") - - # Open the file and load the file - with open(yamel_file_path) as f: - read_in_data = yaml.load(f, Loader=SafeLoader) - f.close() - -### Read in file - #read_yaml(read_in_data) - model = read_in_data.get("model") - model_name = model.get("ModelName") - - # Read in Simulation information - simulation = read_in_data.get("simulation") - simulation_coupling_interval = simulation.get("coupling_interval") - simulation_run_length_sec = simulation.get("run_length_sec") - simulation_nx = simulation.get("nx") - - # Read in Coupling infomration - coupling = read_in_data.get("coupling") - coupling_out_vars = coupling.get("out_vars") - coupling_in_vars = coupling.get("in_vars") - restart_file = coupling.get("restart_file") # This feature is not used for now. TODO - -### Pass the values to original code - - # Init OASIS - comp = pyoasis.Component(model_name) - local_comm = comp.localcomm - # Get rank in local communicator - mype = comp.localcomm.rank - npes = comp.localcomm.size - - # BUG : shouldnt it be the npes and not mpye (?) - mype_value = str(100+mype) - out_model = '{model_name}.out_{mype_value}'.format(model_name = model_name, mype_value = mype_value) - - logging.basicConfig(filename=out_model, format='%(message)s', level=logging.DEBUG) - logging.debug('-----------------------------------------------------------') - logging.info('I am {model_name} process with rank : {mype}'.format(model_name = model_name, - mype = mype)) - #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) - logging.debug('in my local communicator gathering {} processes'.format(npes)) - logging.debug('----------------------------------------------------------') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # PARTITION DEFINITION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - # Definition of the local partition - il_size, il_offset = def_local_partition(simulation_nx, npes, mype) - logging.debug('Local partition definition') - logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) - partition = pyoasis.ApplePartition(il_offset, il_size) - #partition = pyoasis.SerialPartition(simulation_nx) - # if npes > 1: - # il_size, il_offset = def_local_partition(nx, npes, mype) - # logging.debug('Local partition definition') - # logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) - # partition = pyoasis.ApplePartition(il_offset, il_size) - # else: - # partition = pyoasis.SerialPartition(nx) - - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # DECLARATION OF THE COUPLING FIELDS - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - # out_coupling_fields={} - - # for v in coupling_out_vars: - # out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) - # logging.warning('var_id {}, added as OASIS_OUT var'.format(v)) - - in_coupling_fields = {} # Create a dictionary to store the variables - - for name in coupling_in_vars: - var = pyoasis.Var(name, partition, OASIS.IN) - in_coupling_fields[name] = var - logging.debug('var_id {}: {}'.format(name, var._id)) - - # in_coupling_fields={} - - # for v in coupling_in_vars: - # in_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.IN) - # logging.debug('var_id {}: {}'.format(name, var._id)) - # logging.info('var_id {}, added as OASIS_IN var'.format(v)) - - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION OF DEFINITION PHASE - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of initialisation phase') - - comp.enddef() - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TIME STEP LOOP - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('Timestep, field min, mean and max value') - - field_data = pyoasis.asarray(np.full(simulation_nx, -1.0)) - - for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): - - logging.debug('ITAP_SEC: {} receiving fields'.format(itap_sec)) - logging.debug(str(in_coupling_fields.keys())) - for id, field in in_coupling_fields.items(): - field.get(itap_sec, field_data) - logging.debug('{} -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(field_data), np.mean(field_data), np.max(field_data))) - logging.debug('--------------------------------------\n') - - logging.debug('ITAP_SEC: {} sending fields'.format(itap_sec)) - logging.debug(str(out_coupling_fields.keys())) - for id, field in out_coupling_fields.items(): - sigma=1 - mu=1 - # send dummy data (100 for runoff, random for other variables) - #TODO send dummy data read from oasis restart file - if id == "A_Runoff": - field_data[:]=1.4658e-06 - field_data[:]=100 - else: - field_data[:]=sigma * np.random.randn(simulation_nx) + mu - field.put(itap_sec, field_data) - logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(field_data), np.mean(field_data), np.max(field_data))) - logging.debug('--------------------------------------\n') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of the program') - - print('Model {} is finished successfully.'.format(model_name)) - - del comp - - - -- GitLab From 17e7786cb0ac319ec66ebc7c9311dc590a538b42 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 6 Sep 2023 11:46:57 +0200 Subject: [PATCH 34/39] Resolved issue: Eliminating hard-coded MPI process type for partitioning, ensuring non-empty out_coupling_vars, and and no dependency on MPI num_processes. --- sources/ece3-toy-model/toy_model.py | 81 +++++++++++++---------------- tests/launch_ece3_toy_model_mn4.cmd | 2 +- tests/run_example.sh | 2 - 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/sources/ece3-toy-model/toy_model.py b/sources/ece3-toy-model/toy_model.py index ff89349..2f92a65 100644 --- a/sources/ece3-toy-model/toy_model.py +++ b/sources/ece3-toy-model/toy_model.py @@ -2,7 +2,6 @@ # Copyright 2023 - Barcelona Supercomputing Center # Author: Rodrigo Martín Posada (2021), updated by : Amirpasha Mozaffari (2023) # TBD -# note: merged for both datacoupler and toy-model import yaml from yaml.loader import SafeLoader @@ -87,37 +86,37 @@ if __name__ == '__main__': # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # PARTITION DEFINITION # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # for more than one processor is using a parallel partition and for single processor a serial if npes > 1: il_size, il_offset = def_local_partition(simulation_nx, npes, mype) logging.debug('Local partition definition') logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) partition = pyoasis.ApplePartition(il_offset, il_size) - par_type="Apple" + field_data_size = il_size + logging.debug('Grid points in the current Apple - partition is: {},'.format(field_data_size)) else: partition = pyoasis.SerialPartition(simulation_nx) - par_type="Serial" - - out_coupling_fields={} - - for v in coupling_out_vars: - out_coupling_fields[v] = pyoasis.Var(v, partition, OASIS.OUT) - logging.debug('var_id {}, added as OASIS_OUT var'.format(v)) + field_data_size = simulation_nx + logging.debug('Grid points in the current Serial - partition is: {},'.format(field_data_size)) - + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # DECLARATION OF THE COUPLING FIELDS # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - + + out_coupling_fields={} in_coupling_fields = {} # Create a dictionary to store the variables - for name in coupling_in_vars: - var = pyoasis.Var(name, partition, OASIS.IN) - in_coupling_fields[name] = var - logging.debug('var_id {}: {}'.format(name, var._id)) - + for name in coupling_out_vars: + out_coupling_fields[name] = pyoasis.Var(name, partition, OASIS.OUT) + logging.debug('var_id {}, added as OASIS_OUT var'.format(name)) + for name in coupling_in_vars: + in_coupling_fields[name] = pyoasis.Var(name, partition, OASIS.IN) + logging.debug('var_id {}, added as OASIS_IN var'.format(name)) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # TERMINATION OF DEFINITION PHASE # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -130,38 +129,32 @@ if __name__ == '__main__': # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.debug('Timestep, field min, mean and max value') + fields = {} + fields = pyoasis.asarray(np.full(field_data_size, -1.0)) - if npes > 1: - fields = {} - - for name in coupling_in_vars: - fields[name] = pyoasis.asarray(np.full(il_size, -1.0)) - - for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): - for name in coupling_in_vars: - in_coupling_fields[name].get(itap_sec, fields[name]) - - else: - fields = {} - fields = pyoasis.asarray(np.full(simulation_nx, -1.0)) + for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): + logging.debug('ITAP_SEC: {} receiving fields'.format(itap_sec)) + logging.debug(str(in_coupling_fields.keys())) - for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): - for id, field in in_coupling_fields.items(): - field.get(itap_sec, fields) + for id, field in in_coupling_fields.items(): + field.get(itap_sec, fields) + logging.debug('{} -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(fields), np.mean(fields), np.max(fields))) - for id, field in out_coupling_fields.items(): - sigma=1 - mu=1 - # send dummy data (100 for runoff, random for other variables) - #TODO send dummy data read from oasis restart file - if id == "A_Runoff": - fields[:]=1.4658e-06 - fields[:]=100 - else: - fields[:]=sigma * np.random.randn(simulation_nx) + mu - field.put(itap_sec, fields) + for id, field in out_coupling_fields.items(): + sigma=1 + mu=1 + # send dummy data (100 for runoff, random for other variables) + #TODO send dummy data read from oasis restart file + + if id == "A_Runoff": + fields[:]=1.4658e-06 + fields[:]=100 + else: + fields[:]=sigma * np.random.randn(simulation_nx) + mu + field.put(itap_sec, fields) + logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(fields), np.mean(fields), np.max(fields))) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/tests/launch_ece3_toy_model_mn4.cmd b/tests/launch_ece3_toy_model_mn4.cmd index bba5b19..06fd41c 100755 --- a/tests/launch_ece3_toy_model_mn4.cmd +++ b/tests/launch_ece3_toy_model_mn4.cmd @@ -5,7 +5,7 @@ #SBATCH -N 1 #SBATCH -n 3 #SBATCH -c 1 -#SBATCH -t 1:00:00 +#SBATCH -t 0:05:00 #SBATCH --exclusive #load python and netcdf modules diff --git a/tests/run_example.sh b/tests/run_example.sh index 95e278d..5429dd9 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -30,8 +30,6 @@ user=`whoami` srcdir=`pwd` datadir=$srcdir/data -#exe1='python3 general_toy_model.py' -#source_exe1=$srcdir/general_toy_model.py exe1='python3 toy_model.py' toy_model_dir=$srcdir/../sources/ece3-toy-model -- GitLab From 7282cb9ac458d5f4b5dd52931c6c9183d7991606 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Fri, 8 Sep 2023 10:07:57 +0200 Subject: [PATCH 35/39] fix : Using two dictionaries to for send/receive fields in toy_model --- sources/ece3-toy-model/toy_model.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/sources/ece3-toy-model/toy_model.py b/sources/ece3-toy-model/toy_model.py index 2f92a65..adfd1bd 100644 --- a/sources/ece3-toy-model/toy_model.py +++ b/sources/ece3-toy-model/toy_model.py @@ -104,16 +104,21 @@ if __name__ == '__main__': # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # DECLARATION OF THE COUPLING FIELDS # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - + out_field_data = pyoasis.asarray(np.full(field_data_size, -1.0)) out_coupling_fields={} + in_coupling_fields = {} # Create a dictionary to store the variables + in_field_data={} for name in coupling_out_vars: - out_coupling_fields[name] = pyoasis.Var(name, partition, OASIS.OUT) + var = pyoasis.Var(name, partition, OASIS.OUT) + out_coupling_fields[name] = var logging.debug('var_id {}, added as OASIS_OUT var'.format(name)) for name in coupling_in_vars: - in_coupling_fields[name] = pyoasis.Var(name, partition, OASIS.IN) + var = pyoasis.Var(name, partition, OASIS.IN) + in_coupling_fields[name] = var + in_field_data[name] = pyoasis.asarray(np.full(field_data_size, -1.0)) logging.debug('var_id {}, added as OASIS_IN var'.format(name)) @@ -129,9 +134,6 @@ if __name__ == '__main__': # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.debug('Timestep, field min, mean and max value') - fields = {} - fields = pyoasis.asarray(np.full(field_data_size, -1.0)) - for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): logging.debug('ITAP_SEC: {} receiving fields'.format(itap_sec)) @@ -139,8 +141,8 @@ if __name__ == '__main__': for id, field in in_coupling_fields.items(): - field.get(itap_sec, fields) - logging.debug('{} -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(fields), np.mean(fields), np.max(fields))) + field.get(itap_sec, in_field_data[id]) + logging.debug('{} -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(in_field_data[id]), np.mean(in_field_data[id]), np.max(in_field_data[id]))) for id, field in out_coupling_fields.items(): sigma=1 @@ -149,12 +151,12 @@ if __name__ == '__main__': #TODO send dummy data read from oasis restart file if id == "A_Runoff": - fields[:]=1.4658e-06 - fields[:]=100 + out_field_data[:]=1.4658e-06 + out_field_data[:]=100 else: - fields[:]=sigma * np.random.randn(simulation_nx) + mu - field.put(itap_sec, fields) - logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(fields), np.mean(fields), np.max(fields))) + out_field_data[:]=sigma * np.random.randn(simulation_nx) + mu + field.put(itap_sec, out_field_data) + logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(out_field_data), np.mean(out_field_data), np.max(out_field_data))) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- GitLab From 361b9b822de32f5bf59f33a3b5016120f86dbb55 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Tue, 12 Sep 2023 16:32:51 +0200 Subject: [PATCH 36/39] Fixing all the issues that were raised in mr4. Also, preparing for future development: co2box & co2flux. --- sources/data-coupler/DataCoupler.py | 3 +- sources/data-coupler/DataCouplerUtils.py | 2 - sources/ece3-toy-model/toy_model.py | 6 +- tests/data/IFS_toy.py | 166 +++++++++++++++++ tests/data/launch_generate_yml.sh | 23 --- tests/data/namcouple | 28 --- tests/data/namcouple_2line.sh | 36 ---- tests/data/namelist_python.amip.sh | 18 -- tests/data/namelist_python.amip_yaml.sh | 19 -- .../template_conf_datacoupler_forcing.yaml | 2 +- tests/launch-mn4.cmd | 28 --- tests/launch_ece3_data_coupler_mn4.cmd | 34 +++- tests/launch_ece3_toy_model_mn4.cmd | 10 +- tests/run_example.sh | 167 ++++------------- tests/toy_model.py | 168 ++++++++++++++++++ 15 files changed, 396 insertions(+), 314 deletions(-) create mode 100644 tests/data/IFS_toy.py delete mode 100755 tests/data/launch_generate_yml.sh delete mode 100644 tests/data/namcouple delete mode 100755 tests/data/namcouple_2line.sh delete mode 100755 tests/data/namelist_python.amip.sh delete mode 100755 tests/data/namelist_python.amip_yaml.sh delete mode 100644 tests/launch-mn4.cmd create mode 100644 tests/toy_model.py diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index f9052e1..1b19bfb 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -23,7 +23,8 @@ class DataCoupler: def __init__(self,yaml_conf_file): ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ - StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_DataCoupler_yaml_input(yaml_conf_file) + StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin , \ + = read_DataCoupler_yaml_input(yaml_conf_file) if LDebug: logging.basicConfig(filename=LogFileName, format='%(message)s', level=logging.DEBUG) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 99fd148..99e75fb 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -222,13 +222,11 @@ def read_namelist(NAMELIST_FILE_NAME,NAMELIST_SECTION): raise Exception('DataCoupler: Invalid configuration ids, all ids must be unique') else: oasisOut_vars_config = None - return RunLengthSec, TimeStepSec, StartYear, StartMonth, StartDay, FixYear, LDebug, fileIn_vars_config, oasisOut_vars_config ## YAMLUtil - # Read the DataCoupler YAML def read_DataCoupler_yaml_input(yaml_file): diff --git a/sources/ece3-toy-model/toy_model.py b/sources/ece3-toy-model/toy_model.py index adfd1bd..3937b7e 100644 --- a/sources/ece3-toy-model/toy_model.py +++ b/sources/ece3-toy-model/toy_model.py @@ -22,10 +22,6 @@ def def_local_partition(nx, npes, mype): return il_size, il_offset -def variable_exists(var_name): - return var_name in globals() - - if __name__ == '__main__': ### Read in YAML file @@ -154,7 +150,7 @@ if __name__ == '__main__': out_field_data[:]=1.4658e-06 out_field_data[:]=100 else: - out_field_data[:]=sigma * np.random.randn(simulation_nx) + mu + out_field_data[:]=sigma * np.random.randn(field_data_size) + mu field.put(itap_sec, out_field_data) logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(out_field_data), np.mean(out_field_data), np.max(out_field_data))) diff --git a/tests/data/IFS_toy.py b/tests/data/IFS_toy.py new file mode 100644 index 0000000..85f03b6 --- /dev/null +++ b/tests/data/IFS_toy.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python3 +# Copyright 2021 - Barcelona Supercomputing Center +# Author: Rodrigo Martín Posada +# MIT License + +import f90nml +import pyoasis +from pyoasis import OASIS # pylint: disable=no-name-in-module +import numpy as np +import logging + +NAMELIST_FILE_NAME = 'namelist.amip' +L080_NX = 35718 # number of grid cells at T159 resolution +L128_NX = 88838 # number of grid cells at T255 resolution +L256_NX = 348528 # number of grid cells at T511 resolution +CO2_CMODE = False # is CO2 concentration-mode active? +CO2_EMODE = False # is CO2 emission-mode active? + + +def def_local_partition(nx, npes, mype): + il_size = nx // npes + il_offset = mype * il_size + if (npes-mype) <= nx % npes: + il_size += 1 + il_offset += (nx % npes) - (npes-mype) + return il_size, il_offset + + +if __name__ == '__main__': + # Constants from namelist + nml = f90nml.read(NAMELIST_FILE_NAME) + COUPLING_INTERVAL = nml['NAMAMIP']['TimeStepSec'] + RUN_LENGTH_SEC = nml['NAMAMIP']['RunLengthSec'] + + # Init OASIS + comp = pyoasis.Component("IFS_TOY") + local_comm = comp.localcomm + # Get rank in local communicator + mype = comp.localcomm.rank + npes = comp.localcomm.size + + # Unit for output messages + out_ifs = 'IFS_toy.out_'+str(100+mype) + logging.basicConfig(filename=out_ifs, format='%(message)s', level=logging.DEBUG) + logging.debug('-----------------------------------------------------------') + logging.debug('I am IFS-toy process with rank : {}'.format(mype)) + logging.debug('in my local communicator gathering {} processes'.format(npes)) + logging.debug('----------------------------------------------------------') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # PARTITION DEFINITION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + with open('namcouple', 'r') as f: + #contents = f.read() + contents = "" + for line in f: + li=line.strip() + if not li.startswith("#"): + contents += line + # TODOD find a better way to detect CO2_CMODE + if 'GLOBAL GLOBAL' in contents: + CO2_CMODE = True + if 'A_CO2_emis ' in contents: + CO2_EMODE = True + if 'L080' in contents: + nx = L080_NX + elif 'L128' in contents: + nx = L128_NX + elif 'L256' in contents: + nx = L256_NX + else: + raise Exception('Invalid IFS grid in namcouple') + # Definition of the local partition + il_size, il_offset = def_local_partition(nx, npes, mype) + logging.debug('Local partition definition') + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + partition = pyoasis.ApplePartition(il_offset, il_size) + if CO2_CMODE or CO2_EMODE: + #nx_co2 = 2 # for 2 hemisphere box model + nx_co2 = 1 + if mype == 0: + logging.debug('Local serial partition') + logging.debug('nx_co2 = {} mype = {}'.format(nx_co2, mype)) + partition2 = pyoasis.SerialPartition(nx_co2) + else: + nx_co2 = 0 + partition2 = None + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # DECLARATION OF THE COUPLING FIELDS + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + A_SST = pyoasis.Var("A_SST", partition, OASIS.IN) + A_Ice_frac = pyoasis.Var("A_Ice_frac", partition, OASIS.IN) + logging.debug('var_id A_SST, var_id A_Ice_frac {} {}'.format(A_SST._id, A_Ice_frac._id)) + if CO2_CMODE: + if mype == 0: + A_CO2_cconc = pyoasis.Var("A_CO2_cconc", partition2, OASIS.IN) + logging.debug('var_id A_CO2_cconc {}'.format(A_CO2_cconc._id)) + A_CO2_econc = pyoasis.Var("A_CO2_econc", partition2, OASIS.IN) + logging.debug('var_id A_CO2_econc {}'.format(A_CO2_cconc._id)) + if CO2_EMODE: + A_CO2_emis = pyoasis.Var("A_CO2_emis", partition, OASIS.IN) + logging.debug('var_id A_CO2_emis {}'.format(A_CO2_emis._id)) + A_CO2_land = pyoasis.Var("A_CO2_land", partition, OASIS.IN) + logging.debug('var_id A_CO2_land {}'.format(A_CO2_land._id)) + A_CO2_ocean = pyoasis.Var("A_CO2_ocean", partition, OASIS.IN) + logging.debug('var_id A_CO2_ocean {}'.format(A_CO2_ocean._id)) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION OF DEFINITION PHASE + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of initialisation phase') + + comp.enddef() + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TIME STEP LOOP + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('Timestep, field min, mean and max value') + + field_recv_A_SST = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_Ice_frac = pyoasis.asarray(np.full(il_size, -1.0)) + if CO2_CMODE and mype == 0: + field_recv_A_CO2_cconc = pyoasis.asarray(np.full(nx_co2, -1.0)) + field_recv_A_CO2_econc = pyoasis.asarray(np.full(nx_co2, -1.0)) + if CO2_EMODE: + field_recv_A_CO2_emis = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_CO2_land = pyoasis.asarray(np.full(il_size, -1.0)) + field_recv_A_CO2_ocean = pyoasis.asarray(np.full(il_size, -1.0)) + + for itap_sec in range(0, RUN_LENGTH_SEC, COUPLING_INTERVAL): + A_SST.get(itap_sec, field_recv_A_SST) + A_Ice_frac.get(itap_sec, field_recv_A_Ice_frac) + + logging.debug('ITAP_SEC: {}'.format(itap_sec)) + logging.debug('A_SST -> {:.3e} {:.3e} {:.3e}'.format( + np.min(field_recv_A_SST), + np.mean(field_recv_A_SST), + np.max(field_recv_A_SST))) + logging.debug('A_Ice_frac -> {:.3e} {:.3e} {:.3e}'.format( + np.min(field_recv_A_Ice_frac), + np.mean(field_recv_A_Ice_frac), + np.max(field_recv_A_Ice_frac))) + if CO2_CMODE: + if mype == 0: + A_CO2_cconc.get(itap_sec, field_recv_A_CO2_cconc) + logging.debug('A_CO2_cconc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_cconc), np.mean(field_recv_A_CO2_cconc), np.max(field_recv_A_CO2_cconc))) + A_CO2_econc.get(itap_sec, field_recv_A_CO2_econc) + logging.debug('A_CO2_econc -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_econc), np.mean(field_recv_A_CO2_econc), np.max(field_recv_A_CO2_econc))) + if CO2_EMODE: + A_CO2_emis.get(itap_sec, field_recv_A_CO2_emis) + logging.debug('A_CO2_emis -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_emis), np.mean(field_recv_A_CO2_emis), np.max(field_recv_A_CO2_emis))) + A_CO2_land.get(itap_sec, field_recv_A_CO2_land) + logging.debug('A_CO2_land -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_land), np.mean(field_recv_A_CO2_land), np.max(field_recv_A_CO2_land))) + A_CO2_ocean.get(itap_sec, field_recv_A_CO2_ocean) + logging.debug('A_CO2_ocean -> {:.3e} {:.3e} {:.3e}'.format( np.min(field_recv_A_CO2_ocean), np.mean(field_recv_A_CO2_ocean), np.max(field_recv_A_CO2_ocean))) + logging.debug('--------------------------------------\n') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of the program') + + del comp diff --git a/tests/data/launch_generate_yml.sh b/tests/data/launch_generate_yml.sh deleted file mode 100755 index a79780e..0000000 --- a/tests/data/launch_generate_yml.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# slurm specific options for Marenostrum4 -#SBATCH --qos=debug -#SBATCH -N 1 -#SBATCH -n 3 -#SBATCH -c 1 -#SBATCH -t 1:00:00 -#SBATCH --exclusive - -#load python and netcdf modules -export PYTHONPATH="" -module load intel/2017.4 -module load intel/2017.4 -module load python/3.6.1 -module load netcdf/4.2 -module load CDO/1.9.3 -module list -export MPIRUN="mpirun" - - -# run IFS+NEMO+runoff toy model -mpirun -np 1 python3 generate_yaml.py --model_name datacoupler --template_name template_amip.yaml --file_name exp1_aimp.yaml --leg_length_sec 5097600 --cpl_freq_amip_sec 86400 --StartYear 2005 --StartMonth 01 --StartDay 01 --FixYear 0 diff --git a/tests/data/namcouple b/tests/data/namcouple deleted file mode 100644 index b3f68b7..0000000 --- a/tests/data/namcouple +++ /dev/null @@ -1,28 +0,0 @@ -# ================================================================================================= -# General OASIS configuration -# ================================================================================================= - $NFIELDS - 1 - $END -# ------------------------------------------------------------------------------------------------- - $RUNTIME - 5097600 - $END -# ------------------------------------------------------------------------------------------------- - $NLOGPRT - 0 0 - $END -# ------------------------------------------------------------------------------------------------- - $STRINGS -# ================================================================================================= -# Fields send from AMIP to IFS -# ================================================================================================= -# --- AMIP forcing data --- [ifs amip] - AMIP_sst:AMIP_sic A_SST:A_Ice_frac 1 86400 1 rstas.nc EXPOUT - AMIP L128 LAG=0 - P 0 P 0 - SCRIPR - GAUSWGT LR SCALAR LATITUDE 1 9 2.0 -# ------------------------------------------------------------------------------------------------- - $END -# ================================================================================================= diff --git a/tests/data/namcouple_2line.sh b/tests/data/namcouple_2line.sh deleted file mode 100755 index 6150ed3..0000000 --- a/tests/data/namcouple_2line.sh +++ /dev/null @@ -1,36 +0,0 @@ -cat << EOF -# ================================================================================================= -# General OASIS configuration -# ================================================================================================= - \$NFIELDS - 1 - \$END -# ------------------------------------------------------------------------------------------------- - \$RUNTIME - ${leg_length_sec} - \$END -# ------------------------------------------------------------------------------------------------- - \$NLOGPRT - 0 0 - \$END -# ------------------------------------------------------------------------------------------------- - \$STRINGS -# ================================================================================================= -# Fields send from AMIP to IFS -# ================================================================================================= -# --- AMIP forcing data --- [ifs amip] - AMIP_sst A_SST 1 86400 1 rstas.nc EXPOUT - AMIP L${ifs_grid} LAG=0 - P 0 P 0 - SCRIPR - GAUSWGT LR SCALAR LATITUDE 1 9 2.0 - - AMIP_sic A_Ice_frac 1 86400 1 rstas.nc EXPOUT - AMIP L${ifs_grid} LAG=0 - P 0 P 0 - SCRIPR - GAUSWGT LR SCALAR LATITUDE 1 9 2.0 -# ------------------------------------------------------------------------------------------------- - \$END -# ================================================================================================= -EOF diff --git a/tests/data/namelist_python.amip.sh b/tests/data/namelist_python.amip.sh deleted file mode 100755 index d135769..0000000 --- a/tests/data/namelist_python.amip.sh +++ /dev/null @@ -1,18 +0,0 @@ -cat << EOF -!----------------------------------------------------------------------- -&NAMAMIP -!----------------------------------------------------------------------- - RunLengthSec = ${leg_length_sec} - TimeStepSec = ${cpl_freq_amip_sec} - StartYear = ${leg_start_date_yyyymmdd:0:4} - StartMonth = ${leg_start_date_yyyymmdd:4:2} - StartDay = ${leg_start_date_yyyymmdd:6:2} - FixYear = ${ifs_cmip_fixyear} -${sst_conf_var} -${sic_conf_var} -${co2_conf_var} -${oasis_conf_var} - LDebug = false -!----------------------------------------------------------------------- -/ -EOF diff --git a/tests/data/namelist_python.amip_yaml.sh b/tests/data/namelist_python.amip_yaml.sh deleted file mode 100755 index 8d8046e..0000000 --- a/tests/data/namelist_python.amip_yaml.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - - -cat << EOF -# YAML file input - -RunLengthSec : ${leg_length_sec} -TimeStepSec : ${cpl_freq_amip_sec} -StartYear : ${leg_start_date_yyyymmdd:0:4} -StartMonth : ${leg_start_date_yyyymmdd:4:2} -StartDay : ${leg_start_date_yyyymmdd:6:2} -FixYear : ${ifs_cmip_fixyear} -$sst_conf_var_yml -$sic_conf_var_yml -$co2_conf_var_yml -$oasis_conf_var_yml -LDebug : false - -EOF diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml index 3a6cfc9..0513c92 100755 --- a/tests/data/template_conf_datacoupler_forcing.yaml +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -8,7 +8,7 @@ type : 1 # DataCoupler is 1, ToyModel is 2 ModelNameSend : AMIPFORC ModelNameReceive : IFS_TOY LogFileName : amip.log -YamlConfName : ${yaml_conf_name} +YamlConfName : ${yaml_conf_file} PartitionType : ApplePartition ## Run Information diff --git a/tests/launch-mn4.cmd b/tests/launch-mn4.cmd deleted file mode 100644 index 58fd6d9..0000000 --- a/tests/launch-mn4.cmd +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -#SBATCH --qos=debug -#SBATCH -N 1 -#SBATCH -n 5 -#SBATCH -c 1 -#SBATCH -t 0:05:00 -#SBATCH --exclusive - -module load python/3.6.1 -module load netcdf/4.2 -module load CDO/1.9.3 -module list -export MPIRUN="mpirun" - -source ../sources/oasis3-mct/generated/python/init.sh - -#bash ./run_example.sh pythoncompat forcing 4 2005-01-01 2005-03-01 0 128 true -#bash ./run_example.sh fortran forcing 4 2005-01-01 2005-03-01 0 128 true -#bash ./run_example-t1279.sh python forcing 4 2010-01-01 2010-03-01 0 128 true - -#bash ./run_example.sh datacoupler co2 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_co2.yaml -#bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true false - -bash ./run_example.sh datacoupler forcing 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_forcing.yaml -#bash ./run_example.sh python co2 4 2005-01-01 2005-03-01 0 128 true -#bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true -#bash ./run_example.sh co2box co2 4 2005-01-01 2005-03-01 0 128 true false -#bash ./run_example.sh co2box co2 4 2005-01-01 2005-05-01 0 128 true false diff --git a/tests/launch_ece3_data_coupler_mn4.cmd b/tests/launch_ece3_data_coupler_mn4.cmd index 834c568..cbba3bc 100644 --- a/tests/launch_ece3_data_coupler_mn4.cmd +++ b/tests/launch_ece3_data_coupler_mn4.cmd @@ -1,21 +1,37 @@ #!/bin/bash - -# slurm specific options for Marenostrum4 #SBATCH --qos=debug #SBATCH -N 1 #SBATCH -n 5 #SBATCH -c 1 #SBATCH -t 0:05:00 #SBATCH --exclusive +# Please indicate the machine that is in use. for now only includes "BSC_MN4" & "EC_HPC2020" +platform="BSC_MN4" + +if [ $platform = BSC_MN4 ]; then + # slurm specific options for Marenostrum4 + + module load python/3.6.1 + module load netcdf/4.2 + module load CDO/1.9.3 + module list + export MPIRUN="mpirun" + source ../sources/oasis3-mct/generated/python/init.sh + +elif [ $platform = EC_HPC2020 ] ; then + + module reset + #module load python3/3.8.8-01 prgenv/intel intel/2021.4.0 intel-mkl/19.0.5 hpcx-openmpi/2.9.0 hdf5-parallel/1.10.6 netcdf4-parallel/4.7.4 cdo + module load python3/3.10.10-01 prgenv/intel intel/2021.4.0 hpcx-openmpi/2.9.0 hdf5-parallel/1.12.2 netcdf4-parallel/4.9.1 cdo + module list + export MPIRUN="mpirun -oversubscribe" + source ../sources/oasis3-mct/generated/python/init.sh + export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${NETCDF4_PARALLEL_DIR}/lib:${ECCODES_DIR}/lib:${HDF5_DIR}/lib" + echo LD_LIBRARY_PATH: $LD_LIBRARY_PATH -#load python and netcdf modules -module load python/3.6.1 -module load netcdf/4.2 -module load CDO/1.9.3 -module list -export MPIRUN="mpirun" +fi -source ../sources/oasis3-mct/generated/python/init.sh +#source ../sources/oasis3-mct/generated/python/init.sh #bash ./run_example.sh pythoncompat forcing 4 2005-01-01 2005-03-01 0 128 true #bash ./run_example.sh fortran forcing 4 2005-01-01 2005-03-01 0 128 true diff --git a/tests/launch_ece3_toy_model_mn4.cmd b/tests/launch_ece3_toy_model_mn4.cmd index 06fd41c..f554c88 100755 --- a/tests/launch_ece3_toy_model_mn4.cmd +++ b/tests/launch_ece3_toy_model_mn4.cmd @@ -13,14 +13,10 @@ export PYTHONPATH="" module load python/3.6.1 module load netcdf/4.2 -#set -xuve +set -xuve # setup pyOasis environment -export PYOASIS_ROOT=/gpfs/scratch/bsc32/bsc32051/git/python-amip-reader/sources/oasis3-mct/generated -export LD_LIBRARY_PATH=${PYOASIS_ROOT}/lib:${LD_LIBRARY_PATH} -export PYTHONPATH=${PYOASIS_ROOT}/python:${PYTHONPATH} -export MPIRUN4PY="mpirun" - +source ../sources/oasis3-mct/generated/python/init.sh ## timestamp=$(date +%Y%m%d_%H%M%S) @@ -51,5 +47,5 @@ echo "prep is finished" cd $rundir # run IFS+NEMO+runoff toy model -mpirun -np 1 python3 $rundir/$toy_model --conf ifs_toy_model.yaml : -np 1 python3 $rundir/$toy_model --conf nemo_toy_model.yaml : -np 1 python3 $rundir/$toy_model --conf runoff_toy_model.yaml +mpirun -np 1 python3 ${rundir}/${toy_model} --conf ifs_toy_model.yaml : -np 1 python3 ${rundir}/${toy_model} --conf nemo_toy_model.yaml : -np 1 python3 ${rundir}/${toy_model} --conf runoff_toy_model.yaml diff --git a/tests/run_example.sh b/tests/run_example.sh index 5429dd9..b3a4755 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -1,12 +1,12 @@ #!/bin/bash ## Usage -# if [ $# -ne 9 ]; then -# echo 'Invalid args.' -# echo 'Usage ./run_example.sh ' -# echo 'Try ./run_example.sh python forcing 4 1990-01-01 1991-01-01 0 L128 true' -# exit 1 -# fi +if [ $# -ne 10 ]; then + echo 'Invalid args.' + echo 'Usage ./run_example.sh ' + echo 'Try .bash ./run_example.sh datacoupler forcing 4 2005-01-01 2005-03-01 0 128 true false template_conf_datacoupler_forcing.yaml' + exit 1 +fi set -xuve @@ -22,7 +22,7 @@ ifs_cmip_fixyear=$6 ifs_grid=$7 amip_interpolate=$8 co2_interpolate=$9 -yaml_conf_file=${10} +yaml_conf_template=${10} host=`uname -n` user=`whoami` @@ -36,8 +36,7 @@ toy_model_dir=$srcdir/../sources/ece3-toy-model cp -f $toy_model_dir/*.py $srcdir source_exe1=$srcdir/toy_model.py -py_script='python3 DataCouplerPreprocessor.py' - +namlist_yaml_conf_creator_script='python3 DataCouplerPreprocessor.py' if [ $model = fortran ]; then exe2='./amip-forcing' @@ -52,17 +51,15 @@ elif [ $model = python ] || [ $model = pythoncompat ]; then # exe2='python3 -m cProfile -s cumtime amip_forcing.py' source_exe2=$srcdir/../sources/amip-forcing/src/python/*.py elif [ $model = datacoupler ] ; then - # TODO - #exe2='python3 AMIPDataCoupler.py' exe2='python3 DataCoupler.py' # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' # exe2='python3 -m cProfile -s cumtime amip_forcing.py' source_exe2=$srcdir/../sources/data-coupler/*.py -elif [ $model = co2box ] ; then - exe2='python3 CO2BoxDataCoupler.py' +# elif [ $model = co2box ] ; then + # exe2='python3 CO2BoxDataCoupler.py' # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' # exe2='python3 -m cProfile -s cumtime amip_forcing.py' - source_exe2=$srcdir/../sources/data-coupler/*.py + # source_exe2=$srcdir/../sources/data-coupler/*.py else echo 'Invalid args. You must specify a language for the AMIP reader: | ' exit 1 @@ -95,16 +92,14 @@ ln -sf $datadir/ICMGGa22e+000000 $rundir/. ln -sf $datadir/*.txt $rundir/. # Get SST and SIC #if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then -if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then +if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] || [ $model=datacoupler ]; then ln -sf $datadir/forcing/siconcbcs*.nc $rundir/. ln -sf $datadir/forcing/tosbcs*.nc $rundir/. ln -sf $datadir/forcing/rmp_AMIP_to_L${ifs_grid}_GAUSWGT*.nc $rundir/. - if [ $amip_mode = co2 ]; then - ln -sf $datadir/co2/CO2-em-anthro_*.nc $rundir/. - ln -sf $datadir/co2/CO2-em-AIR-anthro_*.nc $rundir/. - ln -sf $datadir/co2/mole-fraction-of-carbon-dioxide-in-air_*.nc* $rundir/. - ln -sf $datadir/co2/rmp_CO2_emis_to_B${ifs_grid}_GAUSWGT*.nc $rundir/. - fi + ln -sf $datadir/co2/CO2-em-anthro_*.nc $rundir/. + ln -sf $datadir/co2/CO2-em-AIR-anthro_*.nc $rundir/. + ln -sf $datadir/co2/mole-fraction-of-carbon-dioxide-in-air_*.nc* $rundir/. + ln -sf $datadir/co2/rmp_CO2_emis_to_B${ifs_grid}_GAUSWGT*.nc $rundir/. else ln -sf $datadir/$amip_mode/HadI*.nc $rundir/. ln -sf $datadir/$amip_mode/rmp_PSIC_to_${ifs_grid}_GAUSWGT.nc $rundir/. @@ -135,128 +130,30 @@ leg_start_date_yyyymmdd=$(date -u -d "${leg_start_date}" +%Y%m%d) if [ $model = fortran ] || [ $model = pythoncompat ]; then if [ $amip_mode = forcing ]; then . ./namelist.amip.sh > ./namelist.amip - else - . ./namelist_primavera.amip.sh > ./namelist.amip - - fi -else - #if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then - if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then - i=1 - ii=1 - if [ $model = co2box ] || [ $model = datacoupler ]; then - var=FileInputVars - else - var=Vars - fi - sst_conf_var=${var}"("$((i++))",:) = 'AMIP_sst_monthly', 'AMIP', 'AMIP_sst', 'tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc', 'tosbcs', 1870, 2016, 'monthly', ${amip_interpolate}, 1, 273.15, 271.38, ,true,true," - sst_conf_var_yml="${var}("$((ii++))"): AMIP_sst_monthly, AMIP', AMIP_sst, tosbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, tosbcs, 1870, 2016, monthly, ${amip_interpolate}, 1, 273.15, 271.38, , true, true" - - sic_conf_var=${var}"("$((i++))",:) = 'AMIP_sic_monthly', 'AMIP', 'AMIP_sic', 'siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc', 'siconcbcs', 1870, 2016, 'monthly', ${amip_interpolate}, 0.01, 0, 0, 1,true,true," - sic_conf_var_yml="${var}("$((ii++))"): AMIP_sic_monthly, AMIP, AMIP_sic, siconcbcs_input4MIPs_SSTsAndSeaIce_CMIP_PCMDI-AMIP-1-1-3_gn_187001-201706.nc, siconcbcs, 1870, 2016, monthly, ${amip_interpolate}, 0.01, 0, 0, 1, true, true" + . ./namcouple.sh > ./namcouple - j=1 - jj=1 - oasis_conf_var_yml="" - oasis_conf_var="!OasisOutputVars(j,:) = , , , , , \n" - oasis_conf_var=$'\n'"OasisOutputVars("$((j++))",:) = 'AMIP_sst', 'AMIP', 'daily', 1, 0, true," - oasis_conf_var_yml="OasisOutputVars("$((jj++))") : AMIP_sst, AMIP, daily, 1, 0, true"$'\n' - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = 'AMIP_sic', 'AMIP', 'daily', 1, 0, true," - oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : AMIP_sic, AMIP, daily, 1, 0, true"$'\n' - if [ $amip_mode = co2 ]; then - co2_conf_var="" - co2_conf_var+="!FileInputVars(i,:) = "$'\n' - #[ $model = co2box ] && mod=CO2BOX || mod=AMIP - if [ $model = co2box ] ; then - mod=CO2BOX - CO2_CMODE=true # set to false to disable co2 concentrations reading - CO2_EMODE=true # set to false to disable emissions reading - else - mod=AMIP - CO2_CMODE=false # don't change this! - CO2_EMODE=true # don't change this! - fi - #this fix is required to correctly read the co2 files which havereftime 0-1-1, which isn't supported by python netcdf4 - #cdo -R -setreftime,1849-01-01,00:00 mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod - #this fix is required to correctly read the CO2_em_monthly files which have a 365day calendar and also to convert from a grid point/sectors fields to a global one - #cdo -L -setcalendar,gregorian -fldsum -vertsum -mul CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc co2-area.nc CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc - if [ ${CO2_CMODE} == true ] ; then - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_cconc_monthly', 'GLOBAL', '"$mod"_CO2_cconc', 'mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod', 'mole_fraction_of_carbon_dioxide_in_air', 1849, 2014, 'monthly', ${co2_interpolate}, 1, 0, , ,true,true,"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_econc_monthly', 'GLOBAL', '"$mod"_CO2_econc', 'mole-fraction-of-carbon-dioxide-in-air_input4MIPs_GHGConcentrations_CMIP_UoM-CMIP-1-2-0_gr1-GMNHSH_184901-201412.nc.mod', 'mole_fraction_of_carbon_dioxide_in_air', 1849, 2014, 'monthly', ${co2_interpolate}, 'co2_ppm_to_mass', 0, , ,false,false,"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_em_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 86400, 0, , ,true,true,"$'\n' - # add land/ocean fluxes equal to 0.5/0.1 that of emissions, for demonstration purposes - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_land_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 43200, 0, , ,true,true,"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_ocean_monthly_GLOBAL', 'GLOBAL', '"$mod"_CO2_econc', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412-global.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 8640, 0, , ,true,true,"$'\n' - fi - if [ ${CO2_EMODE} == true ] ; then - # this is the 3D monthly emissions used for ECE4, the calendar fix mentionned below is probably required - co2_conf_var_yml="" - - - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_em_monthly', 'CO2_emis', '"$mod"_CO2_emis', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 1, 0, , ,true,true,"$'\n' - co2_conf_var_yml+="${var}("$((ii++))"): CO2_em_monthly, CO2_emis, "$mod"_CO2_emis, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 1, 0, , ,true,true"$'\n' - # add land/ocean fluxes equal to 0.5/0.1 that of emissions, for demonstration purposes - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_land_monthly', 'CO2_emis', '"$mod"_CO2_land', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.5, 0, , ,true,true,"$'\n' - co2_conf_var_yml+="${var}("$((ii++))"): CO2_land_monthly, CO2_emis, "$mod"_CO2_land, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 0.5, 0, , , true, true"$'\n' - co2_conf_var+=${var}"("$((i++))",:) = 'CO2_ocean_monthly', 'CO2_emis', '"$mod"_CO2_ocean', 'CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc', 'CO2_em_anthro', 1750, 2018, 'monthly', ${co2_interpolate}, 0.1, 0, , ,true,true,"$'\n' - co2_conf_var_yml+="${var}("$((ii++))"): CO2_ocean_monthly, CO2_emis, "$mod"_CO2_ocean, CO2-em-anthro_input4MIPs_emissions_CMIP_CEDS-2017-05-18_gn_200001-201412.nc, CO2_em_anthro, 1750, 2018, monthly, ${co2_interpolate}, 0.1, 0, , ,true,true" - - - - fi - #OasisOutputVars(i,:) = - if [ ${CO2_CMODE} == true ] ; then - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_cconc', 'GLOBAL', 'daily', 1, 0, true," - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_econc', 'GLOBAL', 'daily', 'co2_mass_to_ppm', 0, false," - fi - if [ ${CO2_EMODE} == true ] ; then - # this is the 3D monthly emissions used for ECE4 - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_emis', 'CO2_emis', 'daily', 1, 0, true," - oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_emis, CO2_emis, daily, 1, 0, true"$'\n' - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_land', 'CO2_emis', 'daily', 1, 0, true," - oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_land, CO2_emis, daily, 1, 0, true"$'\n' - oasis_conf_var+=$'\n'"OasisOutputVars("$((j++))",:) = '"$mod"_CO2_ocean', 'CO2_emis', 'daily', 1, 0, true," - oasis_conf_var_yml+="OasisOutputVars("$((jj++))") : "$mod"_CO2_ocean, CO2_emis, daily, 1, 0, true" - fi - else - co2_conf_var="" - fi + elif [ $amip_mode = primavera ]; then + . ./namelist_primavera.amip.sh > ./namelist.amip + . ./namcouple_primavera.sh > ./namcouple else - sst_conf_var="Vars(1,:) = 'AMIP_sst_daily', 'PSST', 'AMIP_sst', 'HadISST2_prelim_0to360_alldays_sst_[year].nc', 'sst', 1850, 2016, 'daily', false, 1, 0, , ," - sic_conf_var="Vars(2,:) = 'AMIP_sic_daily', 'PSIC', 'AMIP_sic', 'HadISST2_prelim_0to360_alldays_sic_[year].nc', 'sic', 1850, 2016, 'daily', false, 1, 0, , ," - co2_conf_var="" - oasis_conf_var="" + echo 'Error: for fortran or pythoncompat models, Only forcing or primavera is valid for amip_mode.' + exit 9 fi - . ./namelist_python.amip.sh > ./namelist.amip - +else + # Create the name of the experiment conf yaml based on the OasisCPLNG name in template yaml - #yaml_conf_name=$(grep -F "ModelNameReceive" "$yaml_conf_file" | awk '{print $3}')'_exp_conf.yaml' - yaml_conf_name='DataCoupler_exp_conf.yaml' - - . ./$yaml_conf_file > $yaml_conf_name + #yaml_conf_file=$(grep -F "ModelNameReceive" "$yaml_conf_template" | awk '{print $3}')'_exp_conf.yaml' + yaml_conf_file='DataCoupler_exp_conf.yaml' + . ./$yaml_conf_template > $yaml_conf_file - [ $model = co2box ] && . ./namelist.co2box.sh > ./namelist.co2box -fi -if [ $amip_mode = forcing ]; then - - input="namcouple_empty.yaml" namcouple_output="namcouple" - toy_model_yaml_conf_output="yaml_conf_name_ifs_toy_model.yaml" + toy_model_yaml_conf_output="yaml_conf_file_ifs_toy_model.yaml" # Run the py namcouple creator - $py_script --conf $yaml_conf_name --namcouple_output $namcouple_output --toy_model_yaml_conf_output $toy_model_yaml_conf_output - - -elif [ $amip_mode = co2 ]; then - [ $model = co2box ] && . ./namcouple_co2box.sh > ./namcouple || . ./namcouple_co2.sh > ./namcouple -else - . ./namcouple_primavera.sh > ./namcouple + $namlist_yaml_conf_creator_script --conf $yaml_conf_file --namcouple_output $namcouple_output --toy_model_yaml_conf_output $toy_model_yaml_conf_output fi # Creating namcouple with python - - - ###################################################################### ### Definition of mpirun command and batch script @@ -264,11 +161,7 @@ echo 'Executing the model using mpirun : ${MPIRUN}' # To seprate the DataCoupler with YAML input file from legecy codes if [ $model = datacoupler ] ; then - if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] ; then - - - ${MPIRUN} -np $nproc_exe1 $exe1 --conf $toy_model_yaml_conf_output : -np $nproc_exe2 $exe2 --conf $yaml_conf_name - fi + ${MPIRUN} -np $nproc_exe1 $exe1 --conf $toy_model_yaml_conf_output : -np $nproc_exe2 $exe2 --conf $yaml_conf_file else ${MPIRUN} -np $nproc_exe1 $exe1 : -np $nproc_exe2 $exe2 fi diff --git a/tests/toy_model.py b/tests/toy_model.py new file mode 100644 index 0000000..3937b7e --- /dev/null +++ b/tests/toy_model.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python3 +# Copyright 2023 - Barcelona Supercomputing Center +# Author: Rodrigo Martín Posada (2021), updated by : Amirpasha Mozaffari (2023) +# TBD + +import yaml +from yaml.loader import SafeLoader +import logging +import argparse +import os +import pyoasis +from pyoasis import OASIS # pylint: disable=no-name-in-module +import numpy as np + + +def def_local_partition(nx, npes, mype): + il_size = nx // npes + il_offset = mype * il_size + if (npes-mype) <= nx % npes: + il_size += 1 + il_offset += (nx % npes) - (npes-mype) + return il_size, il_offset + + +if __name__ == '__main__': + +### Read in YAML file + current_path = os.getcwd() + parser=argparse.ArgumentParser() + #parser.add_argument("--run_dir",type=str) + parser.add_argument("--conf",type=str) + args = parser.parse_args() + yamel_file_path = os.path.join(current_path,args.conf) + + if os.path.isfile(yamel_file_path) == False: + print("YAML file does not exist. Aborted") + raise NameError("YAML file does not exist.") + + # Open the file and load the file + with open(yamel_file_path) as f: + read_in_data = yaml.load(f, Loader=SafeLoader) + f.close() + +### Read in file + #read_yaml(read_in_data) + model = read_in_data.get("model") + model_name = model.get("ModelName") + + # Read in Simulation information + simulation = read_in_data.get("simulation") + simulation_coupling_interval = simulation.get("coupling_interval") + simulation_run_length_sec = simulation.get("run_length_sec") + simulation_nx = simulation.get("nx") + + # Read in Coupling infomration + coupling = read_in_data.get("coupling") + coupling_out_vars = coupling.get("out_vars") + coupling_in_vars = coupling.get("in_vars") + restart_file = coupling.get("restart_file") # This feature is not used for now. TODO + +### Pass the values to original code + + # Init OASIS + comp = pyoasis.Component(model_name) + local_comm = comp.localcomm + # Get rank in local communicator + mype = comp.localcomm.rank + npes = comp.localcomm.size + + # BUG : shouldnt it be the npes and not mpye (?) + mype_value = str(100+mype) + out_model = '{model_name}.out_{mype_value}'.format(model_name = model_name, mype_value = mype_value) + + logging.basicConfig(filename=out_model, format='%(message)s', level=logging.DEBUG) + logging.debug('-----------------------------------------------------------') + logging.info('I am {model_name} process with rank : {mype}'.format(model_name = model_name, + mype = mype)) + #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) + logging.debug('in my local communicator gathering {} processes'.format(npes)) + logging.debug('----------------------------------------------------------') + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # PARTITION DEFINITION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # for more than one processor is using a parallel partition and for single processor a serial + + if npes > 1: + il_size, il_offset = def_local_partition(simulation_nx, npes, mype) + logging.debug('Local partition definition') + logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) + partition = pyoasis.ApplePartition(il_offset, il_size) + field_data_size = il_size + logging.debug('Grid points in the current Apple - partition is: {},'.format(field_data_size)) + else: + partition = pyoasis.SerialPartition(simulation_nx) + field_data_size = simulation_nx + logging.debug('Grid points in the current Serial - partition is: {},'.format(field_data_size)) + + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # DECLARATION OF THE COUPLING FIELDS + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + out_field_data = pyoasis.asarray(np.full(field_data_size, -1.0)) + out_coupling_fields={} + + in_coupling_fields = {} # Create a dictionary to store the variables + in_field_data={} + + for name in coupling_out_vars: + var = pyoasis.Var(name, partition, OASIS.OUT) + out_coupling_fields[name] = var + logging.debug('var_id {}, added as OASIS_OUT var'.format(name)) + + for name in coupling_in_vars: + var = pyoasis.Var(name, partition, OASIS.IN) + in_coupling_fields[name] = var + in_field_data[name] = pyoasis.asarray(np.full(field_data_size, -1.0)) + logging.debug('var_id {}, added as OASIS_IN var'.format(name)) + + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION OF DEFINITION PHASE + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of initialisation phase') + + comp.enddef() + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TIME STEP LOOP + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('Timestep, field min, mean and max value') + + + for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): + logging.debug('ITAP_SEC: {} receiving fields'.format(itap_sec)) + logging.debug(str(in_coupling_fields.keys())) + + + for id, field in in_coupling_fields.items(): + field.get(itap_sec, in_field_data[id]) + logging.debug('{} -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(in_field_data[id]), np.mean(in_field_data[id]), np.max(in_field_data[id]))) + + for id, field in out_coupling_fields.items(): + sigma=1 + mu=1 + # send dummy data (100 for runoff, random for other variables) + #TODO send dummy data read from oasis restart file + + if id == "A_Runoff": + out_field_data[:]=1.4658e-06 + out_field_data[:]=100 + else: + out_field_data[:]=sigma * np.random.randn(field_data_size) + mu + field.put(itap_sec, out_field_data) + logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(out_field_data), np.mean(out_field_data), np.max(out_field_data))) + + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # TERMINATION + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + logging.debug('End of the program') + + print('Model {} is finished successfully.'.format(model_name)) + + del comp + + + -- GitLab From b850301cc0d3feacbcf69752cdfae2d460f5c605 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 13 Sep 2023 13:01:21 +0200 Subject: [PATCH 37/39] cleanup codes + fixing minor issue with toy_model for Datacoupler --- sources/data-coupler/AMIPDataCoupler.py | 38 ---- sources/data-coupler/DataCoupler.py | 2 +- .../data-coupler/DataCouplerPreprocessor.py | 10 +- sources/data-coupler/DataCouplerUtils.py | 3 +- sources/ece3-toy-model/ifs_toy_model.yaml | 1 - sources/ece3-toy-model/nemo_toy_model.yaml | 1 - sources/ece3-toy-model/runoff_toy_model.yaml | 1 - .../template_conf_datacoupler_forcing.yaml | 1 - tests/launch_ece3_data_coupler_mn4.cmd | 7 +- tests/run_example.sh | 36 ++-- tests/toy_model.py | 168 ------------------ 11 files changed, 24 insertions(+), 244 deletions(-) delete mode 100644 sources/data-coupler/AMIPDataCoupler.py delete mode 100644 tests/toy_model.py diff --git a/sources/data-coupler/AMIPDataCoupler.py b/sources/data-coupler/AMIPDataCoupler.py deleted file mode 100644 index 13009f4..0000000 --- a/sources/data-coupler/AMIPDataCoupler.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2022 - Barcelona Supercomputing Center -# Authors: Etienne Tourigny, Rodrigo Martín Posada -# MIT License - -from DataCoupler import DataCoupler -import argparse -import sys - -# Constants -NAMELIST_FILE_NAME = 'namelist.amip' -NAMELIST_SECTION = 'NAMAMIP' -LOG_FILE_NAME = 'amip.log' -CPLNG_COMP_NAME = 'AMIPFORC' -YAML_INPUT_FILE_NAME = "namelist.amip_exp1.yaml" - -if __name__ == '__main__': - # receive the yaml experiment input file is it exists , otherwise pass - try: - parser=argparse.ArgumentParser() - parser.add_argument("--yaml_experiment_input_file",type=str,default=YAML_INPUT_FILE_NAME) - args = parser.parse_args() - YAML_INPUT_FILE_NAME = args.yaml_experiment_input_file - except: - print("NOTE: Could note read in the input yaml file : {}".format(YAML_INPUT_FILE_NAME), file=sys.stderr) - else: - print("NOTE: input yaml file is : {}".format(YAML_INPUT_FILE_NAME), file=sys.stderr) - - # Setup - amip = DataCoupler(NAMELIST_FILE_NAME, NAMELIST_SECTION, YAML_INPUT_FILE_NAME, LOG_FILE_NAME) - amip.setup_data_coupler() - amip.setup_oasis(CPLNG_COMP_NAME, write_grid=True, write_grid_mask=True, - write_grid_corners= True, write_grid_areas = True) - # Time loop - amip.run_time_loop() - # Finalize - amip.finalise_data_coupler() - diff --git a/sources/data-coupler/DataCoupler.py b/sources/data-coupler/DataCoupler.py index 1b19bfb..cf8156b 100644 --- a/sources/data-coupler/DataCoupler.py +++ b/sources/data-coupler/DataCoupler.py @@ -22,7 +22,7 @@ class DataCoupler: def __init__(self,yaml_conf_file): - ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + ModelNameSend, ModelNameReceive, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin , \ = read_DataCoupler_yaml_input(yaml_conf_file) diff --git a/sources/data-coupler/DataCouplerPreprocessor.py b/sources/data-coupler/DataCouplerPreprocessor.py index f65033a..855c906 100644 --- a/sources/data-coupler/DataCouplerPreprocessor.py +++ b/sources/data-coupler/DataCouplerPreprocessor.py @@ -73,7 +73,7 @@ $END return lines_to_append -def create_yaml_conf_name_ifs_toy_model(filename,ModelName,PartitionTypeReceive,run_length_sec,coupling_interval,nx,OasisOutputVars_readin): +def create_yaml_conf_name_ifs_toy_model(filename,ModelName,run_length_sec,coupling_interval,nx,OasisOutputVars_readin): coupling_out_vars=[] @@ -90,8 +90,6 @@ def create_yaml_conf_name_ifs_toy_model(filename,ModelName,PartitionTypeReceive, # yaml metadata model: ModelName : {ModelName} - #PartitionTypeSend : SerialPartition - PartitionTypeReceive : {PartitionType} simulation: coupling_interval : {coupling_interval} @@ -107,7 +105,7 @@ coupling: in_vars : {in_vars} restart_file : /path/ """ - append_multiple_lines_to_file(filename, lines_to_append.format(ModelName=ModelName,PartitionType=PartitionTypeReceive,coupling_interval=coupling_interval,run_length_sec=run_length_sec,nx=nx,out_vars=coupling_out_vars,in_vars=coupling_in_vars )) + append_multiple_lines_to_file(filename, lines_to_append.format(ModelName=ModelName,coupling_interval=coupling_interval,run_length_sec=run_length_sec,nx=nx,out_vars=coupling_out_vars,in_vars=coupling_in_vars )) if __name__ == '__main__': @@ -124,7 +122,7 @@ if __name__ == '__main__': # Read the yaml file - ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ + ModelNameSend, ModelNameReceive, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth, \ StartDay, FixYear, GridInfo, LDebug, fileIn_vars_config, oasisOut_vars_config, OasisOutputVars_readin = read_DataCoupler_yaml_input(yaml_conf_file) number_of_fields = len(OasisOutputVars_readin) @@ -145,4 +143,4 @@ if __name__ == '__main__': # Creating the yaml_conf_name_ifs_toy_model ifs_conf_yaml = toy_model_yaml_conf_output - create_yaml_conf_name_ifs_toy_model(ifs_conf_yaml,ModelNameReceive,PartitionType, RunLengthSec, TimeStepSec,GridInfo,OasisOutputVars_readin) + create_yaml_conf_name_ifs_toy_model(ifs_conf_yaml,ModelNameReceive, RunLengthSec, TimeStepSec,GridInfo,OasisOutputVars_readin) diff --git a/sources/data-coupler/DataCouplerUtils.py b/sources/data-coupler/DataCouplerUtils.py index 99e75fb..bac601b 100644 --- a/sources/data-coupler/DataCouplerUtils.py +++ b/sources/data-coupler/DataCouplerUtils.py @@ -242,7 +242,6 @@ def read_DataCoupler_yaml_input(yaml_file): ModelNameSend = read_in.get('ModelNameSend') ModelNameReceive = read_in.get('ModelNameReceive') LogFileName = read_in.get('LogFileName') - PartitionType = read_in.get('PartitionType') ## Run Information @@ -276,6 +275,6 @@ def read_DataCoupler_yaml_input(yaml_file): # Variable configuration for this experiment OasisOutputVars_conf = list(OasisOutputVars_readin.values()) - return ModelNameSend, ModelNameReceive, LogFileName, PartitionType, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ + return ModelNameSend, ModelNameReceive, LogFileName, RunLengthSec, TimeStepSec, StartYear, StartMonth,\ StartDay, FixYear, GridInfo, LDebug, FileInputVarFields_conf, OasisOutputVars_conf, OasisOutputVars_readin diff --git a/sources/ece3-toy-model/ifs_toy_model.yaml b/sources/ece3-toy-model/ifs_toy_model.yaml index 8ef5c82..0beb1db 100644 --- a/sources/ece3-toy-model/ifs_toy_model.yaml +++ b/sources/ece3-toy-model/ifs_toy_model.yaml @@ -7,7 +7,6 @@ model: ModelName : IFS_TOY - PartitionType : SerialPartition simulation: coupling_interval : 2700 diff --git a/sources/ece3-toy-model/nemo_toy_model.yaml b/sources/ece3-toy-model/nemo_toy_model.yaml index d346675..16201ec 100644 --- a/sources/ece3-toy-model/nemo_toy_model.yaml +++ b/sources/ece3-toy-model/nemo_toy_model.yaml @@ -7,7 +7,6 @@ model: ModelName : NEMO_TOY - PartitionType : SerialPartition simulation: coupling_interval : 2700 diff --git a/sources/ece3-toy-model/runoff_toy_model.yaml b/sources/ece3-toy-model/runoff_toy_model.yaml index 47d9126..e78f53b 100644 --- a/sources/ece3-toy-model/runoff_toy_model.yaml +++ b/sources/ece3-toy-model/runoff_toy_model.yaml @@ -7,7 +7,6 @@ model: ModelName : RUNOFF_TOY - PartitionType : SerialPartition simulation: coupling_interval : 2700 diff --git a/tests/data/template_conf_datacoupler_forcing.yaml b/tests/data/template_conf_datacoupler_forcing.yaml index 0513c92..23e89c7 100755 --- a/tests/data/template_conf_datacoupler_forcing.yaml +++ b/tests/data/template_conf_datacoupler_forcing.yaml @@ -9,7 +9,6 @@ ModelNameSend : AMIPFORC ModelNameReceive : IFS_TOY LogFileName : amip.log YamlConfName : ${yaml_conf_file} -PartitionType : ApplePartition ## Run Information RunLengthSec : ${leg_length_sec} diff --git a/tests/launch_ece3_data_coupler_mn4.cmd b/tests/launch_ece3_data_coupler_mn4.cmd index cbba3bc..7a8948d 100644 --- a/tests/launch_ece3_data_coupler_mn4.cmd +++ b/tests/launch_ece3_data_coupler_mn4.cmd @@ -1,4 +1,5 @@ #!/bin/bash +# slurm specific options for MN4 #SBATCH --qos=debug #SBATCH -N 1 #SBATCH -n 5 @@ -9,14 +10,12 @@ platform="BSC_MN4" if [ $platform = BSC_MN4 ]; then - # slurm specific options for Marenostrum4 - + # Environment for MN4 module load python/3.6.1 module load netcdf/4.2 module load CDO/1.9.3 module list export MPIRUN="mpirun" - source ../sources/oasis3-mct/generated/python/init.sh elif [ $platform = EC_HPC2020 ] ; then @@ -31,7 +30,7 @@ elif [ $platform = EC_HPC2020 ] ; then fi -#source ../sources/oasis3-mct/generated/python/init.sh +source ../sources/oasis3-mct/generated/python/init.sh #bash ./run_example.sh pythoncompat forcing 4 2005-01-01 2005-03-01 0 128 true #bash ./run_example.sh fortran forcing 4 2005-01-01 2005-03-01 0 128 true diff --git a/tests/run_example.sh b/tests/run_example.sh index b3a4755..184d215 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -31,13 +31,6 @@ srcdir=`pwd` datadir=$srcdir/data -exe1='python3 toy_model.py' -toy_model_dir=$srcdir/../sources/ece3-toy-model -cp -f $toy_model_dir/*.py $srcdir - -source_exe1=$srcdir/toy_model.py -namlist_yaml_conf_creator_script='python3 DataCouplerPreprocessor.py' - if [ $model = fortran ]; then exe2='./amip-forcing' if [ $amip_mode = forcing ]; then @@ -47,19 +40,13 @@ if [ $model = fortran ]; then fi elif [ $model = python ] || [ $model = pythoncompat ]; then exe2='python3 amip_forcing.py' - # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' - # exe2='python3 -m cProfile -s cumtime amip_forcing.py' + source_exe2=$srcdir/../sources/amip-forcing/src/python/*.py elif [ $model = datacoupler ] ; then exe2='python3 DataCoupler.py' - # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' - # exe2='python3 -m cProfile -s cumtime amip_forcing.py' + source_exe2=$srcdir/../sources/data-coupler/*.py -# elif [ $model = co2box ] ; then - # exe2='python3 CO2BoxDataCoupler.py' - # exe2='coverage run -p --branch --include=*/amip-forcing/src/python/* amip_forcing.py' - # exe2='python3 -m cProfile -s cumtime amip_forcing.py' - # source_exe2=$srcdir/../sources/data-coupler/*.py + else echo 'Invalid args. You must specify a language for the AMIP reader: | ' exit 1 @@ -70,7 +57,13 @@ CO2_EMODE=false # - Define rundir rundir=${srcdir}/work_${model}_${amip_mode}_${nproc_exe1}_${leg_start_date}_${leg_end_date}_${ifs_cmip_fixyear}_${ifs_grid}_${amip_interpolate} -# export COVERAGE_FILE=${rundir}/../.coverage + +# Copy the ece_3_toy_model to run_dir +toy_model_script=$srcdir/../sources/ece3-toy-model/toy_model.py +namlist_yaml_conf_creator_script='python3 DataCouplerPreprocessor.py' +cp -f $toy_model_script $rundir +exe1='python3 '$toy_model_script + echo '*****************************************************************' #echo '*** '$casename' : '$run @@ -91,7 +84,6 @@ mkdir -p $rundir ln -sf $datadir/ICMGGa22e+000000 $rundir/. ln -sf $datadir/*.txt $rundir/. # Get SST and SIC -#if [ $amip_mode = forcing ] || [ $amip_mode = co2 ]; then if [ $amip_mode = forcing ] || [ $amip_mode = co2 ] || [ $model=datacoupler ]; then ln -sf $datadir/forcing/siconcbcs*.nc $rundir/. ln -sf $datadir/forcing/tosbcs*.nc $rundir/. @@ -117,11 +109,11 @@ else fi cp -f $datadir/*.sh $rundir/. cp -f $datadir/*.yaml $rundir/. -cp -f $source_exe1 $rundir/. ln -sf $source_exe2 $rundir/. cp -f $srcdir/*.py $rundir/. cd $rundir +###################################################################### ### Generate namelist leg_length_sec=$(( $(date -u -d "${leg_end_date}" +%s) - $(date -u -d "${leg_start_date}" +%s) )) cpl_freq_amip_sec=86400 # Always @@ -140,12 +132,15 @@ if [ $model = fortran ] || [ $model = pythoncompat ]; then exit 9 fi else + + # Comleting the YAML template that user has provided and store it (yaml_conf_file) - # Create the name of the experiment conf yaml based on the OasisCPLNG name in template yaml + # TODO: dynamically genarte YAML file name based on the exp. #yaml_conf_file=$(grep -F "ModelNameReceive" "$yaml_conf_template" | awk '{print $3}')'_exp_conf.yaml' yaml_conf_file='DataCoupler_exp_conf.yaml' . ./$yaml_conf_template > $yaml_conf_file + # Generating a namcouple based on the input on the YAML file above to be used by OASIS namcouple_output="namcouple" toy_model_yaml_conf_output="yaml_conf_file_ifs_toy_model.yaml" @@ -153,7 +148,6 @@ else $namlist_yaml_conf_creator_script --conf $yaml_conf_file --namcouple_output $namcouple_output --toy_model_yaml_conf_output $toy_model_yaml_conf_output fi -# Creating namcouple with python ###################################################################### ### Definition of mpirun command and batch script diff --git a/tests/toy_model.py b/tests/toy_model.py deleted file mode 100644 index 3937b7e..0000000 --- a/tests/toy_model.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2023 - Barcelona Supercomputing Center -# Author: Rodrigo Martín Posada (2021), updated by : Amirpasha Mozaffari (2023) -# TBD - -import yaml -from yaml.loader import SafeLoader -import logging -import argparse -import os -import pyoasis -from pyoasis import OASIS # pylint: disable=no-name-in-module -import numpy as np - - -def def_local_partition(nx, npes, mype): - il_size = nx // npes - il_offset = mype * il_size - if (npes-mype) <= nx % npes: - il_size += 1 - il_offset += (nx % npes) - (npes-mype) - return il_size, il_offset - - -if __name__ == '__main__': - -### Read in YAML file - current_path = os.getcwd() - parser=argparse.ArgumentParser() - #parser.add_argument("--run_dir",type=str) - parser.add_argument("--conf",type=str) - args = parser.parse_args() - yamel_file_path = os.path.join(current_path,args.conf) - - if os.path.isfile(yamel_file_path) == False: - print("YAML file does not exist. Aborted") - raise NameError("YAML file does not exist.") - - # Open the file and load the file - with open(yamel_file_path) as f: - read_in_data = yaml.load(f, Loader=SafeLoader) - f.close() - -### Read in file - #read_yaml(read_in_data) - model = read_in_data.get("model") - model_name = model.get("ModelName") - - # Read in Simulation information - simulation = read_in_data.get("simulation") - simulation_coupling_interval = simulation.get("coupling_interval") - simulation_run_length_sec = simulation.get("run_length_sec") - simulation_nx = simulation.get("nx") - - # Read in Coupling infomration - coupling = read_in_data.get("coupling") - coupling_out_vars = coupling.get("out_vars") - coupling_in_vars = coupling.get("in_vars") - restart_file = coupling.get("restart_file") # This feature is not used for now. TODO - -### Pass the values to original code - - # Init OASIS - comp = pyoasis.Component(model_name) - local_comm = comp.localcomm - # Get rank in local communicator - mype = comp.localcomm.rank - npes = comp.localcomm.size - - # BUG : shouldnt it be the npes and not mpye (?) - mype_value = str(100+mype) - out_model = '{model_name}.out_{mype_value}'.format(model_name = model_name, mype_value = mype_value) - - logging.basicConfig(filename=out_model, format='%(message)s', level=logging.DEBUG) - logging.debug('-----------------------------------------------------------') - logging.info('I am {model_name} process with rank : {mype}'.format(model_name = model_name, - mype = mype)) - #logging.debug('I am IFS-toy process with rank : {}'.format(mype)) - logging.debug('in my local communicator gathering {} processes'.format(npes)) - logging.debug('----------------------------------------------------------') - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # PARTITION DEFINITION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # for more than one processor is using a parallel partition and for single processor a serial - - if npes > 1: - il_size, il_offset = def_local_partition(simulation_nx, npes, mype) - logging.debug('Local partition definition') - logging.debug('il_size = {} il_offset = {} mype = {}'.format(il_size, il_offset, mype)) - partition = pyoasis.ApplePartition(il_offset, il_size) - field_data_size = il_size - logging.debug('Grid points in the current Apple - partition is: {},'.format(field_data_size)) - else: - partition = pyoasis.SerialPartition(simulation_nx) - field_data_size = simulation_nx - logging.debug('Grid points in the current Serial - partition is: {},'.format(field_data_size)) - - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # DECLARATION OF THE COUPLING FIELDS - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - out_field_data = pyoasis.asarray(np.full(field_data_size, -1.0)) - out_coupling_fields={} - - in_coupling_fields = {} # Create a dictionary to store the variables - in_field_data={} - - for name in coupling_out_vars: - var = pyoasis.Var(name, partition, OASIS.OUT) - out_coupling_fields[name] = var - logging.debug('var_id {}, added as OASIS_OUT var'.format(name)) - - for name in coupling_in_vars: - var = pyoasis.Var(name, partition, OASIS.IN) - in_coupling_fields[name] = var - in_field_data[name] = pyoasis.asarray(np.full(field_data_size, -1.0)) - logging.debug('var_id {}, added as OASIS_IN var'.format(name)) - - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION OF DEFINITION PHASE - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of initialisation phase') - - comp.enddef() - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TIME STEP LOOP - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('Timestep, field min, mean and max value') - - - for itap_sec in range(0, simulation_run_length_sec, simulation_coupling_interval): - logging.debug('ITAP_SEC: {} receiving fields'.format(itap_sec)) - logging.debug(str(in_coupling_fields.keys())) - - - for id, field in in_coupling_fields.items(): - field.get(itap_sec, in_field_data[id]) - logging.debug('{} -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(in_field_data[id]), np.mean(in_field_data[id]), np.max(in_field_data[id]))) - - for id, field in out_coupling_fields.items(): - sigma=1 - mu=1 - # send dummy data (100 for runoff, random for other variables) - #TODO send dummy data read from oasis restart file - - if id == "A_Runoff": - out_field_data[:]=1.4658e-06 - out_field_data[:]=100 - else: - out_field_data[:]=sigma * np.random.randn(field_data_size) + mu - field.put(itap_sec, out_field_data) - logging.debug('{} put -> {:.3e} {:.3e} {:.3e}'.format( id, np.min(out_field_data), np.mean(out_field_data), np.max(out_field_data))) - - - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - # TERMINATION - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - logging.debug('End of the program') - - print('Model {} is finished successfully.'.format(model_name)) - - del comp - - - -- GitLab From edbec4964cf921419d0aa0bc9f90bedb2d42ec59 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 13 Sep 2023 16:02:05 +0200 Subject: [PATCH 38/39] code clean up on run_example.py --- tests/run_example.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/run_example.sh b/tests/run_example.sh index 184d215..0c04bbe 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -58,11 +58,9 @@ CO2_EMODE=false # - Define rundir rundir=${srcdir}/work_${model}_${amip_mode}_${nproc_exe1}_${leg_start_date}_${leg_end_date}_${ifs_cmip_fixyear}_${ifs_grid}_${amip_interpolate} -# Copy the ece_3_toy_model to run_dir -toy_model_script=$srcdir/../sources/ece3-toy-model/toy_model.py -namlist_yaml_conf_creator_script='python3 DataCouplerPreprocessor.py' -cp -f $toy_model_script $rundir -exe1='python3 '$toy_model_script +# Copy the ece_3_toy_model to run_dir +exe1='python3 toy_model.py' +source_exe1=/../$srcdir/../sources/ece3-toy-model/toy_model.py echo '*****************************************************************' @@ -109,6 +107,7 @@ else fi cp -f $datadir/*.sh $rundir/. cp -f $datadir/*.yaml $rundir/. +ln -sf $source_exe1 $rundir/. ln -sf $source_exe2 $rundir/. cp -f $srcdir/*.py $rundir/. cd $rundir @@ -144,7 +143,8 @@ else namcouple_output="namcouple" toy_model_yaml_conf_output="yaml_conf_file_ifs_toy_model.yaml" - # Run the py namcouple creator + # Run the py namcouple creator + namlist_yaml_conf_creator_script='python3 DataCouplerPreprocessor.py' $namlist_yaml_conf_creator_script --conf $yaml_conf_file --namcouple_output $namcouple_output --toy_model_yaml_conf_output $toy_model_yaml_conf_output fi -- GitLab From 54d4fa3ce7776c60b13b6837868ee91c1ed75863 Mon Sep 17 00:00:00 2001 From: Amirpasha Mozaffari Date: Wed, 13 Sep 2023 17:00:11 +0200 Subject: [PATCH 39/39] Fixing remaining comments for merge 4 --- tests/launch_ece3_toy_model_mn4.cmd | 2 +- tests/run_example.sh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/launch_ece3_toy_model_mn4.cmd b/tests/launch_ece3_toy_model_mn4.cmd index f554c88..8ed9b73 100755 --- a/tests/launch_ece3_toy_model_mn4.cmd +++ b/tests/launch_ece3_toy_model_mn4.cmd @@ -29,7 +29,7 @@ srcdir=$testdir/../sources/ece3-toy-model rundir=${testdir}/work_ece3_toy_model_${timestamp} -#rm -rf $rundir +rm -rf $rundir mkdir -p $rundir for f in masks.nc grids.nc areas.nc rstas.nc rstos.nc; do diff --git a/tests/run_example.sh b/tests/run_example.sh index 0c04bbe..596a259 100755 --- a/tests/run_example.sh +++ b/tests/run_example.sh @@ -30,6 +30,10 @@ user=`whoami` srcdir=`pwd` datadir=$srcdir/data +# ece_3_toy_model as exe1 +exe1='python3 toy_model.py' +source_exe1=/../$srcdir/../sources/ece3-toy-model/toy_model.py + if [ $model = fortran ]; then exe2='./amip-forcing' @@ -58,10 +62,6 @@ CO2_EMODE=false # - Define rundir rundir=${srcdir}/work_${model}_${amip_mode}_${nproc_exe1}_${leg_start_date}_${leg_end_date}_${ifs_cmip_fixyear}_${ifs_grid}_${amip_interpolate} -# Copy the ece_3_toy_model to run_dir -exe1='python3 toy_model.py' -source_exe1=/../$srcdir/../sources/ece3-toy-model/toy_model.py - echo '*****************************************************************' #echo '*** '$casename' : '$run -- GitLab