diff --git a/.gitmodules b/.gitmodules index c4226bf3e..99258b968 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ path = src/esm_tests/resources url = https://github.com/esm-tools/esm_tests_info branch = release +[submodule "couplings"] + path = couplings + url = https://github.com/esm-tools/esm_iterative_coupling.git diff --git a/couplings b/couplings new file mode 160000 index 000000000..16cc8552e --- /dev/null +++ b/couplings @@ -0,0 +1 @@ +Subproject commit 16cc8552eb2180bdd71cd41f882dff08d1f9b3d0 diff --git a/couplings/.ignore b/couplings/.ignore deleted file mode 100644 index ec013748f..000000000 --- a/couplings/.ignore +++ /dev/null @@ -1 +0,0 @@ -dEBM diff --git a/couplings/__init__.py b/couplings/__init__.py deleted file mode 100644 index 95aae3859..000000000 --- a/couplings/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# This file is left intentionally blank to retrieve configurations that are -# directly bundled with the package. diff --git a/couplings/coupling_dual-hemisphere/dEBM/install_debm.sh b/couplings/coupling_dual-hemisphere/dEBM/install_debm.sh deleted file mode 100755 index def132a62..000000000 --- a/couplings/coupling_dual-hemisphere/dEBM/install_debm.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -MACHINE=$1 - -if [[ ${MACHINE} == "albedo" ]]; then - module load nco/5.0.1 netcdf-fortran/4.5.4-intel2021.6.0 - module load intel-oneapi-compilers/2022.1.0 - fortran_compiler=ifort #gfortran - nc_config=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/bin/nf-config - export NETCDF_LIB=$($nc_config --flibs) - export NETCDF_INC=$($nc_config --includedir) - NETCDFFROOT=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz - export PATH=${NETCDFFROOT}:${NETCDFFROOT}/include:${NETCDFFROOT}/lib:$PATH - export LD_LIBRARY_PATH=${NETCDFFROOT}/lib:${NETCDFROOT}/lib:$LD_LIBRARY_PATH -elif [[ ${MACHINE} == "levante" ]]; then - module load nco/5.0.6-gcc-11.2.0 intel-oneapi-compilers/2022.0.1-gcc-11.2.0 - module load intel-oneapi-mkl/2022.0.1-gcc-11.2.0 openmpi/4.1.2-intel-2021.5.0 netcdf-fortran/4.5.3-openmpi-4.1.2-intel-2021.5.0 - nc_config=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/bin/nf-config - export NETCDF_LIB=$($nc_config --flibs) - export NETCDF_INC=$($nc_config --includedir) - NETCDFFROOT=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/ - export PATH=${NETCDFFROOT}:${NETCDFFROOT}/include:${NETCDFFROOT}/lib:$PATH - export LD_LIBRARY_PATH=${NETCDFFROOT}/lib:${NETCDFROOT}/lib:$LD_LIBRARY_PATH -else - echo " * Unknown machine! No installation possible" - exit -fi - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -cd ${thisdir}/Fortran/ - -make diff --git a/couplings/coupling_dual-hemisphere/dEBM/namelist.debm b/couplings/coupling_dual-hemisphere/dEBM/namelist.debm deleted file mode 100644 index 28fd03884..000000000 --- a/couplings/coupling_dual-hemisphere/dEBM/namelist.debm +++ /dev/null @@ -1,40 +0,0 @@ -&runctl -lresume=.false. ! if restart, read snow height from 'restart_debm.nc' - ! .false. by default -use_shortwave_radiation_TOA=.true. ! if incorporate top incoming shortwave -use_mask=.false. ! ice mask -debug_switch=.true. ! debug option - ! .false. by default -debug_lon=241 ! if debug_switch=.true. -debug_lat=107 ! debug grid point(debug_lon,debug_lat,debug_mon,debug_year) -debug_mon=7 ! will be print during simulation -debug_year=1 -/ - -&debm -filename_in='input/Amon_AWI-ESM-1-1-LR_historical_r1i1p1f1_gn_dEBM_1951_5km.nc' ! input filename - -precipitation_varname='precip' -temperature_varname='temp2' -shortwave_radiation_downward_varname='swd' -shortwave_radiation_TOA_varname='srad0d' -cloud_cover_varname='aclcov' -emissivity_varname='emiss' -!transmissivity_varname='tau' -mapping_varname='thk' -longitude_varname='lon' -latitude_varname='lat' -time_varname='time' - -hydmth_str = 10 ! the beginning of the hydrological year, also start month for snow height integration - ! October for Northern Hemisphere - ! April Southern Hemisphere -stddev=3.5 ! constant standard deviation -obliquity=23.446 ! obliquity -cloud_bias=0.155 ! cloud bias -Ans = .845 ! Albedo for new snow -Ads = .73 ! Albedo for dry snow -Aws = .55 ! Albedo for wet snow -tau_cs = .75 ! expected clear sky transmissivity -residual = 0 ! residual heat flux (e.g. due to flux into the ice sheet -/ diff --git a/couplings/coupling_dual-hemisphere/echam/coupling_dual-ice2echam.functions b/couplings/coupling_dual-hemisphere/echam/coupling_dual-ice2echam.functions deleted file mode 100644 index bc6b21fdf..000000000 --- a/couplings/coupling_dual-hemisphere/echam/coupling_dual-ice2echam.functions +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/ksh - -## @fn ice2echam() -ice2echam() { - echo " ==================================================================" - echo " *** S T A R T I N G ice2echam *** "; echo - - . ${FUNCTION_PATH}/../echam/coupling_ice2echam.functions - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - echo " * working on the northern hemisphere first ..." - export PISM_HEMISPHERE="pism_nh" - ice2echam_1st - wait - for FILE in "echam6_new_orography_before_calnoro_high_res.nc" "echam6_new_orography_before_calnoro_low_res.nc" "ice_mask_current_T63grid.nc" "ice_domain_current_T63grid.nc" "ice_discharge_T63grid.nc"; do - if [[ -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/${FILE} ]] - then - cdo -s sellonlatbox,0,360,0,90 ${COUPLE_DIR}/${PISM_HEMISPHERE}/$FILE ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_ice2echam - ncecat -O ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE tmp 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/nco_ice2echam; mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE - ncwa -a time ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE tmp 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/nco_ice2echam; mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE - ncpdq -O -a lat,lon,record ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE tmp 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/nco_ice2echam; mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE - fi - done - - echo " * ... now switching to the southern hemisphere" - export PISM_HEMISPHERE="pism_sh" - ice2echam_1st - wait - for FILE in "echam6_new_orography_before_calnoro_high_res.nc" "echam6_new_orography_before_calnoro_low_res.nc" "ice_mask_current_T63grid.nc" "ice_domain_current_T63grid.nc" "ice_discharge_T63grid.nc"; do - if [[ -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/${FILE} ]] - then - cdo -s sellonlatbox,0,360,-90,0 ${COUPLE_DIR}/${PISM_HEMISPHERE}/$FILE ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_ice2echam - ncecat -O ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE tmp 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/nco_ice2echam; mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE - ncwa -a time ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE tmp 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/nco_ice2echam; mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE - ncpdq -O -a lat,lon,record ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE tmp 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/nco_ice2echam; mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/sellonlatbox.$FILE - - ncrcat -O "${COUPLE_DIR}/pism_nh/sellonlatbox.$FILE" "${COUPLE_DIR}/pism_sh/sellonlatbox.$FILE" "${COUPLE_DIR}/$FILE" 2>>${COUPLE_DIR}/nco_ice2echam - ncpdq -O -a record,lat,lon ${COUPLE_DIR}/$FILE tmp 2>>${COUPLE_DIR}/nco_ice2echam; mv tmp ${COUPLE_DIR}/$FILE - ncwa -O -a record ${COUPLE_DIR}/$FILE tmp 2>>${COUPLE_DIR}/nco_ice2echam; mv tmp ${COUPLE_DIR}/$FILE - fi - done - - ice2echam_2nd -} diff --git a/couplings/coupling_dual-hemisphere/echam/coupling_echam2ice.functions b/couplings/coupling_dual-hemisphere/echam/coupling_echam2ice.functions deleted file mode 100644 index d65d54ebf..000000000 --- a/couplings/coupling_dual-hemisphere/echam/coupling_echam2ice.functions +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/ksh -## @file -## @author Dr. Paul Gierz -## @author Alfred Wegener Institute for Polar and Marine Research -## @author Bremerhaven, Germany -## -## @brief Functions for preparing `ECHAM6` output for use with a generic ice sheet model - -# Here, variables which control the program flow are "declared", even if they are defined in other files -## @var ECHAM_TO_ISM_multiyear_mean -## Controls whether or not a multi-year mean is made from `atmosphere_file_for_ice.nc` -## Originally defined in ::echam_after_last_run_in_chunk -export ECHAM_TO_ISM_multiyear_mean - -##@var ECHAM_TO_ISM_atmosphere_forcing -## Controls whether `ECHAM6` output is used to prepare a forcing file for a generic ice sheet model. -## Originally defined in ::echam_after_last_run_in_chunk -export ECHAM_TO_ISM_atmosphere_forcing - -## @fn echam2ice() -## @brief Container for all functionality of `ECHAM6` to a generic ice sheet -## -## This function contains all functions needed to gather standard `ECHAM6` output for use with a -## generic ice sheet model. The following steps are preformed: -## 1. Generation of forcing -## 2. Preparing a grid description for later use with `cdo remap` -## 3. Preparing a file describing the names `ECHAM6` uses for its variables -## -## The variable #ECHAM_TO_ISM_atmosphere_forcing must be set to `1` -## for this function to be called (This is the default value). -## -## (Re)-initializes an empty file in `COUPLE_DIR` to store standard error of cdo output (for cleaner logs) -echam2ice() { - echo " ==================================================================" - echo " *** S T A R T I N G echam2ice *** "; echo - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - . ${FUNCTION_PATH}/../general/general_helpers.functions - - :> ${COUPLE_DIR}/cdo_stderr_echam2ice - iterative_coupling_echam6_ice_make_forcing - iterative_coupling_echam6_ice_write_grid - iterative_coupling_echam6_ice_write_names - - echo "*** build dynamic link of ${RESTART_DIR_echam}/restart_${EXP_ID}_echam_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}.nc" - ln -sf ${RESTART_DIR_echam}/restart_${EXP_ID}_echam_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}.nc ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc - - for STREAM in jsbach veg - do - rfile_1=${RESTART_DIR_jsbach}/restart_${EXP_ID}_${STREAM}_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}.nc - rfile_2=${RESTART_DIR_jsbach}/restart_${EXP_ID}_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}_${STREAM}.nc - if [ -f ${rfile_1} ]; then - ln -sf ${rfile_1} ${RESTART_DIR_jsbach}/restart_${EXP_ID}_${STREAM}.nc - elif [ -f ${rfile_2} ]; then - ln -sf ${rfile_2} ${RESTART_DIR_jsbach}/restart_${EXP_ID}_${STREAM}.nc - else - echo " * no ${rfile_1} or ${rfile_2} found ..." - exit - fi - done - - echo " *** F I N I S E D echam2ice *** " - echo " ==================================================================" -} - - -## @fn iterative_coupling_echam6_ice_make_forcing() -## @brief Container for all functionality to prepare forcing -## -## Preforms the following steps: -## 1. Constructs an input list of files from which the `ECHAM6` output will be extracted -## 2. Selects relevant variables from these files -## 3. Concatenates files to single file for further manipulation -## 4. Generates a multiyear mean, if `ECHAM_TO_ISM_multiyear_mean` is `1` -## 5. Adds `atmosphere_file_for_ice.nc` to the couple directory via `add_to`. -iterative_coupling_echam6_ice_make_forcing() { - echo " Preparing echam6 file for processing in an ice sheet model..." - - ECHAM_TO_ISM_multiyear_mean=${ECHAM_TO_ISM_multiyear_mean:-1} - - echam_ice_construct_input_list - echam_ice_select_relevant_variables - echam_ice_concatenate_files - if [ "x${ECHAM_TO_ISM_multiyear_mean}" == "x1" ]; then - echam_ice_generate_multiyear_mean - fi - #add_to $(pwd)/atmosphere_file_for_ice.nc atmosphere_file_for_ice.nc couple - cp $(pwd)/atmosphere_file_for_ice.nc ${COUPLE_DIR}/atmosphere_file_for_ice.nc - - echo; echo " ...done."; echo -} - -## @fn iterative_coupling_echam6_ice_write_grid() -## @brief Writes grids via `cdo griddes` -## -## Uses `cdo griddes` to determine the atmosphere grid information in the file `atmosphere.griddes`. -## Adds this to the couple directory. -iterative_coupling_echam6_ice_write_grid() { - echo " Writing echam6 grid description to generic atmosphere.griddes..." - - echo ""; echo " * generating griddes" - ${cdo} -s griddes atmosphere_file_for_ice.nc > atmosphere.griddes 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - #add_to $(pwd)/atmosphere.griddes atmosphere.griddes couple - cp $(pwd)/atmosphere.griddes ${COUPLE_DIR}/atmosphere.griddes - - echo; echo " ...done."; echo -} - -## @fn iterative_coupling_echam6_ice_write_names() -## @brief Writes names and units of atmospheric variables to `atmosphere_names_for_ice.dat` -## -## (Re)-initializes an empty file atmosphere_names_for_ice.dat -## @note This function currently only generates names useful for the `PISM` mass-ablation scheme PDD! -iterative_coupling_echam6_ice_write_names() { - echo " Writing echam6 names and units for use with generic atmosphere_file_for_ice.nc" - - :> atmosphere_names_for_ice.dat - echo ""; echo " * temperature below firn" - echo "atmosphere_name_temperature_below_firn=tsurf" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_temperature=K" >> atmosphere_names_for_ice.dat - echo ""; echo " * temperature" - echo "atmosphere_name_temperature=temp2" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_temperature=K" >> atmosphere_names_for_ice.dat - echo ""; echo " * precipitation" - echo "atmosphere_name_precipitation=aprt" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_precipitation=kg/m2/s" >> atmosphere_names_for_ice.dat - echo ""; echo " * elevation" - echo "atmosphere_name_elevation=orog" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_elevation=m" >> atmosphere_names_for_ice.dat - echo ""; echo " * shortwave downward radiation" - echo "atmosphere_name_shortwave=swd" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_shortwave=W/m2" >> atmosphere_names_for_ice.dat - echo ""; echo " * emissivity" - echo "atmosphere_name_emissivity=emiss" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_emissivity=frac" >> atmosphere_names_for_ice.dat - echo ""; echo " * wind speed" - echo "atmosphere_name_wind=uv" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_wind=m/s" >> atmosphere_names_for_ice.dat - #echo ""; echo " * longwave downward radiation" - #echo "atmosphere_name_longwave=lwd" >> atmosphere_names_for_ice.dat - #echo "atmosphere_units_longwave=W/m2" >> atmosphere_names_for_ice.dat - echo ""; echo " * cloud cover" - echo "atmosphere_name_cloud_cover=cc" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_cloud_cover=frac" >> atmosphere_names_for_ice.dat - echo ""; echo " * spec. humidity@2m" - echo "atmosphere_name_humidity=q2m" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_humidity=frac" >> atmosphere_names_for_ice.dat - echo ""; echo " * atm. transmissivity" - echo "atmosphere_name_transmissivity=tau" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_transmissivity=frac" >> atmosphere_names_for_ice.dat - echo ""; echo " * TOA shortwave downward radiation" - echo "atmosphere_name_TOAshortwave=TOAswd" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_TOAshortwave=W/m2" >> atmosphere_names_for_ice.dat - #add_to $(pwd)/atmosphere_names_for_ice.dat atmosphere_names_for_ice.dat couple - cp $(pwd)/atmosphere_names_for_ice.dat ${COUPLE_DIR}/atmosphere_names_for_ice.dat - - echo; echo " ...done."; echo -} - -## @fn echam_ice_construct_input_list() -## @brief constructs the list of input files -## -## By using a parsed version of `CHUNK_END_DATE_echam` and `number_of_years_for_forcing`, -## this constructs a list of files which match: -## `${DATA_DIR_echam}/${EXP_ID}_echam6_echam_${year}${month}.grb` -## -## @warning Construction of the input list is **directly** dependent on the formatting of `ECHAM6` -## output filenames. **A change in the convention of output filenames will break this function.** -echam_ice_construct_input_list() { - echo ""; echo " * constructing input list" - - CHUNK_END_YEAR_echam=$(date -d "${CHUNK_END_DATE_echam:?Missing_var}" +%Y) - CHUNK_END_MONTH_echam=$(date -d "${CHUNK_END_DATE_echam:?Missing_var}" +%m) - CHUNK_END_DAY_echam=$(date -d "${CHUNK_END_DATE_echam:?Missing_var}" +%d) - - test_if_set CHUNK_END_YEAR_echam - number_of_years_for_forcing=${number_of_years_for_forcing:-1} - start_year_couple=$(( CHUNK_END_YEAR_echam - number_of_years_for_forcing + 1 )) - end_year_couple=${CHUNK_END_YEAR_echam} - echam6_file_list_for_ice="" - for year in $(seq $start_year_couple $end_year_couple ); do - for month in $(seq -f "%02g" 1 12); do - if [ -f "${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_ism" ]; then - current_file="${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_ism" - elif [ -f "${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_echam" ]; then - current_file="${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_echam" - else - echo ""; echo " FILE ${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_echam not found! " - exit 42 - fi - echam6_file_list_for_ice="$echam6_file_list_for_ice $current_file" - done - done - -} - -## @fn echam_ice_select_relevant_variables() -## @brief Cuts out orography, precipitation, and 2-m air temperature from `ECHAM6` output. -## -## Selects variables `geosp`, `aprl`, `aprc`, `temp2` 'sradsu', 'srads', -# 'trads'. 'tradsu' and 'aclcov' from files in `echam6_file_list_for_ice` -## In the output, `aprt` = `aprl` + `aprc`, and `orog`=`geosp`/9.81, -# 'swd'= 'srads'-'sradsu' and 'lwd'= 'trads'-'tradsu' -## -## @todo This function needs to be more flexible and also select variables needed for different -## mass balance schemes, e.g. an EBM. -echam_ice_select_relevant_variables() { - echo ""; echo " * selecting relevant variables" - - processed_echam6_file_list_for_ice="" - - if [[ "x${oro_update_var}" == "xgeosp" ]]; then - for file in ${echam6_file_list_for_ice}; do - filename=$(basename $file) - ${cdo} -s -f nc \ - -expr,"orog=geosp/9.81; aprt=aprl+aprc; temp2=temp2; tsurf=tsurf; swd=srads-sradsu; cc=aclcov; \ - emiss=(trads-tradsu)/(5.6703744e-8*temp2^4); \ - tau=((srad0d<5)? 0.5 : ((srads-sradsu)/srad0d)); TOAswd=srad0d; q2m=q2m; - uv=(u10^2+v10^2)^(1/2)" \ - -setcodetab,${file}.codes \ - -selcode,169,167,143,142,144,129,176,204,177,205,164,184,54,165,166 \ - $file \ - "${filename%.*}"_for_ice.nc 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - #-expr,"temp2=temp2; orog=geosp/9.81; aprt=aprl+aprc; swd=srads-sradsu; lwd=trads-tradsu; cc=aclcov" \ - #-setcodetab,echam \ - #-selcode,169,143,142,129,176,204,177,205,164 \ - - processed_echam6_file_list_for_ice="$processed_echam6_file_list_for_ice ${filename%.*}_for_ice.nc" - done - else - for file in ${echam6_file_list_for_ice}; do - filename=$(basename $file) - ${cdo} -s -f nc \ - -expr,"aprt=aprl+aprc; temp2=temp2; tsurf=tsurf; swd=srads-sradsu; cc=aclcov; \ - emiss=(trads-tradsu)/(5.6703744e-8*temp2^4); \ - tau=((srad0d<5)? 0.5 : ((srads-sradsu)/srad0d)); TOAswd=srad0d; q2m=q2m; - uv=(u10^2+v10^2)^(1/2)" \ - -setcodetab,${file}.codes \ - -selcode,169,167,143,142,144,129,176,204,177,205,164,184,54,165,166 \ - $file \ - "${filename%.*}"_for_ice.nc 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - #-expr,"temp2=temp2; orog=geosp/9.81; aprt=aprl+aprc; swd=srads-sradsu; lwd=trads-tradsu; cc=aclcov" \ - #-setcodetab,echam \ - #-selcode,169,143,142,129,176,204,177,205,164 \ - processed_echam6_file_list_for_ice="$processed_echam6_file_list_for_ice ${filename%.*}_for_ice.nc" - done - fi - unset echam6_file_list_for_ice -} - -## @fn echam_ice_concatenate_files() -## @brief Combines files from `processed_echam6_file_list_for_ice` -## -## Combines all files in the `processed_echam6_file_list_for_ice` to a file `atmosphere_file_for_ice.nc`, -## and removes the individual files. -echam_ice_concatenate_files() { - echo ""; echo " * concatenating files" - - test -f atmosphere_file_for_ice.nc && rm atmosphere_file_for_ice.nc - ${cdo} -s cat ${processed_echam6_file_list_for_ice} atmosphere_file_for_ice.nc 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - if [[ ! "x${oro_update_var}" == "xgeosp" ]]; then - - latest_restart_file="${RESTART_DIR_echam}/restart_${EXP_ID}_echam_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}.nc" - echo " * latest_restart_file=${latest_restart_file}" - - cdo -s chname,oromea,orog -selname,oromea ${latest_restart_file} orog_tmp - ncks -A -v orog orog_tmp atmosphere_file_for_ice.nc 2>> ${COUPLE_DIR}/nco_stderr_echam2ice - rm orog_tmp - fi - - #rm ${processed_echam6_file_list_for_ice} - unset processed_echam6_file_list_for_ice -} - -## @fn echam_ice_generate_multiyear_mean() -## @brief Makes a multiyear mean of `atmosphere_file_for_ice.nc` -## -## If the switch #ECHAM_TO_ISM_multiyear_mean is set to `1`, a multi-year monthly mean of `atmosphere_file_for_ice.nc` is made. -echam_ice_generate_multiyear_mean() { - echo ""; echo " * making multi-year monthly mean" - - ################################## - CHUNK_END_YEAR_echam=$(date -d "${CHUNK_END_DATE_echam:?Missing_var}" +%Y) - CHUNK_START_YEAR_echam=$(date -d "${CHUNK_START_DATE_echam:?Missing_var}" +%Y) - - start_year_couple=$(( CHUNK_START_YEAR_echam + 1 )) - echo "* select years from ${start_year_couple} to ${CHUNK_END_YEAR_echam} " - ################################## - - ################################### - ## LA: choose minimum temperature - #echo ""; echo " * selcting year with minimum summer temp2 over NA" - #${cdo} -s -yearmean -selmon,4,5,6 -selname,temp2 atmosphere_file_for_ice.nc tmp - #${cdo} -s -sellonlatbox,-100,-55,40,60 tmp tmp2 - #${cdo} -s -fldmean tmp2 tmp3 - #${cdo} -s -eq -timmin tmp3 tmp3 tmp4 - #${cdo} -s -remapnn,${COUPLE_DIR}/atmosphere.griddes tmp4 tmp5 - #${cdo} -s -splityear tmp5 year - #${cdo} -s -splityear atmosphere_file_for_ice.nc atm.year - - ##for YEAR in $(CHUNK_START_YEAR_echam..CHUNK_END_YEAR_echam) - #for YEAR in $(seq ${CHUNK_START_YEAR_echam} 1 ${CHUNK_END_YEAR_echam}) - #do - # echo ""; echo " * processing year ${YEAR}" - # ${cdo} -s -ifthen year${YEAR}.nc atm.year${YEAR}.nc tmp.year${YEAR}.nc - #done - #${cdo} -s -ymonsum -cat "tmp.year*.nc" tmp.final - #mv tmp.final atmosphere_file_for_ice.nc - ##rm tmp tmp2 tmp3 tmp4 tmp5 atm.year* year* tmp.year* - ################################### - - ${cdo} -s -ymonmean -selyear,${start_year_couple}/${CHUNK_END_YEAR_echam} atmosphere_file_for_ice.nc tmp 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - mv -f tmp atmosphere_file_for_ice.nc -} - -# emacs: -*- mode: shell; -# vim: expandtab copyindent preserveindent softtabstop=0 shiftwidth=4 tabstop=4 -# -- last line diff --git a/couplings/coupling_dual-hemisphere/echam/coupling_ice2echam.functions b/couplings/coupling_dual-hemisphere/echam/coupling_ice2echam.functions deleted file mode 100644 index 8a7e9ca87..000000000 --- a/couplings/coupling_dual-hemisphere/echam/coupling_ice2echam.functions +++ /dev/null @@ -1,1563 +0,0 @@ -#!/usr/bin/ksh - -## @fn ice2echam_1st() -ice2echam_1st() { - echo " ==================================================================" - echo " *** S T A R T I N G ice2echam_1st for ${PISM_HEMISPHERE} *** "; echo - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - ISM_TO_ECHAM_update_orography=${ISM_TO_ECHAM_update_orography:-1} - ISM_TO_ECHAM_update_glacial_mask=${ISM_TO_ECHAM_update_glacial_mask:-1} - ISM_TO_ECHAM_update_land_runoff=${ISM_TO_ECHAM_update_land_runoff:-1} - HOSING_CORRECTION=${HOSING_CORRECTION:-0} - - :> nco_stderr_ice2echam; :> cdo_stderr_ice2echam - - counter=0 - COUNT_MAX=30 - while [ ${counter} -lt ${COUNT_MAX} ] - do - echo " * inside while loop " - if [ -f ${COUPLE_DIR}/../outdata//${PISM_HEMISPHERE}/latest_ex_file_pism.nc ]; then - break - fi - - echo; echo " * File ${COUPLE_DIR}/../outdata//${PISM_HEMISPHERE}/latest_ex_file_pism.nc not found. Waiting for 10 seconds ..." - sleep 10 - counter=$((counter+1)) - done - - read_names ice atmosphere - define_echam_names - if [ "$ISM_TO_ECHAM_update_glacial_mask" -eq 1 ]; then - iterative_coupling_ice_echam6_update_glacial_mask_1st - fi - if [ "$ISM_TO_ECHAM_update_orography" -eq 1 ]; then - iterative_coupling_ice_echam6_update_orography_1st - fi - if [ "$ISM_TO_ECHAM_update_land_runoff" -eq 1 ]; then - iterative_coupling_ice_echam6_update_land_runoff_1st - fi - - echo " *** F I N I S H E D ice2echam_1st *** " - echo " ==================================================================" -} -## @fn ice2echam_2nd() -ice2echam_2nd() { - echo " ==================================================================" - echo " *** S T A R T I N G ice2echam_2nd for ${PISM_HEMISPHERE} *** "; echo - - if [ "$ISM_TO_ECHAM_update_orography" -eq 1 ]; then - iterative_coupling_ice_echam6_update_orography_2nd - fi - if [ "$ISM_TO_ECHAM_update_glacial_mask" -eq 1 ]; then - iterative_coupling_ice_echam6_update_glacial_mask_2nd - fi - if [ "$ISM_TO_ECHAM_update_land_runoff" -eq 1 ]; then - iterative_coupling_ice_echam6_update_land_runoff_2nd - fi - - echo " *** F I N I S H E D ice2echam_2nd *** " - echo " ==================================================================" -} - -## @fn define_echam_names() -define_echam_names() { - echam_glacial_mask_name=glac -} - -## @fn iterative_coupling_ice_echam6_update_orography_1st() -iterative_coupling_ice_echam6_update_orography_1st() { - echo " Updating orography and gravity wave drag parameterization in echam6" - update_orography_select_field - if [ "$MACHINE" == "levante" ]; then - hi_res_init_oro="/pool/data/ECHAM5/T511/T511_jan_surf.nc" - fi - if [ -f ${hi_res_init_oro} ] - then - regrid_to_echam ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference.nc remapbil T511 - regrid_to_echam ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference.nc remapbil - update_orography_apply_orography_anomaly_high_res - update_orography_prepare_calnoro_high_res - else - regrid_to_echam ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference.nc remapbil - update_orography_apply_orography_anomaly - update_orography_prepare_calnoro - fi -} -## @fn iterative_coupling_ice_echam6_update_orography_2nd() -iterative_coupling_ice_echam6_update_orography_2nd() { - update_orography_run_calnoro - update_orography_generate_target_orography_file - #set_in_jsbach_restart_file elevation ${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc OROMEA unpack - #update_orography_set_namelist_modifications_next_echam_run - echo; echo " ...done."; echo -} - -update_orography_from_martins_script() { -cdo -L -remapbil,${RES_echam}grid / - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference_T511grid.nc / - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference_${RES_echam}grid.nc -#cdo -L -setmisstoc,0. -ifthen slf.nc ${COUPLE_DIR}/ice_orog_difference_${RES_echam}grid.nc dummy.nc -#mv dummy.nc ${COUPLE_DIR}/ice_orog_difference_${RES_echam}grid.nc -ECHAM_g=9.80665 -if [ -L ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc ]; then - rfile=$(readlink ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc) -else - rfile=${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc -fi -cdo -L -sp2gp -gp2sp -add -selvar,GEOSP ${rfile} -mulc,${ECHAM_g} / - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference_${RES_echam}grid.nc / - ${COUPLE_DIR}/${PISM_HEMISPHERE}/echam6_new_orography_before_calnoro_low_res.nc -mv geosp.nc ${output_dir}/input/echam6/GEOSP_${paleo_time}_${RES_echam}.nc -} - -update_oromea_from_martins_script() { -ofile=${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc - -cdo -L -remapnn,r720x360 -setgrid,T511grid -selvar,OROMEA ${hi_res_init_oro} oromea_pi_r720x360.nc -cdo -L -remapnn,r720x360 ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference_T511grid.nc anom_topo_r720x360.nc -#cdo -L -setmisstoc,0. -ifthen -remapnn,r720x360grid slf.nc anom_topo_r720x360.nc dummy.nc -#mv dummy.nc anom_topo_r720x360.nc -cdo -L -add oromea_pi_r720x360.nc anom_topo_r720x360.nc oromea_r720x360.nc -cdo -L -mul oromea_r720x360.nc -gtc,0. oromea_r720x360.nc dummy.nc; mv dummy.nc oromea_r720x360.nc -CALNORO_RES=${echam_res:1:3} # use defined ECHAM6 grid resolution for calnoro -cp oromea_r720x360.nc topodata.nc -echo ${CALNORO_RES} | ${calnoro_dir}/calnoro -cdo -L -s -f nc -setgrid,${echam_res}grid -invertlat sso_par_fil.srv calnoro_output.nc -cdo -L -chvar,var51,OROMEA,var52,OROSTD,var53,OROSIG,var54,OROGAM,var55,OROTHE,var56,OROPIC,var57,OROVAL calnoro_output.nc ${ofile} -cdo -L -mul -selvar,OROMEA ${ofile} -gtc,0. -selvar,OROMEA ${ofile} oromea.tmp -# save geosp and oro-xxx in different files. why oromea from original file @PG? -cdo -L -replace ${ofile} oromea.tmp dummy.nc; mv dummy.nc ${ofile} -rm oromea.tmp -rm oromea_pi_r720x360.nc anom_topo_r720x360.nc oromea_r720x360.nc topodata.nc sso_par_fil.srv calnoro_output.nc -} - - -## @fn update_orography_apply_orography_anomaly_high_res() -update_orography_apply_orography_anomaly_high_res() { - echo; echo " * applying surface height changes to high-resolution echam topography" - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference_T511grid.nc - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/echam6_new_orography_before_calnoro_high_res.nc - ncrename -v ${ice_orography_difference_name},oromea $ifile - cdo -s -setmisstoc,0 $ifile tmp; mv tmp $ifile - if [[ -f ${ofile} ]] - then - rfile=${ofile} - ncks -O -v oromea $rfile tmp_oromea - else - rfile=${hi_res_init_oro} - ncks -O -v OROMEA $rfile tmp_oromea - ncrename -v OROMEA,oromea tmp_oromea - fi - change_lonlat $ifile oromea - # LA: need to backup echam6_new_orography_before_calnoro!!! - ncbo -O --operation=add $ifile tmp_oromea $ofile 2>> nco_stderr_ice2echam - - update_orography_apply_orography_anomaly -} - -## @fn iterative_coupling_ice_echam6_update_glacial_mask_1st() -iterative_coupling_ice_echam6_update_glacial_mask_1st() { - echo " Updating Glacial Mask in echam6" - set_glacial_mask_select_field - set_glacial_mask_echam_restart_file_1st $ifile -} -## @fn iterative_coupling_ice_echam6_update_glacial_mask_2nd) -iterative_coupling_ice_echam6_update_glacial_mask_2nd() { - set_glacial_mask_echam_restart_file_2nd $ifile - if [ -d ${COUPLE_DIR}/jsbach_init_file_modifications ]; then - rm -rf ${COUPLE_DIR}/jsbach_init_file_modifications - fi - mkdir ${COUPLE_DIR}/jsbach_init_file_modifications - here=$(pwd) - cd ${COUPLE_DIR}/jsbach_init_file_modifications - set_glacial_mask_echam_make_dummy_jan_surf - set_glacial_mask_jsbach_update_init_file - cd $here - rm -rf ${COUPLE_DIR}/jsbach_init_file_modifications - set_glacial_mask_jsbach_update_restart_jsbach - set_glacial_mask_jsbach_update_restart_veg - echo; echo " ...done."; echo -} - -## @fn iterative_coupling_ice_echam6_update_land_runoff_1st() -iterative_coupling_ice_echam6_update_land_runoff_1st() { - echo " Setting Glacial Runoff for incorporation in HD-Model via oasis3-mct" - update_land_runoff_select_glacial_discharge - regrid_to_echam ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_discharge.nc -} -## @fn iterative_coupling_ice_echam6_update_land_runoff_2nd() -iterative_coupling_ice_echam6_update_land_runoff_2nd() { - update_land_runoff_fill_missing - if [ "x${HOSING_CORRECTION}" == "x1" ]; then - echo; echo " * Correcting freshwater input by hosing " - distribute_total_discharge_over_ocean - else - echo; echo " * NOT correcting freshwater input by hosing " - fi - update_land_runoff_prepare_for_oasis - update_land_runoff_set_namcouple_override - #update_land_runoff_set_namelist_modifications_next_echam_run - #update_land_runoff_set_namelist_modifications_next_jsbach_run - echo; echo " ...done."; echo -} - -## @fn update_orography_select_field() -update_orography_select_field() { - echo; echo " * selecting orography difference over ice run" - cdo -s selvar,${ice_orography_difference_name} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_for_atmosphere.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference.nc - rmlist="$rmlist ${COUPLE_DIR}/ice_orog_difference.nc" -} - -## @fn update_orography_apply_orography_anomaly() -update_orography_apply_orography_anomaly() { - echo; echo " * applying surface height changes to echam topography" - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference_${RES_echam}grid.nc - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/echam6_new_orography_before_calnoro_low_res.nc - ncrename -v ${ice_orography_difference_name},oromea $ifile - cdo -s -setmisstoc,0 $ifile tmp; mv tmp $ifile - if [ -L ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc ]; then - rfile=$(readlink ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc) - else - rfile=${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc - fi - ncks -O -v oromea $rfile tmp_oromea - change_lonlat $ifile oromea - ncbo -O --operation=add $ifile tmp_oromea $ofile 2>> nco_stderr_ice2echam -} - -## @fn update_orography_prepare_calnoro_high_res() -update_orography_prepare_calnoro_high_res() { - echo; echo " * preparing for external program CALNORO" - ifile=${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc - ofile=topodata.nc - cdo -s -P 28 \ - -remapnn,r720x360 \ - -setgrid,T511grid \ - -chname,oromea,OROMEA \ - $ifile \ - $ofile 2>>cdo_stderr_ice2echam -} - -## @fn update_orography_prepare_calnoro() -update_orography_prepare_calnoro() { - echo; echo " * preparing for external program CALNORO" - ifile=${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc - ofile=topodata.nc - cdo -s -P 28 \ - -remapnn,r720x360 \ - -setgrid,${RES_echam}grid \ - -chname,oromea,OROMEA \ - $ifile \ - $ofile 2>>cdo_stderr_ice2echam -} - -## @fn update_orography_run_calnoro() -update_orography_run_calnoro() { - echo; echo " * running CALNORO" - ofile=${COUPLE_DIR}/calnoro_output.nc - if [ ! -f calnoro ]; then - if [ ! -f ${FUNCTION_PATH}/../utils/calnoro ]; then - if [ -f ${FUNCTION_PATH}/../utils/install_calnoro.sh ]; then - echo " install_calnoro.sh found. Running installation ..." - currentdir=$(pwd) - cd ${FUNCTION_PATH}/../utils/ - ./install_calnoro.sh ${MACHINE} - cd ${currentdir} - cp ${FUNCTION_PATH}/../utils/calnoro . - else - echo " !!! FATAL ERROR: Compiled external utility CALNORO not found" - echo " !!! Looking in: ${FUNCTION_PATH}/../utils/" - echo " !!! FATAL ERROR: Please compile this program using the install_calnoro.sh script!" - exit 42 - fi - else - cp ${FUNCTION_PATH}/../utils/calnoro . - fi - fi - # Make sure dimension order is correct: - change_lonlat topodata.nc OROMEA - - module list - if [ "$MACHINE" == "levante" ]; then - export LD_LIBRARY_PATH=/sw/spack-levante/netcdf-fortran-4.5.3-jlxcfz/lib/:$LD_LIBRARY_PATH - elif [ "$MACHINE" == "albedo" ]; then - export LD_LIBRARY_PATH=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/lib/:$LD_LIBRARY_PATH - tmp_mods=$( module list -t | tail -n +2 ) - module purge - fi - - echo ${RES_echam/T/} | ./calnoro > ${COUPLE_DIR}/calnoro_stdout_stderr 2>&1 - - if [ "$MACHINE" == "albedo" ]; then - module load $tmp_mods - fi - - cdo -s -f nc -setgrid,$RES_echam -invertlat sso_par_fil.srv $ofile 2>>cdo_stderr_ice2echam - #rm sso_par_fil.srv topodata.nc -} - -## @fn update_orography_generate_target_orography_file() -update_orography_generate_target_orography_file() { - echo; echo " * generating target orography file for linear stepwise change of echam6 orography" - ifile=${COUPLE_DIR}/calnoro_output.nc - ofile=${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc - - typeset -A orography_names - orography_names[var51]=OROMEA - orography_names[var52]=OROSTD - orography_names[var53]=OROSIG - orography_names[var54]=OROGAM - orography_names[var55]=OROTHE - orography_names[var56]=OROPIC - orography_names[var57]=OROVAL - - for varname in "${!orography_names[@]}"; do - ncrename -v ${varname},${orography_names[$varname]} ${ifile} tmp; mv tmp ${ifile} - done - - ## Ensure that we use the OROMEA from the "raw" PISM-corrected orography, - ## not what is given from the calnoro program - - - ############################################################ - # Define the method for orography update (oro_update_mod): - # 1: use low-resolution reference; take all sub-grid scale parameters from CALNORO; take GEOSP from low-res input - # 2: use low-resolution reference; take all sub-grid scale parameters from CALNORO; take OROMEA and GEOSP from low-res input - # (like it has been done before) - # 3: use high-resolution reference; take all sub-grid scale parameterds from CALNORO; take OROMEA and GEOSP from high-res input - # 4: update orography but keep sub-grid scale parameters from unit.24 - # 5: update orography but change sub-grid scale parameters only in ice domain where ice mask or change of ice mask (ice loss/ice gain) - - if [ "x${oro_update_mod}" == "x1" ]; then # according to Martins script: OROMEA from calnoro; GEOSP from input - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - elif [ "x${oro_update_mod}" == "x2" ]; then # old coupling scheme: OROMEA and GEOSP from low-res input - cdo -s -replace \ - ${ifile} \ - -chname,oromea,OROMEA -remapnn,${RES_echam}grid ${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc \ - tmp 2>>cdo_stderr_ice2echam - mv tmp ${ifile} - - # Take the GEOSP field from the "raw" PISM-corrected orography, and not - # what is given from the calnoro program - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - elif [ "x${oro_update_mod}" == "x3" ]; then # new coupling scheme: OROMEA and GEOSP from high-res input - cdo -s -replace \ - ${ifile} \ - -chname,oromea,OROMEA -remapnn,${RES_echam}grid ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - tmp 2>>cdo_stderr_ice2echam - mv tmp ${ifile} - - # Take the GEOSP field from the "raw" PISM-corrected orography, and not - # what is given from the calnoro program - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - # - elif [ "x${oro_update_mod}" == "x4" ]; then # new coupling scheme: OROMEA and GEOSP from high-res input but overwrite with unit.24 sub-grid parameters - cdo -s -replace \ - ${ifile} \ - -chname,oromea,OROMEA -remapnn,${RES_echam}grid ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - tmp 2>>cdo_stderr_ice2echam - mv tmp ${ifile} - - # Take the GEOSP field from the "raw" PISM-corrected orography, and not - # what is given from the calnoro program - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - - cdo -s replace ${ofile} ${INIT_DIR_echam}/unit.24 tmp_replace; mv tmp_replace ${ofile} - # - - elif [ "x${oro_update_mod}" == "x5" ]; then # masked: new coupling scheme: OROMEA and GEOSP from high-res input - cdo -s -replace \ - ${ifile} \ - -chname,oromea,OROMEA -remapnn,${RES_echam}grid ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - tmp 2>>cdo_stderr_ice2echam - mv tmp ${ifile} - - # Take the GEOSP field from the "raw" PISM-corrected orography, and not - # what is given from the calnoro program - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - - if [ -L ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc ]; then - rfile=$(readlink ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc) - else - rfile=${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc - fi - - cdo -s -ifthen ${COUPLE_DIR}/ice_domain_current_T63grid.nc -gtc,0 \ - -add ${COUPLE_DIR}/ice_mask_current_T63grid.nc -selname,GLAC ${INIT_DIR_echam}/unit.24 \ #${COUPLE_DIR}/ice_mask_before_T63grid.nc \ - ${COUPLE_DIR}/mask_oro_update.nc -# cdo -s selname,glac ${rfile} ${COUPLE_DIR}/ice_mask_before_T63grid.nc - for VAR in "OROMEA" "OROSTD" "OROSIG" "OROGAM" "OROTHE" "OROPIC" "OROVAL" - do - cdo -s ifthenelse -setmisstoc,0 ${COUPLE_DIR}/mask_oro_update.nc \ - -selname,${VAR} ${ofile} \ - -selname,${VAR} ${INIT_DIR_echam}/unit.24 ${VAR}.orotmp - - done - cdo -s merge *.orotmp ORO_merged #; mv ORO_merged ${ofile}; rm *.orotmp - cdo -s replace ${ofile} ORO_merged tmp; mv tmp ${ofile} - # - fi - ############################################################ - ln -sf ${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${COUPLE_DIR}/latest_target_orography.nc - # Destroy# the time dimension; just in case - #if ncdump -h# $ofile | grep -q "time"; then - # ncwa -a time $ofile tmp; mv tmp $ofile - #fi - echo; echo -e "\t\t- finished with target orography generation" -} - -### @fn update_orography_set_namelist_modifications_next_echam_run() -#update_orography_set_namelist_modifications_next_echam_run() { -# echam_variable_modify_file=${COUPLE_DIR}/echam_namelist_switches_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat -# echo; echo " * setting echam variables for update ororgapy to be read from file in next run" -# echo " - echam_variable_modify_file=$echam_variable_modify_file" -# if [ ! -s $echam_variable_modify_file ]; then -# :> $echam_variable_modify_file -# fi -# echo "submodelctl___lupdate_orog___nml_entry=.TRUE." >> $echam_variable_modify_file -# echo "submodelctl___lupdate_orog___nml_file=namelist.echam" >> $echam_variable_modify_file -# add_to ${echam_variable_modify_file} echam_namelist_switches.dat config echam -#} - -## @fn set_glacial_mask_select_field() -set_glacial_mask_select_field() { - echo; echo " * selecting glacial mask" - cdo \ - -selvar,${ice_glacial_mask_name} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_for_atmosphere.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_mask_current.nc 2>> cdo_stderr_ice2echam - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_mask_current.nc tmp -# # Since conflicting module create a challenge, we save -# # the current set of loaded modules, purge the module -# # list, load necessary working modules, do the job by -# # calling ncdump and ncgen, and restore the former -# # purged module list. -# # -# # MODULE-FIX: 1/2 -# module_save_file=/tmp/module2restore_4ncdump_ncgen.$$ -# module save -f $module_save_file -# module purge -# module load netcdf-c - ncdump tmp | sed 's/byte/float/g' | ncgen -o tmp.nc; mv tmp.nc tmp - # - # Recover purged modules - # - # MODULE_FIX: 2/2 -# module restore -f $module_save_file && rm $module_save_file - - mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_mask_current.nc - rmlist="$rmlist ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_mask_current.nc" -} - -## @fn set_glacial_mask_echam_restart_file_1st() -set_glacial_mask_echam_restart_file_1st() { - if [ -L ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc ]; then - ECHAM_RESTART_FILE=$(readlink ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc) - else - ECHAM_RESTART_FILE=${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc - fi - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_mask_current.nc - dfile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_domain_current.nc - cdo -s setrtoc,0,1,1 $ifile $dfile - - echo; echo " * Setting ice mask in: $ECHAM_RESTART_FILE" - echo " from: $ifile" - echo " using region: $dfile" - - # Define the entire area where pism is defined: - ncrename -v ${ice_glacial_mask_name},ice_mask $ifile - ncrename -v ${ice_glacial_mask_name},ice_domain $dfile - - regrid_to_echam $ifile - regrid_to_echam $dfile - - ifile=${ifile%.*}_${RES_echam}grid.nc - dfile=${dfile%.*}_${RES_echam}grid.nc - - cdo -s -setmisstoc,0 $ifile tmp 2>> cdo_stderr_ice2echam; mv tmp $ifile - cdo -s -gec,${ECHAM_GLACIAL_THRESHOLD} $ifile tmp 2>> cdo_stderr_ice2echam; mv tmp $ifile # PG: Ensure the mask is binary after regridding. - - change_lonlat $ifile ice_mask - change_lonlat $dfile ice_domain -} -## @fn set_glacial_mask_echam_restart_file_2nd() -set_glacial_mask_echam_restart_file_2nd() { - ifile=${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc - dfile=${COUPLE_DIR}/ice_domain_current_${RES_echam}grid.nc - - # Restrict the ice mask on the echam grid to only be valid where echam land - cdo -s -setmisstoc,0 -ifthen -selvar,slm $ECHAM_RESTART_FILE $ifile tmp 2>> cdo_stderr_ice2echam; mv tmp $ifile - - cp $ECHAM_RESTART_FILE ${ECHAM_RESTART_FILE%.*}_backup_before_glacial_mask_replacement.nc - cp $ECHAM_RESTART_FILE echam_with_ice_mask.nc - - echo " - Preforming replacement" - - cdo -s -selvar,glac ${ECHAM_RESTART_FILE} just_glac.nc 2>> cdo_stderr_ice2echam - cdo -s -ifthenelse -setmisstoc,0 $dfile -chname,ice_mask,glac $ifile just_glac.nc just_glac_new.nc 2>> cdo_stderr_ice2echam - -# # Since conflicting module create a challenge, we save -# # the current set of loaded modules, purge the module -# # list, load necessary working modules, do the job by -# # calling ncdump and ncgen, and restore the former -# # purged module list. -# # -# # MODULE-FIX: 1/2 -# module_save_file=/tmp/module2restore_4ncdump_ncgen.$$ -# module save -f $module_save_file -# module purge -# module load netcdf-c - ncdump just_glac_new.nc | sed s/int/double/g | ncgen -o tmp; mv tmp just_glac_new.nc - # - # Recover purged modules - # - # MODULE_FIX: 2/2 -# module restore -f $module_save_file && rm $module_save_file - - # This multipliation transforms "float" into "double" - ncap=${ncap:-ncap2} - $ncap -s "glac=glac*1.0000000000000;" \ - just_glac_new.nc \ - just_glac_new.tmp.nc - ncks -A just_glac_new.tmp.nc echam_with_ice_mask.nc - - #mv echam_with_ice_mask.nc ${ECHAM_RESTART_FILE} - [ -f ${ECHAM_RESTART_FILE} ] && mv -f ${ECHAM_RESTART_FILE} ${ECHAM_RESTART_FILE}~ - ncatted -a history_of_appended_files,global,d,, \ - -a history,global,d,, \ - -a command,global,d,, \ - -a source,global,d,, \ - echam_with_ice_mask.nc ${ECHAM_RESTART_FILE} \ - && rm -f ${ECHAM_RESTART_FILE}~ # `ncatted` fails if $ECHAM_RESTART_FILE exists - ncrename -v ice_mask,glac $ifile - rm just_glac_new.nc - rm just_glac_new.tmp.nc - #rmlist="$rmlist ${COUPLE_DIR}/just_glac_new.nc" - #rmlist="$rmlist ${COUPLE_DIR}/just_glac_new.tmp.nc" -} - -## @fn set_glacial_mask_echam_make_dummy_jan_surf() -set_glacial_mask_echam_make_dummy_jan_surf() { - echo; echo " * Generating a dummy unit.24 file with new ice orography and mask" - # Generates a dummy unit.24 file by modifying a copy of the - # The echam restart file has already been modified with the "correct" - # glacial mask", construct a dummy one from the restart - #CLEANUP cp ${BASE_DIR}/${EXP_ID}/awicm/input/echam/unit.24 dummy_jan_surf.nc - cp ${INIT_DIR_echam}/unit.24 dummy_jan_surf.nc - # Fix Lu: --------------------------- - if [[ ${DOMAIN_pism} == "nhem" ]]; then - cdo setclonlatbox,0,0,360,0,90 -selvar,GLAC dummy_jan_surf.nc tmp - cdo -replace dummy_jan_surf.nc tmp dummy_jan_surf.nc2 - mv dummy_jan_surf.nc2 dummy_jan_surf.nc - rm tmp - fi - # Fix Lu: --------------------------- - cdo -s replace dummy_jan_surf.nc \ - ${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - tmp && mv tmp dummy_jan_surf.nc - # Fix Albedo where there are glaciers: - #echam_albedo_on_glaciers=0.7 - echam_albedo_on_glaciers=${ECHAM_ALBEDO_ON_GLACIERS} - cdo -s \ - -setmisstoc,${echam_albedo_on_glaciers} -setrtomiss,-1,2 \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc - cdo -s \ - -selvar,ALB dummy_jan_surf.nc input_if_mask_false.nc - cdo -s -ifthenelse \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc \ - input_if_mask_false.nc \ - dummy_jan_surf_ALB.nc - cdo -s replace \ - dummy_jan_surf.nc \ - -chname,${echam_glacial_mask_name},ALB dummy_jan_surf_ALB.nc \ - tmp; mv tmp dummy_jan_surf.nc - - # Fix lakes where there are glaciers - cdo -s \ - -setrtoc,0,1,0 -selvar,ALAKE dummy_jan_surf.nc input_if_mask_true.nc - cdo -s \ - -selvar,ALAKE dummy_jan_surf.nc input_if_mask_false.nc - cdo -s -ifthenelse \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc \ - input_if_mask_false.nc \ - dummy_jan_surf_ALAKE.nc - cdo -s replace \ - dummy_jan_surf.nc \ - dummy_jan_surf_ALAKE.nc tmp #-chname,${echam_glacial_mask_name},ALAKE dummy_jan_surf_ALAKE.nc \ - mv tmp dummy_jan_surf.nc - - cdo -s \ - -setmisstoc,1 -setrtomiss,-1,2 \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc - cdo -s \ - -selvar,GLAC dummy_jan_surf.nc input_if_mask_false.nc - - cdo -s -ifthenelse \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc \ - input_if_mask_false.nc \ - dummy_jan_surf_GLAC.nc - - cdo -s replace \ - dummy_jan_surf.nc \ - -chname,${echam_glacial_mask_name},GLAC dummy_jan_surf_GLAC.nc \ - tmp; mv tmp dummy_jan_surf.nc -} - -## @fn set_glacial_mask_jsbach_update_init_file() -set_glacial_mask_jsbach_update_init_file() { - echo; echo " * Generating a new JSBACH init file with updated land cover types" - # Get the Program and required .mod files - if [ -f ${FUNCTION_PATH}/../utils/jsbach_init_file ]; then - cp ${FUNCTION_PATH}/../utils/jsbach_init_file . - elif [ -f ${FUNCTION_PATH}/../utils/install_jsbach_init_file.sh ]; then - echo " install_jsbach_init_file.sh found. Running installation ..." - currentdir=$(pwd) - cd ${FUNCTION_PATH}/../utils/ - ./install_jsbach_init_file.sh ${MACHINE} - cd ${currentdir} - cp -v ${FUNCTION_PATH}/../utils/jsbach_init_file . - else - echo -e "\t\t E R O R R --- binary missing, don't know how to proceed" - exit - fi - cp ${FUNCTION_PATH}/../utils/_build/mo_kinds.mod . - cp ${FUNCTION_PATH}/../utils/_build/mo_vegparams.mod . - cleanup_list="$cleanup_list jsbach_init_file mo_kinds.mod mo_vegparams.mod" - # Here we place a slimmed-down version of the Veronika Gayler script: - res_atm=${RES_echam} - res_oce=GENERIC - ntiles=11 # number of jsbach tiles - - dynveg=true # setup for dynamic vegetation - c3c4crop=true # differentiate between C3 and C4 crops - - lpasture=true # distinguish pastures from grasses - read_pasture=LUH2v2h # LUH: read pastures and crops from LUH states as in CMIP5 - # LUH2v2h: read pastures and crops from LUH2 states as in CMIP6 - # false: no separate input file for crops and pastures - pasture_rule=true # allocate pastures primarily on grass lands - - year_ct=1850 # year the cover_types are derived from - year_cf=1850 # year cover fractions are derived from - - landcover_series=false # generate a series of files with cover_types of - # year_ct and fractions from year_cf to year_cf2 - year_cf2=1859 # only used with landcover_series - - echam_fractional=false # initial file for echam runs with fractional - # land sea mask - masks_file=default # file with land sea mask (default: use echam land sea mask) - - mv dummy_jan_surf.nc ${RES_echam}${res_oce}_jan_surf.nc - echo " - Using unit.24 (jan surf) file: ${RES_echam}GENERIC_jan_surf.nc" - echo " --> (This is the dummy file after ice update)" - ln -sf ${INIT_DIR_echam}/unit.91 ${res_atm}${res_oce}_VGRATCLIM.nc - echo " - Using unit.91 (VGRATCLIM) file: ${INIT_DIR_echam}/unit.91" - ln -sf ${INIT_DIR_echam}/unit.90 ${res_atm}${res_oce}_VLTCLIM.nc - echo " - Using unit.90 (VLTCLIM) file: ${INIT_DIR_echam}/unit.90" - - cleanup_list="$cleanup_list ${RES_echam}_jan_surf.nc" - - pool=${POOL_DIR_echam}/ECHAM6/${RES_echam} - pool_land=${POOL_DIR_jsbach}/JSBACH/prepare/${RES_echam} - #------------------------------------------------------------------------------ - # prepare the namelist - #------------------------------------------------------------------------------ - - [[ ${res_oce} = "" ]] && lcouple=.false. || lcouple=.true. - [[ ${dynveg} = true ]] && ldynveg=.true. || ldynveg=.false. - [[ ${c3c4crop} = true ]] && lc3c4crop=.true. || lc3c4crop=.false. - [[ ${read_pasture} != false ]] && lread_pasture=.true. || lread_pasture=.false. - [[ ${landcover_series} = false ]] && year_cf2=${year_cf} - - desert_only=.false. # setup for a desert-only experiment - grass_only=.false. # setup for a grass-only experiment - woods_only=.false. # setup for a woods-only experiment - - cat > namelist < ${COUPLE_DIR}/jsbach_init_file_stdout_stderr 2>&1 - if [ "${MACHINE}" == "ollie" ]; then - module unload netcdf/4.6.2_gnu - module unload hdf5/1.10.2_gnu - module load netcdf - fi - if [[ $? -eq 0 ]]; then - echo -e "\t\t - ...finished with external program jsbach_init_file!" - else - echo "error in jsbach_init_file" - exit 1 - fi - # BUG: How do we know what the output file is called? - mv jsbach_T63GENERIC_11tiles_5layers_1850_dynveg.nc \ - ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc - echo :> ${COUPLE_DIR}/jsbach_init_override_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - - ############################################################################ - # LA UPDATE - ln -sf ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${COUPLE_DIR}/latest_jsbach_init_file.nc - #cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${WORK_DIR}/jsbach.nc - ############################################################################ - - echo "LAND_BOUNDARY_CONDITIONS_jsbach=${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc" > ${COUPLE_DIR}/jsbach_init_override_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - add_to ${COUPLE_DIR}/jsbach_init_override_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat jsbach_init_override.dat config jsbach -} - -set_glacial_mask_jsbach_update_restart_jsbach() { - echo; echo " * updating land cover fractions in jsbach restart file >>jsbach<<" - echo -e "\t\t- Making a temporary directory to work in" - startdir=$(pwd) - if [ -d ${COUPLE_DIR}/update_land_cover_fractions ]; then - # Throw away the temporary working directory from last time to - # avoid merge problems in the next coupling iteration: - rm -rf ${COUPLE_DIR}/update_land_cover_fractions - fi - mkdir -p ${COUPLE_DIR}/update_land_cover_fractions; cd ${COUPLE_DIR}/update_land_cover_fractions - echo -e "\t\t- determining where the glacial mask has advanced and retreated" - echo -e "\t\t- New JSBACH Init File: ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc" - echo -e "\t\t- Old JSBACH Init File: ${FORCING_DIR_jsbach}/jsbach.nc" - cdo -s -sub \ - -selvar,glac ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - -selvar,glac ${FORCING_DIR_jsbach}/jsbach.nc \ - ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc 2>> ${COUPLE_DIR}/update_land_cover_fractions/cdo_stderr_ice2echam - # Make two masks: one for glacial retreat, and one for glacial advance - cdo -s gtc,0 ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc - cdo -s gtc,0 -mulc,-1 ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc - sum_new_glaciers=$(cdo -s -output -fldsum -gtc,0 ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc | tr -d "[:blank:]") - sum_new_land=$(cdo -s -output -fldsum -gtc,0 -mulc,-1 ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc | tr -d "[:blank:]") - echo -e "\t\t- Total number of new glacial cells: >>>$sum_new_glaciers<<<" - echo -e "\t\t- Total number of new deglacial cells: >>>$sum_new_land<<<" - - if [[ $sum_new_glaciers -eq 0 ]] && [[ $sum_new_land -eq 0 ]]; then - echo -e "\t\t- >>>INFO<<< No new land or new glaciers, this routine will be skipped..." - newest_jsbach_restart_file=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc) - ln -sf ${newest_jsbach_restart_file} ${COUPLE_DIR}/latest_jsbach_restart_file.nc - return - fi - - newest_jsbach_restart_file=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc) - # Make a backup copy - #cp $(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc) ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach_backup_$(date +%Y%m%d%H%M%S).nc - - #todo:rm:old:cp ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach_backup_$(date +%Y%m%d%H%M%S).nc - BAK_FILENAME=$(basename $(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc)) - cp ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc ${RESTART_DIR_jsbach}/${BAK_FILENAME%%.nc}_backup_$(date +%Y%m%d%H%M%S).nc - - echo -e "\t\t- Unpacking JSBACH restart file: $newest_jsbach_restart_file" - # Ensure that the unpack binary is here: - if [ ! -f unpack ]; then - if [ -f ${FUNCTION_PATH}/../utils/unpack ]; then - #cp -v ${FUNCTION_PATH}/../utils/unpack ${COUPLE_DIR}/ - cp -v ${FUNCTION_PATH}/../utils/unpack . - elif [ -f ${FUNCTION_PATH}/../utils/install_jsbach_pack_unpack.sh ]; then - echo " install_jsbach_pack_unpack.sh found. Running installation ..." - currentdir=$(pwd) - cd ${FUNCTION_PATH}/../utils/ - ./install_jsbach_pack_unpack.sh ${MACHINE} - cd ${currentdir} - #cp -v ${FUNCTION_PATH}/../utils/unpack ${COUPLE_DIR}/ - cp -v ${FUNCTION_PATH}/../utils/unpack . - else - echo -e "\t\t E R O R R --- unpack binary missing, don't know how to proceed" - exit - fi - fi - - echo " *** unpack binary found here: $(pwd) " 2>&1 > ${COUPLE_DIR}/unpack_script_stdout_stderr - - # Copy the files here: - cp ${newest_jsbach_restart_file} ./ - cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ./ - echo -e "\t\t- Running unpack binary with arguments:" - echo -e "\t\t- Script: ${FUNCTION_PATH}/../utils/unpack_file.ksh" - echo -e "\t\t- Restart File: $(basename ${newest_jsbach_restart_file})" - echo -e "\t\t- Mask file: $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc)" - echo "$(module list)" - ${FUNCTION_PATH}/../utils/unpack_file.ksh \ - $(basename $newest_jsbach_restart_file) \ - $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc) \ - 2>&1 > ${COUPLE_DIR}/unpack_script_stdout_stderr - - echo -e "\t\t- Listing files after program execution:" - ls -ratl - restartfile=2d_$(basename ${newest_jsbach_restart_file}) - # 'cdo showvar' does not work for variables with more than three dimensiones - # Since conflicting module create a challenge, we save - # the current set of loaded modules, purge the module - # list, load necessary working modules, do the job by - # calling ncdump, and restore the former - # purged module list. - # - # MODULE-FIX: 1/2 - module_save_file=/tmp/module2restore_4ncdump.$$ - module save -f $module_save_file - module purge - module load netcdf-c - echo "ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '('" - variables=$(ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '(') - # - # Recover purged modules - # - # MODULE_FIX: 2/2 - module restore -f $module_save_file && rm $module_save_file - echo $variables - - # Rename the "tiles" dimension to "time", since cdo can only handle 4D - # variables if one is called time. This will be corrected again below - ncrename -O -d tiles,time 2d_$(basename ${newest_jsbach_restart_file}) - for var in ${variables}; do - ncks -O --no_abc \ - -v ${var} \ - 2d_$(basename ${newest_jsbach_restart_file}) \ - 2d_restart_${EXP_ID}_jsbach_${var}.nc - - if [ ! -f 2d_restart_${EXP_ID}_jsbach_${var}.nc ]; then - echo -e "\t\t !!! WARNING !!! -- no file for ${var}" - echo -e "\t\t continue loop" - continue - fi - - # Keep the directory clean: make one directory for each variable: - here=$(pwd); mkdir -p ${var}; mv 2d_restart_${EXP_ID}_jsbach_${var}.nc ${var}; cd ${var} - echo -e "\t\t- Updating JSBACH restart file -- ${var}\n" - case ${var} in - cover_fract | cover_fract_pot | veg_ratio) - echo -e "\t\t- Need to set correct cover fractions for retreating and advancing glaciers for $var" - # Split to all the land tiles - # - # NOTE: We use splitrec because we need to - # split fake "timesteps" and not "layers" since - # cdo can't handle 4D without time...remember - # that tiles was renamed to time above. - cdo -s splitrec 2d_restart_${EXP_ID}_jsbach_${var}.nc 2d_restart_${EXP_ID}_jsbach_${var}_tile - mergelist="" - for tile in $(ls 2d_restart_${EXP_ID}_jsbach_${var}_tile0000??.nc); do - case ${tile} in - 2d_restart_${EXP_ID}_jsbach_${var}_tile000001.nc ) - echo -e "\t\t Glacier landpoints for ${var} on ${tile}" - # New glaciers must have exactly 1 or keep the old value - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - ${tile} \ - ${tile}.tmp - # New land must get 1e-10 or keep the old value - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - -mulc,1e-10 ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - ${tile}.tmp \ - ${tile} - - ;; - 2d_restart_${EXP_ID}_jsbach_${var}_tile000007.nc ) - echo -e "\t\t Tundra for ${var} on ${tile}" - # New Glaciers need to be exactly 0 everywhere except on tile 1 - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - -mulc,0 ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - ${tile} \ - ${tile}.tmp - # New land gets the maximum allowed value - # NOTE: This is only valid for 11 tiles!! - # BUG(?): What about the negative values that appear here? - cdo -s -subc,1e-9 \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - ${tile}_maxveg.nc - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - ${tile}_maxveg.nc \ - ${tile}.tmp \ - ${tile} - ;; - *) - echo -e "\t\t Nothing special for ${var} on ${tile}" - # New glacial tiles get exactly 0 - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - -mulc,0 ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - ${tile} ${tile}.tmp - # New land cells get 1e-10: smallest allowed minium - cdo -s -ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - -mulc,1e-10 ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - ${tile}.tmp \ - ${tile} - ;; - esac - # Add the fake time axis after the case - # statement, since the ifthenelse - # clause might do strange things with - # the time axis otherwise: - tile_number=$(echo $tile | rev | cut -d_ -f1 | rev | sed s/tile// | sed s/\.nc//) - cdo -settaxis,${tile_number}-01-01,00:00:00 $tile ${tile}.time; mv ${tile}.time ${tile} - mergelist="$mergelist $tile" - done - cdo -s -O mergetime $mergelist ${var}.tmp - # Ensure the name is correct - cdo -s setvar,$var ${var}.tmp 2d_restart_${EXP_ID}_jsbach_${var}.nc - ;; - soil_moisture) - echo -e "\t\t- Need to change soil moisture for $var" - ;; - layer_moisture) - echo -e "\t\t- Need to change layer moisture for $var" - # NOTE: The layer moisture can't exceed the - # holding capacity, which changes under (new) - # glacier cells. Since the glacial mask was - # used to construct the jsbach.nc forcing file, - # we use those values for new glacial cells: - # - # NOTE 2: the layer moisture variable is called - # layer_moist in jsbach init file, not layer - # moisture. Therefore, the setvar command needs - # to rename it - cdo -s -setvar,${var} -ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - -selvar,layer_moist ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - 2d_restart_${EXP_ID}_jsbach_${var}.nc 2d_restart_${EXP_ID}_jsbach_${var}.tmp - cdo -s -setvar,${var} -ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - -selvar,layer_moist ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - 2d_restart_${EXP_ID}_jsbach_${var}.tmp 2d_restart_${EXP_ID}_jsbach_${var}.nc - ;; - esac - cd $here - done - mergelist="" - for var in ${variables}; do - ncrename -d .time,tiles ${var}/2d_restart_${EXP_ID}_jsbach_${var}.nc 2>&1 >> ${COUPLE_DIR}/nco_stderr_ice2echam - mergelist="$mergelist ${var}/2d_restart_${EXP_ID}_jsbach_${var}.nc" - done - echo -e "\t\t- Creating merge list" - # For debugging: - #echo "Done constructing merge list and renaming time to tiles, these files will be merged" - #for f in $mergelist; do - # ls -l $f - #done - # Merge with ncks, since cdo has issues: - echo -e "\t\t- Merging with ncks, as cdo has problems" - ofile=2d_restart_${EXP_ID}_jsbach_merged.nc - for f in $mergelist; do - ncks -A -h $f $ofile - done - echo -e "\t\t- Done merging, now we need to fix the tiles dimension to be limited again rather than unlimited" - # Turn "tiles" back to a limited dimension: - ncks --fix_rec_dmn tiles $ofile -o tmp; mv tmp $ofile - echo -e "\t\t- Finished with modification of variables, now we need to repack" - - # Ensure that the pack binary is here: - if [ ! -f pack ]; then - #if [ -f ${FUNCTION_PATH}..//utils/_build/pack ]; then - # cp -v ${FUNCTION_PATH}..//utils/_build/pack . - if [ -f ${FUNCTION_PATH}/../utils/pack ]; then - cp -v ${FUNCTION_PATH}/../utils/pack . - else - echo -e "\t\t E R O R R --- pack binary missing, don't know how to proceed" - exit - fi - fi - # Copy the files here: - cp ${newest_jsbach_restart_file} . - cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc . - echo -e "\t\t- Running pack binary with arguments:" - echo -e "\t\t- Script: ${FUNCTION_PATH}/../utils/pack_file.ksh" - echo -e "\t\t- Restart File: $(readlink -f ${ofile})" - echo -e "\t\t- Mask file: $(readlink -f ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc)" - echo -e "\n\t\t - NOTE: Errors with >VARDIMIDS (value 2) is out of range (1:1)< can be ignored (maybe?)" - ${FUNCTION_PATH}/../utils/pack_file.ksh \ - $(basename $ofile) \ - $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc) - - echo -e "\t\t- Listing files after program execution:" - ls -ratl - - mv 1d_$(basename $ofile) ${newest_jsbach_restart_file} - ln -sf ${newest_jsbach_restart_file} ${COUPLE_DIR}/latest_jsbach_restart_file.nc - # Go back to the previous directory - cd ${startdir} -} - -set_glacial_mask_jsbach_update_restart_veg() { - echo; echo " * updating active and bare plant fractions in jsbach restart file >>veg<<" - echo -e "\t\t- Making a temporary directory to work in" - startdir=$(pwd) - if [ -d ${COUPLE_DIR}/update_veg ]; then - # Throw away the temporary working directory from last time to - # avoid merge problems in the next coupling iteration: - rm -rf ${COUPLE_DIR}/update_veg - fi - mkdir -p ${COUPLE_DIR}/update_veg; cd ${COUPLE_DIR}/update_veg - - # TODO: This next block is repeated code, it should be made it's own function - echo -e "\t\t- determining where the glacial mask has advanced and retreated" - echo -e "\t\t- New JSBACH Init File: ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc" - echo -e "\t\t- Old JSBACH Init File: $(readlink ${FORCING_DIR_jsbach}/jsbach.nc)" - cdo -s -selvar,glac -sub \ - ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - ${FORCING_DIR_jsbach}/jsbach.nc \ - ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc 2>> ${COUPLE_DIR}/update_veg/cdo_stderr_ice2echam - # Make two masks: one for glacial retreat, and one for glacial advance - cdo -s gtc,0 ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc ${COUPLE_DIR}/update_veg/new_glaciers.nc - cdo -s gtc,0 -mulc,-1 ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc ${COUPLE_DIR}/update_veg/new_non_glaciers.nc - sum_new_glaciers=$(cdo -s -output -fldsum -gtc,0 ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc | tr -d "[:blank:]") - sum_new_land=$(cdo -s -output -fldsum -gtc,0 -mulc,-1 ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc | tr -d "[:blank:]") - echo -e "\t\t- Total number of new glacial cells: >>>$sum_new_glaciers<<<" - echo -e "\t\t- Total number of new deglacial cells: >>>$sum_new_land<<<" - - if [[ $sum_new_glaciers -eq 0 ]] && [[ $sum_new_land -eq 0 ]]; then - echo -e "\t\t- >>>INFO<<< No new land or new glaciers, this routine will be skipped..." - newest_jsbach_restart_file=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg.nc) - ln -sf ${newest_jsbach_restart_file} ${COUPLE_DIR}/latest_veg_restart_file.nc - return - fi - - newest_jsbach_restart_file=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg.nc) - # Make a backup copy - #todo:rm:old:cp ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg.nc ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg_backup_$(date +%Y%m%d%H%M%S).nc - BAK_FILENAME=$(basename $(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg.nc)) - cp ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg.nc ${RESTART_DIR_jsbach}/${BAK_FILENAME%%.nc}_backup_$(date +%Y%m%d%H%M%S).nc - - echo -e "\t\t- Unpacking JSBACH restart file: $newest_jsbach_restart_file" - # Ensure that the unpack binary is here: - if [ ! -f unpack ]; then - #if [ -f ${FUNCTION_PATH}..//utils/_build/unpack ]; then - # cp -v ${FUNCTION_PATH}..//utils/_build/unpack ./ - if [ -f ${FUNCTION_PATH}/../utils/unpack ]; then - cp -v ${FUNCTION_PATH}/../utils/unpack ./ - else - echo -e "\t\t E R O R R --- unpack binary missing, don't know how to proceed" - exit - fi - fi - # Copy the files here: - cp ${newest_jsbach_restart_file} ./ - cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ./ - echo -e "\t\t- Running unpack binary with arguments:" - echo -e "\t\t- Script: ${FUNCTION_PATH}/../utils/unpack_file.ksh" - echo -e "\t\t- Restart File: $(basename ${newest_jsbach_restart_file})" - echo -e "\t\t- Mask file: $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc)" - ${FUNCTION_PATH}/../utils/unpack_file.ksh \ - $(basename $newest_jsbach_restart_file) \ - $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc) \ - 2>&1 > ${COUPLE_DIR}/unpack_veg_script_stdout_stderr - - echo -e "\t\t- Listing files after program execution:" - ls -ratl - restartfile=2d_$(basename ${newest_jsbach_restart_file}) - # 'cdo showvar' does not work for variables with more than three dimensiones - # Since conflicting module create a challenge, we save - # the current set of loaded modules, purge the module - # list, load necessary working modules, do the job by - # calling ncdump, and restore the former - # purged module list. - # - # MODULE-FIX: 1/2 - module_save_file=/tmp/module2restore_4ncdump.$$ - module save -f $module_save_file - module purge - module load netcdf-c - echo "ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '('" - variables=$(ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '(') - # - # Recover purged modules - # - # MODULE_FIX: 2/2 - module restore -f $module_save_file && rm $module_save_file - echo $variables - - for var in ${variables}; do - ncks -O --no_abc \ - -v ${var} \ - 2d_$(basename ${newest_jsbach_restart_file}) \ - 2d_restart_${EXP_ID}_veg_${var}.nc - - # The following can be turned into an exit if needed: - if [ ! -f 2d_restart_${EXP_ID}_veg_${var}.nc ]; then - echo -e "\t\t !!! WARNING !!! -- no file for ${var}" - echo -e "\t\t continue loop" - continue - fi - - # Keep the directory clean: make one directory for each variable: - here=$(pwd); mkdir -p ${var}; mv 2d_restart_${EXP_ID}_veg_${var}.nc ${var}; cd ${var} - echo -e "\t\t- Updating JSBACH restart file -- ${var}\n" - case ${var} in - bare_fpc ) - # For bare fpc, we need the fraction of "bare" under glaciers to be 1 - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_veg/new_glaciers.nc \ - ${COUPLE_DIR}/update_veg/new_glaciers.nc \ - 2d_restart_${EXP_ID}_veg_${var}.nc \ - 2d_restart_${EXP_ID}_veg_${var}.tmp - # Over newly deglaciated tiles, we put 95% bare soil - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - -mulc,0.95 ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - 2d_restart_${EXP_ID}_veg_${var}.tmp \ - 2d_restart_${EXP_ID}_veg_${var}.nc - cdo -s -setvar,$var 2d_restart_${EXP_ID}_veg_${var}.nc ${var}.tmp - mv ${var}.tmp 2d_restart_${EXP_ID}_veg_${var}.nc - ;; - act_fpc ) - # NOTE: No correction is applied under - # new_glaciers, this is automatically taken - # care of by JSBACH internally. - # - # For active plant cover fraction, we put 0 on - # all tiles except tundra (tile 7) which gets - # 5%. - # - # Split up the levels - cdo -s splitlevel 2d_restart_${EXP_ID}_veg_${var}.nc 2d_restart_${EXP_ID}_veg_${var}_tile - mergelist="" - for tile in $(ls 2d_restart_${EXP_ID}_veg_${var}_tile0000??.nc); do - # NOTE: The period before the old - # dimension name, sfc, indicates - # optional presence of the dimension - # (ncrename -d renames dimensions). It - # seems as if the variable sometimes - # has the correct dimension name tiles - # (or maybe my test case was incorrect - # and had the dimension name sfc). To - # overcome this, we simply ensure that - # if sfc is the dimension name, it - # should be renamed to tiles, and if - # this is already the case, do nothing: - ncrename -d .sfc,tiles $tile - case ${tile} in - 2d_restart_${EXP_ID}_veg_${var}_tile000007.nc ) - echo -e "\t\t- Setting 5% initial cover of tundra for new deglacial cells" - # For the tundra tile - cdo -v -setvar,$var -ifthenelse \ - ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - -mulc,0.05 ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - 2d_restart_${EXP_ID}_veg_${var}_tile000007.nc \ - 2d_restart_${EXP_ID}_veg_${var}_tile000007.tmp - mv 2d_restart_${EXP_ID}_veg_${var}_tile000007.tmp 2d_restart_${EXP_ID}_veg_${var}_tile000007.nc - ;; - * ) - # For all other tiles: - cdo -s -setvar,$var -ifthenelse \ - ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - -mulc,0.0 ${COUPLE_DIR}/update_veg/new_glaciers.nc \ - ${tile} ${tile}.tmp - mv ${tile}.tmp ${tile} - ;; - esac - mergelist="$mergelist $tile" - done - mkdir pre_merge - cp $mergelist pre_merge - echo -e "\t\t >>> PG DEBUG: Command for merging will be: cdo -v -O merge $mergelist ${var}.tmp" - echo -e "\t\t >>> PG DEBUG: The files in merglist ($mergelist) have been copied here:" - echo -e "\t\t >>> PG DEBUG: pre_merge -- directory contents:" - ls -ratlh pre_merge - cdo -v -O merge $mergelist ${var}.tmp - mv -v ${var}.tmp 2d_restart_${EXP_ID}_veg_${var}.nc - # NOTE: Same as above...not sure why this is needed twice?? - ncrename -d .sfc,tiles 2d_restart_${EXP_ID}_veg_${var}.nc - ;; - esac - cd $here - done - mergelist="" - for var in ${variables}; do - mergelist="$mergelist ${var}/2d_restart_${EXP_ID}_veg_${var}.nc" - done - echo -e "\t\t- Creating merge list" - # For debugging: - #echo "Done constructing merge list and renaming time to tiles, these files will be merged" - #for f in $mergelist; do - # ls -l $f - #done - # Merge with ncks, since cdo has issues: - echo -e "\t\t- Merging with ncks, as cdo has problems" - ofile=2d_restart_${EXP_ID}_veg_merged.nc - for f in $mergelist; do - ncks -A -h $f $ofile - done - echo -e "\t\t- Finished with modification of variables, now we need to repack" - # Ensure that the pack binary is here: - if [ ! -f pack ]; then - if [ -f ${FUNCTION_PATH}/../utils/pack ]; then - cp -v ${FUNCTION_PATH}/../utils/pack . - else - echo -e "\t\t E R O R R --- pack binary missing, don't know how to proceed" - exit - fi - fi - # Copy the files here: - cp ${newest_jsbach_restart_file} . - cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc . - echo -e "\t\t- Running pack binary with arguments:" - echo -e "\t\t- Script: ${FUNCTION_PATH}/../utils/pack_file.ksh" - echo -e "\t\t- Restart File: $(readlink -f ${ofile})" - echo -e "\t\t- Mask file: $(readlink -f ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc)" - echo -e "\n\t\t - NOTE: Errors with >VARDIMIDS (value 2) is out of range (1:1)< can be ignored (maybe?)" - ${FUNCTION_PATH}/../utils/pack_file.ksh \ - $(basename $ofile) \ - $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc) - - echo -e "\t\t- Listing files after program execution:" - ls -ratl - - mv 1d_$(basename $ofile) ${newest_jsbach_restart_file} - ln -sf ${newest_jsbach_restart_file} ${COUPLE_DIR}/latest_veg_restart_file.nc - # Go back to the previous directory - cd ${startdir} -} -## @fn update_land_runoff_select_glacial_discharge() -update_land_runoff_select_glacial_discharge() { - echo; echo " * selecting glacial discharge from ice_file_for_atmosphere.nc" - cdo -s -selvar,${ice_mass_loss_varname} ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_for_atmosphere.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_discharge.nc -} - - -## @fn update_land_runoff_fill_missing() -update_land_runoff_fill_missing() { - echo; echo " * filling non-pism areas with 0" - ifile=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.nc - ofile=${COUPLE_DIR}/gfw_atmo.nc - change_lonlat $ifile $ice_mass_loss_varname - # multiply by -1 to get signs correct (in ice sheet, ice mass gain is positive, loss is negative - # in the atmosphere, loss should be positive, gain should be negative) - # PG: Fix for way too much water: - # Divide by minus 1000; oasis gives m/s to FESOM, not kg/m2/s. - cdo -s mulc,-1 -divc,1000 -setmisstoc,0 $ifile $ofile -} - -distribute_total_discharge_over_ocean() { -# echo; echo " * integrate discharge over echam grid" - ifile1=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.nc - ifile2=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.gridarea.nc -# ofile=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.fldsum.nc - cdo -s gridarea ${ifile1} ${ifile2} -# cdo -s fldsum -mul ${ifile1} ${ifile2} ${ofile} - CELL_AREA_FESOM_FILE=${CELL_AREA_FESOM_FILE:-"fesom.mesh.diag.nc"} - echo; echo " * Start apply_hosing_correction.py with: $ifile1 $ifile2 ${MESH_PATH_FESOM}/${CELL_AREA_FESOM_FILE} ${HOSING_FILE_LANDICE_LOSS} " - module load python3 - echo " * HOSING_FILE_LANDICE_LOSS = ${HOSING_FILE_LANDICE_LOSS}" - if [ -f "${HOSING_FILE_LANDICE_LOSS}/landice_yearly_mass_loss.out" ]; then - rm ${HOSING_FILE_LANDICE_LOSS}/landice_yearly_mass_loss.out - fi - - python ${FUNCTION_PATH}/../utils/apply_hosing_correction.py "$ifile1" "$ifile2" "${MESH_PATH_FESOM}/${CELL_AREA_FESOM_FILE}" "${HOSING_FILE_LANDICE_LOSS}" - module unload python3 - echo; echo " * Finished apply_hosing_correction.py " -# -# -# ifile=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.fldsum.nc -# ofile=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.fldsum.flux.nc -# echo; echo " * evenly spread discharge over ocean with total node area = ${TOTAL_NODE_AREA}" -# cdo -f divc,${TOTAL_NODE_AREA} ${ifile} ${ofile} -# TOTAL_DISCHARGE=$( ncdump ${ofile} | awk '/total_ice_mass_loss_flux =/{getline; print}' | tr -d ";" | xargs ) -# -# echo; echo " * write to ${HOSING_FILE_LANDICE_LOSS}"i -# echo 1 > ${HOSING_FILE_LANDICE_LOSS} -# echo ${TOTAL_DISCHARGE} >> ${HOSING_FILE_LANDICE_LOSS} -} - -## @fn update_land_runoff_prepare_for_oasis() -update_land_runoff_prepare_for_oasis() { - echo; echo " * preparing file for oasis" - ifile=${COUPLE_DIR}/gfw_atmo.nc - ofile=${COUPLE_DIR}/gfw_atmo_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc - ncrename -v total_ice_mass_loss_flux,gfw_atmo $ifile tmp; mv tmp $ifile - ncrename -d lon,nx $ifile tmp; mv tmp $ifile - ncrename -d lat,ny $ifile tmp; mv tmp $ifile - ncks -A ${FUNCTION_PATH}/../utils/axis_366.nc $ifile - ncpdq -a time,ny,nx $ifile tmp; mv tmp $ifile - mv $ifile $ofile - cp ${COUPLE_DIR}/gfw_atmo_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${WORK_DIR}/gfw_atmo.nc - ln -sf ${COUPLE_DIR}/gfw_atmo_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${COUPLE_DIR}/latest_gfw_atmo.nc -} - -## @fn update_land_runoff_set_namcouple_override() -update_land_runoff_set_namcouple_override() { - echo; echo " * making a file with instructions to override namcouple" - switch_file=${COUPLE_DIR}/namcouple_override_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - echo "" > $switch_file - echo oasis3mct_add_general_info_to_namcouple 12 2 fesom echam6 \$RUNTIME_awicm >> $switch_file -} - -## @fn update_land_runoff_set_namelist_modifications_next_echam_run() -update_land_runoff_set_namelist_modifications_next_echam_run() { - echam_variable_modify_file=${COUPLE_DIR}/echam_namelist_switches_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - echo; echo " * setting echam variables for land runoff to be read from file in next run" - echo " - echam_variable_modify_file=$echam_variable_modify_file" - if [ ! -s $echam_variable_modify_file ]; then - :> $echam_variable_modify_file - fi - echo "lgfw=1" > ${COUPLE_DIR}/oasis3mct_config_switches.dat - # BUG: Moved to the function below due to bad logic in echam.functions - # add_to ${echam_variable_modify_file} echam_namelist_switches.dat config echam - add_to ${COUPLE_DIR}/oasis3mct_config_switches.dat oasis3mct_config_switches.dat config oasis3mct -} - -## @fn update_land_runoff_set_namelist_modifications_next_jsbach_run() -update_land_runoff_set_namelist_modifications_next_jsbach_run() { - jsbach_variable_modify_file=${COUPLE_DIR}/jsbach_namelist_switches_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - echo; echo " * setting jsbach variables for land runoff to be read from file in next run" - echo " - jsbach_variable_modify_file=$jsbach_variable_modify_file" - if [ ! -s $jsbach_variable_modify_file ]; then - :> $jsbach_variable_modify_file - fi - echo "submodelctl___lgfw___nml_entry=.TRUE." >> $jsbach_variable_modify_file - # Yes, this is correct below: we want to modify the ECHAM namelist, but - # need it to connect to JSBACH: - echo "submodelctl___lgfw___nml_file=namelist.echam" >> $jsbach_variable_modify_file - echo "hydrology_ctl___lgfw___nml_entry=.TRUE." >> $jsbach_variable_modify_file - echo "hydrology_ctl___lgfw___nml_file=namelist.jsbach" >> $jsbach_variable_modify_file - add_to ${jsbach_variable_modify_file} jsbach_namelist_switches.dat config jsbach -} - -## @fn regrid_to_echam() -regrid_to_echam() { - FILENAME=$1 - remapper=$2 - RES=${3:-${RES_echam}} - if [[ "x$remapper" == "x" ]]; then - remapper=remapcon2 - fi - echo " - regridding $FILENAME to echam ${RES} grid with $remapper" - cdo -s -P 28 \ - -$remapper,${RES}grid \ - -setgrid,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - $FILENAME ${FILENAME%.*}_${RES}grid.nc -} - -## @fn set_in_jsbach_restart_file() -set_in_jsbach_restart_file() { - TARGET_VARNAME=$1 - SOURCE_FILENAME=$2 - SOURCE_VARNAME=$3 - unpack=$4 - RESTART_FILE=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc) - echo " * replacing: $TARGET_VARNAME " - echo " in: $RESTART_FILE " - echo " from: $SOURCE_VARNAME " - echo " in: $SOURCE_FILENAME" - if [ ! -z $unpack ]; then - echo " - with unpacking from landpoint grid to latlon grid" - python ${FUNCTION_PATH}/../utils/unpack_jsbach.py $TARGET_VARNAME $RESTART_FILE - ################################################################################ - # $ cdo -h replace - # NAME - # replace - Replace variables - # - # SYNOPSIS - # replace infile1 infile2 outfile - # - # DESCRIPTION - # The replace operator replaces variables in infile1 by variables from infile2 and write - # the result to outfile. Both input datasets need to have the same number of timesteps. - ################################################################################ - cdo -s replace \ - ${TARGET_VARNAME}_lonlat_grid.nc \ - -chname,${SOURCE_VARNAME},${TARGET_VARNAME} \ - -selvar,${SOURCE_VARNAME} ${SOURCE_FILENAME} \ - ${TARGET_VARNAME}_lonlat_grid_replaced.nc - echo " - and repacking from latlon grid to landpoint grid" - # FIXME: The next line is probably wrong, or incomplete. - python ${FUNCTION_PATH}/../utils/pack_jsbach.py ${TARGET_VARNAME} ${TARGET_VARNAME}_lonlat_grid_replaced.nc ${RESTART_FILE} - else - cdo -s replace \ - ${RESTART_FILE} \ - -chname,${SOURCE_VARNAME},${TARGET_VARNAME} \ - -selvar,${SOURCE_VARNAME} ${SOURCE_FILENAME} \ - tmp - cp ${RESTART_FILE} ${RESTART_FILE%.*}_backup_before_replace_${TARGET_VARNAME}_$(date +%Y%m%d%H%M%S).nc - mv tmp ${RESTART_FILE} - fi -} - -## @fn change_lonlat() -change_lonlat() { - file=$1 - varname=$2 - # Since conflicting module create a challenge, we save - # the current set of loaded modules, purge the module - # list, load necessary working modules, do the job by - # calling ncdump, and restore the former - # purged module list. - # - # MODULE-FIX: 1/2 - module_save_file=/tmp/module2restore_4ncdump.$$ - module save -f $module_save_file - module purge - module load netcdf-c nco - if ncdump -h $file | grep "${varname}" | grep -q "lon, lat"; then - echo " - changing lat/lon dimension order for $varname in $file" - ncpdq -a lat,lon $file tmp; mv tmp $file 2>> nco_stderr_ice2echam - fi - # - # Recover purged modules - # - # MODULE_FIX: 2/2 - module restore -f $module_save_file && rm $module_save_file - -} diff --git a/couplings/coupling_dual-hemisphere/echam/env_echam.py b/couplings/coupling_dual-hemisphere/echam/env_echam.py deleted file mode 100644 index 637342e90..000000000 --- a/couplings/coupling_dual-hemisphere/echam/env_echam.py +++ /dev/null @@ -1,49 +0,0 @@ -def prepare_environment(config): - environment_dict = { - "ICE_TO_ECHAM": int(config["general"]["first_run_in_chunk"]), - "ECHAM_TO_ICE": int(config["general"]["last_run_in_chunk"]), - "ECHAM_TO_ISM_multiyear_mean": int(config["echam"].get("multi_year_mean", 1)), - "ISM_TO_ECHAM_update_orography": 1, - "ISM_TO_ECHAM_update_glacial_mask": int(config["echam"].get("update_glacial_mask", True).__bool__()), - "ISM_TO_ECHAM_update_land_runoff": 1, - "COUPLE_DIR": config["general"]["experiment_couple_dir"], - "RES_echam": config["echam"]["resolution"], - "EXP_ID": config["general"]["command_line_config"]["expid"], - "RESTART_DIR_echam": config["echam"]["experiment_restart_out_dir"], - "DATA_DIR_echam": config["echam"]["experiment_outdata_dir"], - "INIT_DIR_echam": config["echam"]["experiment_input_dir"], - "WORK_DIR": config["general"]["thisrun_work_dir"], - "number_of_years_for_forcing": config["model1"]["chunk_size"], - "CHUNK_START_DATE_echam": config["general"]["chunk_start_date"], - "CHUNK_END_DATE_echam": config["general"]["chunk_end_date"], - "END_YEAR_echam": config["general"]["chunk_end_date"].syear, - "END_MONTH_echam": config["general"]["chunk_end_date"].smonth, - "END_DAY_echam": config["general"]["chunk_end_date"].sday, - "FUNCTION_PATH": config["echam"]["workflow"]["subjobs"]["couple_in"]["script_dir"], - "FORCING_DIR_jsbach": config["jsbach"]["experiment_input_dir"], - "RESTART_DIR_jsbach": config["jsbach"]["experiment_restart_out_dir"], - "POOL_DIR_jsbach": config["computer"]["pool_dir"], - "POOL_DIR_echam": config["computer"]["pool_dir"], - "MACHINE": config["computer"]["name"], - "MESH_PATH_FESOM": config["fesom"]["mesh_dir"], - "HOSING_FILE_LANDICE_LOSS": config["fesom"].get("fwf_path", config["general"]["experiment_couple_dir"]), - "HOSING_CORRECTION": int(config["echam"].get("hosing_correction", False).__bool__()), # LA: Not needed anymore with Lu's ECHAM gfw fix - "CELL_AREA_FESOM_FILE": config["fesom"].get("fesom_cell_area_file", "fesom.mesh.diag.nc"), - "ECHAM_ALBEDO_ON_GLACIERS": config["echam"].get("albedo_on_glaciers", 0.7), - "ECHAM_GLACIAL_THRESHOLD": config["echam"].get("glacial_threshold", 0.5), - "oro_update_mod": config["echam"].get("oro_update_mod", 2), - "oro_update_var": config["echam"].get("oro_update_var", "geosp"), - } - - #if environment_dict["ADD_UNCHANGED_ICE"] == False: - # environment_dict["ADD_UNCHANGED_ICE"] = 0 - #elif environment_dict["ADD_UNCHANGED_ICE"] == True: - # environment_dict["ADD_UNCHANGED_ICE"] = 1 - - - print(environment_dict) - return environment_dict - - - - diff --git a/couplings/coupling_dual-hemisphere/fesom/coupling_fesom2ice.functions b/couplings/coupling_dual-hemisphere/fesom/coupling_fesom2ice.functions deleted file mode 100644 index c5fd26fcc..000000000 --- a/couplings/coupling_dual-hemisphere/fesom/coupling_fesom2ice.functions +++ /dev/null @@ -1,756 +0,0 @@ -#!/usr/bin/ksh - -function fesom2ice { - FESOM_TO_ISM_ocean_forcing=${FESOM_TO_ISM_ocean_forcing:-0} - echo " *** S T A R T I N G fesom2ice *** " - echo " LA DEBUG: MESH_PATH=${MESH_DIR_fesom}" - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - echo " Starting coupling_fesom2ice.functions ...." - echo "FESOM_TO_ISM_ocean_forcing=${FESOM_TO_ISM_ocean_forcing}" - - export FileName_depth4levels_FESOM=depth_axis_fesom.nc - iter_coup_interact_method_oce2ice=${iter_coup_interact_method_oce2ice:-} - - iterative_coupling_fesom1x_ice_make_forcing - iterative_coupling_fesom1x_ice_write_grid - iterative_coupling_fesom1x_ice_write_names - - for file in ${cleanup_list} ; do test -f $file && rm $file ; done - unset cleanup_list file -} - -function iterative_coupling_fesom1x_ice_make_forcing { - echo "Preparing fesom1x file for processing in an ice sheet model..." - - FESOM_TO_ISM_multiyear_mean=${FESOM_TO_ISM_multiyear_mean:-1} - FESOM_TO_ISM_total_mean=${FESOM_TO_ISM_total_mean:-1} - - fesom_ice_construct_input_list - fesom_ice_select_relevant_variables - # Come from special FESOM grid to i(lon,lat),j(lon,lat),depth grid - fesom_ice_fesom_build_grid_with_lonlat_depth - fesom_ice_concatenate_files - if [ "x${FESOM_TO_ISM_multiyear_mean:-0}" == "x1" ] ; then - fesom_ice_generate_multiyear_mean - fi - if [ "x${FESOM_TO_ISM_total_mean:-0}" == "x1" ] ; then - fesom_ice_generate_total_mean - fi - - # Since depth array "depth(level)" is lost after each CDO - # command (because the vertical dimension is "level"), we have - # to add the depth array as very last command. - # To keep the "depth" and allow CDO to use this information, - # we have to rename the dimension "level" against "depth" as well. - # Hence use "fesom_ice_rename_level2depth_add_depth" and not - # "fesom_ice_add_depth", because the latter does not work as - # wanted. - # - # These selections of `$iter_coup_interact_method_oce2ice` - # could lead to enormous main memory request, if we use many - # time step. Therefore we collapse the data file into one - # single time step . - if [ "${iter_coup_interact_method_oce2ice}" == "MIXED" -o \ - "${iter_coup_interact_method_oce2ice}" == "TS_RESCALED2FLUX" -o \ - "${iter_coup_interact_method_oce2ice}" == "TEMPSALT2FLUX" -o \ - "${iter_coup_interact_method_oce2ice}" == "TEMP2FLUX" -o \ - "${iter_coup_interact_method_oce2ice}" == "OCEANTEMP" ] ; then - FESOM_TO_ISM_total_mean=1 - fi - - fesom_ice_construct_input_list - fesom_ice_select_relevant_variables - # Come from special FESOM grid to i(lon,lat),j(lon,lat),depth grid - fesom_ice_fesom_build_grid_with_lonlat_depth - fesom_ice_concatenate_files - if [ "x${FESOM_TO_ISM_multiyear_mean}" == "x1" ] ; then - fesom_ice_generate_multiyear_mean - fi - if [ "x${FESOM_TO_ISM_total_mean}" == "x1" ] ; then - fesom_ice_generate_total_mean - fi - - # Since depth array "depth(level)" is lost after each CDO - # command (because the vertical dimension is "level"), we have - # to add the depth array as very last command. - # To keep the "depth" and allow CDO to use this information, - # we have to rename the dimension "level" against "depth" as well. - # Hence use "fesom_ice_rename_level2depth_add_depth" and not - # "fesom_ice_add_depth", because the latter does not work as - # wanted. - # - # Adding the depth works only for z-coordinates - # - if [ -f ${FileName_depth4levels_FESOM} ] ; then - cp ocean_file_for_ice.nc ocean_file_for_ice.before_add_depth.nc - fesom_ice_rename_level2depth_add_depth ${FileName_depth4levels_FESOM} ocean_file_for_ice.nc - cleanup_list="${cleanup_list} $(pwd)/ocean_file_for_ice.before_add_depth.nc" - fi - - #add_to $(pwd)/ocean_file_for_ice.nc ocean_file_for_ice.nc couple - cp $(pwd)/ocean_file_for_ice.nc ${COUPLE_DIR}/ocean_file_for_ice.nc - - if [ "${MACHINE}" == "albedo" ]; then - module unload python - module load python - fi - - echo " ...done." -} - -function iterative_coupling_fesom1x_ice_write_grid { - echo "Writing fesom1x grid description to generic ocean.griddes..." - echo ""; echo " * generating griddes" - NEW_OCE2ICE_GRID=$(build_grid_des ocean_file_for_ice.nc ocean.griddes couple) - export NEW_OCE2ICE_GRID - cp $(pwd)/ocean.griddes ${COUPLE_DIR}/ocean.griddes - - echo "....done." -} - -function iterative_coupling_fesom1x_ice_write_names { - echo "Writing fesom1x names and units for use with generic ocean_file_for_ice.nc" - :> ocean_names_for_ice.dat - echo ""; echo " * temperature" - echo "ocean_name_pot_temperature=temp" >> ocean_names_for_ice.dat - echo "ocean_units_pot_temperature=degC" >> ocean_names_for_ice.dat - echo ""; echo " * salinity" - echo "ocean_name_salinity=salt" >> ocean_names_for_ice.dat - # Since "psu" is not a standard unit, we use "g/kg", which follows the newest definitions - #echo "ocean_units_salinity=psu" >> ocean_names_for_ice.dat - echo "ocean_units_salinity=g/kg" >> ocean_names_for_ice.dat - echo ""; echo " * ice base depth" - echo "ocean_name_ice_base_depth=basedepth" >> ocean_names_for_ice.dat - echo "ocean_units_ice_base_depth=m" >> ocean_names_for_ice.dat - - echo ""; echo " * top/surface tempeature" - echo "ocean_name_pot_temperature_z0=Tsurf" >> ocean_names_for_ice.dat - echo "ocean_units_pot_temperature_z0=degC" >> ocean_names_for_ice.dat - - echo ""; echo " * top/surface salinity" - echo "ocean_name_salinity_z0=Ssurf" >> ocean_names_for_ice.dat - echo "ocean_units_salinity_z0=g/kg" >> ocean_names_for_ice.dat - - echo ""; echo " * top-of-ocean heat flux" - echo "ocean_name_heatflux_z0=fh" >> ocean_names_for_ice.dat - echo "ocean_units_heatflux_z0=W/m2/s" >> ocean_names_for_ice.dat - - echo ""; echo " * top-of-ocean freshwater flux" - echo "ocean_name_fwflux_z0=fw" >> ocean_names_for_ice.dat - echo "ocean_units_fwflux_z0=kg/m2" >> ocean_names_for_ice.dat - - echo ""; echo " * iteration counter" - echo "ocean_name_iter=iter" >> ocean_names_for_ice.dat - echo "ocean_units_iter=1" >> ocean_names_for_ice.dat - - #add_to $(pwd)/ocean_names_for_ice.dat ocean_names_for_ice.dat couple - cp $(pwd)/ocean_names_for_ice.dat ${COUPLE_DIR}/ocean_names_for_ice.dat - echo " ...done." -} - -function fesom_ice_construct_input_list { - echo ""; echo " * constructing input list" - - export CHUNK_END_YEAR_fesom=$(date -d "${CHUNK_END_DATE_fesom:?'Missing variable'}" +%Y) - export CHUNK_END_MONTH_fesom=$(date -d "${CHUNK_END_DATE_fesom:?'Missing variable'}" +%m) - export CHUNK_END_DAY_fesom=$(date -d "${CHUNK_END_DATE_fesom:?'Missing variable'}" +%d) - - number_of_years_for_forcing=${number_of_years_for_forcing:-1} - start_year_couple=$(( CHUNK_END_YEAR_fesom - number_of_years_for_forcing + 1 )) - end_year_couple=${CHUNK_END_YEAR_fesom} - fesom1x_raw_file3D_T_list_for_ice="" - fesom1x_raw_file3D_S_list_for_ice="" - fesom1x_raw_file2D_list_for_ice="" - fesom1x_raw_file2Dstatic_list_for_ice="" - - # - # Standard (monthly) 3dimensional+time FESOM output - # - - for year in $(seq $start_year_couple $end_year_couple ); do - month=01 - #for month in $(seq -f "%02g" 1 12); do - day=01 - variable=temp - current_file=${DATA_DIR_fesom}/${variable}.fesom.${year}.nc - if [ -f $current_file ] ; then - fesom1x_raw_file3D_T_list_for_ice="$fesom1x_raw_file3D_T_list_for_ice $current_file" - else - echo " - Missing 3D fesom file ${current_file}" - echo " S T O P 1 (coupling_fesom2ice.functions::fesom_ice_construct_input_list)" ; exit 1 - fi - - variable=salt - current_file=${DATA_DIR_fesom}/${variable}.fesom.${year}.nc - if [ -f $current_file ] ; then - fesom1x_raw_file3D_S_list_for_ice="$fesom1x_raw_file3D_S_list_for_ice $current_file" - else - echo " - Missing 3D fesom file ${current_file}" - echo " S T O P 2 (coupling_fesom2ice.functions::fesom_ice_construct_input_list)" ; exit 2 - fi - #done - done - -# TODO Activate this part once Ozgur's fesom is ready (allow STOP & exit) - # - # Special 2dimensional+time FESOM output - # - # -- SST, SSS, fluxes through surface - for year in $(seq $start_year_couple $end_year_couple ); do - month=01 - day=01 - current_file=${DATA_DIR_fesom}/${EXP_ID}.${year}.pism.nc - if [ -f $current_file ] ; then - fesom1x_raw_file2D_list_for_ice="$fesom1x_raw_file2D_list_for_ice $current_file" - else - echo " - Missing 2D fesom file ${current_file}" -# echo " S T O P 3 (coupling_fesom2ice.functions::fesom_ice_construct_input_list)" ; exit 3 - fi - #done - done - -# TODO Activate this part once Ozgur's fesom is ready (allow STOP & exit) - # - # Special 2dimensional FESOM output - # - # -- basal ice depth/ice draft - for year in $(seq $start_year_couple $end_year_couple ); do - month=01 - #for month in $(seq -f "%02g" 1 12); do - day=01 - current_file=${DATA_DIR_fesom}/${EXP_ID}.initial.mesh.diag.nc - if [ -f $current_file ] ; then - fesom1x_raw_file2Dstatic_list_for_ice="$fesom1x_raw_file2Dstatic_list_for_ice $current_file" - else - echo " - Missing 2D static fesom file ${current_file}" -# echo " S T O P 4 (coupling_fesom2ice.functions::fesom_ice_construct_input_list)" ; exit 4 - fi - #done - done - - unset variable year month #current_file start_year_couple end_year_couple -} - -function fesom_ice_select_relevant_variables { - echo ""; echo " * selecting relevant variables" - fesom1x_file3D_T_list_for_ice="" - fesom1x_file3D_S_list_for_ice="" - fesom1x_file2D_list_for_ice="" - fesom1x_file2Dstatic_list_for_ice="" - - variable=temp - for file in ${fesom1x_raw_file3D_T_list_for_ice} ; do - echo -n " - >${variable}< from ${file}" - filename=$(basename $file) - output="${filename%.*}"_var4ice.nc - ${cdo} -s -f nc monmean $file $output - fesom1x_file3D_T_list_for_ice="$fesom1x_file3D_T_list_for_ice ${output}" - echo " : STILL alive" - done - - variable=salt - for file in ${fesom1x_raw_file3D_S_list_for_ice} ; do - echo -n " - >${variable}< from ${file}" - filename=$(basename $file) - output="${filename%.*}"_var4ice.nc - ${cdo} -s -f nc monmean $file $output - fesom1x_file3D_S_list_for_ice="$fesom1x_file3D_S_list_for_ice ${output}" - echo " : STILL alive" - done - - variable="2dim-fields" - for file in ${fesom1x_raw_file2D_list_for_ice} ; do - echo -n " - >${variable}< from ${file}" - filename=$(basename $file) - output="${filename%.*}"_var4ice.nc - ${cdo} -s -f nc monmean $file $output - fesom1x_file2D_list_for_ice="$fesom1x_file2D_list_for_ice ${output}" - echo " : STILL alive" - done - - variable="static 2dim-fields" - for file in ${fesom1x_raw_file2Dstatic_list_for_ice} ; do - echo -n " - >${variable}< from ${file}" - filename=$(basename $file) - output="${filename%.*}"_var4ice.nc - cp $file $output #${cdo} -s -f nc selvar,XXX,YYY,ZZZ $file $output - fesom1x_file2D_list_for_ice="$fesom1x_file2D_list_for_ice ${output}" - echo " : STILL alive" - done - - # - # Do NOT delete the raw files! - # - - unset output filename - unset fesom1x_raw_file3D_T_list_for_ice fesom1x_raw_file2D_list_for_ice - unset fesom1x_raw_file3D_S_list_for_ice fesom1x_raw_file2Dstatic_list_for_ice -} - -function fesom_ice_fesom_build_grid_with_lonlat_depth { - # Come from special FESOM grid to i(lon,lat),j(lon,lat),depth grid - if [ "${MACHINE}" == "levante" ]; then - #module unload python3 - module load python3 - fi - echo ""; echo " * build files on propper grid with longitude, latitude, and depth" - echo ""; echo " * using python version $(python --version)" - - pyfesom_script=${FUNCTION_PATH:-${FPATH}}/../utils/fesom_scalar_array_to_LonLat.py - if [ ! -f $pyfesom_script ] ; then - echo " - Missing pyfesom_script ${pyfesom_script}" - echo " S T O P 5 (coupling_fesom2ice.functions::fesom_ice_fesom_build_grid_with_lonlat_depth)" ; exit 5 - fi - - # Path of PYFESOM installation - PYFESOM_PATH=${PYFESOM_PATH:-${FUNCTION_PATH}/pyfesom} - CMOCEAN_PATH=${CMOCEAN_PATH:-${FUNCTION_PATH}/cmocean} - for dir in ${PYFESOM_PATH} ${CMOCEAN_PATH} ; do - base_dir=$(basename $dir) - echo -n " - $base_dir" - if [ ! -d $base_dir ] ; then - echo " - create link" - ln -s $dir - else - echo " - exists in $(pwd)" - fi - done - - processed_fesom1x_file3D_T_list_for_ice="" - processed_fesom1x_file3D_S_list_for_ice="" - processed_fesom1x_file2D_list_for_ice="" - processed_fesom1x_file2Dstatic_list_for_ice="" - -# -------------------------------------------------------- -# -# HOT fix, part 1/2 -# - echo "=====## ---------------------------------------------------------------" - echo " ## HOT fix for the python2 (needed for pyfesom) vs python3 problem" - node_name=$(hostname) - echo " ## Check for computer/node name '${node_name}'" - FLAG_SWITCHED_PYTHON=0 - case ${node_name} in - prod-[0-9]*) - FLAG_SWITCHED_PYTHON=1 - module_python3="python3" - module_python2="python" - ;; - ollie[0-1]) - FLAG_SWITCHED_PYTHON=1 - module_python3="python3" - module_python2="python" - ;; - fat-*[0-9]|fat[0-9]) - FLAG_SWITCHED_PYTHON=1 - module_python3="python3" - module_python2="python" - ;; - xfat*) - FLAG_SWITCHED_PYTHON=1 - module_python3="python3" - module_python2="python" - ;; - m[0-9]*[0-9]) - # Mistral has compute nodes named m-number(several times) - FLAG_SWITCHED_PYTHON=1 - module_python3="python/3.5.2" - module_python2="python/2.7.12" - ;; - mlogin[0-9]*) - # Mistral has compute nodes named m-number(several times) - FLAG_SWITCHED_PYTHON=1 - module_python3="python/3.5.2" - module_python2="python/2.7.12" - ;; - *) - echo " ## Nothing defined for computer '$(hostname)'" - ;; - esac - FLAG_SWITCHED_PYTHON=0 - if [ ${FLAG_SWITCHED_PYTHON} -eq 1 ] ; then - echo " ## ACTIVATE HOT fix for the ${module_python2} vs ${module_python3} problem" - echo "--------- module output --- begin" - module unload ${module_python3} - module load ${module_python2} - echo "--------- module output --- end" - echo " ## unload ${module_python3} and load ${module_python2} : ${node_name}" - else - echo " ## Do not activate HOT fix" - echo "=====## ---------------------------------------------------------------" - fi - - # Several things might be needed for pyfesom. If it isn't installed; - # get it - for required_python_external in xarray joblib cmocean seawater; do - python -c "import $required_python_external" \ - || pip install --user ${required_python_external} \ - && echo -e "\t\t - Using existing ${required_python_external} for python" - done -# -------------------------------------------------------- - - # ------------------------------------------------ - # - # Determine if grid is rotated and how much - # - # See issue #83 : - # [...] from now on all new meshes will be in geographical - # coordinates and old meshes will be converted - # accordingly. This means force_rotation=.FALSE. and - # rotated_grid=.true. will be the fixed options - # - # ==> related code is placed at the end of this file - # - if [ "${MACHINE}" == "albedo" ]; then - module unload python - module load python/3.9.12 - fi - - variable=temp - for file in ${fesom1x_file3D_T_list_for_ice} ; do - filename=$(basename $file) ; logfile=${filename}.${variable}.log - output="${filename%.*}"_goodgrid.nc - - echo -n " - >${variable}< from ${file}" - python $pyfesom_script ${FESOM_MESH_SWITCHES} \ - --FESOM_PATH $DATA_DIR_fesom \ - --FESOM_VARIABLE $variable \ - --FESOM_MESH ${MESH_DIR_fesom} \ - --FESOM_YEARS $start_year_couple $end_year_couple \ - --FESOM_MESH_ROTATED ${MESH_ROTATED_fesom} \ - --FESOM_OUTPUT $output > $logfile - echo " : STILL alive" - - test_file_or_exit $output 6 - processed_fesom1x_file3D_T_list_for_ice="$processed_fesom1x_file3D_T_list_for_ice ${output}" - done - - variable=salt - for file in ${fesom1x_file3D_S_list_for_ice} ; do - filename=$(basename $file) ; logfile=${filename}.${variable}.log - output="${filename%.*}"_goodgrid.nc - - echo -n " - >${variable}< from ${file}" - python $pyfesom_script ${FESOM_MESH_SWITCHES} \ - --FESOM_PATH $DATA_DIR_fesom \ - --FESOM_VARIABLE $variable \ - --FESOM_MESH ${MESH_DIR_fesom} \ - --FESOM_YEARS $start_year_couple $end_year_couple \ - --FESOM_MESH_ROTATED ${MESH_ROTATED_fesom} \ - --FESOM_OUTPUT $output > $logfile - echo " : STILL alive" - - test_file_or_exit $output 7 - processed_fesom1x_file3D_S_list_for_ice="$processed_fesom1x_file3D_S_list_for_ice ${output}" - done - - for file in ${fesom1x_file2D_list_for_ice} ; do - filename=$(basename $file) - output="${filename%.*}"_goodgrid.nc - - ic=0 - for variable in Tsurf Ssurf fh fw ; do - ic=$(( ic + 1 )) - - logfile=${filename}.${variable}.log - input=$file - if [[ "x${variable}" =~ x[q,w]net ]] ; then - echo " + ${variable} set to zero outside of ice fesom ice shelves" - # Set heat and freshwater/mass fluxes to - # zero outside of the ice shelf region - filename=$(echo $fesom1x_file2Dstatic_list_for_ice | cut -d' ' -f1) - test_file_or_exit $filename 8 - input=tmp_cavity_flag_extended - $cdo -O ifthen -selvar,cavity_flag_extended $filename \ - -selvar,${variable} $file $input - fi - - echo -n " - >${variable}< from ${file}" - result_file=tmp_file_$(printf "%04i" $ic)__${variable} - python $pyfesom_script ${FESOM_MESH_SWITCHES} \ - --FESOM_PATH $DATA_DIR_fesom \ - --FESOM_VARIABLE $variable \ - --FESOM_MESH ${MESH_DIR_fesom} \ - --FESOM_YEARS $start_year_couple $end_year_couple \ - --FESOM_MESH_ROTATED ${MESH_ROTATED_fesom} \ - --FESOM_OUTPUT $output > $logfile - echo " : STILL alive" - - test_file_or_exit $result_file 9 - done - $cdo -f nc cat tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* ${output} - - ncks -Av iter tmp_file_0001__[A-Z,a-z]* ${output} && \ - rm tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* - - processed_fesom1x_file2D_list_for_ice="$processed_fesom1x_file2D_list_for_ice ${output}" - done - - for file in ${fesom1x_file2Dstatic_list_for_ice} ; do - filename=$(basename $file) - output="${filename%.*}"_goodgrid.nc - - ic=0 -# TODO: Wait for OG code for cavities in standard FESOM -#TODO : variable names of 1) cavitity mask (extend) -# 2) depth of ice base (top depth of top ocean layer) - for variable in cavity_flag_extended fld ; do - ic=$(( ic + 1 )) - - logfile=${filename}.${variable}.log - echo -n " - >${variable}< from ${file}" - result_file=tmp_file_$(printf "%04i" $ic)__${variable} - python $pyfesom_script ${FESOM_MESH_SWITCHES} \ - --FESOM_PATH $DATA_DIR_fesom \ - --FESOM_VARIABLE $variable \ - --FESOM_MESH ${MESH_DIR_fesom} \ - --FESOM_YEARS $start_year_couple $end_year_couple \ - --FESOM_MESH_ROTATED ${MESH_ROTATED_fesom} \ - --FESOM_OUTPUT $output > $logfile - echo " : STILL alive" - - test_file_or_exit $result_file 10 - done - $cdo -f nc cat tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* ${output} \ - && rm tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* - - processed_fesom1x_file2Dstatic_list_for_ice="$processed_fesom1x_file2Dstatic_list_for_ice ${output}" - done - - if [ 1 -eq 1 ] ; then - # Clean up and discard intermediate temporary files - for file in tmp_cavity_flag_extended $result_file \ - ${fesom1x_file3D_T_list_for_ice} \ - ${fesom1x_file2D_list_for_ice} \ - ${fesom1x_file3D_S_list_for_ice} \ - ${fesom1x_file2Dstatic_list_for_ice} - do - if [ -f $file ] ; then - cleanup_list="${cleanup_list} $(pwd)/$(basename ${file})" - fi - done - rm -f tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* - fi - -# -------------------------------------------------------- -# -# HOT fix, part 2/2 -# - if [ ${FLAG_SWITCHED_PYTHON} -eq 1 ] ; then - echo " ## DEactivate HOT fix for the ${module_python2} vs ${module_python3} problem" - echo " ## unload ${module_python2} and load ${module_python3}" - echo " ## HOT fix for the ${module_python2} (needed for pyfesom) vs ${module_python3} problem" - echo " ## Check computer name" - echo "--------- module output --- begin" - module unload ${module_python2} - module load ${module_python3} - echo "--------- module output --- end" - echo "=====## ---------------------------------------------------------------" - FLAG_SWITCHED_PYTHON=0 - fi -# -------------------------------------------------------- - - unset dir file filename input logfile output result_file - unset fesom1x_file3D_T_list_for_ice fesom1x_file2D_list_for_ice - unset fesom1x_file3D_S_list_for_ice fesom1x_file2Dstatic_list_for_ice - unset FLAG_SWITCHED_PYTHON FESOM_MESH_SWITCHES -} - -function fesom_ice_concatenate_files { - echo ""; echo " * concatenating files" - # New cdo versions sometimes do not allow to overwrite files for - # "collective" commands. Hence delete existing old output file - [[ -f temp.tmp.nc ]] && rm temp.tmp.nc - [[ -f salt.tmp.nc ]] && rm salt.tmp.nc - [[ -f ocean_file_for_ice.nc ]] && rm ocean_file_for_ice.nc - ${cdo} -s ensmean ${processed_fesom1x_file3D_T_list_for_ice} temp.tmp.nc - ${cdo} -s ensmean ${processed_fesom1x_file3D_S_list_for_ice} salt.tmp.nc - ${cdo} -s merge temp.tmp.nc salt.tmp.nc ocean_file_for_ice.nc - #${cdo} -s merge \ - # ${processed_fesom1x_file3D_T_list_for_ice} \ - # ${processed_fesom1x_file3D_S_list_for_ice} \ - # ${processed_fesom1x_file2D_list_for_ice} \ - # ${processed_fesom1x_file2Dstatic_list_for_ice} \ - # ocean_file_for_ice.nc - _flag_extract_depth=1 - # Extract depth axis and Clean up temporary files - for file in \ - ${processed_fesom1x_file3D_T_list_for_ice} \ - ${processed_fesom1x_file3D_S_list_for_ice} \ - ${processed_fesom1x_file2D_list_for_ice} \ - ${processed_fesom1x_file2Dstatic_list_for_ice} - do - if [ -f $file ] ; then - if [ ${_flag_extract_depth} -ne 0 ] ; then - # Shall we add the depth axis (discarded above during merge/cat) - varname_depth="depth" - echo " - extract depth variable >${varname_depth}< axis from >>${file}<<" - - if [ ! -f ${FileName_depth4levels_FESOM} ] ; then - ncks -v ${varname_depth} ${file} ${FileName_depth4levels_FESOM} \ - || echo " ****** FAILED extracting >${varname_depth}< *****" \ - && _flag_extract_depth=0 # Preventing further attempts adding "depth" -# TODO : compute layer bounds and add them also - fi - fi - - if [ 0 -eq 1 ] ; then - cleanup_list="${cleanup_list} $(pwd)/$(basename ${file})" - #OR rm $file - fi - fi - done - - unset _flag_extract_depth file - unset processed_fesom1x_file3D_T_list_for_ice processed_fesom1x_file2D_list_for_ice - unset processed_fesom1x_file3D_S_list_for_ice processed_fesom1x_file2Dstatic_list_for_ice -} - - -function fesom_ice_rename_level2depth_add_depth { - _file_depth=$1 - _file_data=$2 - echo ""; echo " * Rename dimension level and add depth axis >>${_file_depth}<< to >>${_file_data}<<" - if [ $# -lt 2 ] ; then - echo " not enought input variables in coupling_fesom2ice.functions::fesom_ice_rename_level2depth_add_depth" - echo " S T O P 11" - exit 11 - fi - test_file_or_exit ${_file_depth} 12 - test_file_or_exit ${_file_data} 13 - - # Since depth(level) and level is the vertical dimension, the - # "depth" is not recognized by just adding the "depth". As a - # consequence "cdo vertlevel,150/500" does not work as expected. - - # - # REPLACE 'level' with real 'depth' values - # - # Step 1 : rename dimension "level" into "depth" - # - echo $(module list) - ncrename -d level,depth -v level,depth ${_file_data} - #ncrename -d level,depth ${_file_data} - ncatted -a axis,depth,o,c,'Z' ${_file_data} - - # - # Step 2 : Modified depth/level file comparable to the data file - # - _file_depth_level=${_file_depth}.level2depth - if [ ! -f ${_file_depth_level} ] ; then - if [ 1 -eq 0 ] ; then - # This does not work, because we have a missmatch of - # number types between "float" and "double". At the end - # the below added reasonable depth values (via ncks -A) - # are converted into ridiculous large numbers without - # meaning. - # Therefore we first have to convert the depth type - # "float" into "double" and then add this depth. - ncrename -d level,depth ${_file_depth} ${_file_depth_level} - ncatted -a axis,level,d,, \ - -a axis,depth,o,c,'Z' \ - ${_file_depth_level} - else - # As before - ncrename -d level,depth ${_file_depth} ${_file_depth_level}.tmp1 - #ncrename -d level,depth ${_file_depth_level}.tmp1 - ncatted -a axis,level,d,, \ - -a axis,depth,c,c,'Z' \ - ${_file_depth_level}.tmp1 - - # This multipliation transforms "float" into "double" - ncap=${ncap:-ncap2} - $ncap -s "depth=depth*1.0000000000000;" \ - ${_file_depth_level}.tmp1 \ - ${_file_depth_level}.tmp2 - - # Repair the broken meta-data information for depth and - # get the final $_file_depth_level - ncatted \ - -a long_name,depth,o,c,"depth" \ - -a units,depth,o,c,"m" \ - -a description,depth,o,c,"depth below sea level" \ - -a positive,depth,o,c,"down" \ - ${_file_depth_level}.tmp2 \ - ${_file_depth_level} - - # Cleanup - rm -f ${_file_depth_level}.tmp1 ${_file_depth_level}.tmp2 - fi - fi - - # - # Step 3 : Overwrite former "level" values with real "depth" - # - ncks -A ${_file_depth_level} ${_file_data} - - unset _file_data _file_depth _file_depth_level -} - -function fesom_ice_add_depth { - _file_depth=$1 - _file_data=$2 - echo ""; echo " * Adding depth axis >>${_file_depth}<< to >>${_file_data}<<" - if [ $# -lt 2 ] ; then - echo " not enought input variables in coupling_fesom2ice.functions::fesom_ice_add_depth" - echo " S T O P 11" - exit 11 - fi - test_file_or_exit ${_file_depth} 12 - test_file_or_exit ${_file_data} 13 - - #--> This depth is not recognized since depth(level) and - # level is the vertical dimension and, hence, the command - # "cdo vertlevel,150/500" does not work as expected - ncks -A ${_file_depth} ${_file_data} - - unset _file_data _file_depth -} - - -function fesom_ice_generate_multiyear_mean { - input=ocean_file_for_ice.nc - echo ""; echo " * making multi-year monthly mean >>${input}<<" - - bakfile=ocean_file_for_ice.before_ymonmean.nc - test_file_or_exit $input 14 - mv $input $bakfile - - for __var in $($cdo -s showvar ${bakfile} ) - do - $cdo ymonmean -selvar,${__var} ${bakfile} ${input}.TMP_FIX_$$.${__var} - done - $cdo -O merge ${input}.TMP_FIX_$$.* ${input} && rm ${input}.TMP_FIX_$$.* - - $cdo showvar ${input} - #add_to $(pwd)/${bakfile} ${bakfile} couple - cp $(pwd)/${bakfile} ${COUPLE_DIR}/${bakfile} - cleanup_list="${cleanup_list} $(pwd)/${bakfile}" - - unset __var -} - -function fesom_ice_generate_total_mean { - input=ocean_file_for_ice.nc - echo ""; echo " * making total mean >>${input}<<" - - bakfile=ocean_file_for_ice.before_totalmean.nc - test_file_or_exit $input 15 - mv $input $bakfile - if [ 1 -eq 1 ] ; then - ${cdo} timmean $bakfile $input - else - ncwa -a time $bakfile $input - fi - - #add_to $(pwd)/${bakfile} ${bakfile} couple - cp $(pwd)/${bakfile} ${COUPLE_DIR}/${bakfile} - cleanup_list="${cleanup_list} $(pwd)/${bakfile}" - - unset bakfile -} - -# -- last line diff --git a/couplings/coupling_dual-hemisphere/fesom/coupling_ice2fesom.functions b/couplings/coupling_dual-hemisphere/fesom/coupling_ice2fesom.functions deleted file mode 100644 index ae4e3f0ef..000000000 --- a/couplings/coupling_dual-hemisphere/fesom/coupling_ice2fesom.functions +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/ksh - -function ice2fesom { - echo " *** S T A R T I N G ice2fesom ***)" - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - . ${FUNCTION_PATH}/../pism/coupling_ocean2pism.functions - - echo "ICE_TO_FESOM=${ICE_TO_FESOM:-0}" - if [[ "x$ICE_TO_FESOM" == "x0" ]]; then - echo " NOT generating ice forcing for ocean model" - echo " since ICE_TO_FESOM=${ICE_TO_FESOM}" - return - else - echo " Only generating iceberg forcing so far ..." - iterative_coupling_pism_ocean_prepare_ocean_icebergmodel_forcing - return - fi - - # - # ==> if [[ $ICE_TO_FESOM -ge 1 ]]; then - # - # ice2fesom - # 4) Remap/Regrid to FESOM grid - # 5) FESOM Names - # - CHUNK_DATE_TAG_awicm="${CHUNK_START_DATE_awicm}-${CHUNK_END_DATE_awicm}" - - INTERPOL_TYPE_OCE=${INTERPOL_TYPE_OCE:-"dis"} #Standard=dis : "bil" "con" "dis" "nn" - - WEIGHTS_ICE2OCE=${WEIGHTS_ICE2OCE:-weights_ice2oce.${INTERPOL_TYPE_OCE}.nc} - GRIDDES_OCE=${GRIDDES_OCE:-ocean.griddes} - OCEAN_PISM_FORCING_FILE="pism_forcing4ocean_verXXXX.${INTERPOL_TYPE_OCE}.${CHUNK_DATE_TAG_awicm}.nc" - COMBINED_OUTPUT=ice_file_at_ocean.combined.nc - - - iterative_coupling_ice_fesom1x_write_names - - read_names ice fesom - save_griddes ocean - - NOCOLOR='\033[0m' - GREEN='\033[32m' - - echo "Grid method (ocean) : ${iter_coup_regrid_method_ice2oce}" - echo -e " --> Grid method >>> ${GREEN}${iter_coup_regrid_method_ice2oce}${NOCOLOR} <<< ocean" - case $iter_coup_regrid_method_ice2oce in - "INTERPOLATE"|"REMAP") - iterative_coupling_ice_ocean_regrid_interpolate - ;; - "EXTRAPOLATE") - iterative_coupling_ice_ocean_regrid_interpolate - iterative_coupling_ice_ocean_regrid_extrapolate - ;; - "NONE") - # Ocean and ice sheet grid are identical !! - INTERPOL_TYPE_OCE=none - iterative_coupling_ice_ocean_regrid_none - ;; - *) - echo " UNKNOWN regrid method selected!" - echo " Known: INTERPOLATE = REMAP, EXTRAPOLATE, NONE" - echo " S T O P 2" - exit 2 - esac - - for file in ${cleanup_list} ; do test -f $file && rm $file ; done - unset cleanup_list file - unset NOCOLOR GREEN - - echo " ...done." -} - - - -function iterative_coupling_ice_fesom1x_write_names { - echo "Writing fesom1x input names and units for use with generic ocean_file_for_ice.nc" - :> ice_names_for_fesom.dat - - # - # FESOM names - # - echo ""; echo " * freshwater flux" - echo "fesom_name_freshwater_flux=wnet" >> ice_names_for_fesom.dat - echo "fesom_units_freshwater_flux=W/m2" >> ice_names_for_fesom.dat - - echo ""; echo " * heat flux" - echo "fesom_name_heat_flux=qnet" >> ice_names_for_fesom.dat - #echo "fesom_units_heat_flux=kg/m2/s" >> ice_names_for_fesom.dat - echo "fesom_units_heat_flux=m" >> ice_names_for_fesom.dat - - echo ""; echo " * basal ice shelf temperature gradient" - echo "fesom_name_temperature_gradient=dTdz" >> ice_names_for_fesom.dat - echo "fesom_unit_temperature_gradient=K/m" >> ice_names_for_fesom.dat - - echo ""; echo " * landmask" - echo "fesom_name_landmask=mask" >> ice_names_for_fesom.dat - echo "fesom_units_landmask=1" >> ice_names_for_fesom.dat - - echo ""; echo " * oceanmask" - echo "fesom_name_oceanmask=mask" >> ice_names_for_fesom.dat - echo "fesom_units_oceanmask=1" >> ice_names_for_fesom.dat - - echo ""; echo " * iceshelfmask" - echo "fesom_name_iceshelfmask=mask" >> ice_names_for_fesom.dat - echo "fesom_units_iceshelfmask=1" >> ice_names_for_fesom.dat - - add_to $(pwd)/ice_names_for_fesom.dat ice_names_for_fesom.dat couple - echo " ...done." - -} - -# -# Regrid: Interpolation and extrapolation -# -function iterative_coupling_ice_ocean_regrid_interpolate { - echo " * Interpolate GCM forcing..." - - ierr=20 - for file in ${GRIDDES_OCE:?Missing variable} ${COMBINED_OUTPUT:?Missing variable} ; do - ierr=$(( ierr + 1 )) - test_file_or_exit $file $ierr #ierr=++20 - done - - build_weights4remap \ - ${COMBINED_OUTPUT:?Missing variable} \ - ${GRIDDES_OCE:?Missing variable} \ - ${WEIGHTS_ICE2OCE:?Missing variable} \ - ${INTERPOL_TYPE_OCE:?Missing variable} \ - couple - test_file_or_exit $WEIGHTS_ICE2OCE 29 - - echo " => remap,$GRIDDES_OCE,$WEIGHTS_ICE2OCE" - $cdo remap,$GRIDDES_OCE,$WEIGHTS_ICE2OCE \ - ${COMBINED_OUTPUT} \ - ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc - - cleanup_list="${cleanup_list} $(pwd)/${COMBINED_OUTPUT}" -} - - -function iterative_coupling_ice_ocean_regrid_extrapolate { - # - # This has to be called after the interpolation, because after the - # interpolation we have landpoints that does not exist in the - # FESOM ocean grid - regrid_pism_ocean_extrapolate_misstoc=${regrid_pism_ocean_extrapolate_misstoc:-0} - iterative_coupling_pism_ocean_regrid_extra_type=${iterative_coupling_pism_ocean_regrid_extra_type:-setmisstoc} - echo " * Extrapolate GCM forcing with method >>${iterative_coupling_pism_ocean_regrid_extra_type}<< ..." - - _cdo_flag=$( return_allowed_cdo_miss_replace_flags ${iterative_coupling_pism_ocean_regrid_extra_type} ${regrid_pism_ocean_extrapolate_misstoc} ) - - _tmp_file=ice_file_at_ocean.${INTERPOL_TYPE_OCE}_before_extrapolation.nc - mv ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc ${_tmp_file} - - $cdo $_cdo_flag ${_tmp_file} \ - ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc - - echo " ... done" - cleanup_list="${cleanup_list} $(pwd)/${_tmp_file}" - unset _cdo_flag _tmp_file -} - - -function iterative_coupling_ice_ocean_regrid_none { - echo " * Grid-identical GCM forcing (no interpolation)..." - - test_file_or_exit ${COMBINED_OUTPUT} 10 - - mv ${COMBINED_OUTPUT} \ - ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc - - cleanup_list="${cleanup_list} $(pwd)/${COMBINED_OUTPUT}" -} - - -function iterative_coupling_ice_fesom_rename_vars { - echo " * Set final FESOM variable names..." - - test_file_or_exit ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc 11 - - ncrename \ - -v .wnet,${fesom_name_freshwater_flux} \ - -v .qnet,${fesom_name_heat_flux} \ - -v .dTdz,${fesom_name_temperature_gradient} \ - -v .landmask,${fesom_name_landmask} \ - -v .oceanmask,${fesom_name_oceanmask} \ - -v .iceshelfmask,${fesom_name_iceshelfmask} \ - ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc \ - ${OCEAN_PISM_FORCING_FILE} - - cleanup_list="${cleanup_list} $(pwd)/ice_file_for_ocean.${INTERPOL_TYPE_OCE}.nc" -} - -######################################################################## -######################################################################## -# Lars Ackermann 07.09.2020 -######################################################################## -function iterative_coupling_pism_ocean_prepare_ocean_icebergmodel_forcing { - # iceberg coupling LA - #latest_pism_output=${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${YR0_pism}${M0_pism}${D0_pism}-${END_YEAR_pism}${END_MONTH_pism}${END_DAY_pism}.nc - - counter=0 - COUNT_MAX=12 - while [ ${counter} -lt ${COUNT_MAX} ] - do - echo " * inside while loop " - if [ -f ${COUPLE_DIR}/../outdata/pism/latest_ex_file_pism.nc ]; then - break - fi - - echo; echo " * File ${COUPLE_DIR}/../outdata/pism/latest_ex_file_pism.nc not found. Waiting for 10 seconds ..." - sleep 10 - counter=$((counter+1)) - done - - latest_pism_output=${COUPLE_DIR}/../outdata/pism//latest_ex_file_pism.nc - if [[ -f ${latest_pism_output} ]]; then - pism_discharge_file=${COUPLE_DIR}/../outdata/pism/latest_ex_file_pism.nc - #pism_discharge_file=${latest_pism_output} - elif [[ -f ${SPINUP_FILE_pism} ]]; then - pism_discharge_file=${SPINUP_FILE_pism} - fi - - echo "CHUNK_SIZE_pism_standalone: ${CHUNK_SIZE_pism_standalone}" - echo "COUPLE_DIR: ${COUPLE_DIR}" - echo "PISM_DISCHARGE_FILE: ${pism_discharge_file}" - - cdo -s -timmean -selname,tendency_of_ice_amount_due_to_discharge \ - -setgrid,${COUPLE_DIR}/ice.griddes ${pism_discharge_file} ${COUPLE_DIR}/latest_discharge.nc - - use_icesheet_coupling=1 -} - -############################################################################ -############################################################################ - - -# -- last line diff --git a/couplings/coupling_dual-hemisphere/fesom/env_fesom.py b/couplings/coupling_dual-hemisphere/fesom/env_fesom.py deleted file mode 100644 index 0f62376b7..000000000 --- a/couplings/coupling_dual-hemisphere/fesom/env_fesom.py +++ /dev/null @@ -1,57 +0,0 @@ -def prepare_environment(config): - environment_dict = { - "ICE_TO_FESOM": int(config["fesom"].get("use_icebergs", False).__bool__()), - "FESOM_TO_ICE": int(config["general"]["first_run_in_chunk"]), - "MESH_DIR_fesom": config["fesom"]["mesh_dir"], - "MESH_ROTATED_fesom": config["fesom"]["mesh_rotated"], - "DATA_DIR_fesom": config["fesom"]["experiment_outdata_dir"], - "COUPLE_DIR": config["general"]["experiment_couple_dir"], - "number_of_years_for_forcing": config["model1"]["chunk_size"], - "CHUNK_SIZE_pism_standalone": config["model2"]["chunk_size"], - "CHUNK_START_DATE_fesom": config["general"]["chunk_start_date"], - "CHUNK_END_DATE_fesom": config["general"]["chunk_end_date"], - "FUNCTION_PATH": config["fesom"]["workflow"]["subjobs"]["couple_in"]["script_dir"], - "PYFESOM_PATH": "/pf/a/a270124/pyfesom2/", - "EXP_ID": config["general"]["command_line_config"]["expid"], - "iter_coup_regrid_method_ice2oce": "INTERPOLATE", - #"BASIN_FILE": config["fesom"].get("basin_file"), - "MACHINE": config["computer"]["name"], - "ICEBERG_DIR": config["fesom"].get("iceberg_dir", ""), - - #"FESOM_GRID_input": config["fesom"]["grid_input"], - #"solidearth_ice_thickness_file":( - # config["general"]["experiment_couple_dir"] + - # "/ice_thickness.nc" - # ), - #"ADD_UNCHANGED_ICE": config["vilma"].get("add_unchanged_ice", False), - #"EISLASTFILE_vilma": ( - # config["vilma"]["experiment_input_dir"] + - # "/" + - # config["vilma"]["eislastfile"] - # ), - #"RUN_NUMBER_vilma": config["general"]["run_number"], - #"RUN_DATE_STAMP": config["general"]["run_datestamp"], - #"LAST_RUN_DATE_STAMP": config["general"]["last_run_datestamp"], - #"INITIAL_YEAR_vilma": config["general"]["initial_date"].syear, - #"NYEAR_vilma_standalone": config["general"]["nyear"], - #"FINAL_YEAR_vilma": config["general"]["final_date"].syear, - #"EISLASTCONF_vilma":( - # config["vilma"]["experiment_config_dir"] + - # "/inp/" + - # config["vilma"]["eislastconf"] - # ) - - } - - #if environment_dict["ADD_UNCHANGED_ICE"] == False: - # environment_dict["ADD_UNCHANGED_ICE"] = 0 - #elif environment_dict["ADD_UNCHANGED_ICE"] == True: - # environment_dict["ADD_UNCHANGED_ICE"] = 1 - - - print(environment_dict) - return environment_dict - - - - diff --git a/couplings/coupling_dual-hemisphere/general/coupling_general.functions b/couplings/coupling_dual-hemisphere/general/coupling_general.functions deleted file mode 100644 index 4818a2e42..000000000 --- a/couplings/coupling_dual-hemisphere/general/coupling_general.functions +++ /dev/null @@ -1,447 +0,0 @@ -#!/usr/bin/ksh - -module load nco -. ${FUNCTION_PATH}/../general/general_lists.functions - -cdo=cdo - -function read_names { - model_from=$1 - model_to=$2 - echo "*** COUPLE_DIR = ${COUPLE_DIR} ***" - if [ -f ${COUPLE_DIR}/${model_from}_names_for_${model_to}.dat ]; then - namefile=${COUPLE_DIR}/${model_from}_names_for_${model_to}.dat - elif [ -f ${model_from}_names_for_${model_to}.dat ]; then - namefile=${model_from}_names_for_${model_to}.dat - else - echo "Could not find ${COUPLE_DIR}/${model_from}_names_for_${model_to}.dat" - exit 42 - fi - echo; echo -e "\t\t* Reading ${model_from} variable names for ${model_to}" - source ${namefile} -} - -function test_file_or_exit { - # Checks if the file exists and exit if file is missing - # Call: test_file_or_exit FILENAME (ExitCode) - # Christian Rodehacke, AWI, 2018-09-04 - __file=$1 - __error_code=$2 - if [ ! -f ${__file:-/DiesenFileNamenSeheIchSehrSelten_Oder_Fragezeichen} ] ; then - echo " Missing file >>${__file}<< in $(pwd)" - echo " S T O P ${__error_code:-998}" - exit ${__error_code:-998} - fi - - unset __file __error_code -} - -# ---------------------------------------------------------- -# -# CDO (Climate Data Operator) specific functions -# -function build_grid_des { - # Build grid description file (cdo griddes) for provided - # input or use existing older file if both are identical - # Call: build_grid_des InputData, GridDesFileName (TargetDir) (RestartDir) (Var2SelectGrid) - # Christian Rodehacke, AWI, 2018-10-15 - _source_file=$1 - _griddes_file=$2 - _target_dir=$3 - _restart_dir=$4 - _var2grid=$5 - - test_file_or_exit $_source_file - if [ "x${_var2grid}" != "x" ] ; then - $cdo -s griddes -selvar,${_var2grid} $_source_file > $_griddes_file - else - $cdo -s griddes $_source_file > $_griddes_file - fi - - _restart_griddes_file=${_restart_dir}/$_griddes_file - - _new_grid_flag=1 - if [ -f $_restart_griddes_file ] ; then - if [ "x$(diff $griddes_file $_restart_griddes_file)" == "x" ] ; then - # Identical grid description - _new_grid_flag=0 - fi - fi - - if [ "x${_target_dir}" != "x" ] ; then - if [ $_new_grid_flag -ge 1 ] ; then - add_to $(pwd)/$griddes_file $_griddes_file $_target_dir - else - add_to $_restart_dir/$_griddes_file $_griddes_file $_target_dir - fi - fi - - unset _griddes_file _restart_dir _restart_griddes_file _source_file _target_dir - return ${_new_grid_flag} -} - - -function build_weights4remap { - # Build remapping weights (cdo griddes) for provided input - # or use existing restart weights of it exists - # Call: build_grid_des InputData, GridDesFileName WeightFileName RemapType (TargetDir) (RestartDir) (VariableSelection) - # Christian Rodehacke, 2018-09-05 - _source_file=$1 - _griddes_file=$2 - _weight_file=$3 - _remap_type=$4 - _target_dir=$5 - _restart_dir=$6 - _selvar2regrid=$7 - - _restart_weight_file=${_restart_dir}/$_weight_file - - if [ -f $_restart_weight_file ] ; then - echo " - Reuse restart weight file $_restart_weight_file" - use_weight_file=$_restart_weight_file - else - echo " - Compute new weight file >>${_weight_file}<< based on >>${_source_file}<<" - test_file_or_exit $_source_file - test_file_or_exit $_griddes_file - - check_allowed_cdo_remap_flag ${_remap_type} - - if [ "x${vars2regrid}" == "x" ] ; then - $cdo -s gen${_remap_type},${_griddes_file} \ - -seltimestep,1 $_source_file \ - $_weight_file - else - $cdo -s gen${_remap_type},${_griddes_file} \ - -selvar,${_selvar2regrid} -seltimestep,1 $_source_file \ - $_weight_file - fi - use_weight_file=$(pwd)/$_weight_file - - if [ "x${_restart_dir}" != "x" ] ; then - add_to $use_weight_file $_weight_file $(basename ${_restart_dir}) - fi - fi - - if [ "x${_target_dir}" != "x" ] ; then - add_to $use_weight_file $_weight_file $_target_dir - fi - - unset _griddes_file _restart_dir _remap_type _restart_weight_file - unset _selvar2regrid _source_file _target_dir use_weight_file _weight_file -} - - -function check_allowed_cdo_remap_flag { - # Check allowed remapping type flags in the frame work - # of the here used script environment - # Call: check_allowed_cdo_remap_flag RemapType - # Christian Rodehacke, 2018-09-05 - __remap_type=$1 - case ${__remap_type} in - bil) - echo " - Remapping ${__remap_type} : bilinear (for curvelinear grid)" - ;; - bic) - echo " - Remapping ${__remap_type} : bicubic (for curvelinear grid)" - ;; - nn) - echo " - Remapping ${__remap_type} : nearest neighbor (any grid)" - ;; - dis) - echo " - Remapping ${__remap_type} : distance-weighted average (any grid)" - ;; - con) - echo " - Remapping ${__remap_type} : First order conservative (requires corner points)" - ;; - ycon) - echo " - Remapping ${__remap_type} : First order conservative, YAC (requires corner points)" - ;; - con2) - echo " - Remapping ${__remap_type} : Second order conservative (requires corner points)" - ;; - laf) - echo " - Remapping ${__remap_type} : largest area fraction (for spherical grid)" - ;; - *) - echo " UNKNOWN remapping <<${__remap_type}>>" - echo " Known: bil, bic, nn, dis, con, ycon, con2, laf" - echo " S T O P 1" - exit 1 - ;; - esac - unset __remap_type -} - - -function return_allowed_cdo_miss_replace_flags { - # Determine allowd filling missing values flags - # Call: return_allowed_cdo_miss_replace_flags ReplaceType - # Christian Rodehacke, 2018-09-10 - - _fill_type=$1 - _regrid_extra_misstoc=$2 - - case ${_fill_type} in - setmisstoc) - # missing to constant value - #echo " - Set miss to constant ${_regrid_extra_misstoc:-0} (any grid)" - _cdo_flag=${_fill_type},${_regrid_extra_misstoc:-0} - ;; - fillmiss2) - #echo " - Fillmiss2 (any grid)" - # cdo "strip"-like filling - _cdo_flag=${_fill_type} - ;; - setmisstodis) - # distance - #echo " - distance-weighted average values (any grid)" - _cdo_flag=${_fill_type} - ;; - setmisstonn) - # neigherst neigbour - #echo " - nearest neighbor values (any grid)" - _cdo_flag=${_fill_type} - ;; - *) - echo " UNKNOWN extrapolation type <<${_fill_type}>>" - echo " Known: setmisstoc, fillmiss2, setmisstodis, setmisstonn" - echo " S T O P 2" - exit 2 - ;; - esac - - echo "${_cdo_flag[@]}" -} - -# ---------------------------------------------------------- -# -# PISM specific functions -# - -function pism_coupler_to_esm_runsscripts_syntax { - # Transform PISM command line coupler options into esm-runscript syntax - # Call: pism_coupler_to_esm_runsscripts_syntax "-ocean given" - # Christian Rodehacke, 2018-09-17 - - echo "pism_set_coupler__$(echo $* | tr -s '-' '_' | tr -s ' ' '=' )" -} - -function pism_forcing_to_esm_runsscripts_syntax { - # Transform PISM command line forcing file options into esm-runscript syntax - # Call: pism_forcing_to_esm_runsscripts_syntax "-ocean given" - # Christian Rodehacke, 2018-09-17 - _arg1=$(echo $1 | sed s/_file//g | tr -s '-' '_') - _arg2=$2 - - echo "pism_set_forcing_file__$(echo $_arg1 $_arg2 | tr -s ' ' '=')" - unset _arg1 _arg2 -} - - - - - -function get_units4pism_version { - # Resolve the units for provided variables and PISM version - # Call: get_units4pism_version VariableName PISMVersionString - # Christian Rodehacke, 2018-09-10 - - # NOTE: Please keep alphabetic order of variable names in each - # section. This helps maintaining this function - - __varname=$1 - __ver_pism_string=$2 - - __units="IDoNotKnowThisDummyUnit" - - case ${__ver_pism_string:--0.1} in - "0.0") - # TEMPLATE - case ${__varname} in - # - # Atmosphere/Surface forcing related variables - # - - # - # Ocean forcing related variables - # - - # - # Miscellaneous - # - topg) - __units="meter" - ;; - # - # UKNOWN - # - *) - echo "NOT DEFINED VARIABLE >${__varname}< for PISM version >${__ver_pism_string}<" - echo " You may have changed the pism version, which requires different variables and units" - echo "Please adjust function >get_units4pism_version<" - echo " S T O P 999" - exit 999 - ;; - esac - ;; - - "0.7") - case ${__varname} in - # - # Atmosphere/Surface forcing related variables - # - air_temp) - __units="Kelvin" - ;; - air_temp_std) - __units="Kelvin" - ;; - climatic_mass_balance) - __units="kg m-2 s-1" - ;; - ice_surface_temperature) - __units="Kelvin" - ;; - precipitation) - #__units="mm day-1" #Ice equivalent - __units="m second-1" #Ice equivalent - ;; - #snow_depth) - # __units="" - # ;; - surface_altitude) - __units="meter" - ;; - # - # Ocean forcing related variables - # - salinity_ocean) - __units="g kg-1" - ;; - shelfbmassflux) - __units="kg m-2 s-1" - ;; - shelfbtemp) - __units="degC" - ;; - theta_ocean) - __units="degC" - ;; - theta_ocean_ref) - __units="degC" - ;; - # - # Miscellaneous - # - topg) - __units="meter" - ;; - # - # UKNOWN - # - *) - echo "NOT DEFINED VARIABLE >${__varname}< for PISM version >${__ver_pism_string}<" - echo " You may have changed the pism version, which requires different variables and units" - echo "Please adjust function >get_units4pism_version<" - echo " S T O P 10" - exit 10 - ;; - esac - ;; - "1.0" | "1.1" | "1.2") - case ${__varname} in - # - # Atmosphere/Surface forcing related variables - # - air_temp) - __units="Kelvin" - ;; - air_temp_std) - __units="Kelvin" - ;; - climatic_mass_balance) - __units="kg m-2 s-1" - ;; - ice_surface_temperature) - __units="Kelvin" - ;; - precipitation) - __units="kg m-2 second-1" - ;; - # - # Ocean forcing related variables - # - salinity_ocean) - __units="g kg-1" - ;; - shelfbmassflux) - __units="kg m-2 s-1" - ;; - shelfbtemp) - __units="degC" - ;; - theta_ocean) - __units="degC" - ;; - theta_ocean_ref) - __units="degC" - ;; - # - # Miscellaneous - # - topg) - __units="meter" - ;; - # - # UKNOWN - # - *) - echo "NOT DEFINED VARIABLE >${__varname}< for PISM version >${__ver_pism_string}<" - echo " You may have changed the pism version, which requires different variables and units" - echo "Please adjust function >get_units4pism_version<" - echo " S T O P 11" - exit 11 - ;; - esac - ;; - *) - echo "NOT DEFINED PISM version >${__ver_pism_string}<" - echo "Please adjust function >get_units4pism_version<" - echo " S T O P 99" - exit 99 - ;; - esac - - echo "${__units[@]}" - - unset __units __varname __ver_pism_string -} - -function iterative_coupling_pism_regrid_add_xy_array { - _file_name_add_xy=$1 - _model=${2:-"generic"} - - echo; echo -e "\t\t* x- and y-array to 'pism' ${_model} forcing file >>${_file_name_add_xy}<<" - - test_file_or_exit $_file_name_add_xy 10 - - if [ 1 -eq 0 ] ; then - # Problems with float vs double: does not work as expected when using directly: "ncks -A .." - PISM_GRID_XY_FILE=${POOL_DIR_pism}/grids/${DOMAIN_pism}/pismr_${DOMAIN_pism}_${RES_pism}_xy.nc - else - # This is the standard case: generate both float and double files, just in case something strange happens - INITIAL_FILE_pism=${POOL_DIR_pism}/grids/${DOMAIN_pism}/pismr_${DOMAIN_pism}_${RES_pism}_xy.nc - PISM_GRID_xy_file_double=${PISM_GRID_xy_file_double:-xy_file_double.$(basename ${INITIAL_FILE_pism})} - PISM_GRID_xy_file_float=${PISM_GRID_xy_file_float:-xy_file_float.$(basename ${INITIAL_FILE_pism})} - pism_helpers_create_xy_axis ${INITIAL_FILE_pism} ${PISM_GRID_xy_file_double} ${PISM_GRID_xy_file_float} - - PISM_GRID_XY_FILE=${PISM_GRID_xy_file_double} - fi - - test_file_or_exit $PISM_GRID_XY_FILE 11 - - ncrename -v .x,x_org_$$ -v .y,y_org_$$ $_file_name_add_xy && \ - ncks -A -v x,y $PISM_GRID_XY_FILE $_file_name_add_xy - - unset _file_name_add_xy _model -} diff --git a/couplings/coupling_dual-hemisphere/general/general_helpers.functions b/couplings/coupling_dual-hemisphere/general/general_helpers.functions deleted file mode 100644 index a1441ba5a..000000000 --- a/couplings/coupling_dual-hemisphere/general/general_helpers.functions +++ /dev/null @@ -1,478 +0,0 @@ -#!/usr/bin/ksh - - -mecho() -{ - mecho_level=${mecho_level:-1} - this_level=0 - mecho_string="" - if [[ x"${verbose}" = x1 ]] - then - while (( $this_level < $mecho_level )) - do - mecho_string="---"${mecho_string} - this_level=$((this_level + 1)) - done - echo "${mecho_string}> $@" >> $dumpfile - fi - unset mecho_string this_level -} - -becho() -{ - echo " $@" - mecho " $@" -} - -bline() -{ - becho "==================================================================" -} - - -line() -{ - echo " ==================================================================" -} - - -headline() -{ - echo; echo - echo " ${1}..." - line -} - -bheadline() -{ - becho; becho - becho " ${1}..." - bline -} - - -output_changed_vars() -{ - changedvars=`comm -13 <(sort < $DUMP_DIR/oldvars_${ID}_${mecho_level}_$1.txt) <(sort < $DUMP_DIR/newvars_${ID}_${mecho_level}_$1.txt) \ - | sed '/LINENO/d' \ - | sed '/SECONDS/d' \ - | sed '/RANDOM=/d' ` - printf '%s\n' "$changedvars" | while IFS= read -r line - do - mecho "$line" - done - unset line changedvars -} - -run_formatted() -{ - mecho_level=$((mecho_level + 1)) - ID=${JOB_ID:-$$} - #DUMP_DIR=$WORKING_DIR - $set > $DUMP_DIR/oldvars_${ID}_${mecho_level}_$1.txt - eval $@ - $set > $DUMP_DIR/newvars_${ID}_${mecho_level}_$1.txt - output_changed_vars $1 - rm $DUMP_DIR/oldvars_${ID}_${mecho_level}_$1.txt $DUMP_DIR/newvars_${ID}_${mecho_level}_$1.txt - mecho_level=$((mecho_level - 1)) -} - -call_or_exit() -{ - function_exists_or_exit $1 - run_formatted $@ -} - -var_set() -{ - varname=$1 - re='^[0-9]+$' - - eval $varname=\${${varname}:-ERR} - eval varvalue=\$${varname} - - if [[ "x${varvalue}" = "xERR" ]] - then - echo "0" - else - echo "1" - fi - unset varname varvalue re -} - - - -cond_merge() -{ - if [[ -e $2 ]]; then - echo "about to merge $1 and $2" - cdo merge $1 $2 tempout_cond_merge; mv tempout_cond_merge $2; rm $1 - echo "done" - else - mv $1 $2 - fi -} - - - -test_if_set() -{ - varname=$1 - re='^[0-9]+$' - - eval $varname=\${${varname}:-ERR} - eval varvalue=\$${varname} - - if [[ "x${varvalue}" = "xERR" ]] - then - echo "${varname} not set!" - exit 42 - fi - unset varname varvalue re -} - -test_if_number() -{ - varname=$1 - re='^[0-9]+$' - - eval varvalue=\$${varname} - - if [[ ! ${varvalue} =~ $re ]] - then - echo "${varname} not a number!" - exit 42 - fi - unset varname varvalue re -} - -test_if_set_and_number() -{ - test_if_set $1 - test_if_number $1 -} - -function_exists_or_exit() -{ - if ! [[ "`type $1 2>/dev/null`" ]] - then - echo Function $1 not found. - exit 1 - fi -} - -call_if_exists() -{ - if [[ "`type $1 2>/dev/null`" ]] - then - if ! [[ "${@#*pass_down}" = $@ ]]; then - mecho Calling $@... - fi - run_formatted $@ - fi -} - -calc_date() -{ - typeset command="$1" - shift - command calc_date $command -c 1 "$@" - unset command -} - -get_file_names() -{ - typeset pattern="$1" - shift - echo $(printf " $pattern" "$@") - unset pattern -} - -time_merge() -{ - typeset out="$1" - typeset tmp=$(dirname $out)/.$(basename $out) - shift - cat "$@" > $tmp && mv $tmp $out - unset out tmp -} - - - -pass_down_vars() -{ - searchname=$1 - replacename=$2 - mecho Passing down vars from $1 to $2: - list_of_all_vars=`set | awk -v pat="${searchname}\$" ' BEGIN { FS = "=" } ; $1 ~ pat {print $1}'` - for variable in $list_of_all_vars - do - newvar=`echo $variable | sed s/${searchname}/${replacename}/` - eval testvar=\${${newvar}:-ERR} - if [[ "x${testvar}" = "xERR" ]] - then - eval ${newvar}=\$${variable} - fi - done - unset list_of_all_vars replacename searchname newvar testvar variable -} - - -general_execute() -{ - call_if_exists general_$1 - - call_if_exists ${setup_name}_user_$1 - call_if_exists ${setup_name}_$1 - call_if_exists ${setup_name}_USER_$1 - call_if_exists ${setup_name}_pass_down - - for model in $coupled_setup_component_list - do - call_if_exists ${model}_user_$1 - call_if_exists ${model}_$1 - call_if_exists ${model}_USER_$1 - call_if_exists ${model}_pass_down - done -} - - -double_loop() { - - nolastbit=0 - critsize=10000 - verbose=0 # [0,1,2]; only debuggin; must equal 0 for model run - - template=$1 - if [[ "x$verbose" == "x1" ]]; then - echo "template=$template" - fi - len_temp=`printf '%s' "$template" | awk '{ print length($0) }'` - if [[ $verbose = 1 ]]; then - echo "len_temp=$len_temp" - fi - - location1=`awk -v a="${template}" -v b="SUBSTREAM1" 'BEGIN{print index(a,b)}'` - location2=`awk -v a="${template}" -v b="SUBSTREAM2" 'BEGIN{print index(a,b)}'` - if [[ $verbose = 1 ]]; then - echo "location1=$location1" - fi - if [[ $verbose = 1 ]]; then - echo "location2=$location2" - fi - - if [[ $location1 -lt $location2 ]]; then - loc1=$location1 - loc2=$location2 - else - loc1=$location2 - loc2=$location1 - fi - if [[ $verbose = 1 ]]; then - echo "loc1=$loc1" - fi - if [[ $verbose = 1 ]]; then - echo "loc2=$loc2" - fi - - start_pre=0 - len_pre=$(( loc1 - 1 )) - if [[ $verbose = 1 ]]; then - echo "len_pre=$len_pre" - fi - prefix=`printf '%s' "$template" | awk -v start="$start_pre" -v len="$len_pre" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "prefix=$prefix" - fi - - start_mid=$(( loc1 + 10 )) - if [[ $verbose = 1 ]]; then - echo "start_mid=$start_mid" - fi - len_mid=$(( loc2 - start_mid )) - if [[ $verbose = 1 ]]; then - echo "len_mid=$len_mid" - fi - middle=`printf '%s' "$template" | awk -v start="$start_mid" -v len="$len_mid" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "middle=$middle" - fi - - start_end=$((loc2 + 10)) - if [[ $verbose = 1 ]]; then - echo "start_end=$start_end" - fi - len_end=$((len_temp - start_end + 1)) - if [[ $verbose = 1 ]]; then - echo "len_end=$len_end" - fi - lastbit=`printf '%s' "$template" | awk -v start="$start_end" -v len="$len_end" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "lastbit=$lastbit" - fi - if [[ "x${lastbit}" == "x" ]]; then - nolastbit=1 - fi - if [[ $verbose = 1 ]]; then - echo "nolastbit=$nolastbit" - fi - - substreams1=""; substreams2=""; list_of_files="" - firstline=1 - - searchtemplate="`echo $template | sed 's/SUBSTREAM1/*/' | sed 's/SUBSTREAM2/*/' `" - if [[ $verbose = 1 ]]; then - echo "searchtemplate=$searchtemplate" - $(ls $searchtemplate) - fi - if files=$(ls $searchtemplate 2>/dev/null); then - for file in $files; do - if [[ $verbose = 1 ]]; then - echo "file =$file" - fi - len_file=`printf '%s' "$file" | awk '{ print length($0) }'` - if [[ $verbose = 1 ]]; then - echo "len_file=$len_file" - fi - - file_tmp=${file:$len_pre:$len_file} - if [[ $verbose = 1 ]]; then - echo "file_tmp=$file_tmp" - fi - start_mid=`awk -v a="$file_tmp" -v b="${middle}" 'BEGIN{print index(a,b)}'` - if [[ $verbose = 1 ]]; then - echo "start_mid=$start_mid" - fi - start_mid=$(( start_mid + len_pre )) - if [[ $verbose = 1 ]]; then - echo "start_mid=$start_mid" - fi - if [[ "${nolastbit}" == 0 ]]; then - start_end=`awk -v a="$file" -v b="${lastbit}" 'BEGIN{print index(a,b)}'` - else - start_end=$(( len_file + 1 )) - fi - if [[ $verbose = 1 ]]; then - echo "start_end=$start_end" - fi - - sub1_start=$loc1 - if [[ $verbose = 1 ]]; then - echo "sub1_start=$sub1_start" - fi - sub1_len=$(( start_mid - sub1_start )) - if [[ $verbose = 1 ]]; then - echo "sub1_len=$sub1_len" - fi - sub1=`printf '%s' "$file" | awk -v start="${sub1_start}" -v len="${sub1_len}" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "sub1=$sub1" - fi - - sub2_start=$((start_mid + len_mid )) - if [[ $verbose = 1 ]]; then - echo "sub2_start=$sub2_start" - fi - sub2_len=$((start_end - sub2_start)) - if [[ $verbose = 1 ]]; then - echo "sub2_len=$sub2_len" - fi - sub2=`printf '%s' "$file" | awk -v start="${sub2_start}" -v len="${sub2_len}" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "sub2=$sub2" - fi - - if [[ $location1 -lt $location2 ]]; then - substream1=${sub1} - substream2=${sub2} - else - substream1=${sub2} - substream2=${sub1} - fi - if [[ $verbose = 1 ]]; then - echo "substream1=$substream1" - fi - if [[ $verbose = 1 ]]; then - echo "substream2=$substream2" - fi - - found=0 - for stream in $substreams1; do - if [[ $verbose = 1 ]]; then - echo "prefix=$prefix" - fi - if [[ "x${stream}" = "x${substream1}" ]]; then - found=1 - fi - done - if [[ "x$found" = "x0" ]]; then - substreams1="${substreams1} $substream1" - fi - if [[ $verbose = 1 ]]; then - echo "substreams1=$substreams1" - fi - found=0 - for stream in $substreams2; do - if [[ $verbose = 1 ]]; then - echo "stream=$stream" - fi - if [[ "x${stream}" = "x${substream2}" ]]; then - found=1 - fi - done - if [[ "x$found" = "x0" ]]; then - substreams2="${substreams2} $substream2" - fi - if [[ $verbose = 1 ]]; then - echo "substreams2=$substreams2" - fi - done - - for substream1 in $substreams1; do - if [[ $verbose = 2 ]]; then - echo "substream1=$substream1" - fi - for substream2 in $substreams2; do - if [[ $verbose = 2 ]]; then - echo "substream2=$substream2" - fi - file=`echo $template | sed "s/SUBSTREAM1/${substream1}/" | sed "s/SUBSTREAM2/${substream2}/" ` - if [[ $verbose = 2 ]]; then - echo "file=$file" - fi - if found=$(ls $file 2>/dev/null); then - filesize=$(stat -c%s "$file") - if [[ ("$filesize" > "$critsize") ]]; then - if [[ "x$firstline" = "x1" ]]; then - list_of_files=$(printf "$file $substream1 $substream2") - just_the_files=$(printf "$file") - just_the_substreams1=$(printf "$substream1") - just_the_substreams2=$(printf "$substream2") - firstline=0 - else - list_of_files=$(printf "$list_of_files\n $file $substream1 $substream2") - just_the_files=$(printf "$just_the_files\n $file") - just_the_substreams1=$(printf "$just_the_substreams1\n $substream1") - just_the_substreams2=$(printf "$just_the_substreams1\n $substream2") - fi - fi - fi - done - done - fi - if [[ "${firstline}" = "1" ]]; then - echo "firstline=$firstline exit" - exit 21 - else - printf "$list_of_files" - fi -} - -forall_models_and_filetypes() -{ - for model in ${setup_name} $coupled_setup_component_list; do - for filetype in $autofiletypes; do - call_if_exists $@ $model ${filetype} - done - done -} diff --git a/couplings/coupling_dual-hemisphere/general/general_lists.functions b/couplings/coupling_dual-hemisphere/general/general_lists.functions deleted file mode 100644 index f6747408e..000000000 --- a/couplings/coupling_dual-hemisphere/general/general_lists.functions +++ /dev/null @@ -1,324 +0,0 @@ -#!/bin/ksh -l - - - -assemble_total_list() { - totallistname=$1_TOTAL_$2_FILES - inlistname=$1_$3_$2_FILES - - eval totallist=\$\{${totallistname}\} - eval inlist=\$\{${inlistname}\} - - incounter=1 - for inentry in $inlist; do - case $incounter in - 1) - incounter=2 - infrom=$inentry - ;; - 2) - incounter=3 - totalcounter=1 - into=$inentry - alreadyexists=0 - for totalentry in $totallist; do - case $totalcounter in - 1) - totalcounter=2 - ;; - 2) - totalcounter=3 - if [[ "x${into}" = "x${totalentry}" ]]; then - alreadyexists=1 - break - fi - ;; - 3) totalcounter=1 - ;; - esac - done - ;; - 3) - incounter=1 - inwarning=$inentry - if [[ "x${alreadyexists}" = "x0" ]]; then - if ! [[ "x$3" = "xDEFAULT" ]]; then - echo " $infrom $into $inwarning" - fi - totallist="${totallist} $infrom $into $inwarning" - fi - esac - done - eval ${totallistname}=\"${totallist}\" - - unset $inlistname - unset totallistname inlistname totallist inlist incounter inentry infrom into totalcounter alreadyexists totalentry -} - - - -general_get_file_info() { - echo " ==================================================================" - for model in ${setup_name} $coupled_setup_component_list; do - for filetype in $autofiletypes; do - call_if_exists ${model}_prepare_${filetype} - done - echo " ==================================================================" - done -} - -general_assemble_file_info() { - for model in ${setup_name} $coupled_setup_component_list; do - for filetype in $autofiletypes; do - typeset -u ft_uc; ft_uc=${filetype} - list_of_all_vars=`set | awk -v pat="${model}_.*_${ft_uc}_FILES" ' BEGIN { FS = "=" } ; $1 ~ pat {print $1}'` - default=0 - for var in $list_of_all_vars - do - name=`echo $var | cut -d_ -f2` - case $name in - DEFAULT ) - default=1 - ;; - * ) - echo " Processing user defined file list $var" - call_if_exists assemble_total_list $model ${ft_uc} $name - ;; - esac - done - if [[ "x${default}" = "x1" ]]; then - call_if_exists assemble_total_list $model ${ft_uc} DEFAULT - fi - done - done -} - - -add_to() { - datatype=${3:-${filetype}} - thismodel=${4:-${model}} - withwarning=${5:-warn} - - if [[ "x${datatype}" = "xno_warning" ]]; then - withwarning="no_warning"; datatype=${filetype} - fi - if [[ "x${thismodel}" = "xno_warning" ]]; then - withwarning="no_warning"; thismodel=${model} - fi - - typeset -u dt_uc; dt_uc=${datatype} - from=$1 - to=$2 - listname=${thismodel}_DEFAULT_${dt_uc}_FILES - eval list=\$\{${listname}\} - eval $listname=\"$list $from $to $withwarning\" - - unset list to from datatype dt_uc thismodel listname -} - -add_file() { - add_to $@ -} - -remove_old_setups_and_missings() { - pd_model=$1 - datatype=$2 - typeset -u dt_uc; dt_uc=${datatype} - eval list=\$\{${pd_model}_TOTAL_${dt_uc}_FILES\} - eval destdir=\$\{${dt_uc}_DIR_${pd_model}\} - - eval thisdate=\$\{START_DATE_${pd_model}\} - setupfile=$destdir/${pd_model}_${datatype}_setup_${thisdate}.txt - missingfile=$destdir/${pd_model}_${datatype}_missing_${thisdate}.txt - - if [[ -e $setupfile ]]; then - $rm $setupfile >> $dumpfile - fi - if [[ -e $missingfile ]]; then - $rm $missingfile >> $dumpfile - fi -} - - -general_remove_old_files() { - forall_models_and_filetypes remove_old_setups_and_missings - if [[ -e $totalsetupfile ]]; then - $rm $totalsetupfile >> $dumpfile - fi - if [[ -e $totalmissingfile ]]; then - $rm $totalmissingfile >> $dumpfile - fi - -} - -prepare_data() -{ - pd_model=$1 - datatype=$2 - typeset -u dt_uc; dt_uc=${datatype} - eval list=\$\{${pd_model}_TOTAL_${dt_uc}_FILES\} - eval destdir=\$\{${dt_uc}_DIR_${pd_model}\} - - eval run_number=\$\{RUN_NUMBER_${pd_model}\} - eval thisdate=\$\{START_DATE_${pd_model}\} - eval thisenddate=\$\{END_DATE_${pd_model}\} - copy=1 - create_softlink=0 - - eval lresume=\$\{LRESUME_${pd_model}\} - - if [[ "x${lresume}" = "x0" && "x${dt_uc}" = "xRESTART_IN" ]]; then - echo " Restart files not needed for initial runs for ${pd_model} (LRESUME_${pd_model}=$lresume), skipping..." - else - cp_bckp=${cp} - case $datatype in - init | exe | restart_in ) - if [[ ! "x${run_number}" = "x1" ]]; then - copy=0 - fi - ;; - output | restart_out ) - cp="mv" - create_softlink=1 - ;; - esac - - if [[ "x${before_simulation}" = "x1" ]]; then - setupfile=$destdir/${model}_${datatype}_setup_${thisdate}.txt - else - setupfile=$destdir/${model}_${datatype}_results_${enddate}.txt - fi - missingfile=$destdir/${model}_${datatype}_missing_${thisdate}.txt - - counter=1 - for entry in $list; do - case $counter in - 1) - counter=2 - from=$entry - filename=`basename $from` - ;; - 2) - counter=3 - to=$entry - todir=`dirname $to` - toname=`basename $to` - if ! [[ "x$todir" = "x." ]]; then - mkdir -p ${destdir}/$todir - todir=${todir}/ - else - todir="" - fi - ;; - 3) - counter=1 - warning=$entry - - if [[ "x${copy}" = "x1" ]]; then - if [[ -e $from ]]; then - if [[ ! "x${filename}" = "x${toname}" ]]; then - [[ -e ${destdir}/${to} ]] && rm -rf ${destdir}/${to} - echo "$from -> $to" >> $setupfile - else - echo "$from -> ${todir}$filename" >> $setupfile - fi - [[ -e ${destdir}/${todir}${filename} ]] && rm -rf ${destdir}/${todir}${filename} - ${cp} ${from} ${destdir}/${todir}${filename} >> $dumpfile - [[ "x${create_softlink}" = "x1" ]] && ln -svf ${destdir}/${todir}${filename} ${from} >> $dumpfile - else - if ! [[ "x${warning}" = "xno_warning" ]]; then - if [[ ! "x${filename}" = "x${toname}" ]]; then - echo "$from -> $to" >> $missingfile - else - echo "$from -> ${todir}$filename" >> $missingfile - fi - fi - fi - if [[ ! "x${filename}" = "x${toname}" ]]; then - ${ln} ${destdir}/${todir}${filename} ${destdir}/${to} 2>/dev/null >> $dumpfile - fi - - fi - esac - done - - if [[ -e $setupfile ]]; then - if [[ "x${before_simulation}" = "x1" ]]; then - echo "SETUP used for $model $datatype for run starting at ${thisdate}:" >> $totalsetupfile - else - echo "RESULTS obtained for $model $datatype for run ending at ${enddate}:" >> $totalsetupfile - fi - cat $setupfile >> $totalsetupfile - echo >> $totalsetupfile - fi - if [[ -e $missingfile ]]; then - echo "WARNING: THESE FILES WERE MISSING for $model $datatype for run starting at ${thisdate}:" >> $totalmissingfile - cat $missingfile >> $totalmissingfile - echo >> $totalmissingfile - fi - cp=$cp_bckp - fi - unset cp_bckp datatype dt_uc list create_softlink from to destdir filename missingfile setupfile entry thisdate - unset pd_model run_number counter -} - - - -prepare_work() -{ - pw_model=$1 - datatype=$2 - typeset -u dt_uc; dt_uc=${datatype} - eval list=\$\{${model}_TOTAL_${dt_uc}_FILES\} - eval destdir=\$\{${dt_uc}_DIR_${model}\} - eval lresume=\$\{LRESUME_${pw_model}\} - counter=1 - for entry in $list; do - case $counter in - 1) - counter=2 - ;; - 2) - counter=3 - to=$entry - todir=`dirname $to` - toname=`basename $to` - if ! [[ "x$todir" = "x." ]]; then - mkdir -p ${WORK_DIR}/$todir - todir=${todir}/ - else - todir="" - fi - ;; - 3) - counter=1 - case $datatype in - forcing | init | exe | config) - if [[ -e ${destdir}/${to} ]]; then - ${ln} ${destdir}/${to} ${WORK_DIR}/${to} >> $dumpfile - if [[ "x$dt_uc" = "xCONFIG" ]]; then - echo " ${to}:" - echo "===========================================================================================================" - if [[ "x${to##*.}" == "xnc" ]]; then - ncdump -h ${WORK_DIR}/${to}|grep -v "_doc ="|grep -v "_option ="|grep -v "_type ="|grep -v "_choices =" - else - cat ${WORK_DIR}/${to} - fi - echo; echo "===========================================================================================================" - fi - fi - ;; - restart_in) - if [[ "x${lresume}" = "x1" ]]; then - [[ -e ${destdir}/${toname} ]] && ${cp} ${destdir}/${toname} ${WORK_DIR}/${todir}$toname >> $dumpfile - fi - ;; - *) - ;; - esac - esac - done - unset ${model}_TOTAL_${dt_uc}_FILES - unset pw_model datatype dt_uc list to destdir entry counter -} - diff --git a/couplings/coupling_dual-hemisphere/pism/coupling_atmosphere2pism.functions b/couplings/coupling_dual-hemisphere/pism/coupling_atmosphere2pism.functions deleted file mode 100644 index 6337d498c..000000000 --- a/couplings/coupling_dual-hemisphere/pism/coupling_atmosphere2pism.functions +++ /dev/null @@ -1,2494 +0,0 @@ -#!/bin/ksh -## @file -## @author Dr. Paul Gierz -## @author Alfred Wegener Institute for Polar and Marine Research -## @author Bremerhaven, Germany -## -## @brief Functions for preparing a generic atmosphere output for use with the `PISM` ice sheet model. -## -## NOTES and TODO for this file: -## * [ ] Unify name structure, it's a bit messy right now. -## * [ ] Unset all local variables to keep the global namespace clean (sort-of done, could be better). -## * [ ] Get the abstraction levels figured out correctly. We really want 1 -## function to do 1 thing (and only 1 thing) - - -################################################################################ -################################################################################ -# T O P L E V E L :: Calls all other functions -################################################################################ -################################################################################ - - -## @fn atmosphere2pism() -## @brief -## The top-level container which is called if the -## logical switch `ACM_TO_PISM=1` is set. -## -## This is the top-level container which is called if the -## logical switch `ACM_TO_PISM` is set. In this case, the -## following steps are performed: -## -## 1. Variable names as provided by the atmosphere model are read, -## so that they may be easily renamed to correct `PISM` names. -## 2. The `PISM` target grid description is generated or copied to -## the working directory. -## 3. atmospheric forcing is regridded from the original source -## grid (defined by `atmosphere.griddes`) to `PISM` model grid -## defined by `ice.griddes`. The regridding occurs based upon -## the value of `iterative_coupling_atmosphere_pism_regrid_method` -## 4. An approriate `PISM` forcing is generated. In this step, -## variables are renamed to conform to `PISM` standards, and a -## file is generated which will pass approrpriate command flags -## to the `PISM` run. -## 5. Temporary files are removed from the working directory. -## -## Variables Used: -## -## @var bool ACM_TO_PISM -## @var ic_atm2pism_regrid_method -## @var ic_atm2pism_ablation_method -## -## Variables Assigned: -## -## @var INTERPOL_TYPE_ATM :: "bil" -## @var WEIGHTS_ATM2ICE :: weights_atm2ice.${INTERPOL_TYPE_ATM}.nc -## @var GRIDDES_ICE :: ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes -## @var GRIDDES_ATM :: -## @var ic_atm2pism_regrid_method :: The method which will be used to get -## from the general atmosphere grid to the `PISM` grid. Default value is -## "INTERPOLATE", which specifies bilinear interpolation. Choices are: -## -## 1. DOWNSCALE: Performs bilinear interpolation and then applies -## lapse-rate and atmospheric desertification corrections -## 2. INTERPOLATE: Just bilinear interpolation -## 3. REMAP: Just conservative remapping -## -## Given a different option, the function will exit -## -## @var ic_atm2pism_ablation_method :: Which method should be used to get -## from atmospheric information to a surface mass balance. Default value is "PDD", -## which prepares files and `PISM` options for a positive-degree day ablation -## scheme. Current choices are: -## -## 1. PDD: Prepares files/flags for the positive degree day scheme -## 2. DEBM: Prepares files/flags for the diurnal energy balance model (see here: REF to Uta) -## 3. EBM: Prepares files/flags for the SEMIC energy balance model (see here: REF Mario) -atmosphere2pism() { - echo -e "\t\t==================================================================" - echo -e "\t\t*** S T A R T I N G atmosphere2pism *** "; echo - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/general_helpers.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - if [ $(type -p cdo) ] ; then - echo "Use existing 'cdo'" - else - echo "Load 'cdo' module" - module load cdo - fi - cdo=$( which cdo ) - echo -e "\t Used cdo=${cdo}" - echo -e "\t\t---> Preparing to couple generic atmosphere to specific ice sheet model PISM" - ic_atm2pism_prepare - - iterative_coupling_atmosphere_pism_regrid_method=${iterative_coupling_atmosphere_pism_regrid_method:-DOWNSCALE} - bool_atm2pism_regrid_dyn_downscaling=${bool_atm2pism_regrid_dyn_downscaling:-0} - echo -e "\t\t--> Regrid method >>> ${GREEN}${iterative_coupling_atmosphere_pism_regrid_method}${NOCOLOR} <<<" - case $iterative_coupling_atmosphere_pism_regrid_method in - "DYN_DOWNSCALE") - bool_atm2pism_regrid_dyn_downscaling=1 - ic_atm2pism_regrid_dyn_downscale - ;; - "DOWNSCALE") - ic_atm2pism_regrid_downscale - ;; - "INTERPOLATE") - ic_atm2pism_regrid_interpolate - ;; - "REMAP") - ic_atm2pism_regrid_remap - ;; - *) - echo "Unknown regrid method selected!" - echo "Known options: DOWNSCALE, INTERPOLATE, REMAP" - exit 1 - ;; - esac - - # - # Here ANOMALY in air-temperature and precipitation - # - if [[ "x${ANOMALY_AIR_TEMPERATURE:-0}" == "x1" || \ - "x${ANOMALY_PRECIPITATION:-0}" == "x1" ]] ; then - # Initialize require variables and file names - ic_atm2pism_anoforce_initialize - - if [ "x${ANOMALY_AIR_TEMPERATURE:-0}" == "x1" ] ; then - ic_atm2pism_anoforce_offset_temp_air_regridded - ic_atm2pism_anoforce_offset_temp_firn_regridded - # To ensure that we do not have any double accounting - TEMP_ANOM=0 - REDUCE_TEMP=0 - fi - - if [ "x${ANOMALY_PRECIPITATION:-0}" == "x1" ] ; then - if [ 1 -eq 1 ] ; then - # Precipitation is scaled by anomaly (Multiplication of - # actual precipitation by base state) - ic_atm2pism_anoforce_scale_precipitation_regridded - else - # Precipition as an offset (Addition) - ic_atm2pism_anoforce_offset_precipitation_regridded - fi - # To ensure that we do not have any double accounting - PREC_ANOM=0 - fi - fi - - - - iterative_coupling_atmosphere_pism_ablation_method=${iterative_coupling_atmosphere_pism_ablation_method:-PDD} - echo -e "\t\t--> Ablation method >>> ${GREEN}${iterative_coupling_atmosphere_pism_ablation_method}${NOCOLOR} <<<" - case $iterative_coupling_atmosphere_pism_ablation_method in - "PDD") - ic_atm2pism_ablation_pdd - latest_atmo_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - ;; - "DEBM") - ic_atm2pism_ablation_debm - latest_atmo_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - ;; - "EBM") - ic_atm2pism_ablation_ebm - ;; - *) - echo "Unknown mass balance selected!" - echo "Known options: PDD, DEBM, EBM" - exit 2 - ;; - esac - - echo -e "\t\t---> Tidying up after coupling generic atmosphere to specific ice sheet model PISM" - ic_atm2pism_finish_up - - max_retry=12 - retry=0 - sleep 10 # Minimum time for st_new.sh to finish - - ln -sf ${latest_atmo_file} ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_atmo_forcing_file.nc - - while [ ${retry} -lt ${max_retry} ]; do - if [ -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_atmo_forcing_file.nc ]; then - break # call results.sh outside loop - else - (( retry = retry + 1 )) - sleep 1 - fi - done - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_atmo_forcing_file.nc ]; then - echo "Something wrong after waiting for 120 seconds!" - fi - echo -e "\t\t*** F I N I S H E D atmosphere2pism *** " - echo -e "\t\t==================================================================" -} - -################################################################################ -################################################################################ -# P R E P A R E :: Does all the preperation steps: sets variables, reads names -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_prepare() -## @brief Calls functions for preperation -## -## Prefix of called functions: ic_atm2pism_prepare (if not defined elsewhere) -## -## 1. Defines useful constants -## 2. Reads names of variables and units which are in the atmosphere_file_for_ice.nc -## 3. Saves PISM grid description to COUPLE_DIR for use when regridding -## 4. Cleans up missing values out of the atmosphere_file_for_ice -ic_atm2pism_prepare() { - echo; echo -e "\t\tPreparing to recieve atmosphere..." - ic_atm2pism_prepare_define_constants - read_names atmosphere ice - ic_atm2pism_prepare_save_griddes - ic_atm2pism_prepare_clean_missing_values - echo; echo -e "\t\t...done."; echo -} - - -################################################################################ -################################################################################ -# R E G R I D D I N G :: Wraps up functions down downscaling, interpolating, usw. -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_downscale() -## @brief Calls functions for downscaling GCM forcing -## -## Prefix of called functions: ic_atm2pism_regrid_downscale -## -## 1. Splits names into individual files for each atmospheric variable -## 2. Generates an elevation anomaly between the low resolution and high resolution grid -## 3. Downscales temperature -## 4. Downscales precipitation -ic_atm2pism_regrid_dyn_downscale() { - echo; echo -e "\t\tDynamically downscaling atmosphere forcing..." - ic_atm2pism_regrid_dyn_downscale_split_names - ic_atm2pism_regrid_dyn_downscale_generate_elevation_difference - ic_atm2pism_regrid_dyn_downscale_temperature - ic_atm2pism_regrid_dyn_downscale_temperature_below_firn - ic_atm2pism_regrid_dyn_downscale_precipitation - ic_atm2pism_regrid_dyn_downscale_shortwave_downward_radiation - ic_atm2pism_regrid_dyn_downscale_TOAshortwave - ic_atm2pism_regrid_dyn_downscale_humidity - ic_atm2pism_regrid_dyn_downscale_emissivity - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - ic_atm2pism_regrid_dyn_downscale_wind - fi - ic_atm2pism_regrid_dyn_downscale_cloud_cover - ic_atm2pism_regrid_dyn_downscale_transmissivity - - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_regrid_downscale() -## @brief Calls functions for downscaling GCM forcing -## -## Prefix of called functions: ic_atm2pism_regrid_downscale -## -# temperature_varname = 'air_temp' -# shortwave_radiation_downward_varname = 'swd' -# TOA_shortwave_varname = 'TOAswd' -# humidity_varname = 'q2m' -# emissivity_varname = 'emiss' -# cloud_cover_varname = 'cc' -# transmissivity_varname = 'tau' -## 1. Splits names into individual files for each atmospheric variable -## 2. Generates an elevation anomaly between the low resolution and high resolution grid -## 3. Downscales temperature -## 4. Downscales precipitation -ic_atm2pism_regrid_downscale() { - echo; echo -e "\t\tDownscaling atmosphere forcing..." - ic_atm2pism_regrid_downscale_split_names - ic_atm2pism_regrid_downscale_generate_elevation_difference - ic_atm2pism_regrid_downscale_temperature - ic_atm2pism_regrid_downscale_temperature_below_firn - ic_atm2pism_regrid_downscale_precipitation - ic_atm2pism_regrid_downscale_shortwave_downward_radiation - ic_atm2pism_regrid_downscale_TOAshortwave - ic_atm2pism_regrid_downscale_humidity - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - ic_atm2pism_regrid_downscale_wind - fi - ic_atm2pism_regrid_downscale_emissivity - ic_atm2pism_regrid_downscale_cloud_cover - ic_atm2pism_regrid_downscale_transmissivity - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_regrid_interpolate() -## @brief Interpolates temperature and precipitation biliniearly -## -## Prefix of called functions: ic_atm2pism_regrid_interpolate -## -## Uses `cdo -P 8 remapbil` to interpolate atmospheric fields to the `PISM` grid. -ic_atm2pism_regrid_interpolate() { - echo; echo -e "\t\tInterpolating atmosphere forcing..." - ic_atm2pism_regrid_interpolate_temperature - ic_atm2pism_regrid_interpolate_temperature_below_firn - ic_atm2pism_regrid_interpolate_precipitation - ic_atm2pism_regrid_interpolate_shortwave_downward_radiation - ic_atm2pism_regrid_interpolate_TOAshortwave - ic_atm2pism_regrid_interpolate_humidity - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - ic_atm2pism_regrid_interpolate_wind - fi - ic_atm2pism_regrid_interpolate_emissivity - ic_atm2pism_regrid_interpolate_cloud_cover - ic_atm2pism_regrid_interpolate_transmissivity - - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_regrid_remap() -## @brief Conservative remapping of atmospheric fields -## -## Uses `cdo remapcon` to conservatively remap to the `PISM` grid -ic_atm2pism_regrid_remap() { - echo; echo -e "\t\tRemapping atmosphere forcing..." - ic_atm2pism_regrid_remap_temperature - ic_atm2pism_regrid_remap_temperature_below_firn - ic_atm2pism_regrid_remap_precipitation - ic_atm2pism_regrid_remap_shortwave_downward_radiation - ic_atm2pism_regrid_remap_TOAshortwave - ic_atm2pism_regrid_remap_humidity - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - ic_atm2pism_regrid_remap_wind - fi - ic_atm2pism_regrid_remap_emissivity - ic_atm2pism_regrid_remap_cloud_cover - ic_atm2pism_regrid_remap_transmissivity - echo; echo -e "\t\t...done."; echo -} - - -################################################################################ -################################################################################ -# A B L A T I O N :: Wraps up functions for PDD, DEBM, and SEMIC -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_ablation_pdd() -ic_atm2pism_ablation_pdd() { - echo; echo -e "\t\tSetting up SMB scheme PDD..." - ic_atm2pism_ablation_pdd_make_atmosphere_forcing - # TODO(PG): consistent names - iterative_coupling_pism_regrid_add_xy_array \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - "atmosphere" - ic_atm2pism_ablation_pdd_set_options_atmo_given - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_ablation_debm() -ic_atm2pism_ablation_debm() { - echo; echo -e "\t\tSetting up SMB scheme DEBM..." - ic_atm2debm_ablation_debm_make_forcing - ic_atm2debm_ablation_debm_run - ic_debm2pism_ablation_debm_make_surface_forcing - ic_debm2pism_ablation_debm_set_options_surface_given - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_ablation_ebm() -ic_atm2pism_ablation_ebm() { - echo; echo -e "\t\tSetting up SMB scheme EBM (SEMIC)..." - # NOTE: Not yet implemented. Turning this one will break... - ic_atm2semic_ablation_ebm_make_forcing - ic_atm2semic_ablation_ebm_run - ic_semic2pism_ablation_ebm_make_surface_forcing - ic_semic2pism_set_options_surface_given - echo; echo -e "\t\t...done."; echo -} - -################################################################################ -################################################################################ -# F I N I S H :: Does all the clean up steps -################################################################################ -################################################################################ - - -ic_atm2pism_finish_up() { - for file in ${cleanup_list}; do - if [ -f ${file} ]; then - rm ${file} - fi - done -} - - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for preparing -################################################################################ -################################################################################ - - -ic_atm2pism_prepare_define_constants() { - echo; echo -e "\t\t* Defining constants" - INTERPOL_TYPE_ATM="bil" #"bil" "con" "dis" "nn" - WEIGHTS_ATM2ICE=weights_atm2ice.${INTERPOL_TYPE_ATM}.nc - GRIDDES_ICE=${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes - GRIDDES_ATM=atmosphere.griddes - - NOCOLOR='\033[0m' - GREEN='\033[32m' - RED='\033[31m' -} - - -## @fn ic_atm2pism_prepare_save_griddes() -## @brief -## Saves grid description for a ice sheet -## -## Saves a ice.griddes file in the `COUPLE_DIR` of your experiment. By default, -## tries to copy from the `POOL_DIR_pism` -ic_atm2pism_prepare_save_griddes() { - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes ]; then - echo; echo -e "\t\t* Saving ice.griddes" - if [ -f ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes ]; then - cp ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes - else - echo " Was Looking for: ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes" - echo "Could not find griddes file, exiting..." - exit 3 - fi - else - echo; echo -e "\t\t* File ice.griddes is in place" - fi -} - - -ic_atm2pism_prepare_clean_missing_values() { - # Determine if there are any missing values in the - # atmosphere_file_for_ice, and issue a warning. They will be all set to - # 0, but this might have unintended side-effects - echo; echo -e "\t\t* Cleaning up missing values from atmosphere_file_for_ice.nc (If any are found)" - - missing_value_filler=0 - #todo:org:old variables_in_atmosphere_file_for_ice=$($cdo -s vardes ${COUPLE_DIR}/atmosphere_file_for_ice.nc | tr -s ' ' | awk '{print $2}') - variables_in_atmosphere_file_for_ice=$($cdo -s showvar ${COUPLE_DIR}/atmosphere_file_for_ice.nc) - $cdo -s splitvar ${COUPLE_DIR}/atmosphere_file_for_ice.nc ${COUPLE_DIR}/atmosphere_file_for_ice_ - for var in ${variables_in_atmosphere_file_for_ice}; do - current_min=$($cdo -s \ - -output \ - -timmin \ - -fldmin \ - -selvar,$var \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - | tr -s ' ' \ - | awk '{print $NF}') - current_max=$($cdo -s \ - -output \ - -timmax \ - -fldmax \ - -selvar,$var \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - | tr -s ' ' \ - | awk '{print $NF}') - if [ "x$debug_ic_atm2pism_clean_missing_values" == "x1" ]; then - echo -e "\t\t @ DEBUG: The variable ${var} has current_min=${current_min} and current_max=${current_max}" - fi - number_of_missing_values=$($cdo -s \ - -output \ - -timsum \ - -fldsum \ - -setmisstoc,1 \ - -setrtoc,${current_min},${current_max},0 \ - -selvar,$var \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - | tr -s ' ' \ - | awk '{print $NF}') - echo "number_of_missing_values = ${number_of_missing_values}" - if [ "x$number_of_missing_values" != "x0" ]; then - echo -e "\t\t!!! ${RED}W A R N I N G${NOCOLOR}: The variable ${var} has ${number_of_missing_values} missing values." - echo -e "\t\t!!! ${RED}W A R N I N G${NOCOLOR}: These are being set to $missing_value_filler" - $cdo -s \ - -setmisstoc,${missing_value_filler} \ - ${COUPLE_DIR}/atmosphere_file_for_ice_${var}.nc \ - tmp - mv tmp ${COUPLE_DIR}/atmosphere_file_for_ice_${var}.nc - fi - merge_list="$merge_list ${COUPLE_DIR}/atmosphere_file_for_ice_${var}.nc" - done - $cdo -s -O merge $merge_list ${COUPLE_DIR}/atmosphere_file_for_ice.nc -} - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for dynamic downscaling -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_downscale_split_names() -## @brief -## Splits names **and** regrids via `INTERPOL_TYPE_ATM` -## -## Using the `INTERPOL_TYPE_ATM`, weights are generated for remapping, and -## then used to remap `atmosphere_file_for_ice.nc`. -## Variable names are split into seperate files for further processing. -## Error output of the cdo commant is dumped in `cdo_stderr_atm2pism`. -## -## After regridding, all files matching variable names in `cdo vardes atmosphere_file_for_ice` are added to the `cleanup_list` -ic_atm2pism_regrid_dyn_downscale_split_names() { - ic_atm2pism_regrid_downscale_split_names -} - -## @fn ic_atm2pism_regrid_downscale_generate_elevation_difference() -## @brief -## Calculates `evel_hi` minus `elev_lo`. -## -## Using the `INPUT_FILE_pism` variable `usurf` as high resolution orography, the differnce to the low resolution orography is calculed. -## -## @pre -## Assumes that a variable `atmosphere_name_elevation` is present in the `atmosphere_file_for_ice.nc` -ic_atm2pism_regrid_dyn_downscale_generate_elevation_difference() { - echo ""; echo " * calculating elevation difference" - echo "*** INPUT_FILE_pism = ${INPUT_FILE_pism} ***" - if [ -z ${INPUT_FILE_pism} ]; then - echo "Oh no, help." - exit 5 - fi - #INPUT_FILE_NAME_BASE_pism=$(basename ${INPUT_FILE_pism:?Missing variable}) - INPUT_FILE_NAME_BASE_pism=${INPUT_FILE_pism} - #TODO:org:rm: - if $cdo -L -s vardes ${INPUT_FILE_pism} 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism | grep -q usurf; then - #if [ $($cdo -s showvar ${INPUT_FILE_pism} 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism | grep usurf | wc -l) -gt 0 ] ; then - echo ""; echo " * using INPUT_FILE_pism = ${INPUT_FILE_pism}" - echo ""; echo " * using INPUT_FILE_NAME_BASE_pism = ${INPUT_FILE_NAME_BASE_pism}" - elev_hi_file="${INPUT_FILE_NAME_BASE_pism%.*}"_usurf.nc - $cdo -s -selvar,usurf ${INPUT_FILE_pism} usurf.tmp.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - $cdo -s -seltimestep,-1 usurf.tmp.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - #$cdo -s -seltimestep,-1 -selvar,usurf ${INPUT_FILE_pism} ${COUPLE_DIR}/${PISM_HEMISPHERE}/${elev_hi_file} 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - else - elev_hi_file="${INPUT_FILE_NAME_BASE_pism%.*}"_thk_plus_topg.nc - $cdo -s \ - -setrtoc,-10000,0,0 \ - -add \ - -selvar,thk ${INPUT_FILE_pism} \ - -selvar,topg ${INPUT_FILE_pism} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/${elev_hi_file} 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - ncrename -v thk,usurf ${COUPLE_DIR}/${PISM_HEMISPHERE}/${elev_hi_file} ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc - fi - #mv $elev_hi_file ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc - cp ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_elevation}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo.nc - $cdo -s sub \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_minus_lo.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - ncrename -v $atmosphere_name_elevation,usurf \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/tmp.nc - $cdo settbounds,1mon -setreftime,1850-01-01,00:00:00 \ - -setunit,m tmp.nc surface_altitude_coarse_resolution.nc - - cleanup_list="$cleanup_list ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_minus_lo.nc" -} - -ic_atm2pism_regrid_dyn_downscale_temperature_below_firn() { - echo""; echo -e "\t\t* dynamical downscaling temperature below firn" - echo -e "\t\t- falling back to bilinear interpolation for temperature!" - echo -e "\t\t- PISM will internally apply lapse rates to this field!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc -} - -ic_atm2pism_regrid_dyn_downscale_temperature() { - echo""; echo -e "\t\t* dynamical downscaling temperature" - echo -e "\t\t- falling back to bilinear interpolation for temperature!" - echo -e "\t\t- PISM will internally apply lapse rates to this field!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc -} - -ic_atm2pism_regrid_dyn_downscale_precipitation() { - echo""; echo -e "\t\t* dynamical downscaling precipitation" - echo -e "\t\t- falling back to bilinear interpolation for precipitation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc -} - -ic_atm2pism_regrid_dyn_downscale_shortwave_downward_radiation() { - echo""; echo -e "\t\t* downscaling shortwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for SW radiation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_shortwave}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/shortwave_down.nc -} - -ic_atm2pism_regrid_dyn_downscale_TOAshortwave() { - echo""; echo -e "\t\t* downscaling TOA shortwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for SW radiation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_TOAshortwave}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/TOAshortwave.nc -} - -ic_atm2pism_regrid_dyn_downscale_humidity() { - echo""; echo -e "\t\t* downscaling TOA shortwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_humidity}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/humidity.nc -} - -ic_atm2pism_regrid_dyn_downscale_longwave_downward_radiation() { - echo""; echo -e "\t\t* downscaling longwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for LW radiation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_longwave}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/longwave_down.nc -} - -ic_atm2pism_regrid_dyn_downscale_emissivity() { - echo""; echo -e "\t\t* downscaling atm. emissivity" - echo -e "\t\t- falling back to bilinear interpolation for LW radiation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_emissivity}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/emissivity.nc -} - -ic_atm2pism_regrid_dyn_downscale_wind() { - echo""; echo -e "\t\t* downscaling wind velocities" - echo -e "\t\t- falling back to bilinear interpolation for wind velocities!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_wind}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/uv.nc -} - -ic_atm2pism_regrid_dyn_downscale_cloud_cover() { - echo""; echo -e "\t\t* downscaling cloud cover" - echo -e "\t\t- falling back to bilinear interpolation for cloud cover!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_cloud_cover}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/cloud_cover.nc -} - -ic_atm2pism_regrid_dyn_downscale_transmissivity() { - echo""; echo -e "\t\t* downscaling transmissivity" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_transmissivity}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/transmissivity.nc -} -################################################################################ -################################################################################ -# D E T A I L S :: Steps for downscaling -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_downscale_split_names() -## @brief -## Splits names **and** regrids via `INTERPOL_TYPE_ATM` -## -## Using the `INTERPOL_TYPE_ATM`, weights are generated for remapping, and -## then used to remap `atmosphere_file_for_ice.nc`. -## Variable names are split into seperate files for further processing. -## Error output of the cdo commant is dumped in `cdo_stderr_atm2pism`. -## -## After regridding, all files matching variable names in `cdo vardes atmosphere_file_for_ice` are added to the `cleanup_list` -ic_atm2pism_regrid_downscale_split_names() { - echo; echo " * spliting names and regridding via ${INTERPOL_TYPE_ATM}" - - # Umbau wegen dieser Fehlermeldungen - #* spliting names and regridding via remapbil - #cdo(2) remapbil (Abort): Bilinear/bicubic interpolation doesn't support unstructured source grids! - #cdo: posixio.c:660: px_get: Assertion `pxp->bf_refcount <= 0' failed. - # - #/tmp/slurmd/job2388013/slurm_script[73]: eval[73]: eval[73]: eval[393]: atmosphere2pism[12]: ic_atm2pism_regrid_downscale[65]: regrid_downscale_split_names: line 342: 92036: Abort(coredump) - - if [ 1 -eq 0 ] ; then - # IF CDO does not recognize the grid, you activate this mode - # section and it may solve the problem - - VAR4REMAP=$( $cdo -s showvar ../couple/atmosphere_file_for_ice.nc | awk '{print $1}' ) - echo " Fix for missing information metadata information about longitude and latitude: 'lon lat'" - ncatted -a coordinates,${VAR4REMAP},c,c,'lon lat' \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc - - build_weights4remap \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${GRIDDES_ICE:?Missing variable} \ - ${WEIGHTS_ATM2ICE:?Missing variable} \ - ${INTERPOL_TYPE_ATM:?Missing variable} \ - couple \ - dummy_restart_dir_weights \ - $VAR4REMAP - else - build_weights4remap \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${GRIDDES_ICE:?Missing variable} \ - ${WEIGHTS_ATM2ICE:?Missing variable} \ - ${INTERPOL_TYPE_ATM:?Missing variable} \ - couple - fi - - test_file_or_exit $WEIGHTS_ATM2ICE 4 - - $cdo -s -splitname \ - -remap,$GRIDDES_ICE,$WEIGHTS_ATM2ICE \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_ \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - ##atmosphere_file_at_ice.${INTERPOL_TYPE_ATM}.nc # && rm atmosphere_file_for_ice.nc - - for varname in $($cdo -s showvar ${COUPLE_DIR}/atmosphere_file_for_ice.nc); do - cleanup_list="$cleanup_list ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${varname}.nc" - done -} - -## @fn ic_atm2pism_regrid_downscale_generate_elevation_difference() -## @brief -## Calculates `evel_hi` minus `elev_lo`. -## -## Using the `INPUT_FILE_pism` variable `usurf` as high resolution orography, -## the difference to the low resolution orography is calculated. -## -## @pre -## Assumes that a variable `atmosphere_name_elevation` is present in the `atmosphere_file_for_ice.nc` -ic_atm2pism_regrid_downscale_generate_elevation_difference() { - echo ""; echo " * calculating elevation difference" - echo "*** INPUT_FILE_pism = ${INPUT_FILE_pism} ***" - if [ -z ${INPUT_FILE_pism} ]; then - echo "Oh no, help." - exit 5 - fi - INPUT_FILE_NAME_BASE_pism=$(basename ${INPUT_FILE_pism:?Missing variable}) - #INPUT_FILE_NAME_BASE_pism=${INPUT_FILE_pism} - if [ $($cdo -s showvar ${INPUT_FILE_pism} 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism | grep usurf | wc -l) -gt 0 ] ; then - elev_hi_file="${INPUT_FILE_NAME_BASE_pism%.*}"_usurf.nc - $cdo -s -seltimestep,-1 ${INPUT_FILE_pism} usurf.tmp.nc - $cdo -s -selvar,usurf usurf.tmp.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - else - elev_hi_file=elev_hi.nc - echo " * LA DEBUG: INPUT_FILE_pism = ${INPUT_FILE_pism}" - echo " * LA DEBUG: INPUT_FILE_NAME_BASE_pism = ${INPUT_FILE_NAME_BASE_pism%.*}" - $cdo -s \ - -add \ - -setrtoc,-10000,0,0 \ - -selvar,thk ${INPUT_FILE_pism} \ - -selvar,topg ${INPUT_FILE_pism} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/${elev_hi_file} \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - elev_hi_file="${INPUT_FILE_NAME_BASE_pism%.*}"_thk_plus_topg.nc - fi - cp ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_elevation}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo.nc - $cdo -s sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_minus_lo.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - #mv $elev_hi_file ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc - #UKK generate elevation differences for desertification scheme - #the idea is to prevent that the ice sheet grows unlimited, if the HR (high res - #resolution) ice sheet exceeds the height of the LR ice sheet and gets too - #high precipitation rates, due to the lower topography in the LR atmosphere. - #this scheme is only active on HR heights >2000m. - $cdo -maxc,2000 ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_2000.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - $cdo -maxc,2000 ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo_2000.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - $cdo -s -maxc,0 -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_2000.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo_2000.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_minus_lo_2000.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - - cleanup_list="$cleanup_list ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_lo.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_minus_lo.nc usurf.tmp.nc" -} - -## @fn ic_atm2pism_regrid_downscale_temperature() -## @brief -## Downscales atmospheric temperature using a lapse-rate correction -## -## The following operation applies a spatially uniform, temporally constant lapse rate to the -## elevation difference and corrects the interpolated 2m temperature as: -## -## \f[ -## T_{downscaled} = T_{2m} + \Gamma \cdot \left(z_{hi} - z_{lo}\right) -## \f] -## Where: -## \f$ T_{downscaled} \f$ = Downscaled temperature (K) -## -## \f$ T_{2m} \f$ = 2m air temperature (K) -## -## \f$ \Gamma \f$ = Lapse rate (K/1000m) -## -## \f$ z_{hi} \f$ = High resolution orography (m) -## -## \f$ z_{lo} \f$ = Low resolution orography (m) -## -## The lapse-rate correction may be defined via `DOWNSCALING_LAPSE_RATE` -## (default value is -0.007) units of K/1000m. -## -## @note -## Downscaling of temperature can be explicitly turned **OFF** by setting `DOWNSCALE_TEMP` to a value not equal to 1. -## In this case, temperature information is instead generated via bilinear interpolation. -ic_atm2pism_regrid_downscale_temperature() { - DOWNSCALE_TEMP=${DOWNSCALE_TEMP:-1} - if [ "x${DOWNSCALE_TEMP}" == "x1" ]; then - echo ""; echo " * downscaling temperature" - DOWNSCALING_LAPSE_RATE=${DOWNSCALING_LAPSE_RATE:-"-0.005"} #old value = -0.007 - #if [ ${DOWNSCALING_LAPSE_RATE} -gt 0 ]; then #Error message: integer expression expected - if [ `echo "${DOWNSCALING_LAPSE_RATE} >= 0" | bc -l` -gt 0 ]; then - echo "YOUR DOWNSCALING LAPSE RATE IS POSITIVE!" - echo "IT WAS: $DOWNSCALING_LAPSE_RATE" - exit 6 - fi - echo " - Lapse rate applied was gamma=${DOWNSCALING_LAPSE_RATE} (K/km)" - $cdo -s -f nc \ - -add ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc \ - -mulc,${DOWNSCALING_LAPSE_RATE} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_minus_lo.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - echo " - corrections applied (time mean of difference Hi-Res - Lo-Res) " - echo " fldmin: $($cdo -s -output -fldmin -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc)" - echo " fldmean: $($cdo -s -output -fldmean -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc)" - echo " fldmax: $($cdo -s -output -fldmax -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc)" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc - else - echo ""; echo -e "\t\t* NOT downscaling temperature" - echo -e "\t\t- falling back to bilinear interpolation for temperature!" - # Take the already bilinearly interpolated file - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc - fi -} - -ic_atm2pism_regrid_downscale_temperature_below_firn() { - DOWNSCALE_TEMP=${DOWNSCALE_TEMP:-1} - if [ "x${DOWNSCALE_TEMP}" == "x1" ]; then - echo ""; echo " * downscaling temperature_below_firn" - DOWNSCALING_LAPSE_RATE=${DOWNSCALING_LAPSE_RATE:-"-0.005"} #old value = -0.007 - #if [ ${DOWNSCALING_LAPSE_RATE} -gt 0 ]; then #Error message: integer expression expected - if [ `echo "${DOWNSCALING_LAPSE_RATE} >= 0" | bc -l` -gt 0 ]; then - echo "YOUR DOWNSCALING LAPSE RATE IS POSITIVE!" - echo "IT WAS: $DOWNSCALING_LAPSE_RATE" - exit 6 - fi - echo " - Lapse rate applied was Γ=${DOWNSCALING_LAPSE_RATE} (K/km)" - $cdo -s -f nc \ - -add ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc \ - -mulc,${DOWNSCALING_LAPSE_RATE} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_minus_lo.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - echo " - corrections applied (time mean of difference Hi-Res - Lo-Res) " - echo " fldmin: $($cdo -s -output -fldmin -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc)" - echo " fldmean: $($cdo -s -output -fldmean -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc)" - echo " fldmax: $($cdo -s -output -fldmax -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc)" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/temp_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc - else - echo ""; echo -e "\t\t* NOT downscaling temperature_below_firn" - echo -e "\t\t- falling back to bilinear interpolation for temperature_below_firn!" - # Take the already bilinearly interpolated file - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc - fi -} - -## @fn ic_atm2pism_regrid_downscale_precipitation() -## @brief -## Downscales atmospheric precipitaiton using temperature differences and a scaling factor \f$ \gamma \f$ -## -## The following is after Quiquet et al, The Cryosphere, 2012 -## https://www.the-cryosphere.net/6/999/2012/ -## -## \f[ -## P_{downscaled} = P_{lo} \cdot e^{\gamma \cdot (T_{hi} - T_{lo})} -## \f] -## -## The factor gamma is chosen after Huybrechts 2002, but is poorly constrained (see Charbit et al. 2002) -## UKK also it is not clear if it has the right sign and whether it is actually -## doing what we want it to do... -## AND maybe it is unfortunate that temperature and precip downscaling use -## parameters Gamma and gamma, IMO -## UKK!!! In case {DOWNSCALE_PRECIP} == desertification we use a desertif. scheme for -## elevations >2000m mostly following Ziemen et al, 2014. -## only difference: we only aply it if elev_hi > elev_lo... -ic_atm2pism_regrid_downscale_precipitation() { - DOWNSCALE_PRECIP=${DOWNSCALE_PRECIP:-1} - if [ "x${DOWNSCALE_PRECIP}" == "x1" ]; then - echo ""; echo -e "\t\t* downscaling precipitation" - # Now we do precipitation - gamma="-0.07" - echo -e "\t\t- factor γ=${gamma}" - echo -e "\t\t- P_downscaled = P * e ** (gamma * (T_downscaled - T_original))" - $cdo -s \ - -mul \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc \ - -exp \ - -mulc,$gamma \ - -sub \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - echo -e "\t\t- corrections applied (time mean of difference Hi-Res - Lo-Res) " - echo " fldmin: $($cdo -s -output -fldmin -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - echo " fldmean: $($cdo -s -output -fldmean -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - echo " fldmax: $($cdo -s -output -fldmax -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc - if [ "x$backup_temperature" == "x1" ]; then - echo -e "\t\t Restoring interpolated temperature for use in atmo_given_file.nc" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc - DOWNSCALE_TEMP=0 - fi - elif [ "x${DOWNSCALE_PRECIP}" == "desertification" ]; then - echo ""; echo -e "\t\t* downscaling precipitation following desertification scheme -> Ziemen et al, 2014 " - # Now we do precipitation - gamma=${gamma:-"-0.00069315"} - echo -e "\t\t- factor γ=${gamma}" - echo -e "\t\t- P_downscaled = P * e ** (-gamma * max(0,(max(2000,Z_hi) - max(2000,Z_lo))))" - - $cdo -s \ - -mul \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc \ - -exp \ - -mulc,$gamma \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/elev_hi_minus_lo_2000.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - echo -e "\t\t- corrections applied (time mean of difference Hi-Res - Lo-Res) " - echo " fldmin: $($cdo -s -output -fldmin -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - echo " fldmean: $($cdo -s -output -fldmean -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - echo " fldmax: $($cdo -s -output -fldmax -timmean -sub ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/precip_hi.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc - else - echo ""; echo -e "\t\t* NOT downscaling precipitation" - echo -e "\t\t- falling back to bilinear interpolation for precipitation!" - # Take the already bilinearly interpolated file - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc - fi -} - -ic_atm2pism_regrid_downscale_shortwave_downward_radiation() { - echo""; echo -e "\t\t* downscaling shortwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for SW radiation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_shortwave}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/shortwave_down.nc -} - -ic_atm2pism_regrid_downscale_longwave_downward_radiation() { - echo""; echo -e "\t\t* downscaling longwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for LW radiation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_longwave}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/longwave_down.nc -} - -ic_atm2pism_regrid_downscale_TOAshortwave() { - echo""; echo -e "\t\t* downscaling shortwave_radiation_TOA" - echo -e "\t\t- falling back to bilinear interpolation for LW radiation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_TOAshortwave}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/TOAshortwave.nc -} - -ic_atm2pism_regrid_downscale_humidity() { - echo""; echo -e "\t\t* downscaling near_surface_humidity" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_humidity}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/humidity.nc -} - -ic_atm2pism_regrid_downscale_emissivity() { - echo""; echo -e "\t\t* downscaling atm_emissivity" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_emissivity}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/emissivity.nc -} -ic_atm2pism_regrid_downscale_wind() { - echo""; echo -e "\t\t* downscaling wind" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_wind}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/uv.nc -} - -ic_atm2pism_regrid_downscale_cloud_cover() { - echo""; echo -e "\t\t* downscaling cloud cover" - echo -e "\t\t- falling back to bilinear interpolation for cloud cover!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_cloud_cover}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/cloud_cover.nc -} - -ic_atm2pism_regrid_downscale_transmissivity() { - echo""; echo -e "\t\t* downscaling transmissivity" - echo -e "\t\t- UKK falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_transmissivity}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/transmissivity.nc -} -################################################################################ -################################################################################ -# D E T A I L S :: Steps for bilinear interpolation -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_interpolate_temperature() -## @brief -## Interpolates temperature field bilinearly -## -## This uses `cdo remapbil` to bilinearly interpolate the atmospheric temperature to the ice grid. -## It is the fallback option if downscaling is only applied to precipitation. -ic_atm2pism_regrid_interpolate_temperature() { - atmosphere_file=${1:-${COUPLE_DIR}/atmosphere_file_for_ice.nc} - echo ""; echo -e "\t\t* Regridding temperature bilinearly from atmosphere_file_for_ice.nc" - - if [ "x$debug_ic_atm2pism_regrid_interpolate_temperature" == "x1" ]; then - echo -e "\t\t Command is:" - echo " $cdo -v -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_temperature} \ - ${atmosphere_file} ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism" - fi - - $cdo -s -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_temperature} \ - ${atmosphere_file} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_temperature_below_firn() { - atmosphere_file=${1:-${COUPLE_DIR}/atmosphere_file_for_ice.nc} - echo ""; echo -e "\t\t* Regridding temperature_below_firn bilinearly from atmosphere_file_for_ice.nc" - - if [ "x$debug_ic_atm2pism_regrid_interpolate_temperature_below_firn" == "x1" ]; then - echo -e "\t\t Command is:" - echo " $cdo -v -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_temperature_below_firn} \ - ${atmosphere_file} ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism" - fi - - $cdo -s -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_temperature_below_firn} \ - ${atmosphere_file} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -## @fn ic_atm2pism_regrid_interpolate_precipitation() -## @brief -## Interpolates atmospheric precipitation field bilinearly -## -## Uses `cdo remapbil` to interpolate precipitation biliniearly to the ice grid. -## This is the fallback option if downscaling only is applied to temperature. -ic_atm2pism_regrid_interpolate_precipitation() { - echo ""; echo -e "\t\t* Regridding precipitation bilinearly from atmosphere_file_for_ice.nc" - $cdo -v -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_precipitation} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_shortwave_downward_radiation() { - echo ""; echo -e "\t\t* Regridding short-wave downward radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_shortwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/shortwave_down.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_longwave_downward_radiation() { - echo ""; echo -e "\t\t* Regridding long-wave downward radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_longwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/longwave_down.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_TOAshortwave() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_TOAshortwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/TOAshortwave.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_emissivity() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_emissivity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/emissivity.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_wind() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_wind} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/uv.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_humidity() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_humidity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/humidity.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_transmissivity() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_transmissivity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/transmissivity.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_cloud_cover() { - echo ""; echo -e "\t\t* Regridding cloud cover downward radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_cloud_cover} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/cloud_cover.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for conservative remapping -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_remap_temperature() -## @brief -## Conservative remapping for temperature to ice grid -ic_atm2pism_regrid_remap_temperature() { - echo ""; echo -e "\t\t* Regridding temperature conservatively from atmosphere_file_for_ice.nc" - $cdo -s -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_temperature} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_temperature_below_firn() { - echo ""; echo -e "\t\t* Regridding temperature_below_firn conservatively from atmosphere_file_for_ice.nc" - $cdo -s -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_temperature_below_firn} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -## @fn ic_atm2pism_regrid_remap_precipitation() -## @brief -## Conservative remapping for precipitation to ice grid -ic_atm2pism_regrid_remap_precipitation() { - echo ""; echo -e "\t\t* Regridding precipitation conservatively from atmosphere_file_for_ice.nc" - $cdo -s -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_precipitation} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_shortwave_downward_radiation() { - echo ""; echo -e "\t\t* Regridding short-wave downward radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_shortwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/shortwave_down.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_longwave_downward_radiation() { - echo ""; echo -e "\t\t* Regridding long-wave downward radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_longwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/longwave_down.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_TOAshortwave() { - echo ""; echo -e "\t\t* Regridding TOA shortwave radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_TOAshortwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/TOAshortwave.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_emissivity() { - echo ""; echo -e "\t\t* Regridding TOA shortwave radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_emissivity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/emissivity.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_wind() { - echo ""; echo -e "\t\t* Regridding wind velocity from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_wind} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/uv.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_humidity() { - echo ""; echo -e "\t\t* Regridding TOA shortwave radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_humidity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/humidity.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_transmissivity() { - echo ""; echo -e "\t\t* Regridding TOA shortwave radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_transmissivity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/transmissivity.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_cloud_cover() { - echo ""; echo -e "\t\t* Regridding cloud cover downward radiation from atmosphere_file_for_ice.nc" - $cdo -f nc \ - -remapcon,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -selvar,${atmosphere_name_cloud_cover} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/cloud_cover.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism -} - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for PDD -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_make_atmosphere_forcing() -## @brief -## Sets correct temperature and precipitation units, adds a time axis -## -## Sets temperature and precipitation units and combines the files along with a time axis. -ic_atm2pism_ablation_pdd_make_atmosphere_forcing() { - echo; echo -e "\t\t* Generating atmo_given file with sensible metadata" - ic_atm2pism_ablation_pdd_set_temperature_units - ic_atm2pism_ablation_pdd_set_ice_surface_temperature_from_temperature - ic_atm2pism_ablation_pdd_set_precipitation_units - ic_atm2pism_ablation_pdd_merge_preliminary_files - ic_atm2pism_ablation_pdd_set_time_axis -} - -## @fn ic_atm2pism_ablation_pdd_set_temperature_units() -## @brief -## Sets metadata for air temperature when using an atmosphere given scheme in `PISM` -## -## Renames the variable read from atmosphere_name_temperature to air_temp -## -## @fixme This probably should be named atmo_given_set_temperature_metadata instead... -ic_atm2pism_ablation_pdd_set_temperature_units() { - echo -e "\t\t- setting temperature units and variable names" - ncrename \ - -v ${atmosphere_name_temperature},air_temp \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc -} - -## @fn ic_atm2pism_ablation_pdd_set_ice_surface_temperature_from_temperature() -## @brief -## Compute the surface ice temperature from air temperature used by `PISM` -## -## Compute the time-mean ice surface temperature below the seasonal -## influence skip/surface. -## -## @fixme It should be renamed and improved because it is a hot-fix. -ic_atm2pism_ablation_pdd_set_ice_surface_temperature_from_temperature() { - VAR_NAME_IN="air_temp" - VAR_NAME="ice_surface_temp" - echo -e "\t\t- compute ${VAR_NAME} from ${VAR_NAME_IN}" - - # - # To compute the time series of the time-mean, we use - # -add -mulc,0 -selvar,${VAR_NAME_IN} FILE - # -minc,273.15 -timmean -selvar,${VAR_NAME_IN} FILE - # - $cdo -s \ - -setattribute,${VAR_NAME}@long_name="ice_surface_temp" \ - -setvar,${VAR_NAME} \ - -add \ - -mulc,0.0 -selvar,${VAR_NAME_IN} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - -minc,273.15 -timmean -selvar,${VAR_NAME_IN} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/${VAR_NAME}.pism.nc - - ncatted -a standard_name,${VAR_NAME},d,, \ - -a pism_intent,${VAR_NAME},d,, \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/${VAR_NAME}.pism.nc -} - -## @fn ic_atm2pism_ablation_pdd_set_precipitation_units() -## @brief -## Sets metadata for precipitation when using an atmo given scheme in `PISM` -## -## If `$VERSION_pism` is specificed to 0.7, the precipitation field is rescaled to mm/day. -## Otherwise, in `$VERSION_pism` == 1.0 or 1.1, we can use `kg m-2 second-1`. -## File metadata and variable names are set according. -ic_atm2pism_ablation_pdd_set_precipitation_units() { - echo -e "\t\t- setting precipitation units and variable names" - test_if_set VERSION_pism - if [ "x$VERSION_pism" == "x0.7" ]; then - # FIXME(PG): This is currently very specific and assumes that - # the units coming out of the atmosphere model are kg/m2/s - # - # Divide by ice density and convert from kg/m^2s to mm/day ice equivalent - # Next step is skipped if we use pism1.0, then pism wants kg m-2 s-1 - $cdo -s \ - -mulc,3600 -mulc,24 -mulc,1000 -divc,910 \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - tmp \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism \ - && mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc - fi - ncrename \ - -v ${atmosphere_name_precipitation},precipitation \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc - case ${VERSION_pism:--0.1} in - "0.7") - ncatted \ - -a units,precipitation,o,c,"mm day-1" \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - tmp - ;; - "1.0"|"1.1"|"1.2") - ncatted \ - -a units,precipitation,o,c,"kg m-2 second-1" \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - tmp - ;; - *) - echo "Undefined pism version, exiting" - exit 7 - ;; - esac - mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc -} - -ic_atm2pism_ablation_pdd_merge_preliminary_files() { - echo -e "\t\t- merging atmospheric temp and precip together" - $cdo -s -O \ - -merge \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - - file2add=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_surface_temp.pism.nc - if [ -f $file2add ] ; then - echo -e "\t\t\t+ add $(basename $file2add)" - ncks -A $file2add \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - fi -} - - -## @fn ic_atm2pism_ablation_pdd_set_time_axis() -## @brief adds a time axis to a forcing file -## -## Uses a predefined time axis file to attach time bounds to an atmo_given file -## -## @fixme: This function currently does 360 days. This needs to be improved. -ic_atm2pism_ablation_pdd_set_time_axis() { - - echo -e "\t\t- appending time axis to forcing file >>${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc<<" - # Determine how many timesteps we have and set time unit accordingly - nt=$($cdo -s ntime ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc) - if [ "x$nt" == "x1" ]; then - echo -e "\t\t- only ONE timestep given" - time_unit="year" - echo "Dont know what to do" - exit 8 - else - echo -e "\t\t- assuming MONTHLY MEANS (for now -- using 30 equivalent days per month)" - time_calendar="360_day" - fi - - ncatted \ - -a \ - bounds,time,o,c,"time_bnds" \ - -a \ - calendar,time,o,c,${time_calendar} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc tmp && mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc - - ${FUNCTION_PATH}/../utils/CreateTimeAxisNC.bash ${nt} ${COUPLE_DIR}/${PISM_HEMISPHERE}/time_axis_pism.nc 0 classic 365_day #${CHUNK_START_YEAR_pism} - #ncks -A ${POOL_DIR_pism}/time_axis/pismr_timeaxis_12_360day.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc - #ncks -A ${POOL_DIR_pism}/time_axis/pismr_timeaxis_12_360day.nc ${COUPLE_DIR}/atmo_given_file.nc - ncks -A ${COUPLE_DIR}/${PISM_HEMISPHERE}/time_axis_pism.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc - - #FAILURE: ncks -A ${POOL_DIR_pism}/grids/${DOMAIN_pism}/pismr_${DOMAIN_pism}_${RES_pism}_xy.nc ${COUPLE_DIR}/atmo_given_file.nc - # Producesses unrealistic x-/y-arrays with a values like: -8.0e+51, 1.7e+161, 1.e-258 - - echo -e "\t\t- appending unique date-stamp to file name" - echo -e "\t\t- atmo_given_file.nc ---> atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc" - - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - ln -fs ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_atmo_given_file.nc - cleanup_list="${cleanup_list} ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc" -} - -#:org:deactivated -ic_atm2pism_ablation_pdd_set_options_atmo_given() { - echo; echo -e "\t\t* Generating files with option information for PISM" - pism_conf_file_list="${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_config_value_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat" - for pism_conf_file in $pism_conf_file_list; do - if [ ! -f $pism_conf_file ]; then - :> $pism_conf_file - fi - done - - if [ "x${bool_atm2pism_regrid_dyn_downscaling}" == "x1" ]; then - echo; echo -e "\t\t* Write options for dynamic downscaling" - - echo "pism_set_coupler___atmosphere=given,lapse_rate" >> \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - echo "pism_set_forcing_file___atmosphere_lapse_rate=${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_altitude_coarse_resolution.nc" >> \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - else - echo "pism_set_coupler___atmosphere=given" >> \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - fi - - echo "pism_set_coupler___surface=pdd" \ - >> ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - echo "pism_set_forcing_file___atmosphere_given=${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CURRENT_YEAR_pism}-${END_YEAR_pism}.nc" \ - #ccr:org:todo:echo "pism_set_forcing_file___atmosphere_given=${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CURRENT_YEAR_pism}-${END_YEAR_pism}.nc" \ - #ccr:new:todo:echo "pism_set_forcing_file___atmosphere_given=${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc" \ - >> ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - number_of_timesteps_in_atmo_given_file=$($cdo -s \ - nyear \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc) - echo "pism_set_config_value_FORCE___atmosphere_given_period=${number_of_timesteps_in_atmo_given_file}" \ - >> ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - # ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - # echo "pism_set_forcing_file___atmosphere_lapse_rate=${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_altitude_coarse_resolution.nc" >> \ - # ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - #else - # echo "pism_set_coupler___atmosphere=given" >> \ - # ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - #fi - # - #echo "pism_set_coupler___surface=pdd" \ - #>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - #echo "pism_set_forcing_file___atmosphere_given=${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc" \ - #>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - #number_of_timesteps_in_atmo_given_file=$($cdo -s \ - # nyear \ - # ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc) - #echo "pism_set_config_value_FORCE___atmosphere_given_period=${number_of_timesteps_in_atmo_given_file}" \ - #>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat -} - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for DEBM -################################################################################ -################################################################################ -## @fn ic_atm2debm_make_forcing() -## @brief -## Prepares a forcing file for the Fortran implementation of the dEBM mass balance model -ic_atm2debm_ablation_debm_make_forcing() { - echo; echo -e "\t\t* Preparing forcing file from atmosphere_file_for_ice.nc for the dEBM Mass Balance Model" - ic_atm2debm_ablation_debm_make_forcing_set_temperature_units - ic_atm2debm_ablation_debm_make_forcing_set_temperature_below_firn_units - ic_atm2debm_ablation_debm_make_forcing_set_precipitation_units - ic_atm2debm_ablation_debm_make_forcing_set_cloud_cover_units - ic_atm2debm_ablation_debm_make_forcing_set_shortwave_units - ic_atm2debm_ablation_debm_make_forcing_set_longwave_units - ic_atm2debm_ablation_debm_make_forcing_set_TOAshortwave_units - ic_atm2debm_ablation_debm_make_forcing_set_emissivity_units - ic_atm2debm_ablation_debm_make_forcing_set_transmissivity_units - ic_atm2debm_ablation_debm_make_forcing_set_humidity_units - ic_atm2debm_ablation_debm_make_forcing_merge_preliminary_files -} - - -## @fn ic_atm2debm_run() -## @brief -## Downloads dEBM Fortran code, compile and create excute binary file -## Specific steps: -## -## 1) Generates namelists specific for the Fortran dEBM run -## 2) Downloads dEBM code and create dEBM execute binary file; this only do for the first time step -## 3) Run the Fortran version of the dEBM -ic_atm2debm_ablation_debm_run() { - echo; echo -e "\t\t* Running dEBM Model" - ic_atm2debm_ablation_debm_run_modify_nml - ic_atm2debm_ablation_debm_run_compile_binary - ic_atm2debm_ablation_debm_run_execute_binary -} - -## @fn ic_debm2pism_make_surface_forcing() -## @brief -## Sets the metadata and time axis needed for a surface given file which comes out of the dEBM model -## -## Specific steps: -## 1) Sets the temperature variable name -## 2) Converts temperature to Kelvin if needed -## 3) Sets the SMB variable name -## 4) Sets the SMB units to kg/m2/s (see pism-docs) -## 5) Merges results together -## 6) Sets a time axis -ic_debm2pism_ablation_debm_make_surface_forcing() { - echo; echo -e "\t\t* Generating a surface_given file with sensible names, units, and a time axis..." - ic_debm2pism_ablation_debm_make_surface_forcing_add_surface_temperature - ic_debm2pism_ablation_debm_make_surface_forcing_apply_mask - ic_debm2pism_ablation_debm_make_surface_forcing_set_temperature_varname_and_units - ic_debm2pism_ablation_debm_make_surface_forcing_set_smb_varname_and_units - ic_debm2pism_ablation_debm_make_surface_forcing_merge_preliminary_files - ic_debm2pism_ablation_debm_make_surface_forcing_set_time_axis -} - -ic_atm2debm_ablation_debm_make_forcing_set_temperature_units() { - echo -e "\t\t- setting temperature units and variable names" - ncrename -v ${atmosphere_name_temperature},air_temp ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc - echo -e "\t\t- LA DEBUG: REDUCE_TEMP = ${REDUCE_TEMP}" - if [[ "x${REDUCE_TEMP}" == "x1" ]]; then - if [[ "x${REDUCE_TEMP_BY}" == "xanom" ]]; then - echo -e "\t\t- use bias correction from this file ${TEMP2_BIAS_FILE}" - - $cdo -s -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - ${TEMP2_BIAS_FILE} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/remapped.temp2bias_file.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - $cdo -s -sub \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/remapped.temp2bias_file.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.tmp.nc - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.tmp.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc - else - echo -e "\t\t- reduce temperature of dEBM input artificially by ${REDUCE_TEMP_BY} K" - $cdo -subc,${REDUCE_TEMP_BY} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.tmp.nc - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.tmp.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc - fi - fi - # Units skipped, although we need a way to ensure they are in Kelvin -} - - -ic_atm2debm_ablation_debm_make_forcing_set_temperature_below_firn_units() { - echo -e "\t\t- setting temperature below_firn units and variable names" - #LA: variable name stays the same - #ncrename -v ${atmosphere_name_temperature_below_firn},tsurf ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc - # Units skipped, although we need a way to ensure they are in Kelvin -} - - -ic_atm2debm_ablation_debm_make_forcing_set_precipitation_units() { - echo -e "\t\t- setting precipitation units and variable names" - ncrename -v ${atmosphere_name_precipitation},precipitation \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc - ncatted -a units,precipitation,o,c,"kg m-2 second-1" \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc - echo -e "\t\t- LA DEBUG: Use anomaly coupling = ${PREC_ANOM}" - if [[ "x${PREC_ANOM}" == "x1" ]]; then - echo -e "\t\t- use bias correction from this file ${PREC_BIAS_FILE}" - - $cdo -s -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - ${PREC_BIAS_FILE} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/remapped.precbias_file.nc - $cdo -s -P 8 \ - -setmisstoc,0 - -ifthen -gtc,0 ${COUPLE_DIR}/${PISM_HEMISPHERE}/remapped.precbias_file.nc - ${COUPLE_DIR}/${PISM_HEMISPHERE}/remapped.precbias_file.nc tmp.nc - mv tmp.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/remapped.precbias_file.nc - - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - $cdo -s -sub \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/remapped.precbias_file.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.tmp.nc - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.tmp.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc - fi -} - - -ic_atm2debm_ablation_debm_make_forcing_set_cloud_cover_units() { - echo -e "\t\t- NO CHANGES for clouds units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_shortwave_units() { - echo -e "\t\t- NO CHANGES for shortwave units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_TOAshortwave_units() { - echo -e "\t\t- NO CHANGES for TOAshortwave units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_emissivity_units() { - echo -e "\t\t- NO CHANGES for emissivity units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_transmissivity_units() { - echo -e "\t\t- NO UKK CHANGES for transmissivity units and variable names" - #ncrename -v ${atmosphere_name_transmissivity},tau ${COUPLE_DIR}/${PISM_HEMISPHERE}/transmissivity.nc - #ncatted -a units,transmissivity,o,c,"" ${COUPLE_DIR}/${PISM_HEMISPHERE}/transmissivity.nc -} - -ic_atm2debm_ablation_debm_make_forcing_set_humidity_units() { - echo -e "\t\t- NO CHANGES for humidity units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_longwave_units() { - echo -e "\t\t- NO CHANGES for longwave units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_merge_preliminary_files() { - echo -e "\t\t- merging together atmospheric temperature, precip, cloud cover, SW and LW radiation" - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - $cdo -s -O \ - -merge \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/cloud_cover.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/shortwave_down.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/TOAshortwave.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/emissivity.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/transmissivity.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/humidity.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/uv.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - else - $cdo -s -O \ - -merge \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/cloud_cover.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/shortwave_down.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/TOAshortwave.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/emissivity.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/transmissivity.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/humidity.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - fi - echo -e "\t\t- UKK input_file_for_debm_"${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism} - #${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ -} - - -## @fn ic_atm2pism_set_options_surface_given -## @brief -## Sets surface given options for the next PISM run -ic_debm2pism_ablation_debm_set_options_surface_given() { - pism_conf_file_list="${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_config_value_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat" - for pism_conf_file in $pism_conf_file_list; do - if [ ! -f $pism_conf_file ]; then - :> $pism_conf_file - fi - done - - echo "pism_set_coupler___surface=given" >> \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - echo "pism_set_forcing_file___surface_given=${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc" >> \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - echo "pism_set_config_value_FORCE___surface_given_period=$($cdo -s nyear ${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc)" \ - >> ${COUPLE_DIR}/${PISM_HEMISPHERE}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat -} - - -ic_atm2debm_ablation_debm_run_modify_nml() { - PISM_GRID_FILE=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes - number_of_timesteps=$($cdo -s ntime ${COUPLE_DIR}/${PISM_HEMISPHERE}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc) - - number_of_x_points=$(grep 'xsize' $PISM_GRID_FILE | head -n 1 | awk '{print $3}') - number_of_y_points=$(grep 'ysize' $PISM_GRID_FILE | head -n 1 | awk '{print $3}') - TMP=$( grep cobld $( ls -t ${COUPLE_DIR}/../run_*/work/namelist.echam | head -1 ) | sed 's/^[ \t]*//' ) - prefix="cobld = " - MY_OBLIQUITY=${TMP#"$prefix"} - obliquity_value=${MY_OBLIQUITY:-"23.17"} - - echo -e "\t\t- Generating namelist for dEBM Mass Balance Model" - echo -e "\t\t- Obliquity = ${obliquity_value}" - - # Plus ten points for Shan: variable names are actually variable. Sortof... - # UKK Paul, sometimes I don't understand you - -if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - cat -> ${COUPLE_DIR}/${PISM_HEMISPHERE}/namelist.debm << EOF -! This is the namelist file for model general configuration - -&runctl -lresume=.false. ! if restart, read snow height from 'restart_debm.nc' - ! .false. by default -use_shortwave_radiation_TOA=.true. ! if incorporate top incoming shortwave -use_mask=.false. ! ice mask -debug_switch=.true. ! debug option - ! .false. by default -debug_lon=241 ! if debug_switch=.true. -debug_lat=107 ! debug grid point(debug_lon,debug_lat,debug_mon,debug_year) -debug_mon=7 ! will be print during simulation -debug_year=1 -/ - -&debm -filename_in='${COUPLE_DIR}/${PISM_HEMISPHERE}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc' -precipitation_varname='precipitation' -temperature_varname='air_temp' -shortwave_radiation_downward_varname='swd' -shortwave_radiation_TOA_varname='TOAswd' -cloud_cover_varname='cc' -emissivity_varname='emiss' -transmissivity_varname='tau' -windvelocity_varname='uv' -mapping_varname='thk' -longitude_varname='lon' -latitude_varname='lat' -time_varname='time' - -hydmth_str = 10 ! the beginning of the hydrological year, also start month for snow height integration - ! October for Northern Hemisphere - ! April Southern Hemisphere -stddev=3.5 ! constant standard deviation -obliquity=${obliquity_value} -cloud_bias=0.155 ! cloud bias -Ans = .845 ! Albedo for new snow -Ads = .73 ! Albedo for dry snow -Aws = .55 ! Albedo for wet snow -tau_cs = .75 ! expected clear sky transmissivity -residual = 0 ! residual heat flux (e.g. due to flux into the ice sheet -/ -EOF -elif [[ "x${DEBM_BETA}" == "x999" ]]; then - cat -> ${COUPLE_DIR}/${PISM_HEMISPHERE}/namelist.debm << EOF -! This is the namelist file for model general configuration - -&runctl -lresume=.false. ! if restart, read snow height from 'restart_debm.nc' - ! .false. by default -use_shortwave_radiation_TOA=.true. ! if incorporate top incoming shortwave -use_mask=.false. ! ice mask -debug_switch=.true. ! debug option - ! .false. by default -debug_lon=241 ! if debug_switch=.true. -debug_lat=107 ! debug grid point(debug_lon,debug_lat,debug_mon,debug_year) -debug_mon=7 ! will be print during simulation -debug_year=1 -/ - -&debm -filename_in='${COUPLE_DIR}/${PISM_HEMISPHERE}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc' - -precipitation_varname='precipitation' -temperature_varname='air_temp' -shortwave_radiation_downward_varname='swd' -shortwave_radiation_TOA_varname='TOAswd' -cloud_cover_varname='cc' -emissivity_varname='emiss' -transmissivity_varname='tau' -mapping_varname='thk' -longitude_varname='lon' -latitude_varname='lat' -time_varname='time' - -hydmth_str = 10 ! the beginning of the hydrological year, also start month for snow height integration - ! October for Northern Hemisphere - ! April Southern Hemisphere -stddev=3.5 ! constant standard deviation -obliquity=${obliquity_value} -cloud_bias=0.155 ! cloud bias -Ans = .845 ! Albedo for new snow -Ads = .73 ! Albedo for dry snow -Aws = .55 ! Albedo for wet snow -tau_cs = .75 ! expected clear sky transmissivity -residual = 0 ! residual heat flux (e.g. due to flux into the ice sheet -/ -EOF -else - cat -> ${COUPLE_DIR}/${PISM_HEMISPHERE}/namelist.debm << EOF -! This is the namelist file for model general configuration - -&runctl -lresume=.false. ! if restart, read snow height from 'restart_debm.nc' - ! .false. by default -use_shortwave_radiation_TOA=.true. ! if incorporate top incoming shortwave -use_mask=.false. ! ice mask -debug_switch=.true. ! debug option - ! .false. by default -debug_lon=241 ! if debug_switch=.true. -debug_lat=107 ! debug grid point(debug_lon,debug_lat,debug_mon,debug_year) -debug_mon=7 ! will be print during simulation -debug_year=1 -/ - -&debm -filename_in='${COUPLE_DIR}/${PISM_HEMISPHERE}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc' -precipitation_varname='precipitation' -temperature_varname='air_temp' -shortwave_radiation_downward_varname='swd' -shortwave_radiation_TOA_varname='TOAswd' -cloud_cover_varname='cc' -emissivity_varname='emiss' -transmissivity_varname='tau' -mapping_varname='thk' -longitude_varname='lon' -latitude_varname='lat' -time_varname='time' -hydmth_str = 10 ! the beginning of the hydrological year, also start month for snow height integration - ! October for Northern Hemisphere - ! April Southern Hemisphere -stddev=3.5 ! constant standard deviation -obliquity=${obliquity_value} -beta_nml=${DEBM_BETA} -cloud_bias=0.155 ! cloud bias -Ans = .845 ! Albedo for new snow -Ads = .73 ! Albedo for dry snow -Aws = .55 ! Albedo for wet snow -tau_cs = .75 ! expected clear sky transmissivity -residual = 0 ! residual heat flux (e.g. due to flux into the ice sheet -/ -EOF -fi -# cat -> ${COUPLE_DIR}/${PISM_HEMISPHERE}/namelist.debm << EOF -#& debm -# xlen = ${number_of_x_points} -# ylen = ${number_of_y_points} -# tlen = ${number_of_timesteps} -# filename_in = '${COUPLE_DIR}/${PISM_HEMISPHERE}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc' -# precipitation_varname = 'precipitation' -# temperature_varname = 'air_temp' -# shortwave_radiation_downward_varname = 'swd' -# mapping_varname = 'siced' -# longitude_varname = 'lon' -# latitude_varname = 'lat' -# time_varname = 'time' -# stddev = 3.5 -# obliquity = ${obliquity_value} -# !beta = ${DEBM_BETA} -#/ -#EOF - -echo -e "\t\t- Namelist used in this dEBM run was:" -echo -e "\t\t\t >- -[Begin]- - - - - - - - - - - - - - - - - - - - - - - - -" -cat ${COUPLE_DIR}/${PISM_HEMISPHERE}/namelist.debm -echo -e "\t\t\t <- -[End]- - - - - - - - - - - - - - - - - - - - - - - - - -" -} - - -ic_atm2debm_ablation_debm_run_compile_binary() { - debug_compile_ic_atm2debm_binary=${debug_compile_ic_atm2debm_binary:-1} - # Get a user supplied version if available: - echo "*** DEBM_EXE = ${DEBM_EXE} ***" - if [ ! -z ${DEBM_EXE} ]; then - echo "*** Copy DEBM_EXE into ${COUPLE_DIR}/${PISM_HEMISPHERE}" - cp ${DEBM_EXE} ${COUPLE_DIR}/${PISM_HEMISPHERE}/dEBMmain - elif [ ! -z ${FUNCTION_PATH} ]; then - echo "*** Copy DEBM_EXE from ${FUNCTION_PATH} into ${COUPLE_DIR}/${PISM_HEMISPHERE}" - cp ${FUNCTION_PATH}/dEBM/Fortran/dEBMmain ${COUPLE_DIR}/${PISM_HEMISPHERE}/dEBMmain - fi - - # Clone Shan's fortran version if it's not already here: - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/dEBMmain ]; then - echo -e "\t\t- Couldn't find: ${COUPLE_DIR}/${PISM_HEMISPHERE}/dEBMmain" - if [ ! -d ${COUPLE_DIR}/${PISM_HEMISPHERE}/dEBM ]; then - echo -e "\t\t- Cloning dEBM" - git clone --quiet https://github.com/ukrebska/dEBM - fi - # compile it - current_dir=$(pwd) - cd ${FUNCTION_PATH} - ./install_debm.sh ${MACHINE} 2>> debm_compile_stdout_stderr - - if [ -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/dEBMmain ]; then - echo -e "\t\t * dEBM compilation was successful!" - else - echo -e "\t\t!!! F A T A L E R R O R !!! dEBM not successful. Aborting" - exit - fi - cp dEBMmain ${COUPLE_DIR}/${PISM_HEMISPHERE}/ - cd $current_dir - fi -} - - -## @fn execute_ic_atm2debm_binary -## @brief -## Runs the Fortran version of the dEBM Mass Balance Model -## -## Note: -## 1) Also checks if the namelist and binary file exist -## 2) The stdout and stderr of dEBM are piped to -## ${COUPLE_DIR}/ic_atm2debm_stdout_stderr. If the program exits with an error code of -## non-zero, this stdout/stderr file is printed to the console. -ic_atm2debm_ablation_debm_run_execute_binary() { - echo -e "\t\t- Running DEBM Binary" - here=$(pwd) - cd ${COUPLE_DIR}/${PISM_HEMISPHERE} - DEBM_BINARY=dEBMmain - DEBM_NAMELIST=namelist.debm - required_files_to_run_dEBM="$DEBM_NAMELIST $DEBM_BINARY" - echo -e "\t\t! UKK required_files_to_run_dEBM=$DEBM_NAMELIST $DEBM_BINARY" - for required_file in $required_files_to_run_dEBM; do - required_file_exit_code=1 - if [ ! -f $required_file ]; then - echo -e "\t\t!!! F A T A L E R R O R !!! required file for dEBM $required_file could not befound, exiting" - exit $required_file_exit_code - fi - required_file_exit_code=$((required_file_exit_code + 1)) - done - - echo $(module list) > ${COUPLE_DIR}/${PISM_HEMISPHERE}/module.list - echo "PATH=${PATH}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH}; NETCDFFROOT=${NETCDFFROOT}" - ./$DEBM_BINARY > debm_stdout_stderr 2>&1 || cat debm_stdout_stderr - cd - -} - - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_add_surface_temperature -## @brief -## generates a surface forcing that could passes down to PISM: dEBM output + air_temp -## dEBM ouput is generated from above functions -## air_temp is yearly mean air_temperature under zero degC calculated from echam output -ic_debm2pism_ablation_debm_make_surface_forcing_add_surface_temperature() { - echo -e "\t\t- Adding yearly-averaged atmospheric surface temperature to surface given file" - echo -e "\t\t NOTE: this serves as a first-order estimate for surface temperature below the firn layer" - here=$(pwd) - cd ${COUPLE_DIR}/${PISM_HEMISPHERE} - debug_add_surface_temperature=${debug_add_surface_temperature:-0} - - if [ "x${debug_add_surface_temperature}" == "x1" ]; then - echo -e "\t\t@ DEBUG: Getting air temperature" - fi - # Ensure idential lat/lon units - ncatted -h \ - -a coordinates,tsurf,d,, \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn2.nc - - # Combine select air_temperature - #LA: change timmean to ymonmean - if [[ "x${MULTI_YEAR_MEAN_SMB}" == "x1" ]]; then - $cdo -s -O -settaxis,${CHUNK_START_YEAR_pism}-01-16,12:00:00,1mon \ - -merge \ - surface_mass_balance.nc \ - -minc,273.15 -ymonmean -selvar,tsurf \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn2.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/smb.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - else - $cdo -s -O -settaxis,${CHUNK_START_YEAR_pism}-01-16,12:00:00,1mon \ - -merge \ - surface_mass_balance.nc \ - -minc,273.15 -selvar,tsurf \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn2.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/smb.nc \ - 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism - fi - - # Add 'coordinates' attribute to all variables and, afterward, - # erase it for variable which should not have this attribute. - ncatted -h \ - -a coordinates,,o,c,'lon lat' \ - -a coordinates,lat,d,, \ - -a coordinates,lon,d,, \ - -a coordinates,time,d,, \ - -a coordinates,time_2,d,, \ - -a coordinates,x,d,, \ - -a coordinates,y,d,, \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/smb.nc - - cleanup_list="$cleanup_list ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn2.nc" - cd $here -} - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_apply_mask -## @brief -## apply a mask for PISM surface forcing -## -## Specific steps: -## 1) creates a glacial mask -## for the first time step, users could specifiy DEBM_MASK_SOURCE_FILE -## then, fn will generate a glacial mask from PISM latest output -## 2) appply the above mask -ic_debm2pism_ablation_debm_make_surface_forcing_apply_mask() { - echo -en "\t\t- Applying a mask: " - here=$(pwd) - cd ${COUPLE_DIR}/${PISM_HEMISPHERE} - - debug_apply_ic_atm2debm_mask=${debug_apply_ic_atm2debm_mask:-0} - smb_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/smb.nc - - echo "Masking region where dEBM values are used" - # Apply the mask and create glacial mask according to the - # latest output by setting mask.nc 2 3 -> 1; 4 ->0 - mask_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/mask.nc - if [ "x$RUN_NUMBER_pism" == "x1" ]; then - echo -e "\t\t\t- First run, you can specify to use DEBM_MASK_FILE to get the mask you want to use" - DEBM_MASK_FILE=${DEBM_MASK_FILE:-${POOL_DIR_pism}/masks/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_mask_${RES_pism}.nc} - else - $cdo -f nc -selvar,mask ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc $mask_file - DEBM_MASK_FILE=${mask_file} - fi - - echo -e "\t\t\t DEBM_MASK_FILE=${DEBM_MASK_FILE}" - $cdo -s -O -P 8 -b F64 \ - -remapnn,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes \ - -setmisstoc,0 -lec,3 -selvar,mask -seltimestep,-1 \ - $DEBM_MASK_FILE \ - $mask_file - - # apply mask - LIST_OF_DEBM_VARS="SNH ME SMB RZ A tsurf" - for var in ${LIST_OF_DEBM_VARS}; do - #$cdo -s -f nc ifthen ${mask_file} -selvar,${var} $smb_file ${var} 1>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism 2>&1 - $cdo -s -f nc -selvar,${var} $smb_file ${var} \ - 1>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism 2>&1 - done - $cdo -s -O \ - -merge ${LIST_OF_DEBM_VARS} $mask_file \ - surface_mass_balance_masked.nc \ - 1>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism 2>&1 - - # TODO/BUG (sxu): For right now, Paul is just filling in any missing - # values with a setmisstodis, maybe there is a better way to solve - # this? - # IF WE APPLY a mask, we have to provide NONE NaNs outside - # of the not masked region. - # Fast but maybe with artifical strips: - # -fillmiss2 - # More computational demanding but with distance depended: - # -setmisstodis - # - mv surface_mass_balance_masked.nc \ - surface_mass_balance_masked_raw.nc - #$cdo -s -O -fillmiss2 \ - $cdo -s -O -P 8 -setmisstodis \ - surface_mass_balance_masked_raw.nc \ - surface_mass_balance_masked.nc \ - 1>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism 2>&1 - - echo -e "\t\t\t- Clean up" - #for var in ${LIST_OF_DEBM_VARS} $smb_file; do - for var in ${LIST_OF_DEBM_VARS} ; do - if [ -f $var ] ; then - rm $var - echo -e "\t\t\t\t - erase $var" - else - echo -e "\t\t\t\t x miss $var" - fi - done - - - - - - echo "Use dEBM values across the entire domain (equals skipping a mask)" - cp $smb_file surface_mass_balance_masked.nc - - if [ "x${debug_apply_ic_atm2debm_mask}" == "x1" ]; then - echo -e "\t\t@ DEBUG: Opening the results in ncview for you" - # Put this in the background, or it blocks the rest of the script - # If not running interactively, don't do anything: [ -z "$PS1" ] - if [ -z "$PS1" ] ; then - echo -e "\t\t\t Skip not an active shell" - else - echo -e "\t\t\t Open ncview in the background" - ncview surface_mass_balance_masked.nc & - fi - fi - - if [ ! -f surface_mass_balance_masked.nc ] ; then - echo "*** MISSING surface_mass_balance_masked.nc" - echo "*** cp surface_mass_balance.nc surface_mass_balance_masked.nc" - cp $smb_file surface_mass_balance_masked.nc - fi - - $cdo -splitname \ - surface_mass_balance_masked.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_ \ - 1>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism 2>&1 - - cd $here -} - - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_set_temperature_varname_and_units -## @brief -## ## Sets variables name that conform to PISM standards -## -## Sets air_temp to ice_surface_temp -ic_debm2pism_ablation_debm_make_surface_forcing_set_temperature_varname_and_units() { - echo -e "\t\t- Setting variable name and unit for temperature" - echo -e "\t\t In surface_given variant, this corresponds to firn temperature" - - #debm_ice_temp_varname="air_temp" - debm_ice_temp_varname="tsurf" - pism_ice_temp_varname="ice_surface_temp" - ncrename \ - -v ${debm_ice_temp_varname},${pism_ice_temp_varname} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_ice_temp_varname}.nc - # TODO(pg or shan): Unit check -} - - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_set_smb_varname_and_units -## @brief -## ## Sets variables name that conform to PISM standards -## -## Sets SMB to climatic_mass_balance -ic_debm2pism_ablation_debm_make_surface_forcing_set_smb_varname_and_units() { - echo -e "\t\t- Setting variable name and unit for SMB" - - debm_mass_balance_varname="SMB" - pism_mass_balance_varname="climatic_mass_balance" - ncrename \ - -v ${debm_mass_balance_varname},${pism_mass_balance_varname} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_mass_balance_varname}.nc - ncatted -a \ - units,${pism_mass_balance_varname},o,c,"kg m-2 s-1" \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_mass_balance_varname}.nc \ - tmp_${debm_mass_balance_varname} - mv tmp_${debm_mass_balance_varname} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_mass_balance_varname}.nc -} - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_merge_preliminary_files -## @brief -## merge temperature and surface mass balance -## -ic_debm2pism_ablation_debm_make_surface_forcing_merge_preliminary_files() { - echo -e "\t\t- Merging below-firn temperature and surface mass balance together!" - $cdo -O merge \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_ice_temp_varname}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_mass_balance_varname}.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - 1>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_atm2pism 2>&1 -} - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_set_time_axis -## @brief -## adds a time axis to a forcing file -## -ic_debm2pism_ablation_debm_make_surface_forcing_set_time_axis() { - echo -e "\t\t- Adding a time axis" - - # Determine how many timesteps we have and set time unit accordingly - nt=$($cdo -s ntime ${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc) - if [ "x$nt" == "x1" ]; then - echo " - only ONE timestep given" - time_unit="year" - echo "Dont know what to do" - exit 8 - else - echo " - assuming MONTHLY MEANS (for now -- using 30 equivalent days per month)" - time_calendar="360_day" - fi - - ncatted \ - -a \ - bounds,time,o,c,"time_bnds" \ - -a \ - calendar,time,o,c,${time_calendar} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc tmp_with_taxis \ - && mv tmp_with_taxis ${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - - ${FUNCTION_PATH}/../utils/CreateTimeAxisNC.bash ${nt} ${COUPLE_DIR}/${PISM_HEMISPHERE}/time_axis_pism.nc 0 classic 365_day #${CHUNK_START_YEAR_pism} - ncks -A \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/time_axis_pism.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - - #FAILURE: ncks -A ${POOL_DIR_pism}/grids/${DOMAIN_pism}/pismr_${DOMAIN_pism}_${RES_pism}_xy.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc - # Producesses unrealistic x-/y-arrays with a values like: -8.0e+51, 1.7e+161, 1.e-258 - - # PG: Why was this necessary? - # CR: PISM expects as the two dimensional variables labeled 'x' and 'y' - # iterative_coupling_pism_regrid_add_xy_array ${COUPLE_DIR}/${PISM_HEMISPHERE}/atmo_given_file.nc "atmosphere" - # TODO: cleanup_list="${cleanup_list} ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc" - -} - - -################################################################################ -################################################################################ -# U T I L I T Y F U N C T I O N S -################################################################################ -################################################################################ -# NOTE: These probably should be moved to a general file. - - -## @fn cdo_verbosity() -## @brief -## Controls how verbose CDO should be. -cdo_verbosity() { - if [ "x$CDO_QUIET" == "x1" ]; then - cdo="$cdo -s" - elif [ "x$CDO_VERBOSE" == "x1" ]; then - cdo="$cdo -v" - else - cdo=$cdo - fi -} - -################################################################################ -################################################################################ -# D E T A I L S :: Atmospheric anomaly forcing -################################################################################ -################################################################################ -## @fn ic_atm2pism_anoforce_initialize() -## @brief -## Initilize anomaly forcing -## -## To use anomaly forcing, we have to initilize some additional -## variables, which occurs here. -ic_atm2pism_anoforce_initialize(){ - echo""; echo -e "\t\t* initilize anomaly forcing (variables and file names)" - # - # Atmospheric REFERENCE data and its variables. These could be the - # "truth". - # - REFERENCE_ATMOS_FNAME=${REFERENCE_ATMOS_FNAME:-"/work/ab0246/a270096/share/pism/ANT.16km/ATMForcing.piControl.16km.nc"} - REFERENCE_ATMOS_VNAME_ELEVATION="surface_altitude" - REFERENCE_ATMOS_VNAME_TEMP_AIR="air_temp" - REFERENCE_ATMOS_VNAME_TEMP_FIRN="ice_surface_temp" - REFERENCE_ATMOS_VNAME_PRECIP="precipitation" - REFERENCE_ATMOS_VNAME_SMB="climatic_mass_balance" - - # - # Forcing data from driving atmospheric climate/earth system model - # - FORCING_ATMOS_VNAME_TEMP_AIR="temp2" - FORCING_ATMOS_VNAME_TEMP_FIRN="tsurf" - FORCING_ATMOS_VNAME_PRECIP="aprt" - - # - # Atmospheric BASE STATE and it variables. For a climate warming - # simulations, this BASE STATE could prepresent the control - # climate piControl, for instance. - # - BASE_STATE_ATMOS_FNAME=${BASE_STATE_ATMOS_FNAME:-"/work/ab0246/a270096/share/pism/ANT.16km/atmo_given_file_base_state.pism_sh.nc"} - BASE_STATE_ATMOS_VNAME_TEMP_AIR="air_temp" - BASE_STATE_ATMOS_VNAME_TEMP_FIRN="ice_surface_temp" - BASE_STATE_ATMOS_VNAME_PRECIP="precipitation" - #??? BASE_STATE_ATMOS_VNAME_SMB="" - - # - # Report - # - echo -e "\t\t* - Reference ${REFERENCE_ATMOS_FNAME:?Missing variable}" - echo -e "\t\t* - Base state ${BASE_STATE_ATMOS_FNAME:?Missing variable}" - - for _file in $REFERENCE_ATMOS_FNAME $BASE_STATE_ATMOS_FNAME ; do - if [ ! -f $_file ] ; then - echo "ERROR: Atmosphere anomaly coupling; MISSING file $_file" - echo " S T O P" - exit 2 - else - echo -e "\t\t* + $(basename $_file): $($cdo -s showvar $_file)" - fi - done -} - -## @fn ic_atm2pism_anoforce_offset_temp_air_regridded() -## @brief -## Air temperature as an anomaly on top of a reference -## -## Air temperature from the anomaly of the forcing on the -## reference. All the calculations are performed on the regridded ice -## sheet model domain. -ic_atm2pism_anoforce_offset_temp_air_regridded() { - echo""; echo -e "\t\t* anomaly air temperature evolution (offset)" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.NoAnomaly.nc - - _ic_atm2pism_anoforce_addition_regridded \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.NoAnomaly.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc \ - ${FORCING_ATMOS_VNAME_TEMP_AIR:?Miss var 1} \ - ${BASE_STATE_ATMOS_FNAME:?Miss var 2} \ - ${BASE_STATE_ATMOS_VNAME_TEMP_AIR:?Miss var 3} \ - ${REFERENCE_ATMOS_FNAME:?Miss var 4} \ - ${REFERENCE_ATMOS_VNAME_TEMP_AIR:?Miss var 5} - - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc ] ; then - echo "ERROR: Missing output file ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature.nc" - fi -} - -## @fn ic_atm2pism_anoforce_offset_temp_firn_regridded() -## @brief -## Firn temperature as an anomaly on top of a reference -## -## Firn temperature from the anomaly of the forcing on the -## reference. All the calculations are performed on the regridded ice -## sheet model domain. Here, the firn temperature does not exceeds the -## melting temperature. -ic_atm2pism_anoforce_offset_temp_firn_regridded() { - echo""; echo -e "\t\t* anomaly firn temperature evolution (offset)" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.NoAnomaly.nc - - _ic_atm2pism_anoforce_addition_regridded \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.NoAnomaly.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ - ${FORCING_ATMOS_VNAME_TEMP_FIRN:?Miss var 1} \ - ${BASE_STATE_ATMOS_FNAME:?Miss var 2} \ - ${BASE_STATE_ATMOS_VNAME_TEMP_FIRN:?Miss var 3} \ - ${REFERENCE_ATMOS_FNAME:?Miss var 4} \ - ${REFERENCE_ATMOS_VNAME_TEMP_FIRN:?Miss var 5} - - # - # Firn temperature has be at or below the freezing temperature - # - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.tmp.nc - - $cdo -minc,273.15 \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.tmp.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc \ - && rm -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.tmp.nc - - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc ] ; then - echo "ERROR: Missing output file ${COUPLE_DIR}/${PISM_HEMISPHERE}/temperature_below_firn.nc" - fi -} - -## @fn ic_atm2pism_anoforce_offset_precipitation_regridded() -## @brief -## Precipitation as a OFFSET anomaly on top of a reference -## -## Precipitation from the anomaly of the forcing on top of the -## reference, which adds an offset on the reference value. All the -## calculations are performed on the regridded ice sheet model domain. -ic_atm2pism_anoforce_offset_precipitation_regridded() { - echo""; echo -e "\t\t* anomaly precipitation evolution (offset)" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.NoAnomaly.nc - - _ic_atm2pism_anoforce_addition_regridded \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.NoAnomaly.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - ${FORCING_ATMOS_VNAME_PRECIP:?Miss var 1} \ - ${BASE_STATE_ATMOS_FNAME:?Miss var 2} \ - ${BASE_STATE_ATMOS_VNAME_PRECIP:?Miss var 3} \ - ${REFERENCE_ATMOS_VNAME_PRECIP:?Miss var 4} \ - ${REFERENCE_ATMOS_FNAME:?Miss var 5} \ - ${REFERENCE_ATMOS_VNAME_PRECIP:?Miss var 6} - - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc ] ; then - echo "ERROR: Missing output file ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc" - fi -} - -## @fn ic_atm2pism_anoforce_scale_precipitation_regridded() -## @brief -## Precipitation as a scaled anomaly on top of a reference -## -## Precipitation from the anomaly of the forcing on the reference, -## which scales the reference value. All the calculations are -## performed on the regridded ice sheet model domain. -ic_atm2pism_anoforce_scale_precipitation_regridded() { - echo""; echo -e "\t\t* anomaly precipitation evolution (scale)" - mv ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.NoAnomaly.nc - - _ic_atm2pism_anoforce_multiplication_regridded \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.NoAnomaly.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/precipitation.nc \ - ${FORCING_ATMOS_VNAME_PRECIP:?Miss var 1} \ - ${BASE_STATE_ATMOS_FNAME:?Miss var 2} \ - ${BASE_STATE_ATMOS_VNAME_PRECIP:?Miss var 3} \ - ${REFERENCE_ATMOS_FNAME:?Miss var 4} \ - ${REFERENCE_ATMOS_VNAME_PRECIP:?Miss var 5} -} - -## @fn _ic_atm2pism_anoforce_addition_regridded() -## @brief -## Computes the forcing as and additive anomaly on top of a reference -## -## This internal function computes the forcing based on an additive -## anomaly of a forcing field on top of a reference reference field. -_ic_atm2pism_anoforce_addition_regridded() { - _input_force_file=${1:?Missing first input} - _output_force_file=${2:?Missing second input} - _force_var=${3:?Missing third input} - _base_state_force_file=${4:?Missing forth input} - _base_state_force_var=${5:?Missing fifth input} - _reference_file=${6:?Missing sixth input} - _reference_var=${7:?Missing seventh input} - - # - # Check existences of input files - # - for _file in $_input_force_file $_base_state_force_file $_reference_file ; do - if [ ! -f $_file ] ; then - echo "_ic_atm2pism_anoforce_addition_regridded, INPUT: $*" - echo "ERROR: Missing input file $_file" - fi - done - # In case $_input and $_output are identical - if [ "x${_input_force_file}" == "x${_output_force_file}" ] ; then - mv $_input_force_file ${_input_force_file}.NoAnomaly.tmp.nc - _input_force_file=${_input_force_file}.NoAnomaly.tmp.nc - fi - - # - # Do the math: Var = Var_ref + (Var_forcing-Var_forcing_base) - # - $cdo -O -setvar,$_force_var \ - -add -selvar,$_reference_var $_reference_file \ - -sub -selvar,$_force_var $_input_force_file \ - -selvar,$_base_state_force_var $_base_state_force_file \ - $_output_force_file -} - -## @fn _ic_atm2pism_anoforce_multiplication_regridded() -## @brief -## Computes the forcing as an multiplication anomaly on top of a reference -## -## This internal function computes the forcing based on a -## multiplicative anomaly of a forcing field on top of a reference -## reference field. -_ic_atm2pism_anoforce_multiplication_regridded() { - _input_force_file=${1:?Missing first input} - _output_force_file=${2:?Missing second input} - _force_var=${3:?Missing third input} - _base_state_force_file=${4:?Missing forth input} - _base_state_force_var=${5:?Missing fifth input} - _reference_file=${6:?Missing sixth input} - _reference_var=${7:?Missing seventh input} - _multi_value_max=${8:-10} - #??_multi_value_min=${9:-0} - - # - # Check existences of input files - # - - for _file in $_input_force_file $_base_state_force_file $_reference_file ; do - if [ ! -f $_file ] ; then - echo "_ic_atm2pism_anoforce_multiplication_regridded, INPUT: $*" - echo "ERROR: Missing input file $_file" - fi - done - # In case $_input and $_output are identical - if [ "x${_input_force_file}" == "x${_output_force_file}" ] ; then - mv $_input_force_file ${_input_force_file}.NoAnomaly.tmp.nc - _input_force_file=${_input_force_file}.NoAnomaly.tmp.nc - fi - - # - # Do the math: Var = Var_ref * min(multi_value_max, (Var_forcing/Var_forcing_base)) - # - $cdo -O -setvar,$_force_var \ - -mul -selvar,$_reference_var $_reference_file \ - -fillmiss2 -minc,$_multi_value_max \ - -div -selvar,$_force_var $_input_force_file \ - -selvar,$_base_state_force_var $_base_state_force_file \ - $_output_force_file -} diff --git a/couplings/coupling_dual-hemisphere/pism/coupling_awiesm2pism.functions b/couplings/coupling_dual-hemisphere/pism/coupling_awiesm2pism.functions deleted file mode 100644 index f5abb0ca4..000000000 --- a/couplings/coupling_dual-hemisphere/pism/coupling_awiesm2pism.functions +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/ksh -awiesm2pism() { - . ${FUNCTION_PATH}/../pism/coupling_atmosphere2pism.functions - . ${FUNCTION_PATH}/../pism/coupling_ocean2pism.functions - . ${FUNCTION_PATH}/../pism/pism_helpers.functions - . ${FUNCTION_PATH}/../general/general_lists.functions - - if [ -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_atmo_forcing_file.nc ]; then - rm ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_atmo_forcing_file.nc - fi - - if [ -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_ocean_forcing_file.nc ]; then - rm ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_ocean_forcing_file.nc - fi - atmosphere2pism - ocean2pism -} diff --git a/couplings/coupling_dual-hemisphere/pism/coupling_ocean2pism.functions b/couplings/coupling_dual-hemisphere/pism/coupling_ocean2pism.functions deleted file mode 100644 index 68c71e46c..000000000 --- a/couplings/coupling_dual-hemisphere/pism/coupling_ocean2pism.functions +++ /dev/null @@ -1,1119 +0,0 @@ -#!/usr/bin/ksh - -function ocean2pism { - echo " *** S T A R T I N G ocean2pism *** (PISM version ${VERSION_pism})" - - if [ "$MACHINE" == "levante" ]; then - module load cdo - fi - echo $(module list) - . ${FUNCTION_PATH}/../general/coupling_general.functions - . ${FUNCTION_PATH}/../general/general_lists.functions - - #CHUNK_DATE_TAG_pism="${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}" - CHUNK_DATE_TAG_pism="${CURRENT_YEAR_pism}-${END_YEAR_pism}" - - INTERPOL_TYPE_OCE=${INTERPOL_TYPE_OCE:-"dis"} #Standard=dis : "bil" "con" "dis" "nn", "bil" doesn't work for FESOM - WEIGHTS_OCE2ICE=${WEIGHTS_OCE2ICE:-weights_oce2ice.${INTERPOL_TYPE_OCE}.nc} - GRIDDES_ICE=${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes - GRIDDES_OCE=${GRIDDES_OCE:-ocean.griddes} - PISM_OCEAN_FORCING_FILE=${COUPLE_DIR}/${PISM_HEMISPHERE}/"ocean_forcing4pism_ver${VERSION_pism}.${INTERPOL_TYPE_OCE}.${CHUNK_DATE_TAG_pism}.nc" - - OCEAN_3EQN_ICE_FORCE_PY_SCRIPT=${FUNCTION_PATH:-${FPATH}}/ocean_3eqn_ismforce.py - - PISM_OCEAN_SWITCH="" - PISM_OCEAN_FILE_SWITCH="" - - iter_coup_regrid_method_oce2ice=${iter_coup_regrid_method_oce2ice:-EXTRAPOLATE} - iter_coup_interact_method_oce2ice=${iter_coup_interact_method_oce2ice:-OCEANTEMPSALT} #CCR - - read_names ocean ice - save_griddes ice - - NOCOLOR='\033[0m' - GREEN='\033[32m' - - echo "Interaction (ocean) : ${iter_coup_interact_method_oce2ice} (1/2)" - echo -e " --> Interaction >>> ${GREEN}${iter_coup_interact_method_oce2ice}${NOCOLOR} <<< ocean (Step 1/2: names)" - case $iter_coup_interact_method_oce2ice in - "DIRECT") - # - # Take DIRECTly the forcing coming from the ocean model - # - PISM_OCEAN_SWITCH="-ocean given" - PISM_OCEAN_FILE_SWITCH="-ocean_given_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_direct_forcing - ;; - "MIXED"|"TS_RESCALED2FLUX") - # - # Take directly the forcing coming from the ocean model - # and rescale it with `ocean_3eqn_iceforce.py` computed - # fluxes -- NOT YET IMPLEMENTED - # - PISM_OCEAN_SWITCH="-ocean given" - PISM_OCEAN_FILE_SWITCH="-ocean_given_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_mixed_forcing - ;; - "OCEANTEMP") - # - # Provide the ice sheet model (here PISM) the temperature - # 3dim field (constant in time) and the PISM computes the - # basal ice shelf conditions - # - PISM_OCEAN_SWITCH="-ocean o3d" - PISM_OCEAN_FILE_SWITCH="-ocean_o3d_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_temp_forcing - ;; - "OCEANTEMPSALT") - # - # Provide the ice sheet model (here PISM) the temperature - # and salinity 3dim fields (constant in time) and the PISM - # computes the basal ice shelf conditions - # - PISM_OCEAN_SWITCH="-ocean th" - PISM_OCEAN_FILE_SWITCH="-ocean_th_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_tempsalt_forcing - ;; - "PICO_OCEAN") - # - # Provide the ice sheet model temperature and salinity - # fields and PISM computes via the "PICO" submodel the - # ice shelf conditions - # - #PISM_OCEAN_SWITCH="-ocean pico -ocean.pico.continental_shelf_depth 700" - - PISM_OCEAN_SWITCH="-ocean pico" - PISM_OCEAN_FILE_SWITCH="-ocean_pico_file ${PISM_OCEAN_FORCING_FILE}" - PISM_OCEAN_PICO_BASINS_FILE=${PISM_OCEAN_PICO_BASINS_FILE:-${PISM_OCEAN_FORCING_FILE}} - echo " * Doing iterative_coupling_ocean_pism_prepare_ocean_tempsalt_forcing ..." - iterative_coupling_ocean_pism_prepare_ocean_tempsalt_forcing - echo " ...done." - - #echo " * Doing iterative_coupling_ocean_pism_prepare_pico_ocean_forcing ..." - #iterative_coupling_ocean_pism_prepare_pico_ocean_forcing ${PISM_OCEAN_PICO_BASINS_FILE} ${PISM_OCEAN_FORCING_FILE} - #echo " ...done." - ;; - "TEMP2FLUX") - # - # Use the python script `ocean_3eqn_iceforce.py` and - # compute the basal temporal evolving conditions based - # only on the 3dim oceanic temperature distribution - # - PISM_OCEAN_SWITCH="-ocean given" - PISM_OCEAN_FILE_SWITCH="-ocean_given_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_temp2flux_forcing - ;; - "TEMPSALT2FLUX") - # - # Use the python script `ocean_3eqn_iceforce.py` and - # compute the basal temporal evolving conditions based on - # 3dim oceanic temperature and salinity distributions - # - PISM_OCEAN_SWITCH="-ocean given" - PISM_OCEAN_FILE_SWITCH="-ocean_given_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_tempsalt2flux_forcing - ;; - *) - echo " UNKNOWN mass balance selected!" - echo " Known: DIRECT, MIXED, OCEANTEMP, PICO_OCEAN, TEMP2FLUX, TEMPSALT2FLUX" - echo " S T O P 1" - exit 1 - esac - - echo "Grid method (ocean) : ${iter_coup_regrid_method_oce2ice}" - echo -e " --> Grid method >>> ${GREEN}${iter_coup_regrid_method_oce2ice}${NOCOLOR} <<< ocean" - case $iter_coup_regrid_method_oce2ice in - "INTERPOLATE"|"REMAP") - iterative_coupling_ocean_pism_regrid_interpolate - ;; - "EXTRAPOLATE") - iterative_coupling_ocean_pism_regrid_interpolate - iterative_coupling_ocean_pism_regrid_extrapolate - ;; - "NONE") - # Ocean and ice sheet grid are identical !! - INTERPOL_TYPE_OCE=none - SM_OCEAN_FORCING_FILE3 iterative_coupling_ocean_pism_regrid_none - ;; - *) - echo " UNKNOWN regrid method selected!" - echo " Known: INTERPOLATE = REMAP, EXTRAPOLATE, NONE" - echo " S T O P 2" - exit 2 - esac - - echo "Interaction (ocean) : ${iter_coup_interact_method_oce2ice} (2/2)" - echo -e " --> Interaction >>> ${GREEN}${iter_coup_interact_method_oce2ice}${NOCOLOR} <<< ocean (Step 2/2: final file)" - case $iter_coup_interact_method_oce2ice in - "DIRECT") - iterative_coupling_ocean_pism_compute_ocean_direct_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "MIXED"|"TS_RESCALED2FLUX") - iterative_coupling_ocean_pism_compute_ocean_mixed_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "OCEANTEMP") - iterative_coupling_ocean_pism_compute_ocean_temp_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "OCEANTEMPSALT") - iterative_coupling_ocean_pism_compute_ocean_tempsalt_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "PICO_OCEAN") - iterative_coupling_ocean_pism_compute_ocean_tempsalt_forcing ${PISM_OCEAN_FORCING_FILE} - PISM_OCEAN_PICO_BASINS_FILE=${PISM_OCEAN_PICO_BASINS_FILE:-${PISM_OCEAN_FORCING_FILE}} - - echo " * Doing iterative_coupling_ocean_pism_prepare_pico_ocean_forcing ..." - iterative_coupling_ocean_pism_prepare_pico_ocean_forcing ${PISM_OCEAN_PICO_BASINS_FILE} ${PISM_OCEAN_FORCING_FILE} - echo " ...done." - ;; - "TEMP2FLUX") - iterative_coupling_ocean_pism_compute_ocean_temp2flux_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "TEMPSALT2FLUX") - iterative_coupling_ocean_pism_compute_ocean_tempsalt2flux_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - *) - echo " UNKNOWN mass balance selected!" - echo " Known: DIRECT, MIXED, OCEANTEMP, TEMP2FLUX, TEMPSALT2FLUX" - echo " S T O P 3" - exit 3 - esac - - - # - # Here ANOMALY in ocean-temperature and salinity - # - if [[ "x${ANOMALY_OCEAN_TEMPERATURE:-0}" == "x1" || \ - "x${ANOMALY_OCEAN_SALINITY:-0}" == "x1" ]] ; then - # Initialize require variables and file names - ic_oce2pism_anoforce_initialize - - if [ "x${ANOMALY_OCEAN_TEMPERATURE:-0}" == "x1" ] ; then - ic_oce2pism_anoforce_offset_temp_oce_regridded - fi - - if [ "x${ANOMALY_OCEAN_SALINITY:-0}" == "x1" ] ; then - ic_oce2pism_anoforce_offset_salt_oce_regridded - fi - fi - - #iterative_coupling_ocean_pism_set_options - iterative_coupling_ocean_pism_regrid_set_time_axis ${PISM_OCEAN_FORCING_FILE} - iterative_coupling_pism_regrid_add_xy_array ${PISM_OCEAN_FORCING_FILE} "ocean" - - ln -sf "${COUPLE_DIR}/${PISM_HEMISPHERE}/ocean_forcing4pism_ver${VERSION_pism}.${INTERPOL_TYPE_OCE}.${CHUNK_DATE_TAG_pism}.nc" "${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_ocean_forcing_file.nc" - - for file in ${cleanup_list} ; do test -f $file && rm $file ; done - - unset cleanup_list file - - unset NOCOLOR GREEN - unset PISM_OCEAN_SWITCH PISM_OCEAN_FILE_SWITCH PISM_OCEAN_FORCING_FILE - - max_retry=12 - retry=0 - sleep 10 # Minimum time for st_new.sh to finish - - while [ ${retry} -lt ${max_retry} ]; do - if [ -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_ocean_forcing_file.nc ]; then - break # call results.sh outside loop - else - (( retry = retry + 1 )) - sleep 10 - fi - done - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_ocean_forcing_file.nc ]; then - echo "Something wrong after waiting for 120 seconds!" - fi - echo " ...done." -} - -function save_griddes { - model_type=$1 - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/${model_type}.griddes ]; then - echo "Saving ${model_type}.griddes" - if [ -f ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes ]; then - cp ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/${model_type}.griddes - else - echo " Was Looking for: ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes" - echo "Could not find griddes file, exiting..." - echo " S T O P 4 (coupling_ocean2pism.functions::save_griddes)" - exit 4 - fi - else - echo "${model_type}.griddes is in place" - fi -} - - -# -# Compute actual forcing files : Convert variable names to pism names -# -function iterative_coupling_ocean_pism_prepare_ocean_direct_forcing { - echo "Preparing direct ocean forcing (${PISM_OCEAN_SWITCH:-Unknown}) file with sensible units..." - # PISM0.7 : shelfbtemp [degC], shelfbmassflux [kg m-2 s-1] -## $cdo -select,name=wnet,Tsurf - - # Rename all input variables - cdo_table_file=cdo_partable.txt - iterative_coupling_ocean_pism_fesom2pism_names $cdo_table_file - - # Extend the list: Delete not needed one - cat >> $cdo_table_file <> $cdo_table_file <> $cdo_table_file <> $cdo_table_file <flux forcing (${PISM_OCEAN_SWITCH:-Unknown}) file with sensible units..." - # PISM0.7 : shelfbtemp [degC], shelfbmassflux [kg m-2 s-1] - # Rename all input variables - cdo_table_file=cdo_partable.txt - iterative_coupling_ocean_pism_fesom2pism_names $cdo_table_file - - # Extend the list: Delete not needed one - cat >> $cdo_table_file <flux forcing (${PISM_OCEAN_SWITCH:-Unknown}) file with sensible units..." - # PISM0.7 : shelfbtemp [degC], shelfbmassflux [kg m-2 s-1] - - # Rename all input variables - cdo_table_file=cdo_partable.txt - iterative_coupling_ocean_pism_fesom2pism_names $cdo_table_file - - # Extend the list: Delete not needed one - cat >> $cdo_table_file < ${_file:-cdo_partable.txt} < remap,$GRIDDES_ICE,$WEIGHTS_OCE2ICE" - $cdo remap,$GRIDDES_ICE,$WEIGHTS_OCE2ICE \ - ocean_file_for_ice.pism_names.nc \ - ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc - - cleanup_list="${cleanup_list}" # $(pwd)/ocean_file_for_ice.nc $(pwd)/ocean_file_for_ice.pism_names.nc" -} - -function iterative_coupling_ocean_pism_regrid_extrapolate { - # - # This has to be called after the interpolation, because after the - # interpolation we have landpoints that does not exist in the - # FESOM ocean grid - regrid_ocean_pism_extrapolate_misstoc=${regrid_ocean_pism_extrapolate_misstoc:-0} - iterative_coupling_ocean_pism_regrid_extra_type=${iterative_coupling_ocean_pism_regrid_extra_type:-fillmiss2} - echo " * Extrapolate GCM forcing with method >>${iterative_coupling_ocean_pism_regrid_extra_type}<< ..." - - _cdo_flag=$( return_allowed_cdo_miss_replace_flags ${iterative_coupling_ocean_pism_regrid_extra_type} ${regrid_ocean_pism_extrapolate_misstoc} ) - - _tmp_file=ocean_file_at_ice.${INTERPOL_TYPE_OCE}_before_extrapolation.nc - mv ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${_tmp_file} - - $cdo $_cdo_flag ${_tmp_file} \ - ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc - - echo " ... done" - cleanup_list="${cleanup_list} $(pwd)/${_tmp_file}" - unset _cdo_flag _tmp_file -} - -function iterative_coupling_ocean_pism_regrid_none { - echo " * Grid-identical GCM forcing (no interpolation)..." - - test_file_or_exit ${COUPLE_DIR}/ocean_file_for_ice.nc 7 - - mv ${COUPLE_DIR}/ocean_file_for_ice.nc \ - ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc - - cleanup_list="${cleanup_list}" # $(pwd)/ocean_file_for_ice.nc" -} - -# -# Compute actual boundary conditions for ice sheet/shelf if wanted -# -function iterative_coupling_ocean_pism_compute_ocean_direct_forcing { - _file=$1 - _action_string=": rename file" - echo " * Building direct ocean forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - mv -f ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/$(basename ${_file}) - echo " ...done." -} - -function iterative_coupling_ocean_pism_compute_ocean_mixed_forcing { - _file=$1 - _action_string=": Rescale basal melt and temperature with temperature and salt to basal melt and temperature" - echo " * Building mixed ocean forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - - echo -e "CCR: \033[41m NOT YET IMPLEMENTED (A) \033[0m" - echo " S T O P "; exit 1999 - cp ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/$(basename ${_file}) - - - echo " ...done." -} - - -function iterative_coupling_ocean_pism_compute_ocean_temp_forcing { - _file=$1 - _action_string=": rename file" - echo " * Building ocean temperature-based forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - mv -f ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/$(basename ${_file}) - # Nothing to do, since ocean forcing is already in the right format - echo " ...done." -} - - -function iterative_coupling_ocean_pism_compute_ocean_tempsalt_forcing { - _file=$1 - if [ 0 -eq 1 ] ; then - _action_string=": vertical mean (150-600m) of temperature and salinity" ; - cdovert_flag="-sellevel,150/600" - else - _action_string=": vertical mean (index 1-20) of temperature and salinity" - cdovert_flag="-sellevidx,1/20" - fi - echo " * Building ocean temperature-based forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - - iterative_coupling_ocean_pism_fesom2pism_collapse_depth ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/$(basename ${_file}) "${cdovert_flag}" - - echo " ...done." -} - - -function iterative_coupling_ocean_pism_compute_ocean_temp2flux_forcing { - _file=$1 - _action_string=": temperature to basal melt and temperature" - echo " * Building ocean temperature->flux forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - - echo -e "CCR: \033[41m NOT YET IMPLEMENTED (B) \033[0m" - echo -e "CCR: \033[41m YOU may switch to NOT YET IMPLEMENTED 'TEMPSALT2FLUX' \033[0m" - echo " S T O P "; exit 2999 - - cp ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/$(basename ${_file}) - - echo " ...done." -} - -function iterative_coupling_ocean_pism_compute_ocean_tempsalt2flux_forcing { - _file=$1 - _action_string=": temperature+salt to basal melt and temperature ($(basename $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT))" - echo " * Building ocean temperature+salt->flux forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - - - test_file_or_exit ${INPUT_FILE_pism} 14 - - case ${VERSION_pism:--0.1} in - "0.7") - _upper_ice_temperature_varname="ice_surface_temp" - ;; - "1.0"|"1.1") - _upper_ice_temperature_varname="ice_surface_temp" - ;; - *) - echo "NOT DEFINED PISM version >${VERSION_pism}<" - echo "Please adjust function >iterative_coupling_ocean_pism_compute_ocean_tempsalt2flux_forcing< in 'coupling_ocean2pism.functions'" - echo " S T O P 15" - exit 15 - ;; - esac - - echo " ---------- starting $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT -------------" - _out_fname=${COUPLE_DIR}/${PISM_HEMISPHERE}/$(basename $_file ) - _py_logging_file="hydrography2ism_ocean_forcing.log" - echo "==> python $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT --OCEAN_INPUT_FILE ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc --ISM_INPUT_FILE ${INPUT_FILE_pism} --OCEAN_TEMP_VARIABLE $_oce_temp3D_varn --OCEAN_SALT_VARIABLE $_oce_salt3D_varn --ISM_ICE_TEMP_VARIABLE $_upper_ice_temperature_varname --ISM_GRID_HEIGHT 0 --ISM_GRID_LENGTH 0 --OUT_CALC_FRONTAL_MELT False --OUT_CALC_LESS_BASAL_LOW_CAVITY False --LOGGING_OUTPUT_FILE ${_py_logging_file} --OUTPUT_FILE ${_out_fname} --LOGGING_OUTPUT_LEVEL INFO" - - echo "Python version:" - python --version - - python $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT \ - --OCEAN_INPUT_FILE ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc \ - --ISM_INPUT_FILE ${INPUT_FILE_pism} \ - --OCEAN_TEMP_VARIABLE $_oce_temp3D_varn \ - --OCEAN_SALT_VARIABLE $_oce_salt3D_varn \ - --ISM_ICE_TEMP_VARIABLE $_upper_ice_temperature_varname \ - --ISM_GRID_HEIGHT 0 \ - --ISM_GRID_LENGTH 0 \ - --OUT_CALC_FRONTAL_MELT False \ - --OUT_CALC_LESS_BASAL_LOW_CAVITY False \ - --LOGGING_OUTPUT_FILE ${_py_logging_file} \ - --OUTPUT_FILE ${_output_filename} -# Standard -# --OUT_CALC_BASAL_MELT True \ -# --OUT_CALC_BASAL_TEMP True \ -# --OUT_CALC_FRONTAL_MELT False \ -# --OUT_CALC_LESS_BASAL_LOW_CAVITY False \ -# -# Plus frontal melting -# --OUT_CALC_FRONTAL_MELT True -# --OUT_CALC_MERGE_BASAL_FRONTAL_MELT True \ - - echo " ---------- returned from $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT --------" - for MessageTag in WARNING ERROR CRITICAL ; do - _nummer=$(grep ${MessageTag} ${_py_logging_file} | wc -l) - if [ ${_nummer} -gt 0 ] ; then - echo "** Found $_nummer ${MessageTag}(s)" - grep ${MessageTag} ${_py_logging_file} - fi - done - - test_file_or_exit ${_out_fname} 15 - - unset _upper_ice_temperature_varname _file _py_logging_file _nummer _out_fname - echo " ...done." -} - -## -## Auxillary functions -## -#function iterative_coupling_ocean_pism_set_options { -# echo ""; echo " * set PISM setting for ocean forcing" -# pism_conf_file_list="${COUPLE_DIR}/pism_coupler_${CHUNK_DATE_TAG_pism}.dat ${COUPLE_DIR}/pism_forcing_${CHUNK_DATE_TAG_pism}.dat ${COUPLE_DIR}/pism_config_value_${CHUNK_DATE_TAG_pism}.dat" -# for pism_conf_file in $pism_conf_file_list; do -# if [ ! -f $pism_conf_file ]; then -# :> $pism_conf_file -# fi -# done -# -# echo "$(pism_coupler_to_esm_runsscripts_syntax ${PISM_OCEAN_SWITCH[@]})" \ -# >> ${COUPLE_DIR}/pism_coupler_${CHUNK_DATE_TAG_pism}.dat -# echo "$(pism_forcing_to_esm_runsscripts_syntax ${PISM_OCEAN_FILE_SWITCH[@]})" \ -# >> ${COUPLE_DIR}/pism_forcing_${CHUNK_DATE_TAG_pism}.dat -#} - -function iterative_coupling_ocean_pism_regrid_set_time_axis { - _file_name_add_timeaxis=$1 - echo ""; echo " * setting time axis >>${_file_name_add_timeaxis}<<" - _script2build_time_axis=${FUNCTION_PATH}/../utils/CreateTimeAxisNC.bash - - test_file_or_exit ${_file_name_add_timeaxis} 8 - # Number of timesteps in file - _nt=$( ${cdo} -s ntime ${_file_name_add_timeaxis} ) - - if [ $_nt -lt 1 ]; then - echo " - No time step (continue without adjusting the time axis)" - else - __file_taxis=time_axis.steps$(printf '%05i' ${_nt}).nc - - test -f ${__file_taxis} && rm ${__file_taxis} - if [ ! -f ${__file_taxis} ] ; then - if [ ! -f ${_script2build_time_axis} ] ; then - echo " - Missing ${_script2build_time_axis}" - echo " S T O P 9 (coupling_ocean2pism.functions::iterative_coupling_ocean_pism_regrid_set_time_axis)" - exit 9 - else - echo " - Use $_script2build_time_axis to determine continious time axis" - #${_script2build_time_axis} ${_nt} ${__file_taxis} - #${_script2build_time_axis} ${_nt} ${__file_taxis} 0 classic 360 double - #${_script2build_time_axis} ${_nt} ${__file_taxis} 0 classic 365 double - ${_script2build_time_axis} ${_nt} ${__file_taxis} 0 classic 365 float - - fi - else - # Should not be here if we delete $__file_taxis before. - echo " - Reuse time axis file ${__file_taxis}" - fi - - ncks -A ${__file_taxis} ${_file_name_add_timeaxis} - fi - - unset _file_name_add_timeaxis __file_taxis -} - -function iterative_coupling_ocean_pism_fesom2pism_collapse_time { - # NOTE: Could be called at any time (also before regridding and - # reshuffling data with pyfesom script), because the time axis is - # well defined regardless of representation of ocean data as a - # array or 3dim field. - _file_time=$1 - echo ""; echo " * collapse time axis/dimension of >>${_file_time}<<" - - - test_file_or_exit ${_file_time:?Missing file name to collapse time dimension} 12 - - if [ 1 -eq 1 ] ; then - _tmp_file=${_file_time}_before_timmean.nc - mv -f ${_file_time} ${_tmp_file} - $cdo timmean ${_tmp_file} ${_file_time} - else - # Does not work. Why? I do not know - _tmp_file=${_file_time}_before_ncwa.nc - mv -f ${_file_time} ${_tmp_file} - ncwa -a time ${_tmp_file} ${_file_time} - fi - - cleanup_list="${cleanup_list} $(pwd)/${_tmp_file}" - - unset _file_time _tmp_file -} - - -function iterative_coupling_ocean_pism_fesom2pism_collapse_depth { - # NOTE: Could be called ONLY AFTER reshuffling data with pyfesom - # script, because the depth axis is not established before. - # - # Example: - # iterative_coupling_ocean_pism_fesom2pism_collapse_depth ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/$(basename ${_file}) "-sellevel,150/600" - # - _file_input=$1 - echo ""; echo " * collapse depth axis/dimension of >>${_file_input}<<" - test_file_or_exit ${_file_input:?Missing file name to collapse depth dimension} 13 - - if [ $# -ge 2 ] ; then - _file_output=$2 - else - # Swap input / output, because input and output file name are identical - _file_output=${_file_input} - _file_input=${_file_input}_before_vertmean.nc - mv -f ${_file_output} ${_file_input} - fi - if [ $# -ge 3 ] ; then - _cdovert_sel_flag=$3 - else - #_cdovert_sel_flag="-sellevel,150/600" - _cdovert_sel_flag="-sellevidx,1/20" - fi - - #--> This depth is not recognized since depth(level) - # level is the vertical dimension - ## - ## Ensure depth axis is present by adding the - ## corresponding file array/axis - ## - #_file_depth=${FileName_depth4levels_FESOM:-fesom_depth_axis.nc} - #if [ -f ${_file_depth} ] ; then - # echo " - adding depth array from >>${_file_depth}<<" - # ncks -A ${_file_depth} ${_file_input} - #fi - - echo " - collapse type ${_cdovert_sel_flag} -> $(basename ${_file_output})" - $cdo -vertmean ${_cdovert_sel_flag} ${_file_input} ${_file_output} - echo " ^ Note: Warnings about missing levels are commonly OK" - - cleanup_list="${cleanup_list} $(pwd)/${_file_input}" - - unset _cdovert_sel_flag _file_depth _file_input -} - -################################################################################ -################################################################################ -# D E T A I L S :: Hydrographic (Oceanographic) anomaly forcing -################################################################################ -################################################################################ -## @fn ic_oce2pism_anoforce_initialize() -## @brief -## Initilize anomaly forcing -## -## To use anomaly forcing, we have to initilize some additional -## variables, which occurs here. -ic_oce2pism_anoforce_initialize(){ - echo""; echo -e "\t\t* initilize anomaly forcing (variables and file names)" - # - # Hydrographic/Ocean REFERENCE data and its variables. These could - # be the "truth". - # - REFERENCE_OCEAN_FNAME=${REFERENCE_OCEAN_FNAME:-"/work/ab0246/a270096/share/pism/ANT.16km/OCEForcing.piControl.16km.nc"} - REFERENCE_OCEAN_VNAME_TEMP_OCEAN="theta_ocean" - REFERENCE_OCEAN_VNAME_SALT_OCEAN="salinity_ocean" - REFERENCE_OCEAN_VNAME_BASIN="basins" - REFERENCE_OCEAN_VNAME_RETREAT="land_ice_area_fraction_retreat" - - # - # Forcing data from driving ocean climate/earth system model - # - FORCING_OCEAN_VNAME_TEMP_OCEAN="temp" - FORCING_OCEAN_VNAME_SALT_OCEAN="salt" - FORCING_OCEAN_VNAME_TEMP_OCEAN=${REFERENCE_OCEAN_VNAME_TEMP_OCEAN} - FORCING_OCEAN_VNAME_SALT_OCEAN=${REFERENCE_OCEAN_VNAME_SALT_OCEAN} - - # - # Hydrographic/Ocean BASE STATE and it variables. For a climate - # warming simulations, this BASE STATE could prepresent the - # control climate piControl, for instance. - # - BASE_STATE_OCEAN_FNAME=${BASE_STATE_OCEAN_FNAME:-"/work/ab0246/a270096/share/pism/ANT.16km/ocean_forcing4pism_base_state.pism_sh.nc"} - BASE_STATE_OCEAN_VNAME_TEMP_OCEAN="theta_ocean" - BASE_STATE_OCEAN_VNAME_SALT_OCEAN="salinity_ocean" - - # - # Thresholds - # - OCEAN_TEMP_LOWER_THRESHOLD=${OCEAN_TEMP_LOWER_THRESHOLD:--260.} - OCEAN_SALT_LOWER_THRESHOLD=${OCEAN_SALT_LOWER_THRESHOLD:-0.0} - - # - # Report - # - echo -e "\t\t* - Reference ${REFERENCE_OCEAN_FNAME:?Missing variable}" - echo -e "\t\t* - Base state ${BASE_STATE_OCEAN_FNAME:?Missing variable}" - - for _file in $REFERENCE_OCEAN_FNAME $BASE_STATE_OCEAN_FNAME ; do - if [ ! -f $_file ] ; then - echo "ERROR: Ocean anomaly coupling; MISSING file $_file" - echo " S T O P" - exit 2 - else - echo -e "\t\t* + $(basename $_file): $(cdo -s showvar $_file)" - fi - done -} - -## @fn ic_oce2pism_anoforce_offset_temp_oce_regridded() -## @brief -## Ocean temperature as an anomaly on top of a reference -## -## Ocean temperature from the anomaly of the forcing on the -## reference. All the calculations are performed on the regridded ice -## sheet model domain. -ic_oce2pism_anoforce_offset_temp_oce_regridded(){ - echo""; echo -e "\t\t* anomaly ocean temperature evolution (offset)" - - mv ${PISM_OCEAN_FORCING_FILE} \ - ${PISM_OCEAN_FORCING_FILE}.NoTempAno.nc - - _ic_oce2pism_anoforce_addition_regridded \ - ${PISM_OCEAN_FORCING_FILE}.NoTempAno.nc \ - ${PISM_OCEAN_FORCING_FILE} \ - ${FORCING_OCEAN_VNAME_TEMP_OCEAN:?Miss Var 1} \ - ${BASE_STATE_OCEAN_FNAME:?Miss Var 2} \ - ${BASE_STATE_OCEAN_VNAME_TEMP_OCEAN:?Miss Var 3} \ - ${REFERENCE_OCEAN_FNAME:?Miss Var 4} \ - ${REFERENCE_OCEAN_VNAME_TEMP_OCEAN:?Miss Var 5} \ - ${OCEAN_TEMP_LOWER_THRESHOLD:?Miss Var 6} - - if [ ! -f ${PISM_OCEAN_FORCING_FILE} ] ; then - echo "ERROR: Missing output file ${PISM_OCEAN_FORCING_FILE}" - fi -} - -## @fn ic_oce2pism_anoforce_offset_salt_oce_regridded() -## @brief -## Ocean salinity as an anomaly on top of a reference -## -## Ocean salinity from the anomaly of the forcing on the reference. -## All the calculations are performed on the regridded ice sheet model -## domain. -ic_oce2pism_anoforce_offset_salt_oce_regridded() { - echo""; echo -e "\t\t* anomaly ocean salinity evolution (offset)" - - mv ${PISM_OCEAN_FORCING_FILE} \ - ${PISM_OCEAN_FORCING_FILE}.NoSaltAno.nc - - _ic_oce2pism_anoforce_addition_regridded \ - ${PISM_OCEAN_FORCING_FILE}.NoSaltAno.nc \ - ${PISM_OCEAN_FORCING_FILE} \ - ${FORCING_OCEAN_VNAME_SALT_OCEAN:?Miss Var 1} \ - ${BASE_STATE_OCEAN_FNAME:?Miss Var 2} \ - ${BASE_STATE_OCEAN_VNAME_SALT_OCEAN:?Miss Var 3} \ - ${REFERENCE_OCEAN_FNAME:?Miss Var 4} \ - ${REFERENCE_OCEAN_VNAME_SALT_OCEAN?Miss Var 5} \ - ${OCEAN_SALT_LOWER_THRESHOLD:?Miss Var 6} - - if [ ! -f ${PISM_OCEAN_FORCING_FILE} ] ; then - echo "ERROR: Missing output file ${PISM_OCEAN_FORCING_FILE}" - fi -} - -## @fn _ic_oce2pism_anoforce_addition_regridded() -## @brief -## Computes the forcing as and additive anomaly on top of a reference -## -## This internal function computes the forcing based on an additive -## anomaly of a forcing field on top of a reference reference field. -_ic_oce2pism_anoforce_addition_regridded() { - _input_force_file=${1:?Missing first input} - _output_force_file=${2:?Missing second input} - _force_var=${3:?Missing third input} - _base_state_force_file=${4:?Missing forth input} - _base_state_force_var=${5:?Missing fifth input} - _reference_file=${6:?Missing sixth input} - _reference_var=${7:?Missing seventh input} - _multi_value_min=${8:-0} - - # - # Check existences of input files - # - for _file in $_input_force_file $_base_state_force_file $_reference_file ; do - if [ ! -f $_file ] ; then - echo "_ic_oce2pism_anoforce_addition_regridded, INPUT: $*" - echo "ERROR: Missing input file $_file" - fi - done - # In case $_input and $_output are identical - if [ "x${_input_force_file}" == "x${_output_force_file}" ] ; then - mv $_input_force_file ${_input_force_file}.NoAnomaly.tmp.nc - _input_force_file=${_input_force_file}.NoAnomaly.tmp.nc - fi - - # - # Do the math: Var = max(multi_value_min, Var_ref + (Var_forcing-Var_forcing_base)) - # - cdo -O -setvar,$_force_var -maxc,$_multi_value_min \ - -add -selvar,$_reference_var $_reference_file \ - -sub -selvar,$_force_var $_input_force_file \ - -selvar,$_base_state_force_var $_base_state_force_file \ - $_output_force_file - - # - # Add all remaining unchanged variables from the input forcing file - # to the output forcing file. It is needed because the ocean file - # may contain several fields, such as ocean temperature and salinity. - # - ncks -A -xv $_force_var $_input_force_file $_output_force_file -} - - -# -- last line diff --git a/couplings/coupling_dual-hemisphere/pism/coupling_pism2atmosphere.functions b/couplings/coupling_dual-hemisphere/pism/coupling_pism2atmosphere.functions deleted file mode 100644 index 55e4822ad..000000000 --- a/couplings/coupling_dual-hemisphere/pism/coupling_pism2atmosphere.functions +++ /dev/null @@ -1,509 +0,0 @@ -#!/usr/bin/ksh - -function pism2atmosphere { - echo " ==================================================================" - echo " *** S T A R T I N G pism2atmosphere *** "; echo - - :> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - - echo "PISM_TO_ATMOSPHERE=${PISM_TO_ATMOSPHERE}" - - if [[ $PISM_TO_ATMOSPHERE -eq 1 ]]; then - iterative_coupling_pism_atmosphere_write_grid - iterative_coupling_pism_atmosphere_write_names - iterative_coupling_pism_atmosphere_make_forcing - else - echo " NOT generating ice forcing for atmosphere" - fi - echo - echo " *** F I N I S H E D pism2atmosphere *** " - echo " ==================================================================" -} -function iterative_coupling_pism_atmosphere_make_forcing { - pism_atmosphere_get_newest_output - pism_atmosphere_update_domain_mask - pism_atmosphere_generate_orography_anomaly - pism_atmosphere_generate_ice_thickness_anomaly - pism_atmosphere_generate_runoff - pism_atmosphere_assemble_final_file -} - -function iterative_coupling_pism_atmosphere_write_names { - : > ${COUPLE_DIR}/ice_names_for_atmosphere.dat - GLACIAL_MASK_VARNAME_pism=mask - OROG_VARNAME_pism=usurf - OROG_ANOM_VARNAME_pism=delta_usurf - TOTAL_MASS_LOSS_VARNAME_pism=total_ice_mass_loss_flux - echo "ice_glacial_mask_name=$GLACIAL_MASK_VARNAME_pism" >> ${COUPLE_DIR}/ice_names_for_atmosphere.dat - echo "ice_orography_name=${OROG_VARNAME_pism}" >> ${COUPLE_DIR}/ice_names_for_atmosphere.dat - echo "ice_orography_difference_name=${OROG_ANOM_VARNAME_pism}" >> ${COUPLE_DIR}/ice_names_for_atmosphere.dat - echo "ice_mass_loss_varname=${TOTAL_MASS_LOSS_VARNAME_pism}" >> ${COUPLE_DIR}/ice_names_for_atmosphere.dat -} - -function iterative_coupling_pism_atmosphere_write_grid { - if [ ! -f ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes ]; then - #add_to ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - # ice.griddes couple - cp ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes - fi -} - -function pism_atmosphere_get_newest_output { - echo; echo " * defining the newest PISM file " - # PG: Modification to ensure that we only use SUMMER values (July for Northern Hemisphere): - # LA: Not sure why. Now taking yearly mean. - # LA: Summer value for mask only. Now: Summer value for mask, yearmean for runoff - - # Define list of variables selected from PISM output depending on whether icebergs are used or not - if [ "x${fesom_use_iceberg}" == "x1" ]; then - echo " * use iceberg coupling and exclude iceberg discharge from mass balance" - CDO_SELECT_VAR_LIST="thk,climatic_mass_balance,topg,${OROG_VARNAME_pism},${GLACIAL_MASK_VARNAME_pism},tendency_of_ice_amount,tendency_of_ice_amount_due_to_discharge" - else - echo " * no iceberg coupling" - CDO_SELECT_VAR_LIST="thk,climatic_mass_balance,topg,${OROG_VARNAME_pism},${GLACIAL_MASK_VARNAME_pism},tendency_of_ice_amount" - fi - - LATEST_PISM_FILE_SINGLE=${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${YR0_pism}${M0_pism}${D0_pism}-${END_YEAR_pism}${END_MONTH_pism}${END_DAY_pism}.nc - echo; echo " * OUTPUT_DIR_pism = ${OUTPUT_DIR_pism} " - if [ -f ${LATEST_PISM_FILE_SINGLE} ]; then - echo; echo " * file1 = ${LATEST_PISM_FILE_SINGLE} found ***" - - # Remove old files - if [ -f ${OUTPUT_DIR_pism}/tmp.nc ]; then rm ${OUTPUT_DIR_pism}/tmp.nc; fi - if [ -f ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc ]; then rm ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc; fi - if [ -f ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc ]; then rm ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc; fi - unset PISM_OFILE_LIST - unset PISM_cleanup_list - - # Aggregate PISM output to multi-year monthly mean - echo " *** These fields are selected ${CDO_SELECT_VAR_LIST} *** " - for i in $(seq ${CHUNK_START_YEAR_pism} ${NYEAR} ${CHUNK_END_YEAR_pism}); do - j=$(( $i + ${NYEAR} -1 )) - if [ ${i} -lt 10 ]; then i=0${i}; fi - IFILE="${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${i}0101-${j}1231.nc" - if [[ "x${USE_YMONMEAN}" == "x1" ]]; then - OFILE="${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${i}0101-${j}1231.tendency.timmean.nc" - #PISM_cleanup_list="${PISM_cleanup_list} ${IFILE}" - - if [[ ! -f "${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${i}0101-${j}1231.tendency.timmean.nc" ]]; then - OFILE="${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${i}0101-${j}1231.tendency.timmean.nc" - cdo -ymonmean \ - -select,name="${CDO_SELECT_VAR_LIST}" \ - ${IFILE} \ - ${OFILE} 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - fi - echo; echo " * i = ${i} "; PISM_OFILE_LIST="${PISM_OFILE_LIST} ${OFILE}"; - else - if [[ -f ${IFILE} ]]; then - PISM_OFILE_LIST="${PISM_OFILE_LIST} ${IFILE}" - fi - fi - done - - echo; echo " * Concatenating these files: ${PISM_OFILE_LIST} " - cdo cat ${PISM_OFILE_LIST} ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2awiesm - cdo timmean ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2awiesm - - #rm ${PISM_OFILE_LIST} - else - echo "*** ${LATEST_PISM_FILE_SINGLE} not found ***" - exit 42 - fi - - newest_pism_file=${OUTPUT_DIR_pism}/latest_ex_file_pism.nc - newest_pism_filename=$(basename $newest_pism_file) - newest_pism_file_chunk=${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc - - if [[ ${EX_INT} == "monthly" ]]; then - case $DOMAIN_pism in - "nhem" | "laurentide" | "greenland" | "gris_nhem") - month_to_select=6 - ;; - "shem" | "antarctica" | "Antarctica" | "antarct_cr") - month_to_select=12 - ;; - *) - echo "UNKNOWN PISM domain" - exit 42 - esac - echo " - selecting summer values only! Month=$month_to_select " - echo " - ifile = ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc; ofile = ${COUPLE_DIR}/${PISM_HEMISPHERE}/${EXP_ID}_pism_extra_summer_${YR0_pism}-${END_YEAR_pism}.nc " - - - # Select mask either by minimum ice thickness over year (MIN_MON_SELECT==1) or by summer value (Jun for NH, Dec for SH) - if [[ "x${MIN_MON_SELECT}" == "x1" ]]; then - cdo -s \ - -timmin \ - -selname,thk \ - ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc \ - ${COUPLE_DIR}//${PISM_HEMISPHERE}/${EXP_ID}_pism_extra_summer_${YR0_pism}-${END_YEAR_pism}.nc 2>> ${COUPLE_DIR}//${PISM_HEMISPHERE}/cdo_stderr_pism2awiesm - else - cdo -s \ - -selmon,${month_to_select} \ - -ymonmean \ - ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc \ - ${COUPLE_DIR}//${PISM_HEMISPHERE}/${EXP_ID}_pism_extra_summer_${YR0_pism}-${END_YEAR_pism}.nc 2>> ${COUPLE_DIR}//${PISM_HEMISPHERE}/cdo_stderr_pism2awiesm - fi - # LA: get SMB as another criterion for glacial mask; glacial cell if positive SMB - cdo -s \ - -timmean \ - -selname,climatic_mass_balance \ - ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/${EXP_ID}_pism_extra_smb_${YR0_pism}-${END_YEAR_pism}.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2awiesm - newest_pism_mask_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/${EXP_ID}_pism_extra_summer_${YR0_pism}-${END_YEAR_pism}.nc - else - newest_pism_mask_file=${newest_pism_file} - fi - newest_pism_mask_filename=$(basename $newest_pism_mask_file) - -} - -function pism_atmosphere_update_domain_mask { - echo; echo " Updating script-coupler domain mask..." - echo " (This is the area where changes to ECHAM6 files are allowed to be made)" - - update_domain_mask_select_mask - if [[ "x${MIN_MON_SELECT}" != "x1" ]]; then - update_domain_mask_constrain_minimum_ice_thickness - fi - update_domain_mask_merge_masks - update_domain_mask_set_mask_values_to_binary - echo; echo " ...done." -} - -function pism_atmosphere_generate_orography_anomaly { - echo; echo " Generating orography anomaly..." - generate_orography_anomaly_over_pism_run - correct_lonlat_order ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference.nc - echo; echo " ...done." -} - -function pism_atmosphere_generate_ice_thickness_anomaly { - echo; echo " Generating ice_thickness anomaly..." - generate_ice_thickness_anomaly_over_pism_run - correct_lonlat_order ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_thk_above_flotation_difference.nc - correct_lonlat_order ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_thk_difference.nc - convert_ice_thk_diff_to_flux_over_pism_run - echo; echo " ...done." -} - -function pism_atmosphere_generate_runoff { - echo; echo " Getting variables relevant for ice mass loss..." - generate_runoff_select_variables - generate_runoff_transform_units - generate_runoff_combine_fields - echo; echo " ...done." -} - -function pism_atmosphere_assemble_final_file { - echo; echo " Assembling final ice_file_for_atmosphere.nc and cleaning up..." - files_needed="${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_mask_current.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_flux_total.nc ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_kg_m-2_s-1.nc" - cdo -s -O merge $files_needed ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_for_atmosphere.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - ncwa -a time ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_for_atmosphere.nc tmp; mv tmp ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_for_atmosphere.nc -# rm $files_needed $rmlist - echo; echo " ...done" - unset files_needed -} - -function update_domain_mask_select_mask { - echo ""; echo " * selecting the mask variable" - ifile1=${newest_pism_mask_file} - ifile2=${COUPLE_DIR}/${PISM_HEMISPHERE}/${EXP_ID}_pism_extra_smb_${YR0_pism}-${END_YEAR_pism}.nc - if [[ "x${MIN_MON_SELECT}" == "x1" ]]; then - CRITICAL_THK_FOR_MASK_pism=${CRITICAL_THK_FOR_MASK_pism:-5} - echo ""; echo " * constraining the mask to have at least ${CRITICAL_THK_FOR_MASK_pism} (meters)" - ofile1=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_min_thk.nc - ofile2=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_pos_smb.nc - cdo -s chname,thk,${GLACIAL_MASK_VARNAME_pism} -setmisstoc,0 -ifthenc,1 -gec,${CRITICAL_THK_FOR_MASK_pism} $ifile1 $ofile1 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - cdo -s chname,climatic_mass_balance,${GLACIAL_MASK_VARNAME_pism} -setmisstoc,0 -ifthenc,1 -gtc,0 $ifile2 $ofile2 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - else - ofile1=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}.nc - ofile2=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_pos_smb.nc - cdo -s -selvar,${GLACIAL_MASK_VARNAME_pism} $ifile1 $ofile1 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - cdo -s chname,climatic_mass_balance,${GLACIAL_MASK_VARNAME_pism} -setmisstoc,0 -ifthenc,1 -gtc,0 $ifile2 $ofile2 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - fi - unset ifile1 ifile2 ofile1 ofile2 -} - -function update_domain_mask_constrain_minimum_ice_thickness { - CRITICAL_THK_FOR_MASK_pism=${CRITICAL_THK_FOR_MASK_pism:-5} - echo ""; echo " * constraining the mask to have at least ${CRITICAL_THK_FOR_MASK_pism} (meters)" - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}.nc - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_min_thk.nc - cdo -s -setmisstoc,0 \ - -ifthen \ - -gec,${CRITICAL_THK_FOR_MASK_pism} \ - -selvar,thk \ - ${newest_pism_mask_file} \ - ${ifile} \ - ${ofile} 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - rm $ifile - unset ifile ofile -} - -function update_domain_mask_merge_masks { - echo ""; echo " * merging masks from thicknes and surface mass balance criterions" - ifile1=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_min_thk.nc - ifile2=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_pos_smb.nc - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_merged_mask.nc - #LA: merge both masks: glacial cell if thickness above threshold OR surface mass balance > 0 - cdo -s max $ifile1 $ifile2 $ofile 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - #rm $ifile1 $ifile2 - unset ifile1 ifile2 ofile -} - -function update_domain_mask_set_mask_values_to_binary { - echo ""; echo " * setting binary values for mask: 1=ice, 0=non-ice" - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_merged_mask.nc - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_mask_min_thk_binary.nc - cdo -s \ - -setvals,2,1 \ - -setvals,3,1 \ - -setvals,4,0 \ - $ifile $ofile 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - mv $ofile ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_mask_current.nc - #rm $ifile - unset ifile ofile -} - -function generate_ice_thickness_anomaly_over_pism_run { - echo ""; echo " * calculating ice thickness change over the last pism chunk" - ifile1=${last_year_in_chunk_restart} - ifile2=${first_year_in_chunk_input} - ofile1=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_thk_above_flotation_difference.nc - ofile2=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_thk_difference.nc - cdo -s -expr,"thk_topg=thk+topg" \ - $ifile1 \ - tmp1 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - - cdo -s -expr,"thk_topg=thk+topg" \ - $ifile2 \ - tmp2 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - - cdo -s -chname,"thk_topg","thk_diff" \ - -sub \ - -ifthen -gtc,0 tmp1 tmp1 \ - -ifthen -gtc,0 tmp2 tmp2 \ - $ofile1 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - - rm tmp1 tmp2 - - cdo -s -chname,"thk","thk_diff" \ - -sub \ - -selvar,"thk" \ - $ifile1 \ - -selvar,"thk" \ - $ifile2 \ - $ofile2 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - - #ncks -O -x -v time,GEOSP $ofile tmp.nc 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - #mv tmp.nc $ofile -} - -function convert_ice_thk_diff_to_flux_over_pism_run { - echo ""; echo " * converting thickness difference to freshwater flux over the last pism chunk" - ifile1=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_thk_above_flotation_difference.nc - ifile2=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_thk_difference.nc - ofile1=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_from_thk_above_flotation_difference.nc - ofile2=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_from_thk_difference.nc - - cdo -s -divc,${CHUNK_SIZE_pism_standalone} \ - -chname,"thk_diff","runoff" \ - -mulc,910 \ - $ifile1 \ - $ofile1 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - - cdo -s -divc,${CHUNK_SIZE_pism_standalone} \ - -chname,"thk_diff","runoff" \ - -mulc,910 \ - $ifile2 \ - $ofile2 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - #-mulc,${RES_pism//km} \ - #-mulc,${RES_pism//km} \ -} - -function generate_orography_anomaly_over_pism_run { - echo ""; echo " * calculating surface height change over the last pism chunk" - ifile1=${last_year_in_chunk_restart} - ifile2=${first_year_in_chunk_input} - - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_orog_difference.nc - cdo -s -sub \ - -chname,${OROG_VARNAME_pism},${OROG_ANOM_VARNAME_pism} \ - -expr,"${OROG_VARNAME_pism}=thk+topg" \ - $ifile1 \ - -expr,"${OROG_VARNAME_pism}=thk+topg" \ - $ifile2 \ - $ofile 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - - ncks -O -x -v GEOSP $ofile tmp.nc 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm - mv tmp.nc $ofile -} - -function generate_runoff_select_variables { - echo ""; echo " * selecting vars" - # LA account_all_fw_input needs to be defined - if [[ "x${account_all_fw_input}" == "x1" ]]; then - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_from_thk_difference.nc - else - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_from_thk_above_flotation_difference.nc - fi - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff.nc - - case ${VERSION_pism:--0.1} in - "0.7") - PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"discharge_flux_cumulative,floating_basal_flux_cumulative,grounded_basal_flux_cumulative"} - ;; - "1.0"|"1.1"|"1.2") - # basal_mass_flux_floating = basal kg/m2/s of floating ice - # basal_mass_flux_grounded = basal kg/m2/s of grounded ice - # srunoff = surface runoff (kg/m2/s) - # tendency_of_ice_amount_due_to_discharge = calving + frontal melting (kg/m2/s) - #PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"basal_melt_rate_grounded,tendency_of_ice_amount_due_to_discharge"} - # Only use "tendency_of_ice_amount"; Unit: kg m-2 year-1; for both v1.0 and v1.1 - - #*************************************************************************** - #LA include iceberg model - if [[ "x${fesom_use_iceberg}" == "x1" ]]; then - PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"tendency_of_ice_amount_due_to_discharge,runoff"} #,tendency_of_ice_amount_due_to_calving"} - #PISM_MASS_LOSS_ARRAY=("tendency_of_ice_amount_due_to_surface_mass_flux" "tendency_of_ice_amount_due_to_basal_mass_flux" "tendency_of_ice_amount_due_to_conservation_error" "tendency_of_ice_amount_due_to_flow") - PISM_MASS_LOSS_ARRAY=("tendency_of_ice_amount_due_to_discharge" "runoff") # "tendency_of_ice_amount_due_to_calving") - #*************************************************************************** - else - PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"runoff"} - fi - ;; - *) - echo "Unknown PISM version=${VERSION_pism} specified, exiting..." - exit 42 - ;; - esac - - cdo -s -selvar,${PISM_MASS_LOSS_VARS} \ - $ifile \ - $ofile 2>> ${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2atm -} - -function generate_runoff_transform_units { - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff.nc - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_kg_m-2_s-1.nc - years_to_seconds_divc_factor=3.15569e+07 # $(udunits2 -W s -H year | tail -1 | tr -s ' ' | awk -F'=' '{print $2}' | awk -F'*' '{print $1}' | tr -d '[:space:]') - Gt_to_kg_mulc_factor=1e+12 # $(udunits2 -W kg -H Gt | tail -1 | tr -s ' ' | awk -F'=' '{print $2}' | awk -F'*' '{print $1}'| tr -d '[:space:]') - case ${VERSION_pism:--0.1} in - "0.7") - echo ""; echo " * transforming glaciological units to SI standards" - # We need to go from cummulative to delta T - # FIXME: What if a user wants to run more than one run in a pism chunk? - # Then, we need to find the TOTAL delta T over all the files in this chunk. - echo "cdo -mulc,${Gt_to_kg_mult_factor} -mulc,${years_to_seconds_mult_factor} -divc,$CHUNK_SIZE_pism_standalone -sub -seltimestep,-1 $ifile -seltimestep,1 $ifile $ofile" - cdo -s \ - -mulc,${Gt_to_kg_mulc_factor} \ - -divc,${years_to_seconds_divc_factor} \ - -divc,$CHUNK_SIZE_pism_standalone \ - -sub \ - -seltimestep,-1 $ifile \ - -seltimestep,1 $ifile \ - $ofile - - ncatted -a units,floating_basal_flux_cumulative,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - ncatted -a units,grounded_basal_flux_cumulative,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - ncatted -a units,discharge_flux_cumulative,o,c,"kg second-1" $ofile tmp; mv tmp $ofile - cdo -s aexpr,"discharge_flux_cumulative_per_area=discharge_flux_cumulative/${CELL_AREA_pism}" $ofile tmp; mv tmp $ofile - ncatted -a units,discharge_flux_cumulative,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - cdo -s delvar,discharge_flux_cumulative $ofile tmp; mv tmp $ofile - PISM_MASS_LOSS_VARS="discharge_flux_cumulative_per_area,floating_basal_flux_cumulative,grounded_basal_flux_cumulative" - ;; - "1.0" | "1.1" | "1.2") - #echo "unit transform not needed in pism 1.0, skipping step silently" - #cp $ifile $ofile - echo ""; echo " * Transforming mass flux per year to mass flux per second for PISM 1.1 ${years_to_seconds_divc_factor}" - echo "cdo -divc,${years_to_seconds_divc_factor} $ifile $ofile" - cdo -s -divc,${years_to_seconds_divc_factor} $ifile $ofile - #*************************************************************************** - #LA include iceberg model - if [[ "x${fesom_use_iceberg}" == "x1" ]]; then - cdo -s -divc,${years_to_seconds_divc_factor} -selname,tendency_of_ice_amount_due_to_discharge ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc tmp - ncatted -a units,tendency_of_ice_amount_due_to_discharge,o,c,"kg second-1 m-2" tmp tmp2; rm tmp # ; mv tmp $ofile - ncatted -a units,runoff,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - cdo -s merge tmp2 $ofile tmp; mv tmp ${ofile}; rm tmp2 - #*************************************************************************** - else - ncatted -a units,runoff,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - fi - ;; - *) - echo "Unknown PISM version=${VERSION_pism} specified, exiting..." - exit 42 - ;; - esac - #rmlist="$rmlist $ifile" -} - -function generate_runoff_combine_fields { - echo ""; echo " * combining ${PISM_MASS_LOSS_VARS} to a single field" - echo " - NOTE: Currently we assume all mass loss goes directly to the hydrology scheme" - echo " - NOTE: There is no seperation between calving, grounded basal melt, and" - echo " - NOTE: floating basal melt." - ifile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_kg_m-2_s-1.nc - ofile=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_flux_total.nc - - case ${VERSION_pism:--0.1} in - "0.7") - cdo -s -splitname $ifile ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_flux_ - set -A PISM_MASS_LOSS_ARRAY $(echo $PISM_MASS_LOSS_VARS | sed s/,/\ /g ) - first_varname=${PISM_MASS_LOSS_ARRAY[0]}; unset PISM_MASS_LOSS_ARRAY[0] - #rmlist="$rmlist ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_flux_${first_varname}.nc" - cdo_command_head="cdo -s " - cdo_command_tail=" ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_flux_${first_varname}.nc $ofile" - for element in ${PISM_MASS_LOSS_ARRAY[@]}; do - cdo_command_middle="$cdo_command_middle -add ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_flux_${element}.nc" - rmlist="$rmlist ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_runoff_flux_${element}.nc" - done - cdo_command="$cdo_command_head $cdo_command_middle $cdo_command_tail" - $cdo_command - ;; - "1.0"|"1.1"|"1.2") - #*************************************************************************** - #LA include iceberg model - if [[ "x${fesom_use_iceberg}" == "x1" ]]; then - echo " * substracting discharge from runoff ${ifile}" - cdo -s -chname,tendency_of_ice_amount_due_to_discharge,runoff -sub -selname,tendency_of_ice_amount_due_to_discharge ${ifile} -selname,runoff ${ifile} ${ofile} 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - #*************************************************************************** - else - # Only need tendency of ice amount, do not need to combine fields. - cp $ifile $ofile - fi - ;; - *) - echo "Unknown PISM version=${VERSION_pism} specified, exiting..." - exit 42 - ;; - esac - - - case ${VERSION_pism:--0.1} in - "0.7") - ncrename -v floating_basal_flux_cumulative,total_ice_mass_loss_flux $ofile - ;; - "1.0"|"1.1"|"1.2") - #*************************************************************************** - #LA include iceberg model - if [[ "x${fesom_use_iceberg}" == "x1" ]]; then - ncrename -v runoff,total_ice_mass_loss_flux $ofile - else - ncrename -v runoff,total_ice_mass_loss_flux $ofile - fi - ;; - esac -} - -function correct_lonlat_order { - FILENAME=$1 - echo ""; echo " * correcting $FILENAME lonlat order" - ncpdq -a lat,lon $FILENAME tmp; mv tmp $FILENAME -} diff --git a/couplings/coupling_dual-hemisphere/pism/coupling_pism2awiesm.functions b/couplings/coupling_dual-hemisphere/pism/coupling_pism2awiesm.functions deleted file mode 100644 index 7d93d9b86..000000000 --- a/couplings/coupling_dual-hemisphere/pism/coupling_pism2awiesm.functions +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/ksh -pism2awiesm() { - echo $(module list) - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/general_helpers.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - if [ -f ${COUPLE_DIR}/latest_gfw_atmo.nc ]; then - rm ${COUPLE_DIR}/latest_gfw_atmo.nc - fi - - if [ -f ${COUPLE_DIR}/latest_jsbach_init_file.nc ]; then - rm ${COUPLE_DIR}/latest_jsbach_init_file.nc - fi - - if [ -f ${COUPLE_DIR}/latest_jsbach_restart_file.nc ]; then - rm ${COUPLE_DIR}/latest_jsbach_restart_file.nc - fi - - if [ -f ${COUPLE_DIR}/latest_veg_restart_file.nc ]; then - rm ${COUPLE_DIR}/latest_veg_restart_file.nc - fi - - if [ -f ${COUPLE_DIR}/latest_target_orography.nc ]; then - rm ${COUPLE_DIR}/latest_target_orography.nc - fi - - . ${FUNCTION_PATH}/../pism/coupling_pism2atmosphere.functions - . ${FUNCTION_PATH}/../pism/coupling_pism2ocean.functions - - echo "*** Starting pism2atmosphere ***" - pism2atmosphere 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - - echo "*** Starting pism2ocean ***" - pism2ocean 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm -} diff --git a/couplings/coupling_dual-hemisphere/pism/coupling_pism2ocean.functions b/couplings/coupling_dual-hemisphere/pism/coupling_pism2ocean.functions deleted file mode 100644 index 1c333bf21..000000000 --- a/couplings/coupling_dual-hemisphere/pism/coupling_pism2ocean.functions +++ /dev/null @@ -1,749 +0,0 @@ -#!/bin/ksh - - -function pism2ocean { - echo " *** S T A R T I N G pism2ocean *** (PISM version ${VERSION_pism})" - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - echo "PISM_TO_OCEAN=${PISM_TO_OCEAN:-0}" - if [[ $PISM_TO_OCEAN -le 0 ]]; then - echo " NOT generating ice forcing for ocean model" - echo " since PISM_TO_OCEAN=${PISM_TO_OCEAN}" - return - fi - - # - # ==> if [[ $PISM_TO_OCEAN -ge 1 ]]; then - # - # - # PISM OUTPUT 1a) Temporal stream for ice shelf basal melting (ymonmean/timmeam) - # pism2ocean 1b) Temporal stream for ice berg calving/discharging (ymonmean/timmean) - # 1c) Stream of vertical temperature gradient at base (last year-ymonmean/last record) - # 1d) Stream of mask (ice-free ocean, ice shelf, land) (last record) - # 2) Convert them into sensible units (calving: Gt < area, densities) - # 3) Combine the basal melting, calving, temperature gradient files - # ice2fesom (other file) - # 4) Remap/Regrid to FESOM grid - # 5) FESOM Names - # - CHUNK_DATE_TAG_pism="${CURRENT_YEAR_pism}-${END_YEAR_pism}" - #CHUNK_DATE_TAG_pism="${CURRENT_YEAR_pism}0101-${END_YEAR_pism}1231" - #CHUNK_DATE_TAG_awicm="${CHUNK_START_DATE_awicm}-${CHUNK_END_DATE_awicm}" - -#TODO Get the right file names for the forcing/extra and restart/output file names - PISM_FORCING_EXTRA_FILE=${OUTPUT_DIR_pism}/${EXP_ID}_pismr_extra_${CHUNK_DATE_TAG_pism}.nc - PISM_RESTART_OUTPUT_FILE=${OUTPUT_DIR_pism}/${EXP_ID}_pismr_restart_${CHUNK_DATE_TAG_pism}.nc - COMBINED_OUTPUT=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.combined.nc - - # TODO Are these sensible choices? - iter_coup_interact_method_ice2oce=${iter_coup_interact_method_ice2oce:-BASALSHELF_WATER} - - iterative_coupling_pism_ocean_write_names - read_names ice ocean - - cdo_table_file=cdo_partable.txt - iterative_coupling_pism_ocean_fesom2pism_names $cdo_table_file - - NOCOLOR='\033[0m' - GREEN='\033[32m' - - echo "Interaction (ocean) : ${iter_coup_interact_method_ice2oce}" - echo -e " --> Interaction >>> ${GREEN}${iter_coup_interact_method_ice2oce}${NOCOLOR} <<< ocean" - case $iter_coup_interact_method_ice2oce in - "BASALSHELF_WATER_ICEBERG_WATER") - iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_iceberg_water_forcing - ;; - "BASALSHELF_WATER") - iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - ;; - "ICEBERG_WATER") - iterative_coupling_pism_ocean_prepare_ocean_iceberg_water_forcing - ;; - "ICEBERG_HEAT") - iterative_coupling_pism_ocean_prepare_ocean_iceberg_heat_forcing - ;; - "BASALSHELF_WATER_ICEBERG_WATERHEAT") - iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_iceberg_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_iceberg_heat_forcing - ;; - "BASALSHELF_WATER_ICEBERG_PDF") - iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_iceberg_pdf_forcing - ;; - "BASALSHELF_WATER_ICEBERG_MODEL") - #iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_icebergmodel_forcing - ;; - *) - echo " UNKNOWN mass balance selected!" - echo " Known: BASALSHELF_WATER_ICEBERG_WATER, BASALSHELF_WATER, ICEBERG_WATER, ICEBERG_HEAT," - echo " BASALSHELF_WATER_ICEBERG_WATERHEAT, BASALSHELF_WATER_ICEBERG_PDF, BASALSHELF_WATER_ICEBERG_MODEL" - echo " S T O P 1" - exit 1 - esac - - if [ ${iter_coup_interact_method_ice2oce_ice_temp_gradient:-0} -gt 0 ] ; then - iterative_coupling_pism_ocean_prepare_iceshelf_temperature_gradient_forcing - else - echo " * Skip preparation of temperature gradient in lowest iceshelf layer" - fi - if [ ${iter_coup_interact_method_ice2oce_update_mask:-0} -gt 0 ] ; then - iterative_coupling_pism_ocean_prepare_ocean_update_mask_forcing - else - echo " * Skip preparation of actual masks (ocean, ice shelves, land)" - fi - - iterative_coupling_pism_ocean_prepare_combine_forcings - - for file in ${cleanup_list} ; do test -f $file && rm $file ; done - unset cleanup_list file - unset NOCOLOR GREEN - - unset PISM_FORCING_EXTRA_FILE PISM_RESTART_OUTPUT_FILE cdo_table_file - - echo " ...done." -} - - - -function iterative_coupling_pism_ocean_write_names { - echo "Writing fesom1x input names and units for use with generic ocean_file_for_ice.nc" - :> ice_names_for_ocean.dat - - # - # PISM names - # - case ${VERSION_pism:--0.1} in - "0.0") - _pism_basalshelf_freshwater_flux_varn="B_FW_FLX" - _pism_basalshelf_freshwater_flux_unit="Gt/m2/s" - _pism_iceberg_freshwater_flux_varn="IB_FW_FLX" - _pism_iceberg_freshwater_flux_unit="Gt/m2/s" - #_pism_iceberg_heat_flux_varn="IB_H_FLX" - #_pism_iceberg_heat_flux_unit="W/s/m2" - ;; - "0.7") - #SNAPSHOT! _pism_basalshelf_freshwater_flux_varn="floating_basal_flux" - #SNAPSHOT! _pism_iceberg_freshwater_flux_varn="discharge_flux" - _pism_basalshelf_freshwater_flux_varn="floating_basal_flux_cumulative" - _pism_basalshelf_freshwater_flux_unit="Gt/m2/s" - _pism_iceberg_freshwater_flux_varn="discharge_flux_cumulative" - _pism_iceberg_freshwater_flux_unit="Gt" - ;; - "1.0"|"1.1"|"1.2") - _pism_basalshelf_freshwater_flux_varn="basal_mass_flux_floating" #"floating_basal_flux_cumulative" - _pism_basalshelf_freshwater_flux_unit="kg/m2/year" - _pism_iceberg_freshwater_flux_varn="tendency_of_ice_amount_due_to_discharge" #"discharge_flux_cumulative" - _pism_iceberg_freshwater_flux_unit="kg/m2/year" - ;; - *) - echo "NOT DEFINED PISM version >${VERSION_pism}<" - echo "Please adjust function >iterative_coupling_pism_ocean_write_names<" - echo " S T O P 2" - exit 2 - ;; - esac - - echo ""; echo " * basal iceshelf melt flux" - echo "pism_name_basal_shelf_melt_flux=${_pism_basalshelf_freshwater_flux_varn}" >> ice_names_for_ocean.dat - echo "pism_units_basal_shelf_melt_flux=${_pism_basalshelf_freshwater_flux_unit}" >> ice_names_for_ocean.dat - - echo ""; echo " * ice berg calving" - echo "pism_name_iceberg_calving_flux=${_pism_iceberg_freshwater_flux_varn}" >> ice_names_for_ocean.dat - echo "pism_units_iceberg_calving_flux=${_pism_iceberg_freshwater_flux_unit}" >> ice_names_for_ocean.dat - - # - # OCEAN (generic) names - # - echo ""; echo " * freshwater flux" - echo "ocean_name_freshwater_flux=wnet" >> ice_names_for_ocean.dat - echo "ocean_units_freshwater_flux=W/m2" >> ice_names_for_ocean.dat - - echo ""; echo " * heat flux" - echo "ocean_name_heat_flux=qnet" >> ice_names_for_ocean.dat - #echo "ocean_units_heat_flux=kg/m2/s" >> ice_names_for_ocean.dat - echo "ocean_units_heat_flux=m" >> ice_names_for_ocean.dat - - echo ""; echo " * basal ice shelf temperature gradient" - echo "ocean_name_temperature_gradient=dTdz" >> ice_names_for_ocean.dat - echo "ocean_unit_temperature_gradient=K/m" >> ice_names_for_ocean.dat - - echo ""; echo " * landmask" - echo "ocean_name_landmask=mask" >> ice_names_for_ocean.dat - echo "ocean_units_landmask=1" >> ice_names_for_ocean.dat - - echo ""; echo " * oceanmask" - echo "ocean_name_oceanmask=mask" >> ice_names_for_ocean.dat - echo "ocean_units_oceanmask=1" >> ice_names_for_ocean.dat - - echo ""; echo " * iceshelfmask" - echo "ocean_name_iceshelfmask=mask" >> ice_names_for_ocean.dat - echo "ocean_units_iceshelfmask=1" >> ice_names_for_ocean.dat - - add_to $(pwd)/ice_names_for_ocean.dat ice_names_for_ocean.dat couple - echo " ...done." - - unset _pism_basalshelf_freshwater_flux_varn _pism_basalshelf_freshwater_flux_unit - unset _pism_iceberg_freshwater_flux_varn _pism_iceberg_freshwater_flux_unit - unset _pism_iceberg_heat_flux_varn _pism_iceberg_heat_flux_unit -} - - -# -# Compute actual forcing files : Convert variable names to pism names -# - -function iterative_coupling_pism_ocean_prepare_ocean_iceberg_pdf_forcing { - echo " WE DOT NOT have yet an ICEBERG MODULE, where the fresh water is spread along" - echo " static Probability Density Function (pdf) maps" - echo " Please replace iter_coup_interact_method_ice2oce=${iter_coup_interact_method_ice2oce} with something else" - echo " S T O P 3" - exit 3 - - # - # Please add after this comment the commands that are specific for - # running the iceberg PDF module. - # -} - - -######################################################################## -######################################################################## -# Lars Ackermann 07.09.2020 -######################################################################## -function iterative_coupling_pism_ocean_prepare_ocean_icebergmodel_forcing { - # iceberg coupling LA - #latest_pism_output=${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${YR0_pism}${M0_pism}${D0_pism}-${END_YEAR_pism}${END_MONTH_pism}${END_DAY_pism}.nc - if [[ -f ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc ]]; then - pism_discharge_file=${OUTPUT_DIR_pism}/latest_ex_file_pism.nc - elif [[ -f ${SPINUP_FILE_pism} ]]; then - pism_discharge_file=${SPINUP_FILE_pism} - fi - - echo " * generating latest_discharge.nc" - echo "PISM_DISCHARGE_FILE: ${pism_discharge_file}" - - cdo mulc,${CHUNK_SIZE_pism_standalone} \ - -timmean -selname,tendency_of_ice_amount_due_to_discharge \ - -setgrid,${COUPLE_DIR}/${PISM_HEMISPHERE}/ice.griddes ${pism_discharge_file} ${COUPLE_DIR}/${PISM_HEMISPHERE}/latest_discharge.nc 2>>${COUPLE_DIR}/${PISM_HEMISPHERE}/cdo_stderr_pism2ocean - -# wc -l ../icb/iceberg.restart.ISM | awk '{ print $1 }' > ../icb/num_non_melted_icb_file -# use_icesheet_coupling=1 - -# get_ib_num_after_ice_sheet_coupling -} - -#function get_ib_num_after_ice_sheet_coupling { -# _a="$( wc -l icb/LON.dat | awk '{ print $1 }' )" -# _b="$( cat ../icb/num_non_melted_icb_file )" -# -# ib_num=$(( $_a + $_b )) -# general_replace_namelist_value namelist.config icebergs ib_num $ib_num -# general_replace_namelist_value namelist.config icebergs use_icesheet_coupling ".true." -#} -############################################################################ -############################################################################ - - - -function iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing { - echo " * Preparing basal melting iceshelf(PISM) forcing file with sensible units from >${PISM_FORCING_EXTRA_FILE}<" - # Rename all input variables - - test_file_or_exit $PISM_FORCING_EXTRA_FILE 5 - test_file_or_exit $cdo_table_file 6 - - _out_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.basalwater.nc -#TODO : -#Warning: Number of OMP threads is greater than number of Cores=1! -#srun: error: prod-0177: task 0: Exited with exit code 1 -#srun: Terminating job step 2518500.0 - $cdo ymonmean \ - -selvar,lon,lat,wnet_basal -setpartabn,${cdo_table_file},convert \ - $PISM_FORCING_EXTRA_FILE ${_out_file} - - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} water_loss - - cleanup_list="${cleanup_list} ${_out_file}" - unset _out_file - echo " ...done." -} - - -function iterative_coupling_pism_ocean_prepare_ocean_iceberg_water_forcing { - echo " * Preparing iceberg melting iceshelf(PISM) forcing file with sensible units from >${PISM_FORCING_EXTRA_FILE}<" - # Rename all input variables - - test_file_or_exit $PISM_FORCING_EXTRA_FILE 7 - test_file_or_exit $cdo_table_file 8 - - _out_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.icebergwater.nc - $cdo ymonmean \ - -selvar,lon,lat,wnet_iceberg -setpartabn,${cdo_table_file},convert \ - $PISM_FORCING_EXTRA_FILE ${_out_file} - - case ${VERSION_pism:--0.1} in - "0.7") - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} water_abs - ;; - "1.0"|"1.1"|"1.2") - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} water_loss - ;; - *) - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} water_loss - ;; - esac - - cleanup_list="${cleanup_list} ${_out_file}" - unset _out_file - echo " ...done." -} - - -function iterative_coupling_pism_ocean_prepare_ocean_iceberg_heat_forcing { - echo " * Preparing iceberg heat conversion iceshelf(PISM) forcing file with sensible units from >${PISM_FORCING_EXTRA_FILE}<" - # Rename all input variables - - test_file_or_exit $PISM_FORCING_EXTRA_FILE 9 - test_file_or_exit $cdo_table_file 10 - - # - # Since we shall have a unit "kg ...", we now convert the mass - # into the energy needed to change the phase of the related mass - # from solid to liquid - # TODO : Check if we use a consident set for "heat of fusion of water into ice" - heat_of_fusion_of_water=333550 #Joule kg-1 - - _out_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.icebergheat.nc - $cdo ymonmean \ - -setvar,qnet_iceberg \ - -setunit,"Joule" \ - -selvar,wnet_iceberg -setpartabn,${cdo_table_file},convert \ - $PISM_FORCING_EXTRA_FILE ${_out_file} - - case ${VERSION_pism:--0.1} in - "0.7") - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} heat_abs - ;; - "1.0"|"1.1"|"1.2") - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} heat_loss - ;; - *) - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} heat_loss - ;; - esac - - cleanup_list="${cleanup_list} ${_out_file}" - unset _out_file - echo " ...done." -} - - -function iterative_coupling_pism_ocean_prepare_iceshelf_temperature_gradient_forcing { - echo " * Preparing temperature gradient in lowest iceshelf(PISM) layer from latest restart file with sensible units from >${PISM_RESTART_OUTPUT_FILE}<" - case ${VERSION_pism:--0.1} in - "0.7") - __varname="shelfbtemp" - ;; - "1.0"|"1.1"|"1.2") - __varname="shelfbtemp" - ;; - *) - __varname="shelfbtemp" - ;; - esac - - test_file_or_exit $PISM_RESTART_OUTPUT_FILE 11 - - #ncks -d time,-1,-1 -d z,0,1 -v ${__varname} \ - ncks -d time,-1,-1 -v ${__varname} \ - ${PISM_RESTART_OUTPUT_FILE} ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.bottom_iceshelf_temp.nc - - cleanup_list="${cleanup_list} ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.bottom_iceshelf_temp.nc" - unset __varname - echo " ...done." -} - - -function iterative_coupling_pism_ocean_prepare_ocean_update_mask_forcing { - echo " * Preparing actual masks (ocean, ice shelf, land) from restart file with sensible units from >${PISM_RESTART_OUTPUT_FILE}<" - case ${VERSION_pism:--0.1} in - "0.7") - __varname="mask" - ;; - "1.0"|"1.1"|"1.2") - __varname="mask" - ;; - *) - __varname="mask" - ;; - esac - - test_file_or_exit $PISM_RESTART_OUTPUT_FILE 12 - - ncks -d time,-1,-1 -v ${__varname} \ - ${PISM_RESTART_OUTPUT_FILE} \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.pismmask.nc - - $cdo -setvar,${ocean_name_oceanmask} \ - eqc,4 ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.pismmask.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_ocean.nc - $cdo -setvar,${ocean_name_iceshelfmask} \ - -eqc,3 ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.pismmask.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_iceshelf.nc - $cdo -setvar,${ocean_name_landmask} \ - -lec,2 ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.pismmask.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_land.nc - - if [ 1 -eq 0 ] ; then - # - # Drop time axis - # - for _file in \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_land.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_ocean.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_iceshelf.nc - do - if [ -f ${_file} ] ; then - _file_tmp=${_file%.*}_before_collapse_time.nc - mv -f $_file $_file_tmp - ncwa -a time $_file_tmp ${_file} - cleanup_list="${cleanup_list} ${_file} ${_file_tmp}" - fi - done - fi - - cleanup_list="${cleanup_list} ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.pismmask.nc" - unset _file _file_tmp __varname -} - - -function iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux { - _infile=$1 - _type=$2 - echo " * Convert loss into flux of type >${_type}< (${_infile})..." - if [ ! -f ${_infile} ] ; then - echo " - Missing file ${_infile}" - echo " S T O P 30" - exit 30 - fi - - # - # Physical variables - # - # Determine density of ice - # - if [ -f ${PISM_RESTART_OUTPUT_FILE} ] ; then - density_ice=$(ncdump -h ${PISM_RESTART_OUTPUT_FILE}| grep "pism_config:ice_density =" | tr -d '[:space:],;' | cut -d= -f2) - elif [ -f ${PISM_FORCING_EXTRA_FILE} ] ; then - density_ice=$(ncdump -h ${PISM_FORCING_EXTRA_FILE} | grep "pism_config:ice_density =" | tr -d '[:space:],;' | cut -d= -f2) - fi - density_ice=${density_ice:-910.} - # - # Time step in data file to force the ocean - # - if [ $($cdo -s ntime ${_infile} | tr -d '[:space:]') -gt 1 ] ; then - _time_diff=$(iterative_coupling_get_pism_time_size ${_infile}) - else - if [ $($cdo -s ntime ${PISM_FORCING_EXTRA_FILE} | tr -d '[:space:]') -gt 1 ] ; then - _time_diff=$(iterative_coupling_get_pism_time_size ${PISM_FORCING_EXTRA_FILE}) - else - # Fall back: Delta Time = Years difference - _time_diff=$(echo "86400. * 365.25 * (${END_YEAR_pism}-${CURRENT_YEAR_pism})" | bc -l ) - fi - fi - # - # Area of grid cell - # - _area=$(iterative_coupling_get_pism_area_size ${_infile}) - - # - # CDO commands as multiplier - # - MUL_density="-mulc,${density_ice}" - MUL_recipro_delta_time="-mulc,$( echo 1./${_time_diff} | bc -l)" - MUL_recipro_grid_area="-mulc,$( echo 1./${_area} | bc -l)" - - # - # Combine the CDO flags due to request - # - case ${_type:-"Not provided"} in - heat_loss) - _unit="J m-2 s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time}" - ;; - water_loss) - _unit="m s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time} ${MUL_density_ice}" - ;; - mass_loss) - _unit="kg m-2 s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time}" - ;; - heat_abs) - _unit="J m-2 s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time} ${MUL_recipro_grid_area}" - ;; - water_abs) - _unit="m s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time} ${MUL_recipro_grid_area} ${MUL_density_ice}" - ;; - mass_abs) - _unit="kg m-2 s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time} ${MUL_recipro_grid_area}" - ;; - "Not provided") - echo " - The type was not provided as second argument during the call of the function" - echo " 'iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux'" - echo " Update the call of this function and restart" - echo " S T O P 31" - exit 31 - ;; - *) - echo " - Unkown type=${type}" - echo " => Adjust function 'iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux'" - echo " S T O P 32" - exit 32 - ;; - esac - - _bak=${_infile%.*}_before_loss2flux.nc - mv -f ${_infile} ${_bak} - - $cdo -setunit,"${_unit}" ${_CDO_Factor_flags} \ - ${_bak} ${_infile} - - cleanup_list="${cleanup_list} ${_bak}" - - unset _bak _infile _type _unit _CDO_Factor_flags - unset MUL_recipro_delta_time MUL_recipro_grid_area - unset _area _time_diff -} - - -function iterative_coupling_pism_ocean_prepare_combine_forcings { - echo " * Combine various ice shelf/sheet forcing (PISM) into one file with sensible units..." - - cdo_task_list="" - # - # Fresh water - # - _file1=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.basalwater.nc - _file2=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.icebergwater.nc - if [ -f $_file1 -a -f $_file2 ] ; then - cdo_task_list="${cdo_task_list} -setvar,${ocean_name_freshwater_flux}" - cdo_task_list="${cdo_task_list} -add -selvar,wnet_basal $_file1 -selvar,wnet_iceberg $_file2" - cleanup_list="${cleanup_list} ${_file1}" - cleanup_list="${cleanup_list} ${_file2}" - else - if [ -f $_file1 ] ; then - cdo_task_list="${cdo_task_list} -setvar,${ocean_name_freshwater_flux} -selvar,wnet_basal $_file1" - cleanup_list="${cleanup_list} ${_file1}" - elif [ -f $_file2 ] ; then - cdo_task_list="${cdo_task_list} -setvar,${ocean_name_freshwater_flux} -selvar,wnet_iceberg $_file2" - cleanup_list="${cleanup_list} ${_file2}" - fi - fi - - # - # Heat flux - # - _file1=${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.icebergheat.nc - if [ -f ${_file1} ] ; then - cdo_task_list="${cdo_task_list} -setvar,${ocean_name_heat_flux} -selvar,qnet_iceberg ${_file1}" - cleanup_list="${cleanup_list} ${_file1}" - fi - - # - # Temperature gradient, Masks - # - for _file1 in ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.bottom_iceshelf_temp.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_ocean.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_iceshelf.nc \ - ${COUPLE_DIR}/${PISM_HEMISPHERE}/ice_file_at_ocean.laststep.mask_land.nc - do - if [ -f $_file1 ] ; then - # Drop time axis is done above (search for ncwa) - _file2=${_file1%.*}_before_combine.nc - mv -f $_file1 $_file2 - ncwa -a time $_file2 $_file1 - cleanup_list="${cleanup_list} ${_file2}" - - cdo_task_list="${cdo_task_list} ${_file1}" - cleanup_list="${cleanup_list} ${_file1}" - fi - done - - # - # Auxillary fields - # - _file1=${COUPLE_DIR}/${PISM_HEMISPHERE}/aux_field_pism4ocean.nc - if [ -f ${PISM_RESTART_OUTPUT_FILE} ] ; then - ncks -OQv lon,lat ${PISM_RESTART_OUTPUT_FILE} ${_file1} - elif [ -f ${PISM_FORCING_EXTRA_FILE} ] ; then - ncks -OQv lon,lat ${PISM_FORCING_EXTRA_FILE} ${_file1} - fi - if [ -f $_file1 ] ; then - cdo_task_list="${cdo_task_list} ${_file1}" - fi - cleanup_list="${cleanup_list} ${_file1}" - - # - # Merge - # - if [ -f ${COMBINED_OUTPUT} ] ; then - mv -f ${COMBINED_OUTPUT} ${COMBINED_OUTPUT}~ - cleanup_list="${cleanup_list} ${COMBINED_OUTPUT}~" - fi - $cdo -O merge ${cdo_task_list} ${COMBINED_OUTPUT} - - # - # Attributes related to auxillary fields - # - if [ -f $_file1 ] ; then - ncatted -a coordinates,,c,c,'lon lat' \ - -a coordinates,lat,d,, \ - -a coordinates,lon,d,, \ - -a coordinates,time,d,, \ - -a coordinates,x,d,, \ - -a coordinates,y,d,, \ - ${COMBINED_OUTPUT} - fi - - unset cdo_task_list _file1 _file2 -} - - -# -# Auxillary functions -# -function iterative_coupling_get_pism_area_size { - #TODO : generalize the area computation, so that even - # curvlinear grid are recognized - __file=$1 - if [ ! -f ${__file} ] ; then - echo " * Compute PISM grid size..." - echo " - Missing file ${__file} in >iterative_coupling_get_pism_area_size<" - echo " S T O P 38" - exit 38 - fi - - __area_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/tmp_pism_area.nc - # Compute the area - if [ 0 -eq 1 ] ; then - # NCAP2 version (NCAP does not work) - test -f $__area_file && rm -f $__area_file - ncap2 -Ovs "area=abs( (x(0)-x(1)) * (y(0)-y(1)) );" ${__file} $__area_file - __area_size=$(ncks -CHs '%f' -v area $__area_file) - else - # NCAP2 free alternative - __x0=$(ncks -d x,0 -v x -CHs '%14.4f' ${__file} | tr -d '[:space:]') - __x1=$(ncks -d x,1 -v x -CHs '%14.4f' ${__file} | tr -d '[:space:]') - __y0=$(ncks -d y,0 -v y -CHs '%14.4f' ${__file} | tr -d '[:space:]') - __y1=$(ncks -d y,1 -v y -CHs '%14.4f' ${__file} | tr -d '[:space:]') - - #__area_size=$(echo "((${__x1} - ${__x0}) * (${__y1} - ${__y0}))" | bc -l) - # Ensures positive numbers - __area_size=$(echo "sqrt(((${__x1} - ${__x0}) * (${__y1} - ${__y0}))^2)" | bc -l) - unset __x0 __x1 __y0 __y1 - fi - - echo ${__area_size} - cleanup_list="${cleanup_list} ${__area_file}" - unset __area_file __area_size __file -} - - -function iterative_coupling_get_pism_time_size { - #TODO : generalize the time difference computation, so - # that even all time difference between all time - # steps are computed, such as - # time_diff(0)=time(1)-time(0), ..., - # time(i-1)=time(i)-time(i-1), ..., - # time(n-1)=time(n)-time(n-1), - # time(n) = time(n)-time(n-1) <== repeat the last time difference for the last time step?? - # - __file=$1 - if [ ! -f ${__file} ] ; then - echo " * Compute PISM writing time step size..." - echo " - Missing file ${__file} in >iterative_coupling_get_pism_time_size<" - echo " S T O P 39" - exit 39 - fi - - __time_file=${COUPLE_DIR}/${PISM_HEMISPHERE}/tmp_pism_time.nc - - # Compute the time - if [ 0 -eq 1 ] ; then - # NCAP2 version (NCAP does not work) - test -f $__time_file && rm -f $__time_file - ncap2 -Ovs "timediff=abs( time(1)-time(0) );" ${__file} $__time_file - __time_size=$(ncks -CHs '%f' -v timediff $__time_file) - else - # NCAP2 free alternative - __t0=$(ncks -d time,0 -v time -CHs '%14.6f' ${__file} | tr -d '[:space:]') - __t1=$(ncks -d time,1 -v time -CHs '%14.6f' ${__file} | tr -d '[:space:]') - #__time_size=$(echo "(${__t1} - ${__t0})" | bc -l) - # Ensures a positive number - __time_size=$(echo "sqrt((${__t1} - ${__t0})^2)" | bc -l) - - unset __t0 __t1 - fi - - echo ${__time_size} - cleanup_list="${cleanup_list} ${__time_file}" - unset __time_file __time_size __file -} - - -function iterative_coupling_pism_ocean_fesom2pism_names { - _file=$1 - - # - # These names are constant and are also use above internally (!) - # - _fesom_basalshelf_freshwater_flux_varn="wnet_basal" - _fesom_basalshelf_freshwater_flux_unit="kg m-2" - _fesom_iceberg_freshwater_flux_varn="wnet_iceberg" - # Since PISM discharge/ice berg calving may has the unit "Gt" - # and the implicit timing information, we convert it into "kg" - # and repair later the mass loss into a mass flux - # -> iterative_coupling_pism_ocean_compute_calving_loss_to_calving_flux - ##_fesom_iceberg_freshwater_flux_unit="kg m-2" - _fesom_iceberg_freshwater_flux_unit="kg" - -# -# Controlling sequence -# - -cat > ${_file:-cdo_partable.txt} <${_xy_double}<" - echo " float >${_xy_float}< " - echo " extracted from >>${_pism_init_file}<<" - - _flag_compute_xy=0 - _flag_new_double_file=0 - _flag_new_float_file=0 - # If any of the wanted or restart files is missing, we set the flag - for _file in $_xy_double $_xy_float $_xy_restart_double $_xy_restart_float ; do - test ! -f $_file && _flag_compute_xy=$(( _flag_compute_xy + 1 )) - done - - if [ $_flag_compute_xy -gt 0 ] ; then - if [ ! -f ${_xy_double} ] ; then - if [ "x${_restart_dir}" != "x" ] ; then - # If Restart exists, use it - if [ -f ${_xy_restart_double} ] ; then - cp ${_xy_restart_double} ${_xy_double} - fi - fi - if [ ! -f ${_xy_double} ] ; then - # xy-file still not present: build it - #ncks -v x,y,.mapping ${_pism_init_file} ${_xy_double} && \ - echo "_pism_init_file = ${_pism_init_file}" - echo "_xy_double = ${_xy_double}" - ncks -v x,y ${_pism_init_file} ${_xy_double} && \ - ncatted \ - -a standard_name,x,c,c,"projection_x_coordinate" \ - -a standard_name,y,c,c,"projection_y_coordinate" \ - -a units,x,c,c,"m" -a axis,x,c,c,"X" \ - -a units,y,c,c,"m" -a axis,y,c,c,"Y" \ - ${_xy_double} - _flag_new_double_file=1 - fi - fi - - if [ ! -f ${_xy_float} ] ; then - if [ "x${_restart_dir}" != "x" ] ; then - # If Restart exists, use it - if [ -f ${_xy_restart_float} ] ; then - cp ${_xy_restart_float} ${_xy_float} - fi - fi - if [ ! -f ${_xy_float} ] ; then - # xy-file still not present: build it - # - # Since conflicting module create a challenge, we save - # the current set of loaded modules, purge the module - # list, load necessary working modules, do the job by - # calling ncdump and ncgen, and restore the former - # purged module list. - # - # MODULE-FIX: 1/2 - module_save_file=/tmp/module2restore_4ncdump_ncgen.$$ - module save -f $module_save_file - module purge - module load netcdf-c - ncdump ${_xy_double} | sed 's/double /float /g' | ncgen -o ${_xy_float} - # - # Recover purged modules - # - # MODULE_FIX: 2/2 - module restore -f $module_save_file && rm $module_save_file - - #ncatted \ - # -a standard_name,x,c,c,"projection_x_coordinate" \ - # -a standard_name,y,c,c,"projection_y_coordinate" \ - # -a units,x,c,c,"m" -a axis,x,c,c,"X" \ - # -a units,y,c,c,"m" -a axis,y,c,c,"Y" \ - # ${_xy_float} - fi - fi - fi - - if [ "x${_restart_dir}" != "x" ] ; then - if [ $_flag_new_double_file -ge 1 ] ; then - add_to $(pwd)/$_xy_double $_xy_double $_restart_dir - fi - if [ $_flag_new_float_file -ge 1 ] ; then - add_to $(pwd)/$_xy_float $_xy_float $_restart_dir - fi - fi - - unset _pism_init_file _xy_file_double _xy_file_float _restart_dir - unset _flag_compute_xy _flag_new_double_file _flag_new_float_file - unset _file _restart_xy_double _restart_xy_float _xy_double _xy_float -} - -# -- last line diff --git a/couplings/coupling_dual-hemisphere/utils/CreateTimeAxisNC.bash b/couplings/coupling_dual-hemisphere/utils/CreateTimeAxisNC.bash deleted file mode 100755 index 2a2c66725..000000000 --- a/couplings/coupling_dual-hemisphere/utils/CreateTimeAxisNC.bash +++ /dev/null @@ -1,273 +0,0 @@ -#!/bin/bash -# Builds a netCDF file with a time contentiously increasing time axis -# -# The increasing time axis of $ELEMENTS_NO elements is written to the -# file $OUTPUT_NC. A given offset of $OFFSET is considered. -# -# NOTE: Each month has an identical length and the time are integer-like values -# -# Call: -# CreateTimeAxisNC.bash ELEMENTS_NO (OUTPUT_NC) (OFFSET) (TYPE) (CALENDAR) (NUM_TYPE) -# -# ELEMENTS_NO : Number of time steps -# OUTPUT_NC : Netcdf output file name, optional (default=axis.nc) -# OFFSET : Time offset in years, optional (default=0) -# TYPE : NetCDF file file type, as reported by `ncdump -k` -# (default=classic; -# valid=classic/nc3/3, "64-bit offset"/nc6/6, -# "64-bit data"/nc5/5, netCDF-4/nc4/4, -# "netCDF-4 classic model"/nc7/7) -# CALENDAR : Calendar type 360, 365, ... (default=360) -# NUM_TYPE : Number type of time axis (default=double; -# valid=double, float, int) -# -# Examples: -# ./CreateTimeAxisNC.bash 100 TimeAxis.nc -# ./CreateTimeAxisNC.bash 100 TimeAxis.360.nc 0 classic 360_day double -# -# (c) Christian Rodehacke, AWI, 2017-09-27 (first version) -# Christian Rodehacke, AWI, 2017-09-28 (NetCDF type: optional 4th parameter) -# Christian Rodehacke, AWI, 2018-09-12 (Calendar: optional 5th parameter) -# Christian Rodehacke, AWI, 2018-09-19 (Numeric tyupe:optional 6th parameter) -# -NO_LINES=25 ; NO_NEED_INPUTS=1 -set -e -if [ $# -lt ${NO_NEED_INPUTS} ] ; then - head -n ${NO_LINES} $0 - echo - echo " Need at least ${NO_NEED_INPUTS} input parameter(s)" - echo - exit 1 -fi - -ELEMENTS_NO=$1 -if [ $# -ge 2 ] ; then - OUTPUT_NC=$2 -else - OUTPUT_NC="axis.nc" # default value" -fi -if [ $# -ge 3 ] ; then - OFFSET=$3 -else - OFFSET=0 -fi -if [ $# -ge 4 ] ; then - TYPE=$4 -else - TYPE="classic" -fi -if [ $# -ge 5 ] ; then - CALENDAR=$5 -else - CALENDAR="360" -fi - -if [ $# -ge 6 ] ; then - NUM_TYPE=$6 -else - NUM_TYPE="double" -fi - - -DEBUG_FLAG=0 - - -# ======================================================================== -# -# Subroutines, functions -# -# ======================================================================== - -function CreateTimeAxisNC() { - # Creates a netcdf file with linearily increasing time axis starting at zero - # Call: CreateTimeAxisNC NumberToGo0 TIME_AXIS_FILE (OffsetYear) - NumberToGo0_=$1 - TIME_AXIS_FILE_=$2 - if [ $# -ge 3 ] ; then - OffsetYear_=$3 - else - OffsetYear_=0 - fi - if [ $# -ge 4 ] ; then - calendar_wanted_=$4 - else - calendar_wanted_=360 - fi - if [ $# -ge 5 ] ; then - number_type_=$5 - else - number_type_="double" - fi - # - NoRequire__=2 - if [ $# -lt ${NoRequire__} ] ; then - echo " ***** Missing required ${NoRequire__} input variables in 'CreateTimeAxisNC' in $0 *****" 1>&2 - echo " *** $# :: Received $* *****" 1>&2 - exit 102 - fi - # - # Ensure a dummy value for optional parameter - # - OffsetYear_=${OffsetYear_:=0} - - - # - # Function body - # - SECONDS_PER_DAY_=86400 - MINUTES_PER_DAY_=1440 - - calendar_wanted_=${calendar_wanted_:-360} - - case ${calendar_wanted_} in - "366"|"366_day") - DAYS_PER_YEAR_=366 ; DAYS_PER_MONTH_=30.5 # 366_day; Not used in PISM !! - CALENDAR_="${DAYS_PER_YEAR_}_day" - ;; - "365.242198781"|"standard") - DAYS_PER_YEAR_=365.242198781 ; DAYS_PER_MONTH_=30.436849898 # =(1/12)*365.242198781 : UDUNUITS-2 - CALENDAR_="standard" - ;; - "365"|"365_day"|"noleap") - DAYS_PER_YEAR_=365 ; DAYS_PER_MONTH_=30.416666667 # 365_day=noleap - CALENDAR_="${DAYS_PER_YEAR_}_day" - ;; - "360"|"360_day"|"leap") - DAYS_PER_YEAR_=360 ; DAYS_PER_MONTH_=30 # 360_day - CALENDAR_="${DAYS_PER_YEAR_}_day" - ;; - *) - echo " UNKNOWN calendar <<${calendar_wanted_}>>" - echo " S T O P 4" - exit 4 - ;; - esac - - - # - # *** If you change something here, also change the 'awk' computation below!! - # - ##DAYS_PER_YEAR_=366 ; DAYS_PER_MONTH_=30.5 # 366_day; Not used in PISM !! - ##CALENDAR_="${DAYS_PER_YEAR_}_day" - #DAYS_PER_YEAR_=365.242198781 ; DAYS_PER_MONTH_=30.436849898 # =(1/12)*365.242198781 : UDUNUITS-2 - #CALENDAR_="standard" - #DAYS_PER_YEAR_=365 ; DAYS_PER_MONTH_=30.416666667 # 365_day=noleap - #CALENDAR_="${DAYS_PER_YEAR_}_day" - #DAYS_PER_YEAR_=360 ; DAYS_PER_MONTH_=30 # 360_day - #CALENDAR_="${DAYS_PER_YEAR_}_day" - # - # *** If you change something here, also change the 'awk' computation below!! - # - - CALENDAR_UNIT_="days" ; OffTime_=$(echo "$OffsetYear_ * $DAYS_PER_YEAR_ " | bc -l ) - #CALENDAR_UNIT_="minutes"; OffTime_=$(echo "$OffsetYear_ * $DAYS_PER_YEAR_ * $MINUTES_PER_DAY_ " | bc -l ) - #CALENDAR_UNIT_="seconds"; OffTime_=$(echo "$OffsetYear_ * $DAYS_PER_YEAR_ * $SECONDS_PER_DAY_ " | bc -l ) - - # DOES NOT WORK for calendar "standard" - #CALENDAR_UNIT_="days" ; OffTime_=$(( OffsetYear_ * DAYS_PER_YEAR_ )) - #CALENDAR_UNIT_="minutes"; OffTime_=$(( OffsetYear_ * DAYS_PER_YEAR_ * MINUTES_PER_DAY_ )) - #CALENDAR_UNIT_="seconds"; OffTime_=$(( OffsetYear_ * DAYS_PER_YEAR_ * SECONDS_PER_DAY_ )) - - - time_=$(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*$DAYS_PER_MONTH_+15.0+$OffTime_}else{printf(\",%i\\n\",\$1*$DAYS_PER_MONTH_+15.0+$OffTime_)}}") - time_bnds_=$(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*$DAYS_PER_MONTH_+$OffTime_\",\"(\$1+1)*$DAYS_PER_MONTH_+$OffTime_}else{print \",\"\$1*$DAYS_PER_MONTH_+$OffTime_\",\"(\$1+1)*$DAYS_PER_MONTH_+$OffTime_}}") - - - cat > ${TIME_AXIS_FILE_}.cdl << EOF -netcdf time_axis { -dimensions: - time = UNLIMITED ; - t_nb2 = 2 ; -variables: - //float time(time) ; - //double time(time) ; - ${number_type_} time(time) ; - time:units = "${CALENDAR_UNIT_} since 0000-01-01 00:00:00" ; - time:calendar = "${CALENDAR_}" ; - time:long_name = "time" ; - time:standard_name = "time" ; - time:axis = "T" ; - time:bounds = "time_bnds" ; - time:comment =" Time axis constructed on $(date)" ; - //double time_bnds(time, t_nb2) ; - //double time_bnds(time, t_nb2) ; - ${number_type_} time_bnds(time, t_nb2) ; -// global attributes: - :Comments = "Generic build time axis" ; - :Conventions = "CF-1.3" ; - :Creators = "Christian Rodehacke" ; - :History = "`date`: Created by $USER \n"; - :Title = "Generic time axis" ; - -data: - //For :calendar = "360_day" ; - time = $time_ ; - time_bnds = $time_bnds_ ; - -} -EOF - - -# -## //For :calendar = "360_day" ; -## time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.0+15.0+$OffTime_}else{printf(\",%i\\n\",\$1*30.0+15.0+$OffTime_)}}") ; -## time_bnds = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.0+$OffTime_\",\"(\$1+1)*30.0+$OffTime_}else{print \",\"\$1*30.0+$OffTime_\",\"(\$1+1)*30.0+$OffTime_}}") ; -## //For :calendar = "366_day" ; -## time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.5+15.0}else{printf(\",%i\\n\",\$1*30.5+15.0)}}") ; -## time_bnds = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.5\",\"(\$1+1)*30.5}else{print \",\"\$1*30.5\",\"(\$1+1)*30.5}}") ; -## //For :calendar = "366_day" ; -## time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.5+15.0}else{printf(\",%i\\n\",\$1*30.5+15.0)}}") ; -## time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.5+15.0}else{print \",\"\$1*30.5+15.0}}") ; -# -# //month: time = `seq -s\, 0 ${NumberToGo0_}` ; -# //month: time_bnds = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1\",\"\$1+1}else{print \",\"\$1\",\"\$1+1}}") ; -# -# //time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1/\$STEPS_PER_YEAR}else{print \",\"\$1/\$STEPS_PER_YEAR}}") ; -# //time_bnds = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1/\$STEPS_PER_YEAR\",\"(\$1+1)/\$STEPS_PER_YEAR}else{print \",\"\$1/\$STEPS_PER_YEAR\",\"(\$1+1)/\$STEPS_PER_YEAR}}") ; -# - - ncgen -o ${TIME_AXIS_FILE_} ${TIME_AXIS_FILE_}.cdl -k ${TYPE} && rm ${TIME_AXIS_FILE_}.cdl -} - -# ======================================================================== -# -# Main program -# -# ======================================================================== - -if [ ${DEBUG_FLAG} -gt 0 ] ; then - echo - echo "ELEMENTS_NO : ${ELEMENTS_NO}" - echo "OUTPUT_NC : ${OUTPUT_NC}" - echo "OFFSET : ${OFFSET:=0}" - echo "CALENDAR : ${CALENDAR}" - echo "NUM_TYPE : ${NUM_TYPE}" -fi - -if [ -f ${OUTPUT_NC} ] ;then - echo - echo " OUTPUT_NC=${OUTPUT_NC} exits: $(ls -l ${OUTPUT_NC})" - echo " S T O P 2" - exit 2 -fi - -DIR=$(dirname ${OUTPUT_NC}) -if [ ! -d ${DIR} ] ; then - echo - echo " directory '${DIR}' of '${OUTPUT_NC}' does not exist" - echo " S T O P 3" - exit 3 -fi - -# -# in the function we compute dates from [0 to $ELEMENTS_NO] times TimeStepWith -# Hence we have to reduce $ELEMENTS_NO by one to actually get the requested -# number of elements -# -ELEMENTS_NO=$(( ELEMENTS_NO - 1 )) - -CreateTimeAxisNC ${ELEMENTS_NO} ${OUTPUT_NC} ${OFFSET} ${CALENDAR} ${NUM_TYPE} - - -exit 0 -# -- last line diff --git a/couplings/coupling_dual-hemisphere/utils/apply_hosing_correction.py b/couplings/coupling_dual-hemisphere/utils/apply_hosing_correction.py deleted file mode 100644 index 00e39d7f1..000000000 --- a/couplings/coupling_dual-hemisphere/utils/apply_hosing_correction.py +++ /dev/null @@ -1,53 +0,0 @@ -import pandas as pd -import xarray as xr -import sys -import os.path - -rho_water = 1000 #kg/m3 - -discharge_file = sys.argv[1] -cell_area_echam_file = sys.argv[2] -cell_area_fesom_file = sys.argv[3] -hosing_dir = sys.argv[4] - -if os.path.exists(cell_area_fesom_file): - print(" * Loading total FESOM grid area from ", cell_area_fesom_file) - fl = xr.open_dataset(cell_area_fesom_file, engine="netcdf4") - print(" * Summing up FESOM grid areas") - if "nod_area" in fl.variables: - total_FESOM_cell_area = fl.nod_area[0, :].sum().squeeze().values - elif "cell_area" in fl.variables: - total_FESOM_cell_area = fl.cell_area[:].sum().squeeze().values - print(" * Total cell area = ", total_FESOM_cell_area) -else: - print(" * File does not exist!") - exit - -if os.path.exists(discharge_file): - print(" * Loading ice discharge from ", discharge_file) - fl1 = xr.open_dataset(discharge_file, engine="netcdf4") -else: - print(" * File does not exist!") - exit - -if os.path.exists(discharge_file): - print(" * Loading total ECHAM grid area from ", cell_area_echam_file) - fl2 = xr.open_dataset(cell_area_echam_file, engine="netcdf4") - print(" * Integrate discharge over ECHAM grid") - # Convert kg/s into m3/s - discharge_tot = fl1.total_ice_mass_loss_flux.weighted(fl2.cell_area.squeeze()).sum() / rho_water - print(" * Distribute over FESOM domain evenly") - discharge = -discharge_tot / total_FESOM_cell_area -else: - print(" * File does not exist!") - exit - -if not os.path.isfile(os.path.join(hosing_dir, "landice_nodes_in_region_1.out")): - df = pd.read_csv(os.path.join(os.path.dirname(cell_area_fesom_file), "nod2d.out"), sep="\s+", skiprows=[0], header=None) - n=df.iloc[:, 0] - n.to_csv(os.path.join(hosing_dir, "landice_nodes_in_region_1.out"), header=[str(len(n.values))], index=False) - -mass_loss = discharge.squeeze().values -with open(os.path.join(hosing_dir, "landice_yearly_mass_loss.out"), 'w') as f: - f.write(str(1) + "\n" + str(mass_loss)) - diff --git a/couplings/coupling_dual-hemisphere/utils/axis_366.nc b/couplings/coupling_dual-hemisphere/utils/axis_366.nc deleted file mode 100644 index 287e932b9..000000000 Binary files a/couplings/coupling_dual-hemisphere/utils/axis_366.nc and /dev/null differ diff --git a/couplings/coupling_dual-hemisphere/utils/calnoro.f90 b/couplings/coupling_dual-hemisphere/utils/calnoro.f90 deleted file mode 100644 index ec649d3fb..000000000 --- a/couplings/coupling_dual-hemisphere/utils/calnoro.f90 +++ /dev/null @@ -1,339 +0,0 @@ -PROGRAM calnoro - - WRITE(*,*) 'CALNORO CALLED' - - WRITE(*,*) 'Truncation ?' - READ (*,*) IRES - CALL calres(ires, nlat) - - nlon = 2*nlat - WRITE (*,*) 'RES: ', IRES,' NLAT: ',nlat,' NLON: ',nlon - - CALL sso_par_fil(nlat, nlon) - -END PROGRAM calnoro - -SUBROUTINE calres (ires, nlat) - IF (ires < 21 .OR. ires > 1000) THEN - WRITE(0,*) 'calres: resolution out of range (res=',ires,')' - STOP - END IF - - nlat = NINT((ires*3.+1.)/2.) - IF (MOD(nlat,2) > 0) THEN - nlat = nlat + 1 - nlat2 = NINT(((ires+1)*3.+1.)/2.) - IF (nlat == nlat2) THEN - WRITE(0,*) 'calres: can not calculate number of latitudes for res ', ires - STOP - END IF - END IF -! WRITE (*,*) 'res: ', ires, ' nlat: ', nlat - - RETURN -END SUBROUTINE calres - -SUBROUTINE gauaw (pa, pw, nlat) - - ! Description: - ! - ! Compute abscissas and weights for gaussian integration. - ! - ! Method: - ! - IMPLICIT NONE - - ! Scalar arguments - INTEGER nlat - - ! Array arguments - REAL pa(nlat), pw(nlat) - ! *pa* - array, length at least *k,* to receive abscis abscissas. - ! *pw* - array, length at least *k,* to receive weights. - - - ! Local scalars: - REAL, PARAMETER :: eps = EPSILON(0.0) - REAL :: api - INTEGER, PARAMETER :: itemax = 20 - - INTEGER iter, ins2, isym, jn, jgl - REAL za, zw, z, zan - REAL zk, zkm1, zkm2, zx, zxn, zldn, zmod - - ! Intrinsic functions - INTRINSIC ABS, COS, MOD, TAN, ASIN - - ! Executable statements - - api = 2.*ASIN(1.) - - ins2 = nlat/2+MOD(nlat,2) - - ! Find first approximation of the roots of the - ! Legendre polynomial of degree nlat - - DO jgl = 1, ins2 - z = REAL(4*jgl-1)*api/REAL(4*nlat+2) - pa(jgl) = COS(z+1./(TAN(z)*REAL(8*nlat**2))) - END DO - - ! Computes roots and weights - ! Perform the Newton loop - ! Find 0 of Legendre polynomial with Newton loop - - DO jgl = 1, ins2 - - za = pa(jgl) - - DO iter = 1, itemax+1 - zk = 0.0 - - ! Newton iteration step - - zkm2 = 1.0 - zkm1 = za - zx = za - DO jn = 2, nlat - zk = (REAL(2*jn-1)*zx*zkm1-REAL(jn-1)*zkm2)/REAL(jn) - zkm2 = zkm1 - zkm1 = zk - END DO - zkm1 = zkm2 - zldn = (REAL(nlat)*(zkm1-zx*zk))/(1.-zx*zx) - zmod = -zk/zldn - zxn = zx+zmod - zan = zxn - - ! computes weight - - zkm2 = 1.0 - zkm1 = zxn - zx = zxn - DO jn = 2,nlat - zk = (REAL(2*jn-1)*zx*zkm1-REAL(jn-1)*zkm2)/REAL(jn) - zkm2 = zkm1 - zkm1 = zk - END DO - zkm1 = zkm2 - zw = (1.0-zx*zx)/(REAL(nlat*nlat)*zkm1*zkm1) - za = zan - IF (ABS(zmod) <= eps) EXIT - END DO - - pa(jgl) = zan - pw(jgl) = zw * 2. - - ENDDO - -!DIR$ IVDEP -!OCL NOVREC - DO jgl = 1, nlat/2 - isym = nlat-jgl+1 - pa(isym) = -pa(jgl) - pw(isym) = pw(jgl) - ENDDO - -END SUBROUTINE gauaw - -SUBROUTINE sso_par_fil(nlat, nlon) - -! USE mo_orogwd - IMPLICIT NONE - - INTEGER nlat, nlon - - INTEGER, PARAMETER :: iusn=720, jusn=360 - !INTEGER, PARAMETER :: iusn=1440, jusn=720 - !INTEGER, PARAMETER :: iusn=2160, jusn=1080 - - INTEGER i, j - INTEGER ihead(8) - - REAL zgw(nlat) - REAL xusn(iusn),yusn(jusn),zusn(iusn,jusn) - REAL xlon(nlon),ylat(nlat) - REAL zphi(nlon,nlat),zmea(nlon,nlat), & - zstd(nlon,nlat),zsig(nlon,nlat), & - zgam(nlon,nlat),zthe(nlon,nlat), & - zpic(nlon,nlat),zval(nlon,nlat) - INTEGER mask(nlon,nlat) - REAL xpi, zmin, zmax - - - ! INITIALISATION - - CALL gauaw(ylat, zgw, nlat) - DO j=1,nlat - ylat(j) = ASIN(ylat(j))/(8.*ATAN(1.))*360 -! write (*,*) j, ylat(j) - ENDDO - - xpi=ACOS(-1.) - DO i=1,nlon - xlon(i)=-xpi+2.*(i-1)*xpi/REAL(nlon) - ENDDO - DO j=1,nlat - ylat(j)=ylat(j)*xpi/180. -! write (*,*) j, ylat(j) - ENDDO - - DO i=1,iusn - xusn(i)=-xpi+2.*(REAL(i)-0.5)*xpi/REAL(iusn) - ENDDO - DO j=1,jusn - yusn(j)=xpi/2.-(REAL(j)-0.5)*xpi/REAL(jusn) - ENDDO - -! OPEN(15,file='USN_FMT',form='formatted') - CALL readfield ("OROMEA", zusn, iusn, jusn) - !CALL readfield ("hmean", zusn, iusn, jusn) - - zmin= 10000. - zmax=-10000. - DO j=1,jusn - DO i=1,iusn -! READ(15,*) zusn(i,j) - zmin=MIN(zmin,zusn(i,j)) - zmax=MAX(zmax,zusn(i,j)) - ENDDO - ENDDO - - CLOSE(15) - - PRINT *,' usn min. et max.:',zmin,zmax - - CALL grid_noro(iusn,jusn,xusn,yusn,zusn, & - nlon,nlat,xlon,ylat, & - zphi,zmea,zstd,zsig,zgam,zthe, & - zpic,zval,mask) - - - CALL shift180(zmea, nlat, nlon) - CALL shift180(zstd, nlat, nlon) - CALL shift180(zsig, nlat, nlon) - CALL shift180(zgam, nlat, nlon) - CALL shift180(zthe, nlat, nlon) - CALL shift180(zpic, nlat, nlon) - CALL shift180(zval, nlat, nlon) - - OPEN(22,file='sso_par_fil.srv',form='unformatted') - - - ihead(2) = 0 - ihead(3) = 0 - ihead(4) = 0 - ihead(5) = nlon - ihead(6) = nlat - ihead(7) = 0 - ihead(8) = 0 - - ihead(1) = 51 - WRITE(22) ihead - WRITE(22) zmea - ihead(1) = 52 - WRITE(22) ihead - WRITE(22) zstd - ihead(1) = 53 - WRITE(22) ihead - WRITE(22) zsig - ihead(1) = 54 - WRITE(22) ihead - WRITE(22) zgam - ihead(1) = 55 - WRITE(22) ihead - WRITE(22) zthe - ihead(1) = 56 - WRITE(22) ihead - WRITE(22) zpic - ihead(1) = 57 - WRITE(22) ihead - WRITE(22) zval - - STOP -END SUBROUTINE sso_par_fil - -SUBROUTINE shift180(field, nlat, nlon) - - IMPLICIT NONE - - INTEGER nlat, nlon - - REAL field(nlon, nlat) - REAL tmpfield(nlon, nlat) - - tmpfield(:,:) = field(:,:) - - field(1:nlon/2,:) = tmpfield(nlon/2+1:nlon,:) - field(nlon/2+1:nlon,:) = tmpfield(1:nlon/2,:) - -END SUBROUTINE shift180 - -SUBROUTINE NF_ErrorHandling(func, farg, status) - - CHARACTER (*) func, farg - INTEGER status - - INCLUDE 'netcdf.inc' - - IF (status /= NF_NOERR) THEN - WRITE (0,*) func, '(',farg,') : ', NF_STRERROR(status) - STOP - END IF - -END SUBROUTINE NF_ErrorHandling - -SUBROUTINE readfield (varname, zfield, nlon, nlat) - - USE netcdf - - IMPLICIT NONE - - INTEGER nlat, nlon - REAL zfield(nlon, nlat) - REAL ztmp(nlon) - CHARACTER(*) varname - INTEGER fileid, varid, status - INTEGER jlat, nx, ny - INTEGER start(2), count(2) - CHARACTER(LEN=200) :: dimname - - WRITE (*,*) "READFIELD CALLED:" - WRITE (*,*) " nlat:", nlat, " nlon: ", nlon - WRITE (*,*) " varname: ", varname - - status = nf90_open("topodata.nc", nf90_nowrite, fileid) - CALL NF_ErrorHandling("nf_open", "topodata.nc", status) - - status = nf90_inquire_dimension(fileid, 1, dimname, nx) - status = nf90_inquire_dimension(fileid, 2, dimname, ny) - WRITE (*,*) " ny :", ny, " nx : ", nx - IF(nlon /= nx.OR.nlat /= ny)THEN - WRITE (*,*) ' nlon or nlat bad dimensions' - STOP - ENDIF - - status = nf90_inq_varid(fileid, varname, varid) - CALL NF_ErrorHandling("nf_inq_varid", varname, status) - - DO jlat = 1, nlat - - start(1) = 1 - start(2) = jlat - count(1) = nlon - count(2) = 1 - - status = nf90_get_var(fileid, varid, ztmp, start, count) - CALL NF_ErrorHandling("nf_get_vara_real", varname, status) -! status = nf_get_vara_double(fileid, varid, start, count, ztmp) -! CALL NF_ErrorHandling("nf_get_vara_double", varname, status) - - zfield(1:nlon/2,jlat) = ztmp(nlon/2+1:nlon) - zfield(nlon/2+1:nlon,jlat) = ztmp(1:nlon/2) - - END DO - - status = nf90_close(fileid) - CALL NF_ErrorHandling("nf_close", "topodata.nc", status) - -END SUBROUTINE readfield diff --git a/couplings/coupling_dual-hemisphere/utils/fesom_scalar_array_to_LonLat.py b/couplings/coupling_dual-hemisphere/utils/fesom_scalar_array_to_LonLat.py deleted file mode 100644 index d9a3a6004..000000000 --- a/couplings/coupling_dual-hemisphere/utils/fesom_scalar_array_to_LonLat.py +++ /dev/null @@ -1,287 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Convert FESOM hydrographic output to array at each column point incl lon, lat. - -For the coupling of the FESOM ocean model, the original FESOM output of the -hydrographic fields temp and salt are modified. First values are computed for -all grid point location from the surface layer down to the deepest depth. In -addition for each location the corresponding longitude and latitude information -are provided. - -Dependence: -It depends on the pyfesom code (https://github.com/FESOM/pyfesom) - - -(C) Christian Rodehacke, AWI, 2017-07-12 - -Additional code for command line parsing: - Paul Gierz, AWI, May 7, 2018 -""" - -# -# Command Line Parser -# -import argparse -def parse_arguments(): - parser = argparse.ArgumentParser() - parser.add_argument("--FESOM_PATH", nargs="*", required=True) - parser.add_argument("--FESOM_VARIABLE", nargs="+") - parser.add_argument("--FESOM_MESH", nargs="+") - parser.add_argument("--FESOM_YEARS", nargs="+") - parser.add_argument("--FESOM_OUTPUT", nargs="*", default='fesom_output.nc4') - parser.add_argument("--FESOM_MESH_ROTATED", nargs="*", required=True) - #parser.add_argument("--FESOM_MESH_ALPHA", type=int, default=50) - #parser.add_argument("--FESOM_MESH_BETA", type=int, default=15) - #parser.add_argument("--FESOM_MESH_GAMMA", type=int, default=-90) - return parser.parse_args() - -args = parse_arguments() - -FESOMDATA_OUTPUT = 'fesom_output.nc4' -NAN_REPLACE = 9.96921e36 - -# ---------------------------------------------------------------- -# -# Import external libaries ... -# - -import sys -sys.path.append("./") -sys.path.append("./pyfesom") - -import pyfesom2 as pf -import numpy as np -from netCDF4 import Dataset, MFDataset -import time as time -import xarray as xr -import os - -# ---------------------------------------------------------------- -# -# Some information -# - -print('* Start at '+time.ctime(time.time())) - -# ---------------------------------------------------------------- -# -# Read input data -# -# mesh -print('* Read the mesh MESHPATH=' + " ".join(args.FESOM_MESH)) - -#euler_angle = [args.FESOM_MESH_ALPHA, args.FESOM_MESH_BETA, args.FESOM_MESH_GAMMA] -if not args.FESOM_MESH_ROTATED: - euler_angle = [50, 15, -90] -else: - euler_angle = [0, 0, 0] -print("* Using Euler angles ", euler_angle) - -mesh = pf.load_mesh(*args.FESOM_MESH, abg=euler_angle, usepickle=False) -print("*** mesh.zlev = ", mesh.zlev) - -# -# Oceanographic data -# -#print('* Read the data file args.FESOM_FILE=' + " ".join(args.FESOM_FILE)) -#FID = MFDataset(args.FESOM_PATH + "".join("/temp.fesom.*.01.nc")) -FID = xr.open_dataset(str(args.FESOM_PATH[0]) + str(args.FESOM_VARIABLE[0]) + ".fesom." + str(args.FESOM_YEARS[0]) + ".nc", decode_times=False) - -# ---------------------------------------------------------------- -# -# Initialize size and Preinitialize fields -# -# mesh.n2d = number of 2d nodes, mesh.e2d = number of 2d elements -no_hori_elemnt = mesh.n2d -#no_zlevels = mesh.nlev - 1 -no_zlevels = np.size(mesh.zlev) -#no_zlevels = np.size(mesh_diag.zbar) - -timedim = 'time' if 'time' in FID.dims else 'T' -no_timesteps = FID.dims[timedim] -print("no_timesteps: ", no_timesteps) -sizeVert = no_zlevels -sizeHori = no_hori_elemnt - -sizeFull = (no_timesteps, no_zlevels, no_hori_elemnt) -print("*** sizeFull = ", sizeFull) - -# Fields to write: allocate memory upfront -time_out = np.zeros(no_timesteps, dtype=np.float64) -depth_out = np.zeros(sizeVert, dtype=np.float64) -latitude_out = np.zeros(sizeHori, dtype=np.float64) -longitude_out = np.zeros(sizeHori, dtype=np.float64) -TempFields_out = np.zeros(sizeFull, dtype=np.float64) - -# ---------------------------------------------------------------- -# -# Loop through all depth levels -# -print('* Loop for each time step through all depth levels') - -# -# Depth axis -# -ilevel = -1 -#for depth in mesh_diag.zbar.squeeze().values: -for depth in mesh.zlev: - # Some information - idepth = int(depth) - # - # Prepare data for final netcdf output - # - ilevel = ilevel + 1 - print('* ilevel='+str(ilevel)+' depth='+str(idepth)+\ - ' ('+str(depth)+')') - depth_out[ilevel] = depth - -# -# Time axis -# -time_out = FID.variables['time'][0:no_timesteps] - -# -# Full hydrographic fields -# - -# -# Check shape of input file to process old (2D array) and new (3D array) FESOM files -# -for itime in np.arange(0, no_timesteps, 1, dtype=np.int32): - ##time_out[itime] = FID.variables['time'][itime] - time_read = time_out[itime] - # Some information - print('* TIME('+str(itime)+') = '+str(time_read)) - - ilevel = -1 - #for depth in mesh_diag.zbar.squeeze().values: - for depth in mesh.zlev[:-1]: - # Some information - idepth = int(depth) - print('* depth='+str(idepth)+' ('+str(depth)+\ - ') ++ time('+str(itime)+') = '+str(time_read)) - - # - # Prepare data for final netcdf output - # - ilevel = ilevel + 1 - - flag_verbose=False - - if args.FESOM_YEARS[0] == args.FESOM_YEARS[1]: - level_data = \ - pf.get_data(args.FESOM_PATH[0], args.FESOM_VARIABLE[0], int(args.FESOM_YEARS[0]), mesh, depth=idepth, how="mean") #, flag_verbose) - else: - level_data = \ - pf.get_data(args.FESOM_PATH[0], args.FESOM_VARIABLE[0], [int(args.FESOM_YEARS[0]), int(args.FESOM_YEARS[1])], mesh, depth=idepth, how="mean", use_cftime=True) #, flag_verbose) - level_data[np.where(np.isnan(level_data))] = NAN_REPLACE - TempFields_out[itime, ilevel, :] = level_data - - -# ---------------------------------------------------------------- -# -# Output file -# -print('* Create file "'+args.FESOM_OUTPUT[0]+'"') -#OK: OCE_OUT = Dataset("".join(args.FESOM_OUTPUT), "w", format="NETCDF3_64BIT_OFFSET") -#OCE_OUT = Dataset(args.FESOM_OUTPUT[0], "w", format="NETCDF4") #format="NETCDF3_64BIT_OFFSET") -OCE_OUT = Dataset(args.FESOM_OUTPUT[0], "w", format="NETCDF3_64BIT_OFFSET") #format="NETCDF3_64BIT_OFFSET") - -print('* Create dimensions and define variables') -# -# Create dimensions -# -OCE_OUT.createDimension("time", None) -OCE_OUT.createDimension("level", sizeVert) -OCE_OUT.createDimension("horizontal", no_hori_elemnt) -# -# Create global attributes -# -OCE_OUT.type = "FESOM_ocean_data" -OCE_OUT.title = "FESOM hydrographic ocean data" -OCE_OUT.model_domain = "Generic" -#OCE_OUT.data_input_file = args.FESOM_FILE -OCE_OUT.insitution = 'Alfred Wegener Institute for Polar and Marine Research (AWI)' -OCE_OUT.address = 'Handelshafen, Bremerhaven, Germany' -OCE_OUT.department = "Climate" -OCE_OUT.contact = 'Christian Rodehacke' -OCE_OUT.web = 'http://www.awi.de' -OCE_OUT.acknowledgment = 'ZUWEISS, BMWF, Germany' -OCE_OUT.history = "Created "+time.ctime(time.time()) - -# -# Create variables -# -# -- axis-variables -time_var = OCE_OUT.createVariable("time", "f4", ("time",)) -level_var = OCE_OUT.createVariable("level", "i4", ("level",)) -hori_var = OCE_OUT.createVariable("horizontal", "i4", ("horizontal",)) - -# -- common variables -depth_var = OCE_OUT.createVariable("depth", "f4", ("level",)) -lon_var = OCE_OUT.createVariable("longitude", "f4", ("horizontal",)) -lat_var = OCE_OUT.createVariable("latitude", "f4", ("horizontal",)) - -temp_var = OCE_OUT.createVariable(args.FESOM_VARIABLE[0], "f4", \ - ("time", "level", "horizontal",), fill_value=NAN_REPLACE) -# -# Attributes -# -time_var.long_name = "time" -time_var.axis = "T" -time_var.units = "" #FID.variables['time'].units #"hours since 0001-0101 0:0:0.0" -if hasattr(FID.variables['time'], 'calendar'): - time_var.calendar = FID.variables['time'].calendar #"standard" - -level_var.long_name = "model_level" -level_var.description = "Level number" -level_var.axis = "Z" - -hori_var.long_name = "horizontal_grid_id" -hori_var.description = "Number of horizontal grid element" -hori_var.axis = "X" - -depth_var.long_name = "depth" -depth_var.units = "m" -depth_var.description = "depth below sea level" -depth_var.positive = 'down' - -lon_var.long_name = "longitude" -lon_var.units = "degrees east" -lat_var.long_name = "latitude" -lat_var.units = "degrees north" - -temp_var.long_name = FID.get(args.FESOM_VARIABLE[0]).long_name -temp_var.units = FID.get(args.FESOM_VARIABLE[0]).units -temp_var.coordinates = "longitude latitude" -temp_var.description = "" #FID.variables[args.FESOM_VARIABLE[0]].description -#temp_var.missing_value = NAN_REPLACE - -# -# Write the data fields -# -print('* Write the small fields') -# -- axis variables -#time_var[:] = time_out -level_var[:] = np.arange(0, sizeVert, dtype=np.int32) -hori_var[:] = np.arange(0, sizeHori, dtype=np.int32) - -# -- common variables -depth_var[:] = mesh.zlev -#depth_var[:] = mesh_diag.zbar -lon_var[:] = mesh.x2 -lat_var[:] = mesh.y2 - -print('* Write the larger fields') -temp_var[:] = TempFields_out - -# -# close the files -# -OCE_OUT.close() - -# -# Bye bye -# -print('End at '+time.ctime(time.time())) -print(" ... Bye") diff --git a/couplings/coupling_dual-hemisphere/utils/fesom_to_regular_grid.py b/couplings/coupling_dual-hemisphere/utils/fesom_to_regular_grid.py deleted file mode 100755 index 6778a8e9a..000000000 --- a/couplings/coupling_dual-hemisphere/utils/fesom_to_regular_grid.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python3 - -import argparse, os, sys -import netCDF4 as nc -import numpy as np - -import pyfesom2 as pf -from pyfesom2 import load_mesh, get_data - -def read_data(finname, var): - with nc.Dataset(finname,'r') as fin: - data = fin.variables[var] - # print(data.dimensions) - # print("nz1" in data.dimensions) - # print(len(data.dimensions) == 3) - # print(data.dimensions != ('time', 'nod2', 'nz1')) - ndim = len(data.dimensions) - # check - if ndim == 3 : - print("Read var >>",var,"<< with the dims:") - if data.dimensions == ('time', 'nod2', 'nz1'): - print(data.dimensions) - levdim = 2 - elif data.dimensions == ('time', 'nz1', 'nod2'): - print(data.dimensions) - levdim = 1 - else: - raise ValueError('dimension is not (time nod2 nz1) or (time nz1 nod2)') - - elif ndim == 2: - print("Read var:",var," with the dims:") - print(data.dimensions) - if data.dimensions != ('time', 'nod2'): - raise ValueError('dimension is not (time nod2)') - - levdim = -1 - - data1 = fin.variables[var][:] - return data1, ndim, levdim - - -def function_FESOM2ice_regular_grid( - version_FESOM=2, - meshpath = 'path', abg=[50, 15, -90], - fin='./', - fout='FESOM_for_ice.nc', - depthmax=500., depthmin=300.,): - - if (version_FESOM >= 2) and (version_FESOM < 3) : - print("version:", version_FESOM) - else: - raise ValueError('!!!!! only support for Fesom 2x now, stop !!!!!') - - ####################################### - # predefined var names and time info - varnames = ['temp', 'salt' ] - varnamesout = ['temp', 'salt' ] # fixed names for output file , do not edit - units = ['degC', 'psu'] - unitsout = ['degC', 'g/kg'] # fixed names for output file , do not edit - missingvalue = [0,33.] - nvar = len(varnames) - # - - finname = fin - foutname = fout - depth_range = [depthmin, depthmax] - nlon = 1440 - nlat = 720 - ####################################### - - mesh = pf.load_mesh(meshpath,abg=abg, usepickle=False) - - # get the depth information - if depth_range is None: - depths = mesh.zlev[:-1] - else: - idx = (np.abs(mesh.zlev) >= depth_range[0]) & (np.abs(mesh.zlev) <= depth_range[1]) - depths = mesh.zlev[idx] - - nlev = len(depths) - - # the new regular grids: - lon = np.linspace(-180, 180, nlon) - lat = np.linspace(-90, 90, nlat) - lons, lats = np.meshgrid(lon,lat) - - - # read the time dim: - fin = nc.Dataset(finname,'r') - timein = fin.variables['time'] - ntime = len(timein) - - - # write data - with nc.Dataset(foutname, 'w') as fout: - fout.createDimension('lat', nlat) - latout = fout.createVariable('lat',np.float32, ('lat',)) - latout.units = 'degree_north' - latout.standard_name = 'latitude' - latout[:] = lat - - fout.createDimension('lon', nlon) - lonout = fout.createVariable('lon',np.float32,('lon',)) - lonout.units = 'degree_east' - lonout.standard_name = 'longitude' - lonout[:] = lon - - fout.createDimension('time', None) - timeout = fout.createVariable('time',np.float32,('time',)) - # timeout.setncatts(timein.__dict__) - timeout.standard_name = "time" - timeout.units = "years since 01-01-01 00:00:00" - timeout.calendar = "365_day" - timeout.axis = "T" - - - fout.createDimension('level', None) - levout = fout.createVariable('level',np.float32,('level',)) - levout.units = 'm' - - - fout.description = 'interpolated fesom2.0 data' - - for i in range(nvar): - thevar = varnames[i] - print(">>>>>>>>>> processing >>> ",thevar) - # read data - data, ndim, levdim = read_data(finname, thevar) - print("data.shape, ndim, levdim:") - print(data.shape, ndim, levdim) - - varout = fout.createVariable(thevar,np.float32,('time','level','lat','lon')) - varout.units = unitsout[i] - - for it in range(0,ntime): - print("> time step ", it) - if ndim == 3: - levout[:] = depths - for iz in range(0,nlev): - ilev = pf.ind_for_depth(depths[iz], mesh) - print("> level:", depths[iz]) - if levdim == 2: - level_data = data[it, :, ilev] - elif levdim == 1: - level_data = data[it, ilev, :] - else: - raise ValueError('Something wrong with data!') - - level_data[level_data==0] = np.nan - #idist_fast = pf.fesom2regular(level_data, mesh, lons, lats, how='idist', k=20) - idist_fast = pf.fesom2regular(level_data, mesh, lons, lats ) - new = np.where(np.isnan(idist_fast), missingvalue[i], idist_fast) - varout[it,iz,:,:] = new - - elif ndim == 2: - levout[:] = 0. # meter - print("> surface") - level_data = data[it, :] - idist_fast = pf.fesom2regular(level_data, mesh, lons, lats ) - new = np.where(np.isnan(idist_fast), missingvalue[i], idist_fast) - varout[it,0,:,:] = new - - # close input data - fin.close() - return - -#### defination: -parser = argparse.ArgumentParser(description='Input options') -parser.add_argument("-meshpath", type=str, help='FESOM mesh path') -parser.add_argument("-datain", type=str, help='FESOM data path') -parser.add_argument("-dataout", type=str, help='FESOM output data path') - - - -arguments = parser.parse_args() -print(arguments) - -meshpath = arguments.meshpath -datain = arguments.datain -dataout = arguments.dataout - - -depthmax = os.getenv('OCEAN_depthmax', 300.) -print('... OCEAN depthmax:', depthmax ) - -depthmin = os.getenv('OCEAN_depthmin', 150.) -print('... OCEAN depthmin:', depthmin ) - -a = os.getenv('OCEAN_meshalpha', 0.) -print('... OCEAN meshalpha:', a ) - -b = os.getenv('OCEAN_meshbeta', 0.) -print('... OCEAN meshbeta:', b) - -g = os.getenv('OCEAN_meshgamma', 0.) -print('... OCEAN meshgamma:', g ) - -version = 2. - - -function_FESOM2ice_regular_grid( - version_FESOM=version, - meshpath = meshpath, abg=[a, b, g], - fin=datain, - fout=dataout, - depthmax=depthmax, depthmin=depthmin,) diff --git a/couplings/coupling_dual-hemisphere/utils/gfw_atmo_constant_zero.nc b/couplings/coupling_dual-hemisphere/utils/gfw_atmo_constant_zero.nc deleted file mode 100644 index 7fb599dc7..000000000 Binary files a/couplings/coupling_dual-hemisphere/utils/gfw_atmo_constant_zero.nc and /dev/null differ diff --git a/couplings/coupling_dual-hemisphere/utils/grid_noro.f90 b/couplings/coupling_dual-hemisphere/utils/grid_noro.f90 deleted file mode 100644 index 1a487f596..000000000 --- a/couplings/coupling_dual-hemisphere/utils/grid_noro.f90 +++ /dev/null @@ -1,639 +0,0 @@ -SUBROUTINE grid_noro(imdep, jmdep, xdata, ydata, zdata, & - imar, jmar, x, y, & - zphi,zmea,zstd,zsig,zgam,zthe, & - zpic,zval,mask) - !======================================================================= - ! (F. Lott) (voir aussi z.x. Li, A. Harzallah et L. Fairhead) - ! - ! Compute the Parameters of the SSO scheme as described in - ! LOTT & MILLER (1997) and LOTT(1999). - ! Target points are on a imarxjmar grid. - ! At the poles (if any) the fields value is repeated - ! jmar time. - ! The parameters a,b,c,d represent the limite of the target - ! gridpoint region. The means over this region are calculated - ! from USN data, ponderated by a weight proportional to the - ! surface occupated by the data inside the model gridpoint area. - ! In most circumstances, this weight is the ratio between the - ! surface of the USN gridpoint area and the surface of the - ! model gridpoint area. - ! - ! (c) - ! ----d----- - ! | . . . .| - ! | | - ! (b)a . * . .b(a) - ! | | - ! | . . . .| - ! ----c----- - ! (d) - !======================================================================= - ! INPUT: - ! imdep, jmdep: dimensions X and Y input field - ! xdata, ydata: coordinates X and Y input field - ! zdata: Input field - ! In this version it is assumed that the entry data come from - ! the USNavy dataset: imdep=iusn=2160, jmdep=jusn=1080. - ! OUTPUT: - ! imar, jmar: dimensions X and Y Output field - ! x, y: ccordinates X and Y Output field. - ! zmea: Mean orographie - ! zstd: Standard deviation - ! zsig: Slope - ! zgam: Anisotropy - ! zthe: Orientation of the small axis - ! zpic: Maximum altitude - ! zval: Minimum altitude - !======================================================================= - - - IMPLICIT INTEGER (i,j) - IMPLICIT REAL(x,z) - - PARAMETER(iext=216) - - !#include "dimensions.h" - - - REAL xusn(imdep+2*iext),yusn(jmdep+2) - REAL zusn(imdep+2*iext,jmdep+2) - - INTEGER imdep, jmdep - REAL xdata(imdep),ydata(jmdep) - REAL zdata(imdep,jmdep) - ! - INTEGER imar, jmar - - ! INTERMEDIATE FIELDS (CORRELATIONS OF OROGRAPHY GRADIENT) - - REAL ztz(imar,jmar),zxtzx(imar,jmar) - REAL zytzy(imar,jmar),zxtzy(imar,jmar) - REAL weight(imar,jmar) - REAL num_tot(imar,jmar),num_lan(imar,jmar) - - ! CORRELATIONS OF USN OROGRAPHY GRADIENTS - - REAL zxtzxusn(imdep+2*iext,jmdep+2),zytzyusn(imdep+2*iext,jmdep+2) - REAL zxtzyusn(imdep+2*iext,jmdep+2) - REAL x(imar),y(jmar),zphi(imar,jmar) - ! INPUT FIELDS - REAL zmea(imar,jmar),zstd(imar,jmar) - REAL zsig(imar,jmar),zgam(imar,jmar),zthe(imar,jmar) - REAL zpic(imar,jmar),zval(imar,jmar) - INTEGER mask(imar,jmar) - ! - REAL a(imar),b(imar),c(jmar),d(jmar) - INTEGER ia(imar),ib(imar),ic(jmar),id(jmar) - ! - PRINT *,' Subgrid Scale Orography Parameters' - xpi=ACOS(-1.) - rad = 6371229. - zdeltay=2.*xpi/REAL(jmdep)*rad - - ! print *,'xdata:',xdata - ! print *,'ydata:',ydata - ! print *,'x:',x - ! print *,'y:',y - ! - ! EXTENSION OF THE USN DATABASE TO POCEED COMPUTATIONS AT - ! BOUNDARIES: - ! - - CALL data_treat(zdata,xdata,ydata,imdep,jmdep) - - - DO j=1,jmdep - yusn(j+1)=ydata(j) - DO i=1,imdep - zusn(i+iext,j+1)=zdata(i,j) - xusn(i+iext)=xdata(i) - ENDDO - DO i=1,iext - zusn(i,j+1)=zdata(imdep-iext+i,j) - xusn(i)=xdata(imdep-iext+i)-2.*xpi - zusn(imdep+iext+i,j+1)=zdata(i,j) - xusn(imdep+iext+i)=xdata(i)+2.*xpi - ENDDO - ENDDO - - yusn(1)=ydata(1)+(ydata(1)-ydata(2)) - yusn(jmdep+2)=ydata(jmdep)+(ydata(jmdep)-ydata(jmdep-1)) - DO i=1,imdep/2+iext - zusn(i,1)=zusn(i+imdep/2,2) - zusn(i+imdep/2+iext,1)=zusn(i,2) - zusn(i,jmdep+2)=zusn(i+imdep/2,jmdep+1) - zusn(i+imdep/2+iext,jmdep+2)=zusn(i,jmdep+1) - ENDDO - ! - ! COMPUTE LIMITS OF MODEL GRIDPOINT AREA - ! ( REGULAR GRID) - ! - a(1) = x(1) - (x(2)-x(1))/2.0 - b(1) = (x(1)+x(2))/2.0 - DO i = 2, imar-1 - a(i) = b(i-1) - b(i) = (x(i)+x(i+1))/2.0 - ENDDO - a(imar) = b(imar-1) - b(imar) = x(imar) + (x(imar)-x(imar-1))/2.0 - - IF(y(2) <= y(1))THEN - c(1) = y(1) - (y(2)-y(1))/2.0 - d(1) = (y(1)+y(2))/2.0 - DO j = 2, jmar-1 - c(j) = d(j-1) - d(j) = (y(j)+y(j+1))/2.0 - ENDDO - c(jmar) = d(jmar-1) - d(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0 - ELSE - c(1) = (y(1)+y(2))/2.0 - d(1) = y(1) - (y(2)-y(1))/2.0 - DO j = 2, jmar-1 - d(j) = c(j-1) - c(j) = (y(j)+y(j+1))/2.0 - ENDDO - d(jmar)=c(jmar-1) - c(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0 - ENDIF - - DO ii=1,imar - DO i=2,imdep+2*iext-1 - IF(a(ii) >= xusn(i-1).AND.a(ii) < xusn(i))ia(ii)=i-1 - IF(b(ii) > xusn(i).AND.b(ii) <= xusn(i+1))ib(ii)=i+1 - ENDDO - ENDDO - DO jj=1,jmar - DO j=2,jmdep+1 - IF(c(jj) >= yusn(j).AND.c(jj) < yusn(j-1))ic(jj)=j-1 - IF(d(jj) > yusn(j+1).AND.d(jj) <= yusn(j))id(jj)=j+1 - ENDDO - ENDDO - - ! - ! initialisations: - ! - DO i = 1, imar - DO j = 1, jmar - weight(i,j) = 0.0 - zxtzx(i,j) = 0.0 - zytzy(i,j) = 0.0 - zxtzy(i,j) = 0.0 - ztz(i,j) = 0.0 - zmea(i,j) = 0.0 - zpic(i,j) =-1.e+10 - zval(i,j) = 1.e+10 - ENDDO - ENDDO - ! - ! COMPUTE SLOPES CORRELATIONS ON USN GRID - ! - DO j = 1,jmdep+2 - DO i = 1, imdep+2*iext - zytzyusn(i,j)=0.0 - zxtzxusn(i,j)=0.0 - zxtzyusn(i,j)=0.0 - ENDDO - ENDDO - - - DO j = 2,jmdep+1 - zdeltax=zdeltay*COS(yusn(j)) - DO i = 2, imdep+2*iext-1 - zytzyusn(i,j)=(zusn(i,j+1)-zusn(i,j-1))**2/zdeltay**2 - zxtzxusn(i,j)=(zusn(i+1,j)-zusn(i-1,j))**2/zdeltax**2 - zxtzyusn(i,j)=(zusn(i,j+1)-zusn(i,j-1))/zdeltay & - *(zusn(i+1,j)-zusn(i-1,j))/zdeltax - ENDDO - ENDDO - ! - ! SUMMATION OVER GRIDPOINT AREA - ! - zleny=xpi/REAL(jmdep)*rad - xincr=xpi/2./REAL(jmdep) - DO ii = 1, imar - DO jj = 1, jmar - num_tot(ii,jj)=0. - num_lan(ii,jj)=0. - ! PRINT *,' iteration ii jj:',ii,jj - DO j = ic(jj),id(jj) - zlenx=zleny*COS(yusn(j)) - zdeltax=zdeltay*COS(yusn(j)) - zbordnor=(c(jj)-yusn(j)+xincr)*rad - zbordsud=(yusn(j)-d(jj)+xincr)*rad - weighy=MAX(0.,MIN(zbordnor,zbordsud,zleny)) - DO i = ia(ii),ib(ii) - zbordest=(xusn(i)-a(ii)+xincr)*rad*COS(yusn(j)) - zbordoue=(b(ii)+xincr-xusn(i))*rad*COS(yusn(j)) - weighx=MAX(0.,MIN(zbordest,zbordoue,zlenx)) - num_tot(ii,jj)=num_tot(ii,jj)+1.0 - IF(zusn(i,j) >= 1.)num_lan(ii,jj)=num_lan(ii,jj)+1.0 - weight(ii,jj)=weight(ii,jj)+weighx*weighy - zxtzx(ii,jj)=zxtzx(ii,jj)+zxtzxusn(i,j)*weighx*weighy - zytzy(ii,jj)=zytzy(ii,jj)+zytzyusn(i,j)*weighx*weighy - zxtzy(ii,jj)=zxtzy(ii,jj)+zxtzyusn(i,j)*weighx*weighy - ztz(ii,jj) =ztz(ii,jj) +zusn(i,j)*zusn(i,j)*weighx*weighy - ! mean - zmea(ii,jj) =zmea(ii,jj)+zusn(i,j)*weighx*weighy - ! peacks - zpic(ii,jj)=MAX(zpic(ii,jj),zusn(i,j)) - ! valleys - zval(ii,jj)=MIN(zval(ii,jj),zusn(i,j)) - ENDDO - ENDDO - ENDDO - ENDDO - ! - ! COMPUTE PARAMETERS NEEDED BY THE LOTT & MILLER (1997) AND - ! LOTT (1999) SSO SCHEME. - ! - zllmmea=0. - zllmstd=0. - zllmsig=0. - zllmgam=0. - zllmpic=0. - zllmval=0. - zllmthe=0. - zminthe=0. - ! print 100,' ' - !100 format(1X,A1,'II JJ',4X,'H',8X,'SD',8X,'SI',3X,'GA',3X,'TH') - DO ii = 1, imar - DO jj = 1, jmar - IF (weight(ii,jj) /= 0.0) THEN - ! Mask - IF(num_lan(ii,jj)/num_tot(ii,jj) >= 0.5)THEN - mask(ii,jj)=1 - ELSE - mask(ii,jj)=0 - ENDIF - ! Mean Orography: - zmea (ii,jj)=zmea (ii,jj)/weight(ii,jj) - zxtzx(ii,jj)=zxtzx(ii,jj)/weight(ii,jj) - zytzy(ii,jj)=zytzy(ii,jj)/weight(ii,jj) - zxtzy(ii,jj)=zxtzy(ii,jj)/weight(ii,jj) - ztz(ii,jj) =ztz(ii,jj)/weight(ii,jj) - ! Standard deviation: - zstd(ii,jj)=SQRT(MAX(0.,ztz(ii,jj)-zmea(ii,jj)**2)) - ELSE - PRINT*, 'probleme,ii,jj=', ii,jj - ENDIF - ENDDO - ENDDO - - ! CORRECT VALUES OF HORIZONTAL SLOPES NEAR THE POLES: - - IF(y(jmar) <= -89.95.OR.y(jmar) >= 89.95)THEN - - DO ii = 1, imar - zxtzx(ii,1)=zxtzx(ii,2) - zxtzx(ii,jmar)=zxtzx(ii,jmar-1) - zxtzy(ii,1)=zxtzy(ii,2) - zxtzy(ii,jmar)=zxtzy(ii,jmar-1) - zytzy(ii,1)=zytzy(ii,2) - zytzy(ii,jmar)=zytzy(ii,jmar-1) - ENDDO - - ENDIF - - ! FILTERS TO SMOOTH OUT FIELDS FOR INPUT INTO SSO SCHEME. - - ! FIRST FILTER, MOVING AVERAGE OVER 9 POINTS. - - CALL mva9(zmea,imar,jmar) - CALL mva9(zstd,imar,jmar) - CALL mva9(zpic,imar,jmar) - CALL mva9(zval,imar,jmar) - CALL mva9(zxtzx,imar,jmar) - CALL mva9(zxtzy,imar,jmar) - CALL mva9(zytzy,imar,jmar) - - ! SECOND FILTER FOR SLOPES, MASK AND UNIFORM HORIS RESOLUTION - - DO ii = 1, imar - DO jj = 1, jmar - zxtzx(ii,jj)=zxtzx(ii,jj)*mask(ii,jj) - zxtzy(ii,jj)=zxtzy(ii,jj)*mask(ii,jj) - zytzy(ii,jj)=zytzy(ii,jj)*mask(ii,jj) - ENDDO - ENDDO - - CALL uni_res(zxtzx,y,imar,jmar) - CALL uni_res(zxtzy,y,imar,jmar) - CALL uni_res(zytzy,y,imar,jmar) - - - DO ii = 1, imar - DO jj = 1, jmar - IF (weight(ii,jj) /= 0.0) THEN - ! Coefficients K, L et M: - xk=(zxtzx(ii,jj)+zytzy(ii,jj))/2. - xl=(zxtzx(ii,jj)-zytzy(ii,jj))/2. - xm=zxtzy(ii,jj) - xp=xk-SQRT(xl**2+xm**2) - xq=xk+SQRT(xl**2+xm**2) - xw=1.e-8 - IF(xp <= xw) xp=0. - IF(xq <= xw) xq=xw - IF(ABS(xm) <= xw) xm=xw*SIGN(1.,xm) - ! slope: - zsig(ii,jj)=SQRT(xq)*mask(ii,jj) - ! isotropy: - zgam(ii,jj)=xp/xq*mask(ii,jj) - ! angle theta: - zthe(ii,jj)=57.29577951*ATAN2(xm,xl)/2.*mask(ii,jj) - zphi(ii,jj)=zmea(ii,jj)*mask(ii,jj) - zmea(ii,jj)=zmea(ii,jj)*mask(ii,jj) - zpic(ii,jj)=zpic(ii,jj)*mask(ii,jj) - zval(ii,jj)=zval(ii,jj)*mask(ii,jj) - zstd(ii,jj)=zstd(ii,jj)*mask(ii,jj) - - ! print 101,ii,jj, - ! * zmea(ii,jj),zstd(ii,jj),zsig(ii,jj),zgam(ii,jj), - ! * zthe(ii,jj) - !101 format(1x,2(1x,i2),2(1x,f7.1),1x,f7.4,2x,f4.2,1x,f5.1) - ELSE - ! PRINT*, 'probleme,ii,jj=', ii,jj - ENDIF - zllmmea=MAX(zmea(ii,jj),zllmmea) - zllmstd=MAX(zstd(ii,jj),zllmstd) - zllmsig=MAX(zsig(ii,jj),zllmsig) - zllmgam=MAX(zgam(ii,jj),zllmgam) - zllmthe=MAX(zthe(ii,jj),zllmthe) - zminthe=MIN(zthe(ii,jj),zminthe) - zllmpic=MAX(zpic(ii,jj),zllmpic) - zllmval=MAX(zval(ii,jj),zllmval) - ENDDO - ENDDO - - PRINT *,' MEAN ORO: ',zllmmea - PRINT *,' ST. DEV.: ',zllmstd - PRINT *,' PENTE: ',zllmsig - PRINT *,' ANISOTROP: ',zllmgam - PRINT *,' ANGLE: ',zminthe,zllmthe - PRINT *,' pic: ',zllmpic - PRINT *,' val: ',zllmval - - ! ENSURE PERIODICITY AT HORIZONTAL GRID END - - IF(xdata(imar) >= xdata(1)+2.*xpi-0.001)THEN - DO jj=1,jmar - zmea(imar,jj)=zmea(1,jj) - zpic(imar,jj)=zpic(1,jj) - zval(imar,jj)=zval(1,jj) - zstd(imar,jj)=zstd(1,jj) - zsig(imar,jj)=zsig(1,jj) - zgam(imar,jj)=zgam(1,jj) - zthe(imar,jj)=zthe(1,jj) - ENDDO - ENDIF - - ! - ! VALUES AT THE POLE (IF THERE ARE POLES - ! ON THE GRID CONSIDERED) - ! gamma and theta a 1. and 0. at poles - ! - IF(ydata(1) <= -xpi/2+0.01.OR.ydata(1) >= xpi/2-0.01)THEN - zmeanor=0.0 - zmeasud=0.0 - zstdnor=0.0 - zstdsud=0.0 - zsignor=0.0 - zsigsud=0.0 - zweinor=0.0 - zweisud=0.0 - zpicnor=0.0 - zpicsud=0.0 - zvalnor=0.0 - zvalsud=0.0 - - DO ii=1,imar - zweinor=zweinor+ weight(ii, 1) - zweisud=zweisud+ weight(ii,jmar) - zmeanor=zmeanor+zmea(ii, 1)*weight(ii, 1) - zmeasud=zmeasud+zmea(ii,jmar)*weight(ii,jmar) - zstdnor=zstdnor+zstd(ii, 1)*weight(ii, 1) - zstdsud=zstdsud+zstd(ii,jmar)*weight(ii,jmar) - zsignor=zsignor+zsig(ii, 1)*weight(ii, 1) - zsigsud=zsigsud+zsig(ii,jmar)*weight(ii,jmar) - zpicnor=zpicnor+zpic(ii, 1)*weight(ii, 1) - zpicsud=zpicsud+zpic(ii,jmar)*weight(ii,jmar) - zvalnor=zvalnor+zval(ii, 1)*weight(ii, 1) - zvalsud=zvalsud+zval(ii,jmar)*weight(ii,jmar) - ENDDO - - DO ii=1,imar - zmea(ii, 1)=zmeanor/zweinor - zmea(ii,jmar)=zmeasud/zweisud - zphi(ii, 1)=zmeanor/zweinor - zphi(ii,jmar)=zmeasud/zweisud - zpic(ii, 1)=zpicnor/zweinor - zpic(ii,jmar)=zpicsud/zweisud - zval(ii, 1)=zvalnor/zweinor - zval(ii,jmar)=zvalsud/zweisud - zstd(ii, 1)=zstdnor/zweinor - zstd(ii,jmar)=zstdsud/zweisud - zsig(ii, 1)=zsignor/zweinor - zsig(ii,jmar)=zsigsud/zweisud - zgam(ii, 1)=1. - zgam(ii,jmar)=1. - zthe(ii, 1)=0. - zthe(ii,jmar)=0. - ENDDO - - ENDIF - - RETURN -END SUBROUTINE grid_noro - -SUBROUTINE mva9(x,imar,jmar) - - ! MAKE A MOVING AVERAGE OVER 9 GRIDPOINTS OF THE X FIELDS - - REAL x(imar,jmar),xf(imar,jmar) - REAL weight(-1:1,-1:1) - - - sum=0. - DO is=-1,1 - DO js=-1,1 - weight(is,js)=1./REAL((1+is**2)*(1+js**2)) - sum=sum+weight(is,js) - ENDDO - ENDDO - - DO is=-1,1 - DO js=-1,1 - weight(is,js)=weight(is,js)/sum - ENDDO - ENDDO - - DO j=2,jmar-1 - DO i=2,imar-1 - xf(i,j)=0. - DO is=-1,1 - DO js=-1,1 - xf(i,j)=xf(i,j)+x(i+is,j+js)*weight(is,js) - ENDDO - ENDDO - ENDDO - ENDDO - - DO j=2,jmar-1 - xf(1,j)=0. - is=imar-1 - DO js=-1,1 - xf(1,j)=xf(1,j)+x(is,j+js)*weight(-1,js) - ENDDO - DO is=0,1 - DO js=-1,1 - xf(1,j)=xf(1,j)+x(1+is,j+js)*weight(is,js) - ENDDO - ENDDO - xf(imar,j)=xf(1,j) - ENDDO - - DO i=1,imar - xf(i,1)=xf(i,2) - xf(i,jmar)=xf(i,jmar-1) - ENDDO - - DO i=1,imar - DO j=1,jmar - x(i,j)=xf(i,j) - ENDDO - ENDDO - - RETURN -END SUBROUTINE mva9 - -SUBROUTINE uni_res(xfield,ylat,imar,jmar) - - ! MAKE A MOVING AVERAGE OVER LONGITUDE POINTS - ! TO UNIFORMIZE THE HORIZONTAL RESOLUTION - - REAL xfield(imar,jmar),xfilt(-imar:2*imar,jmar) - REAL ylat(jmar) - - - DO j=1,jmar - DO i=1,imar - xfilt(i+imar,j) = xfield(i,j) - xfilt(i-imar,j) = xfield(i,j) - xfilt(i ,j) = xfield(i,j) - ENDDO - ENDDO - - DO j=2,jmar-1 - ism=1./COS(ylat(j)) - !f77 ism=MIN(ism,imar-1) - ism=MIN(ism,imar-1) - DO i=1,imar - xfield(i,j)=0. - DO is=-ism,ism - xfield(i,j)=xfield(i,j)+xfilt(i+is,j)/REAL(2*ism+1) - ENDDO - ENDDO - ENDDO - - ! POLES TREATMENT FOR SLOPES - - IF(COS(ylat(1)) == 0)THEN - DO i=1,imar - xfield(i,1) =0. - DO ii=1,imar - xfield(i,1) =xfield(i,1)+xfilt(ii,1)/REAL(imar) - ENDDO - ENDDO - ELSE - ism=1./COS(ylat(1)) - !f77 ism=MIN(ism,imar-1) - ism=MIN(ism,imar-1) - DO i=1,imar - xfield(i,1) =0. - DO is=-ism,ism - xfield(i,1)=xfield(i,1)+xfilt(i+is,1)/REAL(2*ism+1) - ENDDO - ENDDO - ENDIF - - IF(COS(ylat(jmar)) == 0)THEN - DO i=1,imar - xfield(i,jmar)=0. - DO ii=1,imar - xfield(i,jmar)=xfield(i,jmar)+xfilt(ii,jmar)/REAL(imar) - ENDDO - ENDDO - ELSE - ism=1./COS(ylat(jmar)) - !f77 ism=MIN(ism,imar-1) - ism=MIN(ism,imar-1) - DO i=1,imar - xfield(i,jmar) =0. - DO is=-ism,ism - xfield(i,jmar)=xfield(i,jmar)+xfilt(i+is,jmar)/REAL(2*ism+1) - ENDDO - ENDDO - ENDIF - - RETURN -END SUBROUTINE uni_res - -SUBROUTINE data_treat(zdata,xdata,ydata,imdep,jmdep) - PARAMETER(iwork=3000,jwork=1500) - REAL zdata(imdep,jmdep),xdata(imdep),ydata(jmdep) - REAL zwork(-iwork:2*iwork,jwork),xwork(-iwork:2*iwork) - REAL xscale(jwork) - INTEGER iscale(jwork) - - IF(iwork < imdep.OR.jwork < jmdep) THEN - WRITE (*,*) 'data_treat: iwork = ', iwork, ' imdep= ', imdep - WRITE (*,*) ' jwork = ', jwork, ' jmdep= ', jmdep - STOP 'iwork < imdep.OR.jwork < jmdep' - END IF - - pi=ACOS(-1.) - DO i=1,imdep - xwork(i)=xdata(i) - xwork(i-imdep)=xdata(i)-2.*pi - xwork(i+imdep)=xdata(i)+2.*pi - DO j=1,jmdep - zwork(i ,j)=zdata(i,j) - zwork(i-imdep,j)=zdata(i,j) - zwork(i+imdep,j)=zdata(i,j) - ENDDO - ENDDO - - xincr=(xdata(2)-xdata(1))/2. - DO j=1,jmdep - xscale(j)=1./ABS(COS(ydata(j)))*xincr - !f77 iscale(j)=MIN(1./ABS(COS(ydata(j))),imdep) - iscale(j)=1./ABS(COS(ydata(j))) - iscale(j)=MIN(iscale(j),imdep) - ! print *,j,iscale(j) - DO i=1,imdep - zdata(i,j)=0. - weight=0. - zlan=0. - ztot=0. - DO is=-iscale(j),iscale(j) - weig = MIN(2.*xincr, & - MAX(xwork(i+is)+xincr-xwork(i)+xscale(j),0.), & - MAX(xwork(i)+xscale(j)-xwork(i+is)+xincr,0.)) - IF(weig > 0.)THEN - ztot=ztot+1. - IF(zwork(i+is,j) >= 1.)zlan=zlan+1. - weight=weight+weig - zdata(i,j)=zdata(i,j)+zwork(i+is,j)*weig - ENDIF - ENDDO - IF(zlan/ztot >= 0.5)THEN - zdata(i,j)=zdata(i,j)/weight - ELSE - zdata(i,j)=0. - ENDIF - ENDDO - ENDDO - - - RETURN -END SUBROUTINE data_treat diff --git a/couplings/coupling_dual-hemisphere/utils/icb_apply_distribution.py b/couplings/coupling_dual-hemisphere/utils/icb_apply_distribution.py deleted file mode 100644 index b52f4f584..000000000 --- a/couplings/coupling_dual-hemisphere/utils/icb_apply_distribution.py +++ /dev/null @@ -1,359 +0,0 @@ -import random -import numpy as np -import numexpr as ne -import xarray as xr -import pandas as pd -import sys -import os -from tqdm import tqdm -from datetime import datetime - -RES_pism = 5 -rho_ice = 910 -height_icb = 250 - -N_min = 0 -N_max = 10000 - -#Nlength = np.array([5000, 500, 100, 50, 20, 10, 5, 2, 1]) #icb_scaled20 -Nlength = np.array([5000, 500, 100, 50, 20, 10, 1, 1, 1]) #icb_scaled21 -#Nlength = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1]) -#sdepth = np.array([40, 67, 133, 175, 250, 250, 250, 250, 250]) * 7/8 -sdepth = np.array([height_icb]*9) -print("sdepth = ", sdepth) -slength_bins = np.array([0, 100, 200, 350, 500, 700, 900, 1200, 1600, 2200]) -svol_bins = np.multiply(slength_bins, slength_bins) * height_icb -print("svol_bins = ", svol_bins) - -mu_length = 250 -trunc_length=0 - -vol_trunc=10e6 #trunc_length**3*16/21 -pism_trunc_fkt=-vol_trunc/(RES_pism*RES_pism*10e6/rho_ice) - -xs = [] -ys = [] -length = [] - -random.seed() - -ifile = sys.argv[1] -mesh_path = sys.argv[2] -icb_path = sys.argv[3] - -nod2d_file = os.path.join(mesh_path, "nod2d.out") -elem2d_file = os.path.join(mesh_path, "elem2d.out") - -#read PISM file -def read_pism_file(ifile): - fl = xr.open_dataset(ifile).squeeze() - - data = fl.tendency_of_ice_amount_due_to_discharge.where(fl.tendency_of_ice_amount_due_to_discharge < pism_trunc_fkt*N_min) - data.to_netcdf(os.path.join(icb_path, "icb_mask.nc")) - #data = fl.discharge_flux_cumulative.where(fl.discharge_flux_cumulative < 0, drop=True) - data = np.array(data).reshape(1, len(data.x)*len(data.y)) - data = data[~np.isnan(data)] - - lon_bnds = fl.lon_bnds.where(fl.tendency_of_ice_amount_due_to_discharge < pism_trunc_fkt*N_min, drop=True) - #lon_bnds = fl.lon_bnds.where(fl.discharge_flux_cumulative < 0, drop=True) - lon_bnds = np.array(lon_bnds).reshape(len(lon_bnds.x)*len(lon_bnds.y), 4) - lon_bnds = lon_bnds[~np.isnan(lon_bnds)] - lon_bnds = lon_bnds.reshape(int(len(lon_bnds)/4), 4) - - lat_bnds = fl.lat_bnds.where(fl.tendency_of_ice_amount_due_to_discharge < pism_trunc_fkt*N_min, drop=True) - #lat_bnds = fl.lat_bnds.where(fl.discharge_flux_cumulative < 0, drop=True) - lat_bnds = np.array(lat_bnds).reshape(len(lat_bnds.x)*len(lat_bnds.y), 4) - lat_bnds = lat_bnds[~np.isnan(lat_bnds)] - lat_bnds = lat_bnds.reshape(int(len(lat_bnds)/4), 4) - - lons = [] - lats = [] - - for x, y in zip(lon_bnds, lat_bnds): - lons.append(np.mean(x)) - lats.append(np.mean(y)) - - return [data, lons, lats] - - -class point: - def __init__(self, x, y): - self.x = x - self.y = y - def to_dict(self): - return {'x': self.x, 'y': self.y} - - -# https://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle -def sign(p1, p2, p3): - return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y) - -def PointInTriangle(pt, v1, v2, v3): - d1 = sign(pt, v1, v2) - d2 = sign(pt, v2, v3) - d3 = sign(pt, v3, v1) - - has_neg = (d1 < 0) or (d2 < 0) or (d3 < 0) - has_pos = (d1 > 0) or (d2 > 0) or (d3 > 0) - - return not (has_neg and has_pos) - - - - -#generate icebergs -def icb_generator(vals, ps1, ps2, ps3, icb_path, rho_ice=910, res_pism=5): - #mu, sigma = mu_length**3*16/21/10e6, 1.2 - mu, sigma = mu_length**2*height_icb/10e6, 1.2 - - points = [] - #depth=length/1.5 - height = [] #height=depth*8/7=length*8/7*2/3=length*16/21 - scaling_tmp = 1 - - with tqdm(total=len(vals), file=sys.stdout, desc='create icebergs') as pbar: - for val, p1, p2, p3 in zip(vals, ps1, ps2, ps3): - disch_cum = val*res_pism*res_pism*10e6/rho_ice - #N = max(int(np.absolute(disch_cum)/(10e6)/10), 1) - N = int(np.absolute(disch_cum)/(10e6)) - if N < N_min: - N = 0 - elif N > N_max: - scaling_tmp = N/N_max - N = N_max - - s = np.random.lognormal(mu, sigma, N)*10e6 - - f_scale = sum(s)/np.absolute(disch_cum) - s_ = s / f_scale / scaling_tmp - - length_tmp = ne.evaluate('(s_/height_icb)**(1/2)') - - #ll = np.digitize(length_tmp, slength_bins) - ll = np.digitize(s_, svol_bins) - for i, (s, d) in enumerate(zip(Nlength, sdepth)): - sbin = np.where(ll==i+1)[0] - if list(sbin): - if len(sbin) <= s: - chunk = [sbin] - else: - chunk = [sbin[k:k + s] for k in range(0, len(sbin), s)] - l = np.array([np.mean(s_[c]) for c in chunk]) - s = np.array([len(c) for c in chunk]) - if not 'length' in locals(): - length = ne.evaluate('(l/height_icb)**(1/2)') - scaling = np.array([s]) - depth = np.array([d]*len(l)) - else: - length = np.append(length, ne.evaluate('(l/height_icb)**(1/2)')) - scaling = np.append(scaling, np.array([s])) - depth = np.append(depth, np.array([d]*len(l))) - - for i in range(len(l)): - r1 = random.random() - r2 = random.random() - - lower_bound = 0.1 - upper_bound = 0.9 - - r1 = r1 * (upper_bound - lower_bound) + lower_bound - r2 = r2 * (upper_bound - lower_bound) + lower_bound - #https://math.stackexchange.com/questions/18686/uniform-random-point-in-triangle - tmp_x = (1-np.sqrt(r1))*p1.x + (np.sqrt(r1)*(1-r2))*p2.x + (r2*np.sqrt(r1))*p3.x - tmp_y = (1-np.sqrt(r1))*p1.y + (np.sqrt(r1)*(1-r2))*p2.y + (r2*np.sqrt(r1))*p3.y - points.append(point(tmp_x, tmp_y)) - #length_tmp = (np.absolute(s_[i])/height_icb)**(1/2) - #length.append(length_tmp) - ##length**2*length*16/21=s_--> length=(s_*21/16)**(1/3) - #length.append(np.absolute(s_[i]*21/16)**(1/3)) - #height.append(height_icb) - #height.append(length[-1]*16/21) - #scaling.append(scaling_tmp) - pbar.update(1) - - points_ = pd.DataFrame.from_records([p.to_dict() for p in points]) - np.savetxt(os.path.join(icb_path, "LON.dat"), points_.x.values) - np.savetxt(os.path.join(icb_path, "LAT.dat"), points_.y.values) - np.savetxt(os.path.join(icb_path, "LENGTH.dat"), length) - np.savetxt(os.path.join(icb_path, "HEIGHT.dat"), depth) - np.savetxt(os.path.join(icb_path, "SCALING.dat"), scaling) - return [points, length] - -def PointTriangle_distance(lon0, lat0, lon1, lat1, lon2, lat2, lon3, lat3): - d1 = ne.evaluate('(lon1 - lon0)**2 + (lat1 - lat0)**2') - d2 = ne.evaluate('(lon2 - lon0)**2 + (lat2 - lat0)**2') - d3 = ne.evaluate('(lon3 - lon0)**2 + (lat3 - lat0)**2') - - dis = d1+d2+d3 - ind = np.where(dis == np.amin(dis)) - - p1 = point(lon1[ind], lat1[ind]) - p2 = point(lon2[ind], lat2[ind]) - p3 = point(lon3[ind], lat3[ind]) - - return [p1, p2, p3], ind - -def find_FESOM_elem(nod2d_file, elem2d_file, lons, lats): - points = [] - nod2d = pd.read_csv(nod2d_file, header=0, names=["lon", "lat", "coastal"], sep='\s+', index_col=0) - elem2d = pd.read_csv(elem2d_file, header=0, names=["nod1", "nod2", "nod3"], sep='\s+') - - lon1=[] - lat1=[] - lon2=[] - lat2=[] - lon3=[] - lat3=[] - - lon1 = nod2d.lon[elem2d.nod1] - lat1 = nod2d.lat[elem2d.nod1] - lon2 = nod2d.lon[elem2d.nod2] - lat2 = nod2d.lat[elem2d.nod2] - lon3 = nod2d.lon[elem2d.nod3] - lat3 = nod2d.lat[elem2d.nod3] - - with tqdm(total=len(lons), file=sys.stdout, desc='find FESOM elements') as pbar: - for lon, lat in zip(lons, lats): - tmp, ind = PointTriangle_distance(lon, lat, np.array(lon1), np.array(lat1), np.array(lon2), np.array(lat2), - np.array(lon3), np.array(lat3)) - - points.append(tmp[:3]) - #print("point in triangle?: ", PointInTriangle(point(lon, lat), tmp[0], tmp[1], tmp[2])) - #print("point: [" + str(lon) + ", " + str(lat) + "]") - #print("triangle: [", str(tmp[0].x) + ", " + str(tmp[0].y) + "], " + "[", str(tmp[1].x) + ", " + str(tmp[1].y) + "], " + "[", str(tmp[2].x) + ", " + str(tmp[2].y) + "]") - pbar.update(1) - return points - - - - - - - - - - - - -data, lons, lats = read_pism_file(ifile) -points = find_FESOM_elem(nod2d_file, elem2d_file, lons, lats) - -ps1, ps2, ps3 = np.transpose(points) -icb_generator(data, ps1, ps2, ps3, icb_path) - -#pos = find_FESOM_elem(nod2d_file, elem2d_file, xs, ys) -# -#np.savetxt("pos.csv", np.array(pos)) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def _generate_rotation_matrix(self): - alphaEuler=50 - betaEuler=15 - gammaEuler=-90 - - al = np.radians(alphaEuler) - be = np.radians(betaEuler) - ga = np.radians(gammaEuler) - - rotate_matrix = np.zeros((3,3)) - rotate_matrix[0,0]=np.cos(ga)*np.cos(al)-np.sin(ga)*np.cos(be)*np.sin(al) - rotate_matrix[0,1]=np.cos(ga)*np.sin(al)+np.sin(ga)*np.cos(be)*np.cos(al) - rotate_matrix[0,2]=np.sin(ga)*np.sin(be) - rotate_matrix[1,0]=-np.sin(ga)*np.cos(al)-np.cos(ga)*np.cos(be)*np.sin(al) - rotate_matrix[1,1]=-np.sin(ga)*np.sin(al)+np.cos(ga)*np.cos(be)*np.cos(al) - rotate_matrix[1,2]=np.cos(ga)*np.sin(be) - rotate_matrix[2,0]=np.sin(be)*np.sin(al) - rotate_matrix[2,1]=-np.sin(be)*np.cos(al) - rotate_matrix[2,2]=np.cos(be) - - self.rotate_matrix = rotate_matrix - -def _g2r(self): - lon1 = np.radians(self.box[0]) - lon2 = np.radians(self.box[1]) - lat1 = np.radians(self.box[2]) - lat2 = np.radians(self.box[3]) - - v1_ = np.zeros((3,1)) - v1_[0]=np.cos(lat1)*np.cos(lon1) - v1_[1]=np.cos(lat1)*np.sin(lon1) - v1_[2]=np.sin(lat1) - vr1 = np.dot(self.rotate_matrix, v1_) - - v2_ = np.zeros((3,1)) - v2_[0]=np.cos(lat2)*np.cos(lon2) - v2_[1]=np.cos(lat2)*np.sin(lon2) - v2_[2]=np.sin(lat2) - vr2 = np.dot(self.rotate_matrix, v2_) - - self.box[0] = np.degrees(math.atan2(vr1[1], vr1[0])) - self.box[2] = np.degrees(math.asin(vr1[2])) - self.box[1] = np.degrees(math.atan2(vr2[1], vr2[0])) - self.box[3] = np.degrees(math.asin(vr2[2])) - -def _r2g(self, lon_r, lat_r): - - A = inv(self.rotate_matrix) - - lon_ = np.radians(lon_r) - lat_ = np.radians(lat_r) - - v_ = np.zeros((3,1)) - v_[0]=np.cos(lat_)*np.cos(lon_) - v_[1]=np.cos(lat_)*np.sin(lon_) - v_[2]=np.sin(lat_) - vr = np.dot(A, v_) - - lon_g = np.degrees(math.atan2(vr[1], vr[0])) - lat_g = np.degrees(math.asin(vr[2])) - return lon_g, lat_g - -def _back_rotate(self): - r2g_v = np.vectorize(self._r2g) - - with open(self.nod_file, 'r') as csvfile: - nodes = pd.read_csv(csvfile, header=None, sep=r'\s* \s*', skiprows=1, engine='python') - nodes.drop(nodes.index[0], inplace=True) - nodes.columns = ['index', 'lon', 'lat', 'mask'] - [lon_tmp, lat_tmp] = r2g_v(np.array(nodes['lon'].values[:], dtype=float).transpose(), - np.array(nodes['lat'].values[:], dtype=float).transpose()) - nodes['lon'] = lon_tmp - nodes['lat'] = lat_tmp - nodes.to_csv('nodes_back_rotated.csv', sep=' ', header=True, index=False) - self.nod_file = 'nodes_back_rotated.csv' diff --git a/couplings/coupling_dual-hemisphere/utils/install_calendar.sh b/couplings/coupling_dual-hemisphere/utils/install_calendar.sh deleted file mode 100755 index 9463bdb26..000000000 --- a/couplings/coupling_dual-hemisphere/utils/install_calendar.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/ksh - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -rm -rf ${thisdir}/calendar/_build/ -mkdir -p ${thisdir}/calendar/_build/ - -gcc ${thisdir}/calendar/time_difference.c -o ${thisdir}/calendar/_build/time_difference diff --git a/couplings/coupling_dual-hemisphere/utils/install_calnoro.sh b/couplings/coupling_dual-hemisphere/utils/install_calnoro.sh deleted file mode 100755 index 22b3a3a13..000000000 --- a/couplings/coupling_dual-hemisphere/utils/install_calnoro.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -MACHINE=$1 - -fortran_compiler=gfortran - -if [[ ${MACHINE} == "albedo" ]]; then - module load gcc/12.1.0 - nc_config=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/bin/nf-config -elif [[ ${MACHINE} == "levante" ]]; then - module load gcc/11.2.0-gcc-11.2.0 - nc_config=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/bin/nf-config -else - echo " * Unknown machine! No installation possible" - exit -fi - -NETCDF_LIB=$($nc_config --flibs) -NETCDF_INCLUDE=-I$($nc_config --includedir) - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -rm -rf ${thisdir}/_build/calnoro -mkdir -p ${thisdir}/_build/ - - - -echo $fortran_compiler \ - ${thisdir}/calnoro.f90 \ - ${thisdir}/grid_noro.f90 \ - -o ${thisdir}/_build/calnoro \ - $NETCDF_LIB $NETCDF_INCLUDE -$fortran_compiler \ - ${thisdir}/calnoro.f90 \ - ${thisdir}/grid_noro.f90 \ - -o ${thisdir}/_build/calnoro \ - $NETCDF_LIB $NETCDF_INCLUDE - -mv _build/calnoro calnoro diff --git a/couplings/coupling_dual-hemisphere/utils/install_jsbach_init_file.sh b/couplings/coupling_dual-hemisphere/utils/install_jsbach_init_file.sh deleted file mode 100755 index 0db567fa3..000000000 --- a/couplings/coupling_dual-hemisphere/utils/install_jsbach_init_file.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -l - -MACHINE=$1 - -fortran_compiler=gfortran - -if [[ ${MACHINE} == "albedo" ]]; then - module load gcc/12.1.0 - nc_config=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/bin/nf-config -elif [[ ${MACHINE} == "levante" ]]; then - module load gcc/11.2.0-gcc-11.2.0 - nc_config=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/bin/nf-config -else - echo " * Unknown machine! No installation possible" - exit -fi - -NETCDF_LIB=$($nc_config --flibs) -NETCDF_INCLUDE=-I$($nc_config --includedir) - -echo "Done loading environment!" - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -prog=jsbach_init_file -srcdir=${thisdir} -rm -rf ${srcdir}/_build/${prog} -mkdir -p ${thisdir}/_build/ - -F90=$fortran_compiler - -echo "Compile ${srcdir}/${prog}.f90..." -echo ${F90} ${F90FLAGS} -o ${srcdir}/_build/${prog} ${srcdir}/${prog}.f90 ${NETCDF_INCLUDE} ${NETCDF_LIBDIR} ${NETCDF_LIB} -${F90} ${F90FLAGS} -o ${srcdir}/_build/${prog} ${srcdir}/${prog}.f90 ${NETCDF_INCLUDE} ${NETCDF_LIBDIR} ${NETCDF_LIB} -mv mo_vegparams.mod mo_kinds.mod ${srcdir}/_build -mv _build/jsbach_init_file jsbach_init_file diff --git a/couplings/coupling_dual-hemisphere/utils/install_jsbach_pack_unpack.sh b/couplings/coupling_dual-hemisphere/utils/install_jsbach_pack_unpack.sh deleted file mode 100755 index bf49fa208..000000000 --- a/couplings/coupling_dual-hemisphere/utils/install_jsbach_pack_unpack.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -l - -MACHINE=$1 - -fortran_compiler=gfortran - -if [[ ${MACHINE} == "albedo" ]]; then - module load gcc/12.1.0 - nc_config=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/bin/nf-config -elif [[ ${MACHINE} == "levante" ]]; then - module load gcc/11.2.0-gcc-11.2.0 - nc_config=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/bin/nf-config -else - echo " * Unknown machine! No installation possible" - exit -fi - -NETCDF_LIB=$($nc_config --flibs) -NETCDF_INCLUDE=-I$($nc_config --includedir) - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -for prog in unpack pack; do - srcdir=${thisdir} - rm -rf ${srcdir}/_build/${prog} - mkdir -p ${thisdir}/_build/ - - F90=$fortran_compiler - - echo "Compile ${srcdir}/${prog}.f90..." - echo ${F90} ${F90FLAGS} -o ${srcdir}/_build/${prog} ${srcdir}/${prog}.f90 ${NETCDF_INCLUDE} ${NETCDF_LIBDIR} ${NETCDF_LIB} - ${F90} ${F90FLAGS} -o ${srcdir}/_build/${prog} ${srcdir}/${prog}.f90 ${NETCDF_INCLUDE} ${NETCDF_LIBDIR} ${NETCDF_LIB} -done - -mv _build/pack pack -mv _build/unpack unpack diff --git a/couplings/coupling_dual-hemisphere/utils/jsbach_init_file.f90 b/couplings/coupling_dual-hemisphere/utils/jsbach_init_file.f90 deleted file mode 100644 index 86fc901c6..000000000 --- a/couplings/coupling_dual-hemisphere/utils/jsbach_init_file.f90 +++ /dev/null @@ -1,4056 +0,0 @@ -!------------------------------------------------------------------------------ -! Program to generate initial files for JSBACH -!------------------------------------------------------------------------------ -! based on Thomas Raddatz' programs -! jsbach_init_file_13tiles.f90 -! jsbach_init_file_8tiles.f90 and -! jsbach_init_file_3or4tiles.f90 -! and scripts and programs by Stefan Hagemann in -! soil_para.com -! -! This script does not exactly reproduces initial files generated with the -! programs listed above. Here the differences: -! - The variables are defined in a new order -! - Added global attributes -! - Added attributes to several variables; particularly cover_type now has -! attributes defining the different land cover types -! - There is no longer a variable lct - only the dimension -! - Consistent use of selected_real_kind _dp -! => slight differences in veg_ratio_factor, albedo_soil_nir, -! albedo_soil_vis, albedo_veg_nir and albedo_veg_vis -! - Consider albedo_compensate with all numbers of tiles -! - The definition of a minimum cover fraction and the scaling happens only -! once, at the end of the calculations -! => small differences in cover_fract, might also lead to different -! cover_type -! -! -! Arrays in the jsbach initial file -! -! ----------------------------------------------------------------------------- -! *) variable description read from file modified? -! ----------------------------------------------------------------------------- -! i init_moist soil wetness jan_surf.nc WS corrected -! i snow snow depth jan_surf.nc SN unchanged -! c slf fract. sea land mask jan_surf.nc SLM unchanged -! c slm sea land mask calculated -! - roughness_length roughness length jan_surf.nc AZ0 unchanged -! - albedo background albedo jan_surf.nc ALB unchanged -! c elevation mean orography jan_surf.nc OROMEA unchanged -! c orography_std_dev orogr. standard dev. jan_surf.nc OROSTD unchanged -! c glac glacier mask jan_surf.nc GLAC unchanged -! c fao FAO soil data flags jan_surf.nc FAO filled -! c maxmoist soil field capacity jan_surf.nc WSMX filled,modifs -! c or soil_parameters.nc -! - forest_fract forest fraction jan_surf.nc FOREST unchanged -! i lai_clim leaf area index VLTCLIM.nc unchanged -! - veg_fract vegetation fraction VGRATCLIM.nc unchanged -! i surf_temp surface temperature TSLCLIM2.nc unchanged -! c/i cover_fract vegetation ratio vegtype_pa14.nc calculated -! c cover_type vegetation cover type vegtype_pa14.nc calculated -! c/i veg_ratio_max max. vegetation ratio vegmax_6.lola reorder -! c/- albedo_veg_vis vegetation albedo (vis) albedo.lola modifs -! c/- albedo_veg_nir vegetation albedo (NIR) albedo.lola modifs -! c albedo_soil_vis soil albedo (visible) albedo.lola modifs -! c albedo_soil_nir soil albedo (NIR) albedo.lola modifs -! c roughness_length_oro roughness without veg topo_75.lola modifs -! c/- natural_veg potential vegetation natural_veg.nc calculated -! c root_depth effective root depth calculated -! c soil_depth soil_depth soil_parameters.nc filled,modifs -! c matrix_potential Saturated matrix pot. soil_parameters.nc filled -! c heat_capacity Volume heat cap. of soil soil_parameters.nc filled -! c heat_conductivity Heat conductivity of s. soil_parameters.nc filled -! c bclapp Clapp&Horneberger exp. soil_paramsters.nc filled -! c hyd_cond_sat Saturated hydraulic soil_parameters.nc filled -! conductivity -! c pore_size_index Soil pore s. dist. index soil_parameters.nc filled -! c soil_porosity Volumetric soil porosity soil_parameters.nc filled -! c wilting_point Volumetric soil soil_parameters.nc filled -! permanent wilting point -! -!*) usage within jsbach -! --------------------- -! i: used for initialization -! c: used throughout the whole simulation -! -: not used in jsbach standard setup -! -!------------------------------------------------------------------------------ -! To compile and run use -! -------------------- -! jsbach_init_file.ksh -! -------------------- -! -! Veronika Gayler , MPI, March 2008: Original code -! Stiig Wilkenskjeld, MPI, January 2012: Added 5-layer soil variables -!------------------------------------------------------------------------------ - -MODULE mo_kinds - ! kind parameters - INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(6,37) - INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307) - INTEGER, PARAMETER :: i4 = SELECTED_INT_KIND(9) - INTEGER, PARAMETER :: i8 = SELECTED_INT_KIND(14) - REAL(dp),PARAMETER :: pi = 3.14159265358979323846_dp - REAL(dp),PARAMETER :: radius_of_earth = 6371000._dp -END MODULE mo_kinds - -MODULE mo_vegparams - USE mo_kinds - ! vegetation parameters - REAL(dp), PARAMETER :: small_fract = 1.E-10_dp - REAL(dp), PARAMETER :: substantial_woody = 0.05_dp - REAL(dp), PARAMETER :: substantial_tundra = 0.05_dp - - ! - ! land cover types as defined in lctlib file - ! - - ! Parameters for nlct=21 - INTEGER, PARAMETER :: lct_glacier = 1 - INTEGER, PARAMETER :: lct_tropical_evergreen = 2 - INTEGER, PARAMETER :: lct_tropical_deciduous = 3 - INTEGER, PARAMETER :: lct_extratrop_evergreen = 4 - INTEGER, PARAMETER :: lct_extratrop_deciduous = 5 - INTEGER, PARAMETER :: lct_temperate_broadl_evergreen = 6 - INTEGER, PARAMETER :: lct_temperate_broadl_deciduous = 7 - INTEGER, PARAMETER :: lct_evergreen_conifer = 8 - INTEGER, PARAMETER :: lct_deciduous_conifer = 9 - INTEGER, PARAMETER :: lct_raingreen_shrub = 10 - INTEGER, PARAMETER :: lct_deciduous_shrub = 11 - INTEGER, PARAMETER :: lct_c3grass = 12 - INTEGER, PARAMETER :: lct_c4grass = 13 - INTEGER, PARAMETER :: lct_pasture = 14 - INTEGER, PARAMETER :: lct_c3pasture = 15 - INTEGER, PARAMETER :: lct_c4pasture = 16 - INTEGER, PARAMETER :: lct_tundra = 17 - INTEGER, PARAMETER :: lct_swamp = 18 - INTEGER, PARAMETER :: lct_crop = 19 - INTEGER, PARAMETER :: lct_c3crop = 20 - INTEGER, PARAMETER :: lct_c4crop = 21 - INTEGER, PARAMETER :: lctmax=21 ! highest lct number - - ! - ! land cover types of the input vegetation maps (1-14) - ! - INTEGER, PARAMETER :: nvegtyp = 14 ! number of vegetation types - INTEGER, PARAMETER :: nwoody = 9 ! number of woody types - INTEGER, PARAMETER :: woody_types(nwoody) = (/1,2,3,4,5,6,7,8,11/) - INTEGER, PARAMETER :: veg_tropical_evergreen = 1 - INTEGER, PARAMETER :: veg_tropical_deciduous = 2 - INTEGER, PARAMETER :: veg_temperate_broadl_evergreen = 3 - INTEGER, PARAMETER :: veg_temperate_broadl_deciduous = 4 - INTEGER, PARAMETER :: veg_evergreen_conifer = 5 - INTEGER, PARAMETER :: veg_deciduous_conifer = 6 - INTEGER, PARAMETER :: veg_raingreen_shrub = 7 - INTEGER, PARAMETER :: veg_deciduous_shrub = 8 - INTEGER, PARAMETER :: veg_c3grass = 9 - INTEGER, PARAMETER :: veg_c4grass = 10 - INTEGER, PARAMETER :: veg_tundra = 11 - INTEGER, PARAMETER :: veg_crop = 12 - INTEGER, PARAMETER :: veg_c3pasture = 13 - INTEGER, PARAMETER :: veg_c4pasture = 14 - - INTEGER, PARAMETER :: lct(nvegtyp) = & - (/lct_tropical_evergreen, lct_tropical_deciduous, & - lct_temperate_broadl_evergreen, lct_temperate_broadl_deciduous, & - lct_evergreen_conifer, lct_deciduous_conifer, & - lct_raingreen_shrub, lct_deciduous_shrub, & - lct_c3grass, lct_c4grass, & - lct_tundra, lct_crop ,lct_c3pasture, lct_c4pasture /) - - INTEGER :: glacier_tile = -1 ! tile that is reserved for glaciers; set in - ! calc_cover_types. - -END MODULE mo_vegparams - -!------------------------------------------------------------------------------ -PROGRAM jsbach_init_file - - USE mo_kinds - USE mo_vegparams - IMPLICIT NONE - INCLUDE 'netcdf.inc' - - INTERFACE - SUBROUTINE open_file(info,infile,ncin,ret_stat) - CHARACTER*100, INTENT(IN) :: infile - LOGICAL, INTENT(IN) :: info - INTEGER, INTENT(OUT) :: ncin - INTEGER, INTENT(OUT), OPTIONAL :: ret_stat - END SUBROUTINE - - SUBROUTINE define_var(ncin, ncout, varname_in, varname_out, outdimids, missval) - USE mo_kinds - INTEGER, INTENT(IN) :: ncin, ncout - CHARACTER*30, INTENT(IN) :: varname_in, varname_out - INTEGER, INTENT(IN) :: outdimids(6) - REAL(dp), INTENT(OUT), OPTIONAL :: missval - END SUBROUTINE - END INTERFACE - - CHARACTER*20 :: svn_rev = "$Revision: 9230 $" - CHARACTER*128 :: svn_url = & - "$HeadURL: https://svn.zmaw.de/svn/cosmos/branches/mpiesm-landveg/contrib/initial_tarfiles/jsbach_init_file.f90 $" - - ! Dimensions - INTEGER :: nlon, nlat, ntiles, nlct, nsoil, ntime - - ! Variables - REAL(dp), ALLOCATABLE, DIMENSION(:) :: lat - REAL(dp), ALLOCATABLE, DIMENSION(:) :: lon - INTEGER, ALLOCATABLE, DIMENSION(:) :: tiles - INTEGER, ALLOCATABLE, DIMENSION(:) :: time_days - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: veg_fract - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: cover_fract - INTEGER, ALLOCATABLE, DIMENSION(:,:,:) :: cover_type - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: cover_type_dp - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: lai - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: elevation - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: elevationrms - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: az0 - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: roughness_oro - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: snow - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: slf - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: slm - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: non_glacier_land - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: lake - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: glac_dp - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: fao - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: forest_fract - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: surf_temp - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: vegfract - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: vegfract_cf - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: veg_ratio_max - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo_veg_vis, albedo_veg_vis_in - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo_veg_nir, albedo_veg_nir_in - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo_soil_vis, albedo_soil_vis_in - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo_soil_nir, albedo_soil_nir_in - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: C3C4_flag - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: C3_crop - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: C4_crop - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: crop - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: pasture - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: potveg - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: natural_veg - REAL(dp), ALLOCATABLE, DIMENSION(:) :: vegfract_for_types - LOGICAL, ALLOCATABLE, DIMENSION(:) :: is_naturalveg - -! soil parameters and soil moisture - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: max_moisture - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: max_soilwater - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: moisture - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: soilwater - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: soilwater_layer - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: soil_depth - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: soil_depth_layer - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: matrix_potential - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: soil_field_capacity - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: heat_capacity - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: heat_conductivity - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: bclapp - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: hyd_cond_sat - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: pore_size_index - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: soil_porosity - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: wilting_point - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: root_depth - REAL(dp), ALLOCATABLE, DIMENSION(:) :: soillev - REAL(dp), ALLOCATABLE, DIMENSION(:) :: layer_depth - - - ! Indices - INTEGER :: i,j,k - - ! dummies and temporary arrays - REAL(dp), ALLOCATABLE, DIMENSION(:) :: dummy - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: grid_area - REAL(dp), ALLOCATABLE, DIMENSION(:) :: gauss_weights - REAL(dp) :: area_tropical_forest, area_temperate_forest - REAL(dp) :: area_woody, area_shrubs, area_crops, area_pasture - REAL(dp) :: area_grass, area_all, area_land, area_lake - REAL(dp) :: area_land_tropics, area_land_extratropics, area_glac - - ! names of the in- and output files - CHARACTER(100):: fnam, fnam0, fnam1, fnam2, fnam3, fnam4, fnam5, fnam6, fnam7 - CHARACTER(100):: fnam8, fnam9, fnam10, fnam11, fnam12, fnam13, fnam14, fnam15 - CHARACTER(100):: fnamout - CHARACTER(8) :: cyear_ct, cyear_cf, ctiles, clayer, cvegtyp - CHARACTER(10) :: dynveg_tag - - ! netcdf - INTEGER :: stat, ncin, ncout, ncid, ncin15, varid, dimid - INTEGER :: outdimids(6) ! netcdf dimension ids in the output file - INTEGER :: dimids(6) ! netcdf dimension ids - CHARACTER(30) :: varname, varname_out - - ! parameters - REAL(dp) :: albedo_compensate - - INTEGER :: second_grass - INTEGER :: second_woody - INTEGER :: dominant_crop - CHARACTER(30) :: resol - LOGICAL :: slm_in_input - REAL(dp) :: missval, missmpo, missbcl, misshca, misshco, misspor - REAL(dp) :: missdep, missfca, misspsi, misshyc, misswpo, missmxm - - ! Namelist Parameters - INTEGER, PARAMETER :: nnml = 30 ! Fortran unit to read namelist - LOGICAL :: lcouple, ldynveg, lc3c4crop, lpasture, lread_pasture, lpasture_rule - LOGICAL :: grid_from_rerun, info, cover_fract_only, echam_fractional - LOGICAL :: desert_only, woods_only, grass_only - LOGICAL :: ignore_measurements - CHARACTER(10) :: res_atm, res_oce, maxmoist_version, pasture_tag - CHARACTER(100) :: masks_file - INTEGER :: year_cf, year_ct - REAL(dp) :: slm_fraction ! only used with T31 in coupled setup, if SLM - ! not available in the echam initial file - - NAMELIST /initctl/ & - res_atm, & ! model resolution (T31, T42, ...) - ntiles, & ! number of tiles - nsoil, & ! number of soil layers - nlct, & ! number of land cover types - year_cf, & ! reference year for cover fractions - year_ct, & ! reference year for cover types - lcouple, & ! initial file for coupled run - res_oce, & ! if coupled: ocean model resolution - ldynveg, & ! initial file for a run with dynamic vegetation - lc3c4crop, & ! initial file for a run with C3 and C4 crops - lpasture, & ! distinguish pastures from grasses - lread_pasture, & ! read pasture and crop fractions from a separate file - pasture_tag, & ! tag to define crops and pasture input file (with lread_pasture) - lpasture_rule, & ! apply the pasture rule: pasture is allocated primarily on grass land - slm_fraction, & ! minimum land fraction of a land grid cell - echam_fractional, & ! echam uses fractional land see mask - masks_file, & ! read land sea, glacier and lake masks from this file - maxmoist_version, & ! maximum soil moisture array as in echam (LSP2) or new (LSP3) - grid_from_rerun, & ! read grid from rerun file instead of jan_surf file - fnam0, & ! filename of restart file (if grid_from_rerun = .TRUE.) - desert_only, & ! Initialize all land as desert - grass_only, & ! Initialize all land with grass - woods_only, & ! Initialize all land with woods - cover_fract_only,& ! Generate file containing just cover fractions and types - ignore_measurements, & ! Ignore measured data, only use background values - info ! TRUE: print some extra information - -!------------------------------------------------------------------------------ -! read namelist -!------------------------------------- - !-- defaults: - res_atm = 'T31' - ntiles = 4 - nsoil = 5 - nlct = 14 - year_ct = 800 - year_cf = 800 - lcouple = .FALSE. - res_oce = 'GR30' - ldynveg = .FALSE. - lc3c4crop = .FALSE. - lpasture = .FALSE. - lread_pasture = .FALSE. - pasture_tag = 'LUH' - lpasture_rule = .FALSE. - slm_fraction = 0.5_dp - echam_fractional = .FALSE. - maxmoist_version = 'LSP3' - grid_from_rerun = .FALSE. - masks_file = 'default' - fnam0 = 'restart_file_name' - desert_only = .FALSE. - grass_only = .FALSE. - woods_only = .FALSE. - cover_fract_only = .FALSE. - ignore_measurements = .FALSE. - info = .TRUE. - - OPEN (nnml, file='namelist') - READ (nnml, initctl) - WRITE(ctiles,'(I0)') ntiles - WRITE(clayer,'(I0)') nsoil - WRITE(cyear_ct,'(I0.4)') year_ct - WRITE(cyear_cf,'(I0.4)') year_cf - WRITE(cvegtyp,'(I0)') nvegtyp - - IF (info) THEN - WRITE(*,*) 'Namelist Parameters ' - WRITE(*,*) ' Atmosphere resolution: ', res_atm - WRITE(*,*) ' Configuration with ocean: ', lcouple - IF (lcouple) & - WRITE(*,*) ' Ocean resolution: ', res_oce - WRITE(*,*) ' Number of tiles: ', ntiles - WRITE(*,*) ' Number of land cover types: ', nlct - WRITE(*,*) ' Reference year for cover types: ', year_ct - WRITE(*,*) ' Reference year for cover fractions: ', year_cf - WRITE(*,*) ' Configuration with dynamic vegetation: ', ldynveg - WRITE(*,*) ' Configuration with C3 and C4 crops: ',lc3c4crop - WRITE(*,*) ' Threshold for land in slm: ', slm_fraction - WRITE(*,*) ' Pasture: ',lpasture - WRITE(*,*) ' read pasture: ',lread_pasture - WRITE(*,*) ' pasture rule: ',lpasture_rule - WRITE(*,*) ' Desert only: ',desert_only - WRITE(*,*) ' Grass only: ',grass_only - WRITE(*,*) ' Woods only: ',woods_only - WRITE(*,*) ' Cover fract only: ',cover_fract_only - WRITE(*,*) ' Ignore measurements: ', ignore_measurements - WRITE(*,*) ' Print extra information: ', info ! Pretty dummy output :-) - WRITE(*,*) ' Read grid from another file: ', grid_from_rerun - IF (grid_from_rerun) & - WRITE (*,*) ' Grid file name: ',fnam0 - WRITE(*,*) '' - ENDIF - -!------------------------------------- -! define filenames -!------------------------------------- - !-- input files: - IF (lcouple) THEN - resol=TRIM(res_atm)//TRIM(res_oce) - ELSE - resol=TRIM(res_atm) - END IF - fnam1=TRIM(resol)//'_jan_surf.nc' - fnam2=TRIM(resol)//'_VLTCLIM.nc' - fnam3=TRIM(resol)//'_VGRATCLIM.nc' - fnam4=TRIM(res_atm)//'_TSLCLIM2.nc' - fnam5='vegtype_'//TRIM(cyear_ct)//'_'//TRIM(res_atm)//'gauss_pa'//TRIM(cvegtyp)//'.nc' - fnam6='vegmax_6_'//TRIM(res_atm)//'.nc' - fnam7='albedo_'//TRIM(res_atm)//'.nc' - fnam8=TRIM(res_atm)//'_topo_75.nc' - fnam9='vegtype_'//TRIM(cyear_cf)//'_'//TRIM(res_atm)//'gauss_pa'//TRIM(cvegtyp)//'.nc' - fnam10='C3C4_mask_'//TRIM(res_atm)//'gauss.nc' - fnam11='C3C4_crop_'//TRIM(res_atm)//'.nc' - fnam12='LUH_states_'//TRIM(cyear_cf)//'_'//TRIM(res_atm)//'.nc' - fnam13='potveg_'//TRIM(res_atm)//'.nc' - fnam14='soil_parameters_'//TRIM(res_atm)//'.nc' - fnam15=TRIM(masks_file) - - !-- output file: - IF (echam_fractional) resol=TRIM(resol)//'_fractional' - IF (cover_fract_only) THEN - fnamout='cover_fract_'//TRIM(res_atm)//'_'//TRIM(ctiles)//'tiles_'//TRIM(cyear_cf)//'.nc' - ELSE - IF (ldynveg) THEN - dynveg_tag='_dynveg' - ELSE - dynveg_tag='_no-dynveg' - END IF - IF (nsoil > 1) THEN - fnamout='jsbach_'//TRIM(resol)//'_'//TRIM(ctiles)//'tiles_'//TRIM(clayer)//'layers_'// & - TRIM(cyear_cf)//TRIM(dynveg_tag)//'.nc' - ELSE - fnamout='jsbach_'//TRIM(resol)//'_'//TRIM(ctiles)//'tiles_'//TRIM(cyear_cf)// & - TRIM(dynveg_tag)//'.nc' - END IF - IF (TRIM(cyear_cf) == '0000') THEN - fnamout='jsbach_'//TRIM(resol)//'_'//TRIM(ctiles)//'tiles_'//TRIM(clayer)//'layers_natural-veg.nc' - END IF - - END IF - - !-- print info - IF (info) THEN - IF (grid_from_rerun) WRITE (*,*) 'input0: ',fnam0 - WRITE (*,*) 'input 1: ',fnam1 - WRITE (*,*) 'input 2: ',fnam2 - WRITE (*,*) 'input 3: ',fnam3 - WRITE (*,*) 'input 4: ',fnam4 - WRITE (*,*) 'input 5: ',fnam5 - WRITE (*,*) 'input 6: ',fnam6 - WRITE (*,*) 'input 7: ',fnam7 - WRITE (*,*) 'input 8: ',fnam8 - WRITE (*,*) 'input 9: ',fnam9 - WRITE (*,*) 'input10: ',fnam10 - WRITE (*,*) 'input11: ',fnam11 - WRITE (*,*) 'input12: ',fnam12 - WRITE (*,*) 'input13: ',fnam13 - WRITE (*,*) 'input14: ',fnam14 - IF (TRIM(fnam15) /= 'default') WRITE (*,*) 'input15: ',fnam15 - - WRITE (*,*) 'output: ',fnamout - WRITE (*,*) ' ' - ENDIF - -!------------------------------------------------------------------------------ -! Check consitency of namelist parameters -!------------------------------------------------------------------------------ - IF (lc3c4crop .AND. (ntiles == 1 .OR. ntiles == 8 .OR. ntiles == 9)) THEN - CALL hdlerr & - (1,'C3 and C4 crops indistinguishable in current setups for 1 or 8 tiles') - END IF - IF (.NOT. lc3c4crop .AND. (ntiles == 5 .OR. ntiles == 10)) THEN - CALL hdlerr & - (1,'lc3c4crop needs to be true in current setups for 5 or 10 tiles') - END IF - IF (ldynveg .AND. (ntiles < 8 .OR. ntiles == 13)) THEN - CALL hdlerr & - (1,'running dynveg not possible with less then 8 tiles or 13 tiles') - END IF - IF (ldynveg .AND. cover_fract_only) THEN - CALL hdlerr & - (1,'generation of land cover maps does not make sense for runs with dynveg') - END IF - IF ((grass_only .OR. woods_only) .AND. (ntiles < 8 .OR. ntiles == 13)) THEN - CALL hdlerr & - (1,'grass/woods-only not implemented for less then 8 or 13 tiles') - END IF - IF ((lpasture .OR. lread_pasture .OR. lpasture_rule) & - .AND. (ntiles /= 11 .AND. ntiles /= 12)) THEN - CALL hdlerr & - (1,'lpasture, lread_pasture and lpasture_rule need a setup with pasture tile') - END IF - IF (lread_pasture .AND. .NOT. lpasture) THEN - CALL hdlerr (1,'lread_pasture can only be used with lpasture') - END IF - IF (lpasture_rule .AND. .NOT. lread_pasture) THEN - CALL hdlerr (1,'pasture rule only possible in a setup with lread_pasture') - END IF - IF (lpasture .AND. ntiles /= 11 .AND. .NOT. ldynveg) THEN - CALL hdlerr (1,'for lpasture you need a pasture tile. Use 11 tiles.') - END IF - -!------------------------------------------------------------------------------ -! Read from input files and define output file -!------------------------------------------------------------------------------ -! input-file0: rerun (or jan_surf) -!------------------------------------- - IF (grid_from_rerun) THEN - CALL open_file(info,fnam0,ncin) - ELSE - CALL open_file(info,fnam1,ncin) - END IF - - stat = nf_inq_dimid(ncin,'lon',dimid) - CALL hdlerr(stat,'cannot find dimension lon') - stat = nf_inq_dimlen(ncin,dimid,nlon) - CALL hdlerr(stat,'problems with nlon') - stat = nf_inq_dimid(ncin,'lat',dimid) - CALL hdlerr(stat,'cannot find dimension lat') - stat = nf_inq_dimlen(ncin,dimid,nlat) - CALL hdlerr(stat,'problems with nlat') - ntime=12 - -!------------------------------------- -! define the output-file dimensions -!------------------------------------- - stat = nf_create(fnamout,NF_CLOBBER,ncout) - CALL hdlerr(stat,'creating '//fnamout) - stat = nf_def_dim(ncout,'lon',nlon,outdimids(1)) - CALL hdlerr(stat,'define lon dimension') - stat = nf_def_dim(ncout,'lat',nlat,outdimids(2)) - CALL hdlerr(stat,'define lat dimension') - stat = nf_def_dim(ncout,'ntiles',ntiles,outdimids(3)) - CALL hdlerr(stat,'define tile dimension') - stat = nf_def_dim(ncout,'lct',nlct,outdimids(4)) - CALL hdlerr(stat,'define lct dimension') - stat = nf_def_dim(ncout,'soillev',nsoil,outdimids(5)) - CALL hdlerr(stat,'define soillev dimension') - stat = nf_def_dim(ncout,'time',ntime,outdimids(6)) - CALL hdlerr(stat,'define time dimension') - - !-- get longitudes - varname='lon' - varname_out='lon' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (lon(nlon)) - stat = nf_get_var_double(ncin,varid,lon) - CALL hdlerr(stat,'get latitudes from '//fnam0) - CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get latitudes - varname='lat' - varname_out='lat' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (lat(nlat)) - stat = nf_get_var_double(ncin,varid,lat) - CALL hdlerr(stat,'get latitudes from '//fnam0) - CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam0) - - !-- define tiles - stat = nf_def_var(ncout, 'ntiles', NF_INT, 1, outdimids(3), varid) - CALL hdlerr(stat,'define var ntiles') - stat = nf_put_att_text(ncout, varid,'long_name', 5, 'tiles') - CALL hdlerr(stat,'define var ntiles') - - !-- define soil layers - stat = nf_def_var(ncout, 'soillev', NF_DOUBLE, 1, outdimids(5), varid) - CALL hdlerr(stat,'define var soillev') - stat = nf_put_att_text(ncout, varid, 'long_name', 27, 'soil layer (lower boundary)') - CALL hdlerr(stat,'define long_name soillev') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define unit soillev') - stat = nf_put_att_text(ncout, varid, 'axis', 1, 'Z') - CALL hdlerr(stat,'define axis type soillev') - - !-- define soil layer thickness - stat = nf_def_var(ncout, 'soil_layer_depth', NF_DOUBLE, 1, outdimids(5), varid) - CALL hdlerr(stat,'define var soil_layer_depth') - stat = nf_put_att_text(ncout, varid, 'long_name', 20, 'soil layer thickness') - CALL hdlerr(stat,'define var soil_layer_depth') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define unit soil_layer_depth') - - !-- define time - stat = nf_def_var(ncout, 'time', NF_INT, 1, outdimids(6), varid) - CALL hdlerr(stat,'define var time') - stat = nf_put_att_text(ncout,varid,'units',16,'days since 1-1-1') - CALL hdlerr(stat,'define time units') - -!------------------------------------- -! input-file1: jan_surf -!------------------------------------- - CALL open_file(info,fnam1,ncin) - IF (TRIM(masks_file) /= 'default') CALL open_file(info, fnam15, ncin15) - - !-- get soil wetness - varname='WS' - varname_out='init_moist' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (moisture(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,moisture) - CALL hdlerr(stat,'get soil wetness from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get snow depth - varname='SN' - varname_out='snow' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (snow(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,snow) - CALL hdlerr(stat,'get snow depth from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get fractional and integer land sea mask (if available) - - ! check whether integer mask is available - IF (TRIM(masks_file) /= 'default') THEN - ncid=ncin15 - ELSE - ncid=ncin - END IF - varname='SLF' - stat=nf_inq_varid(ncid,varname,varid) - IF (stat == NF_NOERR) THEN - slm_in_input=.TRUE. - ELSE - slm_in_input=.FALSE. - varname='SLM' ! contains fractional land sea mask - END IF - - !-- get fractional land sea mask - varname_out='slf' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (slf(nlon,nlat)) ! fractional land sea mask - stat = nf_get_var_double(ncid,varid,slf) - CALL hdlerr(stat,'get fractional land sea mask from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - !-- get fractional lake mask - varname='ALAKE' - varname_out='lake' - stat=nf_inq_varid(ncid,varname,varid) - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (lake(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,lake) - CALL hdlerr(stat,'get lake mask from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - ! -- get integer land sea mask and glacier mask - IF (slm_in_input) THEN - varname='SLM' - varname_out='slm' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (slm(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,slm) - CALL hdlerr(stat,'get integer land sea mask from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - ELSE - ! calculate SLM from SLF and ALAKE - ALLOCATE (slm(nlon,nlat)) ! integer land sea mask - slm=0._dp - IF (TRIM(res_atm) == 'T31' .AND. TRIM(res_oce) == 'GR30') THEN - IF (slm_fraction /= 0.435_dp) THEN - CALL hdlerr(stat,'slm_fraction for T31GR30 should be 0.435') - END IF - DO i=1,nlon - DO j=1,nlat - IF (j <= nlat/3 .OR. j > 2*nlat/3) THEN ! extratropics - IF (slf(i,j) > 0.5_dp) slm(i,j) = 1._dp - ELSE ! tropics - IF (slf(i,j) > slm_fraction) slm(i,j) = 1._dp - IF (slf(i,j) > slm_fraction .AND. slf(i,j) <= 0.5_dp) & - WRITE (*,*) 'Land point while slf is < 0.5: ',i,j,slf(i,j) - END IF - END DO - END DO - ELSE - WHERE (slf(:,:) > slm_fraction .AND. .NOT. lake > 0.5_dp) -! .OR. lake >= 1._dp - slm_fraction .AND. .NOT. lake > 0.5_dp) - slm(:,:) = 1._dp - END WHERE - END IF - varname_out='slm' - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - END IF - - ! LU-maps should be independant from the land-sea-mask (i.e. work with different ocean resolutions) - IF (cover_fract_only) THEN - slm(:,:) = 1._dp - END IF - - varname='GLAC' - varname_out='glac' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (glac_dp(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,glac_dp) - CALL hdlerr(stat,'get glacier mask from'//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - IF (echam_fractional) THEN - missval=-9999._dp - WHERE (slm(:,:) == 0._dp .AND. SPREAD(ABS(lat(:)), DIM=1, NCOPIES=nlon) > 50) - glac_dp(:,:) = missval - END WHERE - WHERE (slf(:,:) > 0._dp .AND. lake(:,:) < 1._dp) - slm(:,:) = 1._dp - END WHERE - CALL extrap(nlon, nlat, lon, lat, slm, missval, 'modal', glac_dp) - END IF - - ! define non-glacier land mask (internally used) - ALLOCATE (non_glacier_land(nlon,nlat)) - WHERE (slm(:,:) > 0._dp .AND. glac_dp(:,:) < 1._dp) - non_glacier_land = 1._dp - ELSEWHERE - non_glacier_land = 0._dp - END WHERE - - !-- get surface roughness length - varname='AZ0' - varname_out='roughness_length' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (az0(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,az0) - CALL hdlerr(stat,'get surface roughness length from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get surface background albedo - varname='ALB' - varname_out='albedo' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo) - CALL hdlerr(stat,'get surface background albedo from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get mean orography - varname='OROMEA' - varname_out='elevation' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (elevation(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,elevation) - CALL hdlerr(stat,'get mean orography from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - !-- get orographic standard deviation - varname='OROSTD' - varname_out='orography_std_dev' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (elevationrms(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,elevationrms) - CALL hdlerr(stat,'get orographic standard deviation from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - !-- get FAO data set (soil data flags) - varname='FAO' - varname_out='fao' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (fao(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,fao) - CALL hdlerr(stat,'get FAO from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get forest fraction - varname='FOREST' - varname_out='forest_fract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (forest_fract(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,forest_fract) - CALL hdlerr(stat,'get forest fraction from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam1) - -!------------------------------------------ -! input-file1 or 14: field capacity of soil -!------------------------------------------ - - IF (maxmoist_version == 'LSP2') THEN - varname='WSMX' - fnam=fnam1 - ELSE IF (maxmoist_version == 'LSP3') THEN - - ! With dynveg, the soilwater in the root zone needs to be above a certain minimum value, - ! not to suppress plant growth with climate change. - IF (ldynveg) THEN - varname='wcap_dynveg' - ELSE - varname='wcap' - END IF - fnam=fnam14 - ELSE - CALL hdlerr(stat,'value for namelist parameter maxmoist_version not supported') - END IF - CALL open_file(info,fnam,ncin) - - varname_out='maxmoist' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (max_moisture(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,max_moisture) - CALL hdlerr(stat,'get field capacity of soil from '//fnam) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missmxm) - IF (maxmoist_version == 'LSP2') missmxm = 0._dp - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam) - -!------------------------------------- -! input-file2: VLTCLIM -!------------------------------------- - CALL open_file(info,fnam2,ncin) - - !-- get climatolgy of the leaf area index - varname='VLTCLIM' - varname_out='lai_clim' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (lai(nlon,nlat,ntime)) - stat = nf_get_var_double(ncin,varid,lai) - CALL hdlerr(stat,'get leaf area index from'//fnam2) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam2) - -!------------------------------------- -! input-file3: VGRATCLIM -!------------------------------------- - CALL open_file(info,fnam3,ncin) - - !-- get climatology of vegetation ratio - varname='VGRATCLIM' - varname_out='veg_fract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (veg_fract(nlon,nlat,ntime)) - stat = nf_get_var_double(ncin,varid,veg_fract) - CALL hdlerr(stat,'get vegetation ratio from'//fnam3) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam3) - -!------------------------------------- -! input-file4: TSLCLIM2 -!------------------------------------- - CALL open_file(info,fnam4,ncin) - - !-- get climatology of land surface temperature - varname='TSLCLIM' - varname_out='surf_temp' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (surf_temp(nlon,nlat,ntime)) - stat = nf_get_var_double(ncin,varid,surf_temp) - CALL hdlerr(stat,'get surface temperature from'//fnam4) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam4) - -!------------------------------------- -! input-file5: cover fractions from Julia Pongratz (30.8.2006) -! based on natural vegetation distribution of Ramankutty -!------------------------------------- - ! With lread_pasture we use natural vegetation and separate maps for crops and pastures. - IF ( .NOT. lread_pasture) THEN - CALL open_file(info,fnam5,ncin) - - !-- get fractional cover - varname='vegfract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (vegfract(nlon,nlat,nvegtyp)) - stat = nf_get_var_double(ncin,varid,vegfract) - CALL hdlerr(stat,'get fractional cover from'//fnam5) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam5) - ELSE - ALLOCATE (vegfract(nlon,nlat,nvegtyp)) - END IF - - varname_out='cover_fract' - CALL define_var_new(ncout, varname_out, 3, outdimids(1:3)) - varname_out='cover_type' - CALL define_var_new(ncout, varname_out, 3, outdimids(1:3)) - -!------------------------------------- -! input-file6: vegmax_6 (max. vegetation cover) -!------------------------------------- - CALL open_file(info,fnam6,ncin) - - !-- get veg_ratio_max - varname='veg_ratio_max' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (veg_ratio_max(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,veg_ratio_max) - CALL hdlerr(stat,'get veg_ratio_max from'//fnam6) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam6) - - IF (desert_only) veg_ratio_max(:,:) = 0._dp - IF (grass_only .OR. woods_only) THEN - WHERE (slm(:,:) > 0.5_dp .AND. glac_dp(:,:) < 0.5_dp) - veg_ratio_max(:,:) = 1._dp - END WHERE - END IF - IF (ignore_measurements) THEN - veg_ratio_max(:,:) = 1._dp - END IF - - !-- veg_ratio_max should be non-zero - missval=0._dp - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missval, 'mean', veg_ratio_max) - WHERE (non_glacier_land(:,:) > 0.5_dp) - veg_ratio_max(:,:) = MAX(small_fract,veg_ratio_max(:,:)) - END WHERE - varname_out='veg_ratio_max' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - -!------------------------------------- -! input-file7: albedo (nir/vis vegetation/soil albedo) -!------------------------------------- - CALL open_file(info,fnam7,ncin) - - !-- get albedo - varname='albedo_veg_vis' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo_veg_vis_in(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo_veg_vis_in) - CALL hdlerr(stat,'get vegetation albedo in vis. range from'//fnam7) - - varname='albedo_veg_nir' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo_veg_nir_in(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo_veg_nir_in) - CALL hdlerr(stat,'get vegetation albedo in NIR from'//fnam7) - - varname='albedo_soil_vis' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo_soil_vis_in(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo_soil_vis_in) - CALL hdlerr(stat,'get soil albedo in vis. range from'//fnam7) - - varname='albedo_soil_nir' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo_soil_nir_in(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo_soil_nir_in) - CALL hdlerr(stat,'get soil albedo in NIR from'//fnam7) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam7) - - ALLOCATE (albedo_veg_vis(nlon,nlat)) - ALLOCATE (albedo_veg_nir(nlon,nlat)) - ALLOCATE (albedo_soil_vis(nlon,nlat)) - ALLOCATE (albedo_soil_nir(nlon,nlat)) - DO j = 1,nlat - albedo_compensate = 0.0_dp - IF (ABS(lat(j)) > 40._dp) THEN - albedo_compensate = 0.01_dp - END IF - IF (ABS(lat(j)) > 50._dp) THEN - albedo_compensate = 0.02_dp - END IF - IF (ABS(lat(j)) > 60._dp) THEN - albedo_compensate = 0.03_dp - END IF - IF (ABS(lat(j)) > 70._dp) THEN - albedo_compensate = 0.04_dp - END IF - IF (.NOT. ignore_measurements) THEN - DO i = 1,nlon/2 - albedo_veg_vis(i,j) = albedo_veg_vis_in(i + nlon/2,j) + albedo_compensate - albedo_veg_nir(i,j) = albedo_veg_nir_in(i + nlon/2,j) + albedo_compensate - albedo_soil_vis(i,j) = albedo_soil_vis_in(i + nlon/2,j) + albedo_compensate - albedo_soil_nir(i,j) = albedo_soil_nir_in(i + nlon/2,j) + albedo_compensate - END DO - DO i = nlon/2 + 1,nlon - albedo_veg_vis(i,j) = albedo_veg_vis_in(i - nlon/2,j) + albedo_compensate - albedo_veg_nir(i,j) = albedo_veg_nir_in(i - nlon/2,j) + albedo_compensate - albedo_soil_vis(i,j) = albedo_soil_vis_in(i - nlon/2,j) + albedo_compensate - albedo_soil_nir(i,j) = albedo_soil_nir_in(i - nlon/2,j) + albedo_compensate - END DO - ELSE ! ignore measured data from the continents, only use background values - albedo_veg_vis(:,j) = albedo_veg_vis_in(1,1) + albedo_compensate - albedo_veg_nir(:,j) = albedo_veg_nir_in(1,1) + albedo_compensate - albedo_soil_vis(:,j) = albedo_soil_vis_in(1,1) + albedo_compensate - albedo_soil_nir(:,j) = albedo_soil_nir_in(1,1) + albedo_compensate - END IF - END DO - DEALLOCATE (albedo_veg_vis_in, albedo_veg_nir_in, albedo_soil_vis_in, albedo_soil_nir_in) - - varname_out='albedo_veg_vis' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - varname_out='albedo_veg_nir' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - varname_out='albedo_soil_vis' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - varname_out='albedo_soil_nir' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - -!------------------------------------- -! input-file8: topo_75 (roughness of the orography) -!------------------------------------- - ALLOCATE (roughness_oro(nlon,nlat)) - IF (.NOT. ignore_measurements) THEN - CALL open_file(info,fnam8,ncin) - - !-- get roughness length - varname='roughness_length_oro' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,roughness_oro) - CALL hdlerr(stat,'get roughness length of the orography from'//fnam8) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam8) - - roughness_oro(:,:) = MIN(20._dp,roughness_oro(:,:)) - ELSE - ! simply taking the same arrays for roughness_length and roughness_length_oro - roughness_oro(:,:) = MIN(20._dp,az0(:,:)) - END IF - varname_out='roughness_length_oro' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - -!------------------------------------- -! input-file9: cover fractions from Julia Pongratz (30.8.2006) -! based on natural vegetation distribution of Ramankutty -!------------------------------------- - - IF (year_ct /= year_cf .AND. .NOT. lread_pasture) THEN - CALL open_file(info,fnam9,ncin) - - !-- get cover fractions of year year_cf - varname='vegfract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (vegfract_cf(nlon,nlat,nvegtyp)) - stat = nf_get_var_double(ncin,varid,vegfract_cf) - CALL hdlerr(stat,'get fractional cover from'//fnam9) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam9) - END IF - -!------------------------------------- -! input-file10: C3/C4 mask -!------------------------------------- - CALL open_file(info,fnam10,ncin) - - !-- get C3/C4 fmask - varname='1C3_0C4' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (C3C4_flag(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,C3C4_flag) - CALL hdlerr(stat,'get C3/C4 flag from'//fnam10) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam10) - - C3C4_flag(:,:) = MIN(1.1_dp,MAX(-0.1_dp,C3C4_flag(:,:))) - -!------------------------------------- -! input-file11: C3 and C4 crops -!------------------------------------- - - ALLOCATE (C3_crop(nlon,nlat)) - C3_crop(:,:) = 0._dp - ALLOCATE (C4_crop(nlon,nlat)) - C4_crop(:,:) = 0._dp - - IF (lc3c4crop) THEN - CALL open_file(info,fnam11,ncin) - - !-- get C3 and C4 maps - varname='C3_crop' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,C3_crop) - CALL hdlerr(stat,'get map of C3 crop from'//fnam11) - varname='C4_crop' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,C4_crop) - CALL hdlerr(stat,'get map of C4 crop from'//fnam11) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam11) - END IF - -!------------------------------------- -! input-file12: pasture and crop fractions -! based on harmonized landuse scenarios needed for CMIP -!------------------------------------- - - ALLOCATE (pasture(nlon,nlat)) - pasture(:,:) = 0._dp - ALLOCATE (crop(nlon,nlat)) - crop(:,:) = 0._dp - - IF (lread_pasture) THEN - CALL open_file(info,fnam12,ncin) - - !-- get pasture fractions - varname='gpast' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,pasture) - CALL hdlerr(stat,'get map of pasture fractions from'//fnam12) - CALL get_missval(ncin, varid, missval) - WHERE (pasture(:,:) == missval) pasture(:,:) = 0._dp - - !-- get crop fractions - varname='gcrop' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,crop) - CALL hdlerr(stat,'get map of crop fractions from'//fnam12) - CALL get_missval(ncin, varid, missval) - WHERE (crop(:,:) == missval) crop(:,:) = 0._dp - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam12) - END IF - -!------------------------------------- -! input-file13: potential vegetation (Julia Pongratz) -! based on natural vegetation distribution of Ramankutty -!------------------------------------- - IF (ldynveg .OR. lread_pasture) THEN - CALL open_file(info,fnam13,ncin) - - !-- get fractional cover - varname='cover_fract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (potveg(nlon,nlat,nvegtyp)) - stat = nf_get_var_double(ncin,varid,potveg) - CALL hdlerr(stat,'get potential vegetation from'//fnam13) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam13) - - varname_out='natural_veg' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 3, outdimids(1:3)) - END IF - -!------------------------------------- -! input-file14: 5 soil layer parameters (Stefan Hagemann) -!------------------------------------- - CALL open_file(info,fnam14,ncin) - - !-- get soil depth - varname='soildepth' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (soil_depth(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,soil_depth) - CALL hdlerr(stat,'get soil depth from'//fnam14) - varname_out='soil_depth' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missdep) - - !-- get soil porosity - varname='volporosity' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (soil_porosity(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,soil_porosity) - CALL hdlerr(stat,'get soil porosity from'//fnam14) - varname_out='soil_porosity' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misspor) - - !-- get soil pore size index - varname='psi_lambda' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (pore_size_index(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,pore_size_index) - CALL hdlerr(stat,'get soil pore size index from'//fnam14) - varname_out='pore_size_index' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misspsi) - - !-- get soil field capacity - varname='volfc' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (soil_field_capacity(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,soil_field_capacity) - CALL hdlerr(stat,'get soil field cap from'//fnam14) - varname_out='soil_field_cap' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missfca) - - !-- get soil heat capacity - varname='heatcapacity' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (heat_capacity(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,heat_capacity) - CALL hdlerr(stat,'get soil heat capacity from'//fnam14) - varname_out='heat_capacity' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misshca) - - !-- get soil heat conductivity - varname='heatcond' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (heat_conductivity(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,heat_conductivity) - CALL hdlerr(stat,'get soil heat conductivity from'//fnam14) - varname_out='heat_conductivity' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misshco) - - !-- get soil moisture potential - varname='matrixpot' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (matrix_potential(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,matrix_potential) - CALL hdlerr(stat,'get soil moisture potential from'//fnam14) - varname_out='moisture_pot' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missmpo) - - !-- get saturated hydraulic conductivity - varname='hydcond' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (hyd_cond_sat(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,hyd_cond_sat) - CALL hdlerr(stat,'get saturated hydraulic conductivity from'//fnam14) - varname_out='hyd_cond_sat' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misshyc) - - !-- get wilting point - varname='volpwp' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (wilting_point(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,wilting_point) - CALL hdlerr(stat,'get wilting point from'//fnam14) - varname_out='wilting_point' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misswpo) - - !-- get Clapp & Hornberger exponent b - varname='bclapp' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (bclapp(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,bclapp) - CALL hdlerr(stat,'get Clapp & Hornberger exponent b from'//fnam14) - varname_out='bclapp' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missbcl) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam14) - - !-- Define output variables to be calculated - varname_out='root_depth' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - - varname_out='layer_moist' - dimids(1:3)=(/outdimids(1),outdimids(2),outdimids(5)/) - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 3, dimids(1:3)) - -!------------------------------------------------------------------------------ -! CREATE OUTPUT FIELDS -!------------------------------------------------------------------------------ -! TILES -!-------------------- - ALLOCATE (tiles(ntiles)) - DO i=1,ntiles - tiles(i) = i - END DO - -! SOIL LAYER -!-------------------- - ALLOCATE (layer_depth(nsoil)) - IF (nsoil == 5) THEN - layer_depth=(/0.065_dp,0.254_dp,0.913_dp,2.902_dp,5.700_dp/) - ELSE IF (nsoil /= 1) THEN - CALL hdlerr(1,"currently only 5 soil layers supported") - END IF - - ALLOCATE (soillev(nsoil)) - soillev(1) = layer_depth(1) - DO i=2,nsoil - soillev(i) = soillev(i-1) + layer_depth(i) - END DO - -!-------------------- -! TIME -!-------------------- - ALLOCATE (time_days(12)) - time_days=(/30,58,89,119,150,180,211,242,272,303,333,364/) - - -!--------------------------------- -! cover types and cover fractions -!--------------------------------- - - ALLOCATE (cover_type(nlon,nlat,ntiles)) - ALLOCATE (cover_fract(nlon,nlat,ntiles)) - ALLOCATE (vegfract_for_types(nvegtyp)) - ALLOCATE (is_naturalveg(ntiles)) - IF (ldynveg .OR. lread_pasture) ALLOCATE (natural_veg(nlon,nlat,ntiles)) - - DO j=1,nlat - DO i=1,nlon - ! - !-- calculate cover fractions depending on the number of tiles - ! - - IF (slm(i,j) < 0.5_dp) THEN - - !-- ocean - cover_type(i,j,:) = 0 - cover_fract(i,j,:) = 0._dp - IF (ldynveg .OR. lread_pasture) natural_veg(i,j,:) = 0._dp - ELSE - - !-- land - - ! if crops and pastures are read from a separate file, use the - ! potential vegetation to get the fractions of the natural types - IF (lread_pasture) vegfract(i,j,:) = potveg(i,j,:) - - - !-- adapt vegetation fractions to derive reasonable types - - vegfract_for_types(:) = vegfract(i,j,:) - CALL adapt_vegfract (lat(j), NINT(C3C4_flag(i,j)), info, .TRUE., & - lpasture, ignore_measurements, vegfract_for_types(:)) - - - !-- calculate the cover types - - CALL calc_cover_types (ntiles, lat(j), NINT(glac_dp(i,j)), & - vegfract_for_types(:), lc3c4crop, C3_crop(i,j), C4_crop(i,j), & - cover_type(i,j,:), second_woody, second_grass, dominant_crop, & - is_naturalveg(:)) - - - !-- make sure all land points have reasonable vegetation fractions - ! (actual vegetation: vegfract; potential vegetation: potveg) - - IF (year_ct == year_cf .OR. lread_pasture) THEN - CALL adapt_vegfract (lat(j), NINT(C3C4_flag(i,j)), info, .FALSE., & - lpasture, ignore_measurements, vegfract(i,j,:)) - ELSE - CALL adapt_vegfract (lat(j), NINT(C3C4_flag(i,j)), info, .FALSE., & - lpasture, ignore_measurements, vegfract_cf(i,j,:)) - vegfract(i,j,:) = vegfract_cf(i,j,:) - END IF - IF (ldynveg .OR. lread_pasture) THEN - CALL adapt_vegfract (lat(j), NINT(C3C4_flag(i,j)), info, .FALSE., & - .FALSE., ignore_measurements, potveg(i,j,:)) - END IF - - - !-- calculate the actual cover fractions - - CALL calc_cover_fractions (ntiles, lat(j), cover_type(i,j,:), & - second_woody, second_grass, NINT(glac_dp(i,j)), vegfract(i,j,:), & - grass_only, woods_only, lc3c4crop, C3_crop(i,j), C4_crop(i,j), & - crop(i,j), lread_pasture, lpasture_rule, pasture(i,j), & - NINT(C3C4_flag(i,j)), cover_fract(i,j,:)) - - !-- make sure, that all vegetation types have a minimum fraction of - ! small_fract and the sum of all vegetation is 1. in all grid cells. - - CALL scale_cover_fract (ntiles, is_naturalveg(:), NINT(glac_dp(i,j)), & - cover_fract(i,j,:)) - - IF (ldynveg .OR. lread_pasture) THEN - - !-- calculate the potential vegetation - - CALL calc_cover_fractions (ntiles, lat(j), cover_type(i,j,:), & - second_woody, second_grass, NINT(glac_dp(i,j)), potveg(i,j,:), & - grass_only, woods_only, lc3c4crop, 0._dp, 0._dp, & - 0._dp, .FALSE., lpasture_rule, 0._dp, & - NINT(C3C4_flag(i,j)), natural_veg(i,j,:)) - - CALL scale_cover_fract (ntiles, is_naturalveg(:), NINT(glac_dp(i,j)), & - natural_veg(i,j,:)) - - !-- make sure, that potential cover fractions of natural vegetation are - ! greater than the actual cover fractions. - - CALL harmonize_fractions (ntiles, is_naturalveg(:), NINT(glac_dp(i,j)), & - natural_veg(i,j,:), cover_fract(i,j,:)) - END IF - - END IF - END DO - END DO - - DEALLOCATE (crop, pasture, vegfract_for_types, C3C4_flag, is_naturalveg) - IF (year_ct /= year_cf .AND. .NOT. lread_pasture) DEALLOCATE(vegfract_cf) - IF (ldynveg .OR. lread_pasture) DEALLOCATE (potveg) - - - IF (.NOT. cover_fract_only) THEN - !-------------------------------------------------- - ! get fao map consistent with land-sea mask - !-------------------------------------------------- - missval=0._dp - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missval, 'modal', fao) - WHERE (glac_dp(:,:) == 1._dp) - fao(:,:) = 3._dp - END WHERE - - !--------------------------------------------------------------------- - ! get soil parameter arrays consistent with land sea and glacier mask - !--------------------------------------------------------------------- - IF (ignore_measurements) THEN - moisture(:,:) = 0.3_dp ! [m] - max_moisture(:,:) = 0.5_dp ! [m] - fao(:,:) = 3._dp ! [] - matrix_potential(:,:) = 0.3_dp ! [m] - bclapp(:,:) = 6._dp ! [] - heat_capacity(:,:) = 2.26E06_dp ! [J m-3 K-1] - heat_conductivity(:,:) = 6._dp ! [J m-1 s-1 K-1] - soil_porosity(:,:) = 0.45_dp ! [m/m] - soil_depth(:,:) = 5._dp ! [m] - soil_field_capacity(:,:) = 0.3_dp ! [m/m] - pore_size_index(:,:) = 0.3_dp ! [] - hyd_cond_sat(:,:) = 6.E-06_dp ! [m/s] - wilting_point(:,:) = 0.15_dp ! [m/m] - END IF - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missmpo, 'mean', matrix_potential) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missbcl, 'mean', bclapp) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misshca, 'mean', heat_capacity) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misshco, 'mean', heat_conductivity) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misspor, 'mean', soil_porosity) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missdep, 'mean', soil_depth) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missfca, 'mean', soil_field_capacity) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misspsi, 'mean', pore_size_index) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misshyc, 'mean', hyd_cond_sat) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misswpo, 'mean', wilting_point) - - - !---------------------------------------------------------------------- - ! get consistant values for water holding capacity and soil parameters - !---------------------------------------------------------------------- - ALLOCATE (max_soilwater(nlon,nlat)) - ALLOCATE (root_depth(nlon,nlat)) - - ! - ! max_soilwater: maximum amount of water possibly held in soil - ! soilwater: initial amount of soil water - ! max_moisture: maximum amount of water reachable for plants - ! moisture: initial amount of water reachable for plants - ! root_depth: length of the roots - ! soil_depth: depth of the soil above bedrock - - ! soil_depth - !------------ - ! Since Lithosols are defined by FAO/Unesco as "soils which are limited in - ! depth by continuous coherent hard rock within 10 cm of the surface," I - ! don't see the need to differentiate between them to such a degree (for - ! my purposes). I consider all Lithosols to be 10 cm thick, and use only - ! the surface texture to distinguish them. (K. Dunne, pers. comm to St. Hagemann, 1995) - ! => soil_depth needs to be at least 10 cm if area is not impermeable. - WHERE (non_glacier_land == 1) - soil_depth(:,:) = MAX(soil_depth(:,:), 0.1_dp) - END WHERE - - ! maximum amount of water fitting into the soil - max_soilwater(:,:) = soil_field_capacity(:,:) * soil_depth(:,:) - - ! max_moisture - !-------------- - ! get max_moisture values for all land grid cells - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missmxm, 'mean', max_moisture) - - ! maximum amount of water in the root zone cannot be more than what is fitting into the soil - max_moisture(:,:) = MIN(max_moisture(:,:), max_soilwater(:,:)) - - ! define small value on glaciers for technical reasons - WHERE (glac_dp == 1) - max_moisture(:,:) = small_fract - END WHERE - - ! root_depth - !------------ - ! root depth is calculated backwards from the maximum amout of water in the root zone - WHERE (soil_field_capacity(:,:) > 0._dp) - root_depth(:,:) = MIN(soil_depth(:,:), max_moisture(:,:)/soil_field_capacity(:,:)) - ELSEWHERE - root_depth(:,:) = 0._dp - ENDWHERE - - DEALLOCATE (max_soilwater) - - - !----------------------------------------------------------- - ! adapt initial soil moisture - !----------------------------------------------------------- - - ALLOCATE (soilwater(nlon,nlat)) - ALLOCATE (soil_depth_layer(nlon,nlat,nsoil)) - ALLOCATE (soilwater_layer(nlon,nlat,nsoil)) - - ! initial soil moisture must be below maximum soil moisture - moisture(:,:) = MIN(moisture(:,:), max_moisture(:,:)) - ! ... and should not be too small to prevent vegetation die back due to initialization - moisture(:,:) = MAX(moisture(:,:), 0.5_dp*max_moisture(:,:)) - - ! initialize soil moisture below the wilting point in desert areas - WHERE (veg_ratio_max(:,:) < 0.2_dp) - moisture(:,:) = MIN(moisture(:,:), 0.3_dp*max_moisture(:,:)) - END WHERE - - ! initial moisture value for each soil level - ! ------------------------------------------ - - ! initial value of total amount of soil water (not in initial file) - WHERE (root_depth(:,:) > 0._dp) - soilwater(:,:) = moisture(:,:) * soil_depth(:,:) / root_depth(:,:) - ELSEWHERE - soilwater(:,:) = 0._dp - ENDWHERE - - ! calculate soil layer depth for each soil level - soil_depth_layer(:,:,1) = MIN(soil_depth(:,:), layer_depth(1)) - DO i=2,nsoil - WHERE (soil_depth(:,:) > SUM(layer_depth(1:i-1))) - soil_depth_layer(:,:,i) = MIN(soil_depth(:,:)-SUM(layer_depth(1:i-1)), layer_depth(i)) - ELSEWHERE - soil_depth_layer(:,:,i) = 0._dp - ENDWHERE - END DO - - ! initial moisture value for each soil level - ! Conservation of soil water (all soil water, even below root zone) - DO i=1,nsoil - WHERE (soilwater(:,:) >= 0._dp .AND. soil_depth(:,:) > 0._dp ) - soilwater_layer(:,:,i) = soilwater(:,:)/soil_depth(:,:) * soil_depth_layer(:,:,i) - ELSEWHERE - soilwater_layer(:,:,i) = 0._dp - ENDWHERE - END DO - - DEALLOCATE(soilwater) - DEALLOCATE(soil_depth_layer) - - END IF ! .NOT. cover_fract_only - -!----------------------------------------------------------- -! calculate areas covered by grass, woods, deserts -!----------------------------------------------------------- - ALLOCATE (dummy(nlat)) - ALLOCATE (gauss_weights(nlat)) - CALL gauaw(dummy,gauss_weights,nlat,pi) - ALLOCATE (grid_area(nlon,nlat)) - IF (echam_fractional) THEN - grid_area(:,:) = slf(:,:) * SPREAD(gauss_weights(:), DIM=1, NCOPIES=nlon) & - * 2._dp * pi * radius_of_earth**2 / REAL(nlon) - ELSE - grid_area(:,:) = SPREAD(gauss_weights(:), DIM=1, NCOPIES=nlon) & - * 2._dp * pi * radius_of_earth**2 / REAL(nlon) - END IF - DEALLOCATE (dummy) - area_tropical_forest = 0._dp - area_temperate_forest = 0._dp - area_woody = 0._dp - area_shrubs = 0._dp - area_crops = 0._dp - area_pasture = 0._dp - area_grass = 0._dp - area_all = 0._dp - area_lake = 0._dp - area_land = 0._dp - area_land_tropics = 0._dp - area_land_extratropics = 0._dp - area_glac = 0._dp - DO j = 1,nlat - DO i = 1,nlon - IF (echam_fractional) THEN - area_all = area_all + gauss_weights(j) * 2._dp * pi * radius_of_earth**2 / REAL(nlon) - ELSE - area_all = area_all + grid_area(i,j) - END IF - IF (lake(i,j) > 0.5_dp) area_lake = area_lake + grid_area(i,j) - IF (slm(i,j) > 0.5_dp) THEN ! land - area_land = area_land + grid_area(i,j) - DO k = 1,ntiles - - ! tropical forest - IF (cover_type(i,j,k) == lct_tropical_evergreen & - .OR. cover_type(i,j,k) == lct_tropical_deciduous) THEN - area_tropical_forest = area_tropical_forest + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - area_woody = area_woody + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! temperate forest - ELSE IF (cover_type(i,j,k) == lct_extratrop_evergreen & - .OR. cover_type(i,j,k) == lct_extratrop_deciduous & - .OR. cover_type(i,j,k) == lct_temperate_broadl_evergreen & - .OR. cover_type(i,j,k) == lct_temperate_broadl_deciduous & - .OR. cover_type(i,j,k) == lct_evergreen_conifer & - .OR. cover_type(i,j,k) == lct_deciduous_conifer) THEN - area_temperate_forest = area_temperate_forest + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - area_woody = area_woody + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! shrubs - ELSE IF (cover_type(i,j,k) == lct_raingreen_shrub & - .OR. cover_type(i,j,k) == lct_deciduous_shrub) THEN - area_shrubs = area_shrubs + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - area_woody = area_woody + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! grass (and pasture) - ELSE IF (cover_type(i,j,k) == lct_c3grass & - .OR. cover_type(i,j,k) == lct_c4grass) THEN - area_grass = area_grass + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! crops - ELSE IF (cover_type(i,j,k) == lct_crop & - .OR. cover_type(i,j,k) == lct_c3crop & - .OR. cover_type(i,j,k) == lct_c4crop) THEN - area_crops = area_crops + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! pasture - ELSE IF (cover_type(i,j,k) == lct_pasture & - .OR. cover_type(i,j,k) == lct_c3pasture & - .OR. cover_type(i,j,k) == lct_c4pasture) THEN - area_pasture = area_pasture + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - END IF - - ! glaciers - IF (glac_dp(i,j) >= 0.5_dp) THEN - area_glac = area_glac + grid_area(i,j) * cover_fract(i,j,k) - - ! tropical land - ELSE IF (j <= nlat/3 .OR. j > 2*nlat/3) THEN - area_land_extratropics = area_land_extratropics & - + grid_area(i,j) * cover_fract(i,j,k) - - ! extratropical land - ELSE - area_land_tropics = area_land_tropics & - + grid_area(i,j) * cover_fract(i,j,k) - END IF - END DO - END IF - END DO - END DO - DEALLOCATE (gauss_weights, grid_area) - DEALLOCATE (non_glacier_land) - - IF (info) THEN - WRITE (*,*) '' - WRITE (*,*) 'The surface of the globe [km2]: ',area_all * 1.e-06 - WRITE (*,*) 'Global land surface [km2]: ',area_land * 1.e-06 - WRITE (*,*) 'Global land surface including lakes [km2]: ',(area_land+area_lake) * 1.e-06 - WRITE (*,*) 'Global glacier [km2]: ',area_glac * 1.e-06_dp - WRITE (*,*) 'Land tropics [km2]: ',area_land_tropics * 1.e-06 - WRITE (*,*) 'Land extratropics [km2]: ',area_land_extratropics * 1.e-06 - WRITE (*,*) 'nlat,nlat/3,2*nlat/3: ',nlat,nlat/3,2*nlat/3 - WRITE (*,*) 'Area of tropical forest [km2]: ',area_tropical_forest * 1.e-06 - WRITE (*,*) 'Area of temperate + boreal forest [km2]: ',area_temperate_forest * 1.e-06 - WRITE (*,*) 'Area of crops[km2]: ',area_crops * 1.e-06 - WRITE (*,*) 'Area of pasture [km2]: ',area_pasture * 1.e-06 - WRITE (*,*) 'Area of all woody types [km2]: ',area_woody * 1.e-06 - WRITE (*,*) 'Area of grass lands (incl. pastures)[km2]: ',area_grass * 1.e-06 - ENDIF - -!------------------------------------------------------------------------------ -! Write the output file -!------------------------------------------------------------------------------ - - CALL set_global_attributes(ncout, year_ct, year_cf, res_oce, res_atm, & - nlct, ntiles, nsoil, lcouple, ldynveg, lc3c4crop, lpasture, lread_pasture, & - lpasture_rule, desert_only, grass_only, woods_only, ignore_measurements, & - echam_fractional, maxmoist_version, pasture_tag, masks_file, svn_url, svn_rev) - stat = nf_enddef(ncout) - CALL hdlerr(stat,'problem with enddef') - - !-- dimension variables - - stat = nf_inq_varid(ncout,'lat',varid) - CALL hdlerr(stat,'cannot find lat') - stat = nf_put_var_double(ncout,varid,lat(:)) - CALL hdlerr(stat,'put variable lat') - DEALLOCATE(lat) - - stat = nf_inq_varid(ncout,'lon',varid) - CALL hdlerr(stat,'cannot find lon') - stat = nf_put_var_double(ncout,varid,lon(:)) - CALL hdlerr(stat,'put variable lon') - DEALLOCATE(lon) - - stat = nf_inq_varid(ncout,'ntiles',varid) - CALL hdlerr(stat,'cannot find ntiles') - stat = nf_put_var_int(ncout,varid,tiles(:)) - CALL hdlerr(stat,'put variable tiles') - DEALLOCATE(tiles) - - stat = nf_inq_varid(ncout,'soillev',varid) - CALL hdlerr(stat,'cannot find soillev') - stat = nf_put_var_double(ncout,varid,soillev(:)) - CALL hdlerr(stat,'put variable soillev') - DEALLOCATE(soillev) - - stat = nf_inq_varid(ncout,'soil_layer_depth',varid) - CALL hdlerr(stat,'cannot find soil_layer_depth') - stat = nf_put_var_double(ncout,varid,layer_depth(:)) - CALL hdlerr(stat,'put variable soil_layer_depth') - DEALLOCATE(layer_depth) - - stat = nf_inq_varid(ncout,'time',varid) - CALL hdlerr(stat,'cannot find time') - stat = nf_put_var_int(ncout,varid,time_days(:)) - CALL hdlerr(stat,'put variable time') - DEALLOCATE(time_days) - - !-- other variables - - stat = nf_inq_varid(ncout,'cover_fract',varid) - CALL hdlerr(stat,'cannot find cover_fract') - stat = nf_put_var_double(ncout,varid,cover_fract(:,:,:)) - CALL hdlerr(stat,'put variable cover_fract') - DEALLOCATE(cover_fract) - - ALLOCATE(cover_type_dp(nlon,nlat,ntiles)) - cover_type_dp(:,:,:)=REAL(cover_type(:,:,:)) - DEALLOCATE(cover_type) - stat = nf_inq_varid(ncout,'cover_type',varid) - CALL hdlerr(stat,'cannot find cover_type') - stat = nf_put_var_double(ncout,varid,cover_type_dp(:,:,:)) - CALL hdlerr(stat,'put variable cover_type') - DEALLOCATE(cover_type_dp) - - IF (.NOT. cover_fract_only) THEN - stat = nf_inq_varid(ncout,'veg_fract',varid) - CALL hdlerr(stat,'cannot find veg_fract') - stat = nf_put_var_double(ncout,varid,veg_fract(:,:,:)) - CALL hdlerr(stat,'put variable veg_fract') - DEALLOCATE(veg_fract) - - stat = nf_inq_varid(ncout,'lai_clim',varid) - CALL hdlerr(stat,'cannot find lai_clim') - stat = nf_put_var_double(ncout,varid,lai(:,:,:)) - CALL hdlerr(stat,'put variable lai_clim') - DEALLOCATE(lai) - - stat = nf_inq_varid(ncout,'elevation',varid) - CALL hdlerr(stat,'cannot find elevation') - stat = nf_put_var_double(ncout,varid,elevation(:,:)) - CALL hdlerr(stat,'put variable elevation') - DEALLOCATE(elevation) - - stat = nf_inq_varid(ncout,'orography_std_dev',varid) - CALL hdlerr(stat,'cannot find orography_std_dev') - stat = nf_put_var_double(ncout,varid,elevationrms(:,:)) - CALL hdlerr(stat,'put variable orography_std_dev') - DEALLOCATE(elevationrms) - - stat = nf_inq_varid(ncout,'roughness_length',varid) - CALL hdlerr(stat,'cannot find roughness_length') - stat = nf_put_var_double(ncout,varid,az0(:,:)) - CALL hdlerr(stat,'put variable roughness_length') - DEALLOCATE(az0) - - stat = nf_inq_varid(ncout,'roughness_length_oro',varid) - CALL hdlerr(stat,'cannot find roughness_length_oro') - stat = nf_put_var_double(ncout,varid,roughness_oro(:,:)) - CALL hdlerr(stat,'put variable roughness_length_oro') - DEALLOCATE(roughness_oro) - - stat = nf_inq_varid(ncout,'albedo',varid) - CALL hdlerr(stat,'cannot find albedo') - stat = nf_put_var_double(ncout,varid,albedo(:,:)) - CALL hdlerr(stat,'put variable albedo') - DEALLOCATE(albedo) - - stat = nf_inq_varid(ncout,'fao',varid) - CALL hdlerr(stat,'cannot find fao') - stat = nf_put_var_double(ncout,varid,fao(:,:)) - CALL hdlerr(stat,'put variable fao') - DEALLOCATE(fao) - - stat = nf_inq_varid(ncout,'maxmoist',varid) - CALL hdlerr(stat,'cannot find maxmoist') - stat = nf_put_var_double(ncout,varid,max_moisture(:,:)) - CALL hdlerr(stat,'put variable maxmoist') - DEALLOCATE(max_moisture) - - stat = nf_inq_varid(ncout,'forest_fract',varid) - CALL hdlerr(stat,'cannot find forest_fract') - stat = nf_put_var_double(ncout,varid,forest_fract(:,:)) - CALL hdlerr(stat,'put variable forest_fract') - DEALLOCATE(forest_fract) - - stat = nf_inq_varid(ncout,'init_moist',varid) - CALL hdlerr(stat,'cannot find init_moist') - stat = nf_put_var_double(ncout,varid,moisture(:,:)) - CALL hdlerr(stat,'put variable init_moist') - DEALLOCATE(moisture) - - stat = nf_inq_varid(ncout,'veg_ratio_max',varid) - CALL hdlerr(stat,'cannot find veg_ratio_max') - stat = nf_put_var_double(ncout,varid,veg_ratio_max(:,:)) - CALL hdlerr(stat,'put variable veg_ratio_max') - DEALLOCATE(veg_ratio_max) - - stat = nf_inq_varid(ncout,'albedo_veg_vis',varid) - CALL hdlerr(stat,'cannot find albedo_veg_vis') - stat = nf_put_var_double(ncout,varid,albedo_veg_vis(:,:)) - CALL hdlerr(stat,'put variable albedo_veg_vis') - DEALLOCATE(albedo_veg_vis) - - stat = nf_inq_varid(ncout,'albedo_veg_nir',varid) - CALL hdlerr(stat,'cannot find albedo_veg_nir') - stat = nf_put_var_double(ncout,varid,albedo_veg_nir(:,:)) - CALL hdlerr(stat,'put variable albedo_veg_nir') - DEALLOCATE(albedo_veg_nir) - - stat = nf_inq_varid(ncout,'albedo_soil_vis',varid) - CALL hdlerr(stat,'cannot find albedo_soil_vis') - stat = nf_put_var_double(ncout,varid,albedo_soil_vis(:,:)) - CALL hdlerr(stat,'put variable albedo_soil_vis') - DEALLOCATE(albedo_soil_vis) - - stat = nf_inq_varid(ncout,'albedo_soil_nir',varid) - CALL hdlerr(stat,'cannot find albedo_soil_nir') - stat = nf_put_var_double(ncout,varid,albedo_soil_nir(:,:)) - CALL hdlerr(stat,'put variable albedo_soil_nir') - DEALLOCATE(albedo_soil_nir) - - stat = nf_inq_varid(ncout,'snow',varid) - CALL hdlerr(stat,'cannot find snow') - stat = nf_put_var_double(ncout,varid,snow(:,:)) - CALL hdlerr(stat,'put variable snow') - DEALLOCATE(snow) - - stat = nf_inq_varid(ncout,'slf',varid) - CALL hdlerr(stat,'cannot find slf') - stat = nf_put_var_double(ncout,varid,slf(:,:)) - CALL hdlerr(stat,'put variable slf') - DEALLOCATE(slf) - - stat = nf_inq_varid(ncout,'lake',varid) - CALL hdlerr(stat,'cannot find lake') - stat = nf_put_var_double(ncout,varid,lake(:,:)) - CALL hdlerr(stat,'put variable lake') - DEALLOCATE(lake) - - stat = nf_inq_varid(ncout,'slm',varid) - CALL hdlerr(stat,'cannot find slm') - stat = nf_put_var_double(ncout,varid,slm(:,:)) - CALL hdlerr(stat,'put variable slm') - DEALLOCATE(slm) - - stat = nf_inq_varid(ncout,'glac',varid) - CALL hdlerr(stat,'cannot find glac') - stat = nf_put_var_double(ncout,varid,glac_dp(:,:)) - CALL hdlerr(stat,'put variable glac') - DEALLOCATE(glac_dp) - - stat = nf_inq_varid(ncout,'surf_temp',varid) - CALL hdlerr(stat,'cannot find surf_temp') - stat = nf_put_var_double(ncout,varid,surf_temp(:,:,:)) - CALL hdlerr(stat,'put variable surf_temp') - DEALLOCATE(surf_temp) - - IF (ldynveg .OR. lread_pasture) THEN - stat = nf_inq_varid(ncout,'natural_veg',varid) - CALL hdlerr(stat,'cannot find natural_veg') - stat = nf_put_var_double(ncout,varid,natural_veg(:,:,:)) - CALL hdlerr(stat,'put variable natural_veg') - DEALLOCATE(natural_veg) - END IF - - stat = nf_inq_varid(ncout,'soil_depth',varid) - CALL hdlerr(stat,'cannot find soil_depth') - stat = nf_put_var_double(ncout,varid,soil_depth(:,:)) - CALL hdlerr(stat,'put variable soil_depth') - DEALLOCATE(soil_depth) - - stat = nf_inq_varid(ncout,'heat_conductivity',varid) - CALL hdlerr(stat,'cannot find heat_conductivity') - stat = nf_put_var_double(ncout,varid,heat_conductivity(:,:)) - CALL hdlerr(stat,'put variable heat_conductivity') - DEALLOCATE(heat_conductivity) - - stat = nf_inq_varid(ncout,'heat_capacity',varid) - CALL hdlerr(stat,'cannot find heat_capacity') - stat = nf_put_var_double(ncout,varid,heat_capacity(:,:)) - CALL hdlerr(stat,'put variable heat_capacity') - DEALLOCATE(heat_capacity) - - stat = nf_inq_varid(ncout,'bclapp',varid) - CALL hdlerr(stat,'cannot find bclapp') - stat = nf_put_var_double(ncout,varid,bclapp(:,:)) - CALL hdlerr(stat,'put variable bclapp') - DEALLOCATE(bclapp) - - stat = nf_inq_varid(ncout,'soil_porosity',varid) - CALL hdlerr(stat,'cannot find soil_porosity') - stat = nf_put_var_double(ncout,varid,soil_porosity(:,:)) - CALL hdlerr(stat,'put variable soil_porosity') - DEALLOCATE(soil_porosity) - - stat = nf_inq_varid(ncout,'moisture_pot',varid) - CALL hdlerr(stat,'cannot find moisture_pot') - stat = nf_put_var_double(ncout,varid,matrix_potential(:,:)) - CALL hdlerr(stat,'put variable moisture_pot') - DEALLOCATE(matrix_potential) - - stat = nf_inq_varid(ncout,'soil_field_cap',varid) - CALL hdlerr(stat,'cannot find soil_field_cap') - stat = nf_put_var_double(ncout,varid,soil_field_capacity(:,:)) - CALL hdlerr(stat,'put variable soil_field_cap') - DEALLOCATE(soil_field_capacity) - - stat = nf_inq_varid(ncout,'hyd_cond_sat',varid) - CALL hdlerr(stat,'cannot find hyd_cond_sat') - stat = nf_put_var_double(ncout,varid,hyd_cond_sat(:,:)) - CALL hdlerr(stat,'put variable hyd_cond_sat') - DEALLOCATE(hyd_cond_sat) - - stat = nf_inq_varid(ncout,'pore_size_index',varid) - CALL hdlerr(stat,'cannot find pore_size_index') - stat = nf_put_var_double(ncout,varid,pore_size_index(:,:)) - CALL hdlerr(stat,'put variable pore_size_index') - DEALLOCATE(pore_size_index) - - stat = nf_inq_varid(ncout,'wilting_point',varid) - CALL hdlerr(stat,'cannot find wilting_point') - stat = nf_put_var_double(ncout,varid,wilting_point(:,:)) - CALL hdlerr(stat,'put variable wilting_point') - DEALLOCATE(wilting_point) - - stat = nf_inq_varid(ncout,'layer_moist',varid) - CALL hdlerr(stat,'cannot find layer_moist') - stat = nf_put_var_double(ncout,varid,soilwater_layer(:,:,:)) - CALL hdlerr(stat,'put variable layer_moist') - DEALLOCATE(soilwater_layer) - - stat = nf_inq_varid(ncout,'root_depth',varid) - CALL hdlerr(stat,'cannot find root_depth') - stat = nf_put_var_double(ncout,varid,root_depth(:,:)) - CALL hdlerr(stat,'put variable root_depth') - DEALLOCATE(root_depth) - - END IF - - stat = nf_close(ncout) - CALL hdlerr(stat,'closing file') - - END PROGRAM jsbach_init_file - -!------------------------------------------------------------------------------ -SUBROUTINE adapt_vegfract (lat, C3C4_flag, info, for_types, lpasture, & - ignore_measurements, vegfract) -!------------------------------------------------------------------------------ -! -! Routine to modify vegetation fractions -! -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - - IMPLICIT NONE - - !-- INTENT(in) - INTEGER, INTENT(in) :: C3C4_flag ! 1 for C3, 0 for C4 grasses - REAL(dp), INTENT(in) :: lat ! latitude - LOGICAL, INTENT(in) :: info ! print some additional information - LOGICAL, INTENT(in) :: for_types ! calculation of cover types will be - ! based on vegfract calculated here - LOGICAL, INTENT(in) :: lpasture ! distinguish pasture from grass lands - LOGICAL, INTENT(in) :: ignore_measurements ! covertypes only depend on latitude - - !-- INTENT(inout) - REAL(dp), INTENT(inout) :: vegfract(nvegtyp) - - !-- LOCAL - INTEGER, SAVE :: icount=0 - INTEGER :: k - INTEGER :: idominant, isecond - -!------------------------------------------------------------------------------ - - IF (nvegtyp /= 14) THEN - CALL hdlerr(1,'adapt_vegfract: Routine for 14 vegetation types') - END IF - - IF (ignore_measurements) THEN - vegfract(:) = 0._dp - END IF - - !-- There should not be negative vegetation coverage (missing value) - - vegfract(:) = MAX(vegfract(:),0._dp) - - !-- Define reasonable cover fractions for land points without any vegetation - - If (SUM(vegfract(:)) <= small_fract+EPSILON(1._dp)) THEN - IF (ABS(lat) < 30._dp) THEN - vegfract(veg_tropical_evergreen) = 2._dp * small_fract - ELSE IF (ABS(lat) < 40._dp) THEN - vegfract(veg_temperate_broadl_evergreen) = 2._dp * small_fract - ELSE - vegfract(veg_evergreen_conifer) = 2._dp * small_fract - END IF - IF (ABS(lat) < 40._dp) THEN - vegfract(veg_raingreen_shrub) = 2._dp * small_fract - vegfract(veg_c4grass) = 2._dp * small_fract - ELSE - vegfract(veg_deciduous_shrub) = 2._dp * small_fract - vegfract(veg_c3grass) = 2._dp * small_fract - END IF - END IF - - !-- change tropical forest to temperate/boreal forest outside 40S-40N - - IF (ABS(lat) > 40._dp) THEN - vegfract(veg_temperate_broadl_evergreen) = vegfract(veg_temperate_broadl_evergreen) & - + vegfract(veg_tropical_evergreen) - vegfract(veg_temperate_broadl_deciduous) = vegfract(veg_temperate_broadl_deciduous) & - + vegfract(veg_tropical_deciduous) - vegfract(veg_tropical_evergreen) = 0._dp - vegfract(veg_tropical_deciduous) = 0._dp - END IF - - IF (.NOT. lpasture) THEN - !-- add C3 pasture to C3 grass and C4 pasture to C4 grass - - vegfract(veg_c3grass) = vegfract(veg_c3grass) + vegfract(veg_c3pasture) - vegfract(veg_c4grass) = vegfract(veg_c4grass) + vegfract(veg_c4pasture) - vegfract(veg_c3pasture) = 0._dp - vegfract(veg_c4pasture) = 0._dp - END IF - - - !-- In case C3 and C4 grasses have the same cover fraction, the C3/C4 flag - ! determines which grass dominates - - IF (ABS(vegfract(veg_c3grass) - vegfract(veg_c4grass)) < small_fract) THEN - !! IF (info) WRITE (*,*) 'C3 and C4 grasses have the same cover fractions: ', & - !! vegfract(veg_c3grass), vegfract(veg_c4grass) - IF (C3C4_flag == 0) THEN - vegfract(veg_c4grass) = MIN(1._dp,vegfract(veg_c4grass) + small_fract*10._dp) - vegfract(veg_c3grass) = MAX(0._dp,vegfract(veg_c3grass) - small_fract*10._dp) - ELSE - vegfract(veg_c4grass) = MAX(0._dp,vegfract(veg_c4grass) - small_fract*10._dp) - vegfract(veg_c3grass) = MIN(1._dp,vegfract(veg_c3grass) + small_fract*10._dp) - END IF - END IF - - IF (for_types) THEN - !-- In case the cover fractions of the two dominant PFTs are the same, they - ! are slightly modified. - - idominant = 1 - DO k = 2,nvegtyp - IF (vegfract(k) > vegfract(idominant)) idominant = k - END DO - IF (idominant /= 1) isecond = 1 - IF (idominant == 1) isecond = 2 - DO k = 2,nvegtyp - IF (vegfract(k) > vegfract(isecond) .AND. k /= idominant) isecond = k - END DO - IF (ABS(vegfract(idominant) - vegfract(isecond)) < small_fract) THEN - IF (info) WRITE (*,*) 'The two dominant PFTs have the same cover fractions: ', & - idominant, isecond, vegfract(idominant), vegfract(isecond) - IF (MOD(icount,2) == 1) THEN - vegfract(idominant) = vegfract(idominant) + small_fract * 10._dp - vegfract(isecond) = vegfract(isecond) - small_fract * 10._dp - ELSE - vegfract(idominant) = vegfract(idominant) - small_fract * 10._dp - vegfract(isecond) = vegfract(isecond) + small_fract * 10._dp - END IF - icount = icount + 1 - END IF - END IF - -END SUBROUTINE adapt_vegfract - -!------------------------------------------------------------------------------ -SUBROUTINE calc_cover_fractions (ntiles, lat, cover_type, second_woody, & - second_grass, glac, vegfract, grass_only, woods_only, lc3c4crop, & - C3_crop, C4_crop, crop, lread_pasture, lpasture_rule, pasture, & - C3C4_flag, cover_fract) -!------------------------------------------------------------------------------ -! -! Routine to calculate land cover types and fractions depending on the number -! of tiles -! -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - - IMPLICIT NONE - - !-- INTENT(in) - INTEGER, INTENT(in) :: ntiles ! number of tiles - REAL(dp), INTENT(in) :: lat ! latitude - INTEGER, INTENT(in) :: glac ! glacier flag (1: glacier) - INTEGER, INTENT(in) :: cover_type(ntiles) - INTEGER, INTENT(in) :: second_woody, second_grass - REAL(dp), INTENT(in) :: vegfract(nvegtyp) - LOGICAL, INTENT(in) :: woods_only, grass_only - LOGICAL, INTENT(in) :: lc3c4crop ! distinguish C3 crops from C4 crops - LOGICAL, INTENT(in) :: lread_pasture ! use pastures of array 'pasture' and - ! crops from array 'crop' - LOGICAL, INTENT(in) :: lpasture_rule ! allocate pasture primarily on grass lands - REAL(dp), INTENT(in) :: C3_crop ! fraction of C3 crops - REAL(dp), INTENT(in) :: C4_crop ! fraction of C4 crops - REAL(dp), INTENT(in) :: crop ! crop fraction (if lread_pasture) - REAL(dp), INTENT(in) :: pasture ! pasture fraction (if lread_pasture) - INTEGER, INTENT(in) :: C3C4_flag ! flag used to decide whether C3 or C4 - ! grass/pasture is dominant - - !-- INTENT(out) - REAL(dp), INTENT(out) :: cover_fract(ntiles) - - !-- LOCAL - INTEGER :: k - REAL(dp) :: vegfract_woody, vegfract_grass - REAL(dp) :: vegfract_c3grass, vegfract_c4grass - REAL(dp) :: vegfract_crop, vegfract_c3crop, vegfract_c4crop - REAL(dp) :: vegfract_c3pasture, vegfract_c4pasture - REAL(dp) :: c3ratio - -!------------------------------------------------------------------------------ - - IF (nvegtyp /= 14) THEN - CALL hdlerr(1,'calc_cover_fractions: Routine for 14 vegetation types') - END IF - - !-- calculate woody fraction and grass fraction - vegfract_woody = 0._dp - DO k=1,nwoody - vegfract_woody = vegfract_woody + vegfract(woody_types(k)) - END DO - vegfract_grass = vegfract(veg_c3grass) + vegfract(veg_c4grass) - - !-- find out C3 ratio of grass land - IF (vegfract_grass > 0._dp) THEN - c3ratio = vegfract(veg_c3grass) / vegfract_grass - ELSE - c3ratio = REAL(C3C4_flag, dp) ! 1 for C3, 0 for C4 - END IF - - !-- apply the pasture rule: pasture is primarily allocated on grass lands - IF (lpasture_rule .AND. lread_pasture) THEN - vegfract_grass = MAX(0._dp, vegfract_grass - pasture) - vegfract_c3grass = vegfract_grass * c3ratio - vegfract_c4grass = vegfract_grass * (1._dp - c3ratio) - ELSE - vegfract_c3grass = vegfract(veg_c3grass) - vegfract_c4grass = vegfract(veg_c4grass) - END IF - - !-- Calculate the fractions of C3 and C4 pasture from the total pasture - IF (lread_pasture) THEN - vegfract_c3pasture = pasture * c3ratio - vegfract_c4pasture = pasture * (1._dp - c3ratio) - ELSE - vegfract_c3pasture = vegfract(veg_c3pasture) - vegfract_c4pasture = vegfract(veg_c4pasture) - END IF - - !-- Calculate crop fractions - IF (lread_pasture) THEN - vegfract_crop = crop - ELSE - vegfract_crop = vegfract(veg_crop) - END IF - IF (lc3c4crop) THEN - !-- Calculate C3 and C4 crop fractions by scaling with C3/C4_crop maps - ! needed only if there is more than one tile reserved for crops - IF ((C3_crop + C4_crop) > EPSILON(1._dp)) THEN - vegfract_c3crop = vegfract(veg_crop) * (C3_crop / (C3_crop + C4_crop)) - vegfract_c4crop = vegfract(veg_crop) * (C4_crop / (C3_crop + C4_crop)) - ELSE - vegfract_c3crop = 0._dp - vegfract_c4crop = 0._dp - END IF - ELSE - vegfract_c3crop = 0._dp - vegfract_c4crop = 0._dp - END IF - - !-- glaciers - IF (glac == 1) THEN - cover_fract(1) = 1._dp - cover_fract(2:ntiles) = 0._dp - ELSE - SELECT CASE (ntiles) - CASE (1) - cover_fract(1) = 1._dp - CASE (3) - cover_fract(1) = vegfract_woody - cover_fract(2) = vegfract_grass - cover_fract(3) = vegfract_crop - CASE (4) - IF (cover_type(3) == lct(second_woody)) THEN - cover_fract(1) = vegfract_woody - vegfract(second_woody) - cover_fract(2) = vegfract_grass - cover_fract(3) = vegfract(second_woody) - ELSE - cover_fract(1) = vegfract_woody - cover_fract(2) = vegfract_grass - vegfract(second_grass) - cover_fract(3) = vegfract(second_grass) - END IF - cover_fract(4) = vegfract_crop - CASE (5) - IF (cover_type(3) == lct(second_woody)) THEN - cover_fract(1) = vegfract_woody - vegfract(second_woody) - cover_fract(2) = vegfract_grass - cover_fract(3) = vegfract(second_woody) - ELSE - cover_fract(1) = vegfract_woody - cover_fract(2) = vegfract_grass - vegfract(second_grass) - cover_fract(3) = vegfract(second_grass) - END IF - cover_fract(4) = vegfract_c3crop - cover_fract(5) = vegfract_c4crop - CASE (6) - cover_fract(1) = vegfract(veg_tropical_deciduous) & - + vegfract(veg_temperate_broadl_deciduous) & - + vegfract(veg_deciduous_conifer) - cover_fract(2) = vegfract(veg_tropical_evergreen) & - + vegfract(veg_temperate_broadl_evergreen) & - + vegfract(veg_evergreen_conifer) - cover_fract(3) = vegfract(veg_raingreen_shrub) & - + vegfract(veg_deciduous_shrub) & - + vegfract(veg_tundra) - cover_fract(4) = vegfract_c3grass - cover_fract(5) = vegfract_c4grass - cover_fract(6) = vegfract_crop - CASE (8) - cover_fract(1) = vegfract(veg_tropical_evergreen) - cover_fract(2) = vegfract(veg_tropical_deciduous) - cover_fract(3) = vegfract(veg_temperate_broadl_evergreen) & - + vegfract(veg_evergreen_conifer) - cover_fract(4) = vegfract(veg_temperate_broadl_deciduous) & - + vegfract(veg_deciduous_conifer) - cover_fract(5) = vegfract(veg_raingreen_shrub) - cover_fract(6) = vegfract(veg_deciduous_shrub) - cover_fract(7) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(8) = vegfract_c4grass - CASE (9) - cover_fract(1) = 0._dp - cover_fract(2) = vegfract(veg_tropical_evergreen) - cover_fract(3) = vegfract(veg_tropical_deciduous) - cover_fract(4) = vegfract(veg_temperate_broadl_evergreen) & - + vegfract(veg_evergreen_conifer) - cover_fract(5) = vegfract(veg_temperate_broadl_deciduous) & - + vegfract(veg_deciduous_conifer) - cover_fract(6) = vegfract(veg_raingreen_shrub) - cover_fract(7) = vegfract(veg_deciduous_shrub) - cover_fract(8) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(9) = vegfract_c4grass - CASE (10) - cover_fract(1) = vegfract(veg_tropical_evergreen) - cover_fract(2) = vegfract(veg_tropical_deciduous) - cover_fract(3) = vegfract(veg_temperate_broadl_evergreen) + vegfract(veg_evergreen_conifer) - cover_fract(4) = vegfract(veg_temperate_broadl_deciduous) + vegfract(veg_deciduous_conifer) - cover_fract(5) = vegfract(veg_raingreen_shrub) - cover_fract(6) = vegfract(veg_deciduous_shrub) - cover_fract(7) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(8) = vegfract_c4grass - cover_fract(9) = vegfract_c3crop - cover_fract(10)= vegfract_c4crop - CASE (11) - cover_fract(1) = vegfract(veg_tropical_evergreen) - cover_fract(2) = vegfract(veg_tropical_deciduous) - cover_fract(3) = vegfract(veg_temperate_broadl_evergreen) + vegfract(veg_evergreen_conifer) - cover_fract(4) = vegfract(veg_temperate_broadl_deciduous) + vegfract(veg_deciduous_conifer) - cover_fract(5) = vegfract(veg_raingreen_shrub) - cover_fract(6) = vegfract(veg_deciduous_shrub) - cover_fract(7) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(8) = vegfract_c4grass - cover_fract(9) = vegfract_c3pasture - cover_fract(10)= vegfract_c4pasture - cover_fract(11) = vegfract_crop - CASE (12) - cover_fract(1) = 0._dp - cover_fract(2) = vegfract(veg_tropical_evergreen) - cover_fract(3) = vegfract(veg_tropical_deciduous) - cover_fract(4) = vegfract(veg_temperate_broadl_evergreen) + vegfract(veg_evergreen_conifer) - cover_fract(5) = vegfract(veg_temperate_broadl_deciduous) + vegfract(veg_deciduous_conifer) - cover_fract(6) = vegfract(veg_raingreen_shrub) - cover_fract(7) = vegfract(veg_deciduous_shrub) - cover_fract(8) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(9) = vegfract_c4grass - cover_fract(10)= vegfract_c3pasture - cover_fract(11)= vegfract_c4pasture - cover_fract(12) = vegfract_crop - CASE (13) - cover_fract(1) = vegfract(veg_tropical_evergreen) - cover_fract(2) = vegfract(veg_tropical_deciduous) - cover_fract(3) = vegfract(veg_temperate_broadl_evergreen) - cover_fract(4) = vegfract(veg_temperate_broadl_deciduous) - cover_fract(5) = vegfract(veg_evergreen_conifer) - cover_fract(6) = vegfract(veg_deciduous_conifer) - cover_fract(7) = vegfract(veg_raingreen_shrub) - cover_fract(8) = 0._dp - cover_fract(9) = vegfract_c3grass - cover_fract(10) = vegfract_c4grass - cover_fract(11) = vegfract(veg_tundra) - cover_fract(12) = 0._dp - cover_fract(13) = vegfract_crop - CASE (14) - cover_fract(1) = 0._dp - cover_fract(2) = vegfract(veg_tropical_evergreen) - cover_fract(3) = vegfract(veg_tropical_deciduous) - cover_fract(4) = vegfract(veg_temperate_broadl_evergreen) - cover_fract(5) = vegfract(veg_temperate_broadl_deciduous) - cover_fract(6) = vegfract(veg_evergreen_conifer) - cover_fract(7) = vegfract(veg_deciduous_conifer) - cover_fract(8) = vegfract(veg_raingreen_shrub) - cover_fract(9) = 0._dp - cover_fract(10)= vegfract_c3grass - cover_fract(11) = vegfract_c4grass - cover_fract(12) = vegfract(veg_tundra) - cover_fract(13) = 0._dp - cover_fract(14) = vegfract_crop - CASE DEFAULT - CALL hdlerr(1,'land cover: number of tiles not supported') - END SELECT - - ! cover fractions for grass-only or woods-only simulations - IF (grass_only) THEN - cover_fract(1:6) = 0._dp - IF (C3C4_flag == 1) THEN - cover_fract(7) = 1._dp - ELSE - cover_fract(8) = 1._dp - END IF - ELSE IF (woods_only) THEN - cover_fract(5:8) = 0._dp - IF (SUM(cover_fract(1:4)) <= small_fract) THEN - IF (ABS(lat) < 30._dp) THEN - cover_fract(1) = 1._dp - ELSE - cover_fract(3) = 1._dp - END IF - END IF - END IF - - END IF - -END SUBROUTINE calc_cover_fractions - -!------------------------------------------------------------------------------ -SUBROUTINE calc_cover_types (ntiles, lat, glac, vegfract, lc3c4crop, C3_crop, & - C4_crop, cover_type, second_woody, second_grass, dominant_crop, & - is_naturalveg) -!------------------------------------------------------------------------------ -! -! Routine to calculate land cover types depending on the number of tiles -! -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - IMPLICIT NONE - - !-- INTENT(IN) - INTEGER, INTENT(in) :: ntiles ! number of tiles - REAL(dp), INTENT(in) :: lat ! latitude - INTEGER, INTENT(in) :: glac ! glacier flag (1: glacier) - REAL(dp), INTENT(in) :: vegfract(nvegtyp) ! vegetated area fraction - LOGICAL, INTENT(in) :: lc3c4crop ! distinguish C3 and C4 crops - REAL(dp), INTENT(in) :: C3_crop - REAL(dp), INTENT(in) :: C4_crop - - !-- INTENT(OUT) - INTEGER, INTENT(out) :: cover_type(ntiles) - INTEGER, INTENT(out) :: second_woody, second_grass, dominant_crop - LOGICAL, INTENT(out) :: is_naturalveg(ntiles) - - !-- LOCAL - INTEGER :: k - INTEGER :: dominant_woody, dominant_grass - INTEGER :: dominant_pft(1) - REAL(dp) :: vegfract_woody - -!------------------------------------------------------------------------------ - - IF (nvegtyp /= 14) THEN - CALL hdlerr(1,'calc_cover_types: Routine for 14 vegetation types') - END IF - - !-- calculate woody fraction and grass fraction - - vegfract_woody = 0._dp - DO k=1,nwoody - vegfract_woody = vegfract_woody + vegfract(woody_types(k)) - END DO - - !-- find out most spread woody type - - dominant_woody = woody_types(1) - DO k = 2,nwoody - IF (vegfract(woody_types(k)) > vegfract(dominant_woody)) & - dominant_woody = woody_types(k) - END DO - - !-- find out second most spread woody type - - IF (woody_types(1) /= dominant_woody) THEN - second_woody = woody_types(1) - ELSE - second_woody = woody_types(2) - END IF - DO k = 1,nwoody - IF (vegfract(woody_types(k)) > vegfract(second_woody) .AND. & - woody_types(k) /= dominant_woody) second_woody = woody_types(k) - END DO - !substantial tundra is always represented - IF (dominant_woody /= veg_tundra .AND. vegfract(veg_tundra) > substantial_tundra) & - second_woody = veg_tundra - - !-- find out most and second most spread grass type - - IF (vegfract(veg_c3grass) > vegfract(veg_c4grass)) THEN - dominant_grass = veg_c3grass - second_grass = veg_c4grass - ELSE - dominant_grass = veg_c4grass - second_grass = veg_c3grass - END IF - - !-- find out most spread crop type - - IF (C3_crop > C4_crop .AND. C3_crop > small_fract) THEN - dominant_crop = lct_c3crop - ELSE IF (C4_crop > C3_crop .AND. C4_crop > small_fract) THEN - dominant_crop = lct_c4crop - ELSE IF (dominant_grass == veg_c3grass) THEN - dominant_crop = lct_c3crop - ELSE - dominant_crop = lct_c4crop - END IF - - !-- find out dominant type - - dominant_pft(:) = MAXLOC(vegfract(:)) - - !-- initialize natural vegetation flag - - IF (glac == 1) THEN - is_naturalveg(:) = .FALSE. - ELSE - is_naturalveg(:) = .TRUE. - END IF - - IF (ntiles == 1) THEN -!------------------------------------------------------------------------------ -! 1 tile: dominant PFT -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - ELSE - cover_type(1) = lct_evergreen_conifer - END IF - ELSE - !-- substantial vegetation - - cover_type(1) = lct(dominant_pft(1)) - - ENDIF - - ELSE IF (ntiles == 3) THEN -!------------------------------------------------------------------------------ -! 3 tiles: 1: woody -! 2: grasses -! 3: crops -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - cover_type(2) = lct_c3grass - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - cover_type(2) = lct_c4grass - ELSE - cover_type(1) = lct_evergreen_conifer - cover_type(2) = lct_c3grass - END IF - ELSE - - !-- substantial vegetation - - cover_type(1) = lct(dominant_woody) - cover_type(2) = lct(dominant_grass) - ENDIF - cover_type(3) = lct_crop - is_naturalveg(3) = .FALSE. - - ELSE IF (ntiles == 4) THEN -!------------------------------------------------------------------------------ -! 4 tiles: 1: woody -! 2: grasses -! 3: second tree or grass (depending on fraction) -! 4: crops -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - cover_type(2) = lct_c3grass - cover_type(3) = lct_evergreen_conifer - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - cover_type(2) = lct_c4grass - cover_type(3) = lct_tropical_evergreen - ELSE - cover_type(1) = lct_evergreen_conifer - cover_type(2) = lct_c3grass - cover_type(3) = lct_temperate_broadl_deciduous - END IF - ELSE - - !-- substantial vegetation - - cover_type(1) = lct(dominant_woody) - cover_type(2) = lct(dominant_grass) - IF (vegfract(second_woody) > vegfract(second_grass) & - .OR. vegfract(second_woody) > substantial_woody) THEN - cover_type(3) = lct(second_woody) - ELSE - cover_type(3) = lct(second_grass) - END IF - END IF - IF (lc3c4crop) THEN - cover_type(4) = dominant_crop - ELSE - cover_type(4) = lct_crop - END IF - is_naturalveg(4) = .FALSE. - - ELSE IF (ntiles == 5) THEN -!------------------------------------------------------------------------------ -! 5 tiles: 1: woody -! 2: grasses -! 3: second tree or grass (depending on fraction) -! 4: C3 crops -! 5: C4 crops -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - cover_type(2) = lct_c3grass - cover_type(3) = lct_evergreen_conifer - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - cover_type(2) = lct_c4grass - cover_type(3) = lct_tropical_evergreen - ELSE - cover_type(1) = lct_evergreen_conifer - cover_type(2) = lct_c3grass - cover_type(3) = lct_temperate_broadl_deciduous - END IF - ELSE - - !-- substantial vegetation - - cover_type(1) = lct(dominant_woody) - cover_type(2) = lct(dominant_grass) - IF (vegfract(second_woody) > vegfract(second_grass) & - .OR. vegfract(second_woody) > substantial_woody) THEN - cover_type(3) = lct(second_woody) - ELSE - cover_type(3) = lct(second_grass) - END IF - END IF - cover_type(4) = lct_c3crop - cover_type(5) = lct_c4crop - - is_naturalveg(4) = .FALSE. - is_naturalveg(5) = .FALSE. - - ELSE IF (ntiles == 6) THEN -!------------------------------------------------------------------------------ -! 6 tiles: 1: deciduous trees -! 2: eveergreen trees -! 3: shrub and tundra -! 4: C3 grasses and pasture -! 5: C4 grasses -! 6: crops -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - cover_type(2) = lct_evergreen_conifer - cover_type(3) = lct_deciduous_shrub - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - cover_type(2) = lct_tropical_evergreen - cover_type(3) = lct_raingreen_shrub - ELSE IF (ABS(lat) < 60._dp) THEN - cover_type(1) = lct_temperate_broadl_deciduous - cover_type(2) = lct_temperate_broadl_evergreen - cover_type(3) = lct_deciduous_shrub - ELSE - cover_type(1) = lct_deciduous_conifer - cover_type(2) = lct_evergreen_conifer - cover_type(3) = lct_tundra - END IF - ELSE - - !-- substantial vegetation - - IF (vegfract(veg_tropical_deciduous) > vegfract(veg_temperate_broadl_deciduous) .AND. & - vegfract(veg_tropical_deciduous) > vegfract(veg_deciduous_conifer)) THEN - cover_type(1) = lct_tropical_deciduous - ELSE IF(vegfract(veg_temperate_broadl_deciduous) > vegfract(veg_tropical_deciduous) .AND. & - vegfract(veg_temperate_broadl_deciduous) >= vegfract(veg_deciduous_conifer)) THEN - cover_type(1) = lct_temperate_broadl_deciduous - ELSE IF(vegfract(veg_deciduous_conifer) > vegfract(veg_tropical_deciduous) .AND. & - vegfract(veg_deciduous_conifer) > vegfract(veg_temperate_broadl_deciduous)) THEN - cover_type(1) = lct_deciduous_conifer - ELSE - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - ELSE - cover_type(1) = lct_temperate_broadl_deciduous - END IF - END IF - - IF (vegfract(veg_tropical_evergreen) > vegfract(veg_temperate_broadl_evergreen) .AND. & - vegfract(veg_tropical_evergreen) > vegfract(veg_evergreen_conifer)) THEN - cover_type(2) = lct_tropical_evergreen - ELSE IF(vegfract(veg_temperate_broadl_evergreen) >= vegfract(veg_tropical_evergreen) .AND. & - vegfract(veg_temperate_broadl_evergreen) > vegfract(veg_evergreen_conifer)) THEN - cover_type(2) = lct_temperate_broadl_evergreen - ELSE IF(vegfract(veg_evergreen_conifer) >= vegfract(veg_tropical_evergreen) .AND. & - vegfract(veg_evergreen_conifer) >= vegfract(veg_temperate_broadl_evergreen)) THEN - cover_type(2) = lct_evergreen_conifer - END IF - - IF (vegfract(veg_raingreen_shrub) > vegfract(veg_deciduous_shrub) .AND. & - vegfract(veg_raingreen_shrub) > vegfract(veg_tundra)) THEN - cover_type(3) = lct_raingreen_shrub - ELSE IF(vegfract(veg_deciduous_shrub) >= vegfract(veg_raingreen_shrub) .AND. & - vegfract(veg_deciduous_shrub) >= vegfract(veg_tundra)) THEN - cover_type(3) = lct_deciduous_shrub - ELSE IF(vegfract(veg_tundra) >= vegfract(veg_raingreen_shrub) .AND. & - vegfract(veg_tundra) > vegfract(veg_deciduous_shrub)) THEN - cover_type(3) = lct_tundra - END IF - END IF - cover_type(4) = lct_c3grass - cover_type(5) = lct_c4grass - IF (lc3c4crop) THEN - cover_type(6) = dominant_crop - ELSE - cover_type(6) = lct_crop - ENDIF - is_naturalveg(6) = .FALSE. - - ELSE IF (ntiles == 8) THEN -!------------------------------------------------------------------------------ -! 8 tiles: 1: tropical broadleaf evergreen 7: C3 grass -! 2: tropical broadleaf deciduous 8: C4 grass -! 3: extra-tropical evergreen -! 4: extra-tropical deciduous -! 5: raingreen shrubs -! 6: deciduous shrubs -!------------------------------------------------------------------------------ - IF (glac == 1) THEN - cover_type(1) = lct_glacier - ELSE - cover_type(1) = lct_tropical_evergreen - ENDIF - cover_type(2) = lct_tropical_deciduous - cover_type(3) = lct_extratrop_evergreen - cover_type(4) = lct_extratrop_deciduous - cover_type(5) = lct_raingreen_shrub - cover_type(6) = lct_deciduous_shrub - cover_type(7) = lct_c3grass - cover_type(8) = lct_c4grass - - ELSE IF (ntiles == 9) THEN -!------------------------------------------------------------------------------ -! 9 tiles: 1: glacier 8: C3 grass -! 2: tropical broadleaf evergreen 9: C4 grass -! 3: tropical broadleaf deciduous -! 4: extra-tropical evergreen -! 5: extra-tropical deciduous -! 6: raingreen shrubs -! 7: deciduous shrubs -!------------------------------------------------------------------------------ - cover_type(1) = lct_glacier - cover_type(2) = lct_tropical_evergreen - cover_type(3) = lct_tropical_deciduous - cover_type(4) = lct_extratrop_evergreen - cover_type(5) = lct_extratrop_deciduous - cover_type(6) = lct_raingreen_shrub - cover_type(7) = lct_deciduous_shrub - cover_type(8) = lct_c3grass - cover_type(9) = lct_c4grass - - glacier_tile = 1 - is_naturalveg(1) = .FALSE. - - ELSE IF (ntiles == 10) THEN -!------------------------------------------------------------------------------ -! 10 tiles: 1: tropical broadleaf evergreen 7: C3 grass -! 2: tropical broadleaf deciduous 8: C4 grass -! 3: extra-tropical evergreen 9: C3 crops -! 4: extra-tropical deciduous 10: C4 crops -! 5: raingreen shrubs -! 6: deciduous shrubs -!------------------------------------------------------------------------------ - IF (glac == 1) THEN - cover_type(1) = lct_glacier - ELSE - cover_type(1) = lct_tropical_evergreen - ENDIF - cover_type(2) = lct_tropical_deciduous - cover_type(3) = lct_extratrop_evergreen - cover_type(4) = lct_extratrop_deciduous - cover_type(5) = lct_raingreen_shrub - cover_type(6) = lct_deciduous_shrub - cover_type(7) = lct_c3grass - cover_type(8) = lct_c4grass - cover_type(9) = lct_c3crop - cover_type(10)= lct_c4crop - - is_naturalveg(9) = .FALSE. - is_naturalveg(10) = .FALSE. - - ELSE IF (ntiles == 11) THEN -!------------------------------------------------------------------------------ -! 11 tiles: 1: tropical broadleaf evergreen 7: C3 grass -! 2: tropical broadleaf deciduous 8: C4 grass -! 3: extra-tropical evergreen 9: C3 pasture -! 4: extra-tropical deciduous 10: C4 pasture -! 5: raingreen shrubs 11: C3/C4 crop -! 6: deciduous shrubs -!------------------------------------------------------------------------------ - IF (glac == 1) THEN - cover_type(1) = lct_glacier - ELSE - cover_type(1) = lct_tropical_evergreen - END IF - cover_type(2) = lct_tropical_deciduous - cover_type(3) = lct_extratrop_evergreen - cover_type(4) = lct_extratrop_deciduous - cover_type(5) = lct_raingreen_shrub - cover_type(6) = lct_deciduous_shrub - cover_type(7) = lct_c3grass - cover_type(8) = lct_c4grass - cover_type(9) = lct_c3pasture - cover_type(10)= lct_c4pasture - cover_type(11)= dominant_crop - - is_naturalveg(9) = .FALSE. - is_naturalveg(10) = .FALSE. - is_naturalveg(11) = .FALSE. - - ELSE IF (ntiles == 12) THEN -!------------------------------------------------------------------------------ -! 12 tiles: 1: glacier 7: deciduous shrubs -! 2: tropical broadleaf evergreen 8: C3 grass -! 3: tropical broadleaf deciduous 9: C4 grass -! 4: extra-tropical evergreen 10: C3 pasture -! 5: extra-tropical deciduous 11: C4 pasture -! 6: raingreen shrubs 12: C3/C4 crop -! -!------------------------------------------------------------------------------ - cover_type(1) = lct_glacier - cover_type(2) = lct_tropical_evergreen - cover_type(3) = lct_tropical_deciduous - cover_type(4) = lct_extratrop_evergreen - cover_type(5) = lct_extratrop_deciduous - cover_type(6) = lct_raingreen_shrub - cover_type(7) = lct_deciduous_shrub - cover_type(8) = lct_c3grass - cover_type(9) = lct_c4grass - cover_type(10)= lct_c3pasture - cover_type(11)= lct_c4pasture - cover_type(12)= dominant_crop - - glacier_tile = 1 - is_naturalveg(1) = .FALSE. - is_naturalveg(10) = .FALSE. - is_naturalveg(11) = .FALSE. - is_naturalveg(12) = .FALSE. - - ELSE IF (ntiles == 13) THEN -!------------------------------------------------------------------------------ -! 13 tiles: 1: tropical broadleaf evergreen 8: deciduous shrubs -! 2: tropical broadleaf deciduous 9: C3 grass -! 3: temperate broadleaf evergreen 10: C4 grass -! 4: temperate broadleaf deciduous 11: tundra -! 5: evergreen coniferous 12: swamps -! 6: deciduous coniferous 13: crops -! 7: raingreen shrubs -!------------------------------------------------------------------------------ - IF (glac == 1) THEN - cover_type(1) = lct_glacier - ELSE - cover_type(1) = lct_tropical_evergreen - END IF - cover_type(2) = lct_tropical_deciduous - cover_type(3) = lct_temperate_broadl_evergreen - cover_type(4) = lct_temperate_broadl_deciduous - cover_type(5) = lct_evergreen_conifer - cover_type(6) = lct_deciduous_conifer - cover_type(7) = lct_raingreen_shrub - cover_type(8) = lct_deciduous_shrub - cover_type(9) = lct_c3grass - cover_type(10)= lct_c4grass - cover_type(11)= lct_tundra - cover_type(12)= lct_swamp - cover_type(13)= lct_crop - - is_naturalveg(13) = .FALSE. - - ELSE IF (ntiles == 14) THEN -!------------------------------------------------------------------------------ -! 14 tiles: 1: glacier 8: raingreen shrubs -! 2: tropical broadleaf evergreen 9: deciduous shrubs -! 3: tropical broadleaf deciduous 10: C3 grass -! 4: temperate broadleaf evergreen 11: C4 grass -! 5: temperate broadleaf deciduous 12: tundra -! 6: evergreen coniferous 13: swamps -! 7: deciduous coniferous 14: crops -! -!------------------------------------------------------------------------------ - cover_type(1) = lct_glacier - cover_type(2) = lct_tropical_evergreen - cover_type(3) = lct_tropical_deciduous - cover_type(4) = lct_temperate_broadl_evergreen - cover_type(5) = lct_temperate_broadl_deciduous - cover_type(6) = lct_evergreen_conifer - cover_type(7) = lct_deciduous_conifer - cover_type(8) = lct_raingreen_shrub - cover_type(9) = lct_deciduous_shrub - cover_type(10)= lct_c3grass - cover_type(11)= lct_c4grass - cover_type(12)= lct_tundra - cover_type(13)= lct_swamp - cover_type(14)= lct_crop - - glacier_tile = 1 - is_naturalveg(1) = .FALSE. - is_naturalveg(14) = .FALSE. - - ELSE - CALL hdlerr(1,'calc_cover_types: number of tiles not supported') - END IF - - IF (ANY(cover_type(:) == 0)) THEN - CALL hdlerr(1,'a cover type is 0. Possible reason: ' & - //'lct definitions do not match this routine') - END IF - -END SUBROUTINE calc_cover_types - -!------------------------------------------------------------------------------ -SUBROUTINE harmonize_fractions(ntiles, is_naturalveg, glac, natural_veg, cover_fract) -!------------------------------------------------------------------------------ -! -! !DESCRIPTION: -! -! Rescaling of cover fractions to assure that potential natural vegetation -! is greater or equal than the actual natural vegetation on all tiles. -! -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - IMPLICIT NONE -! -! !INPUT PARAMETERS: -! - INTEGER, INTENT(in) :: ntiles ! number of tiles - INTEGER, INTENT(in) :: glac ! glacier flag (1:glacier) - LOGICAL, INTENT(in) :: is_naturalveg(ntiles) ! flag for natural vegetation - REAL(dp), INTENT(inout) :: natural_veg(ntiles) ! potentially vegetated fraction - ! of natural vegetation types -! -! !IN- and OUTPUT PARAMETERS: -! - REAL(dp), INTENT(inout) :: cover_fract(ntiles) ! vegetated fraction - -! !LOCAL PARAMETERS - INTEGER :: i - REAL(dp) :: delta(ntiles) ! missmach of actual and potential natural types -!------------------------------------------------------------------------------ - - ! glacier points need not be regarded - - IF (glac == 1) RETURN - - delta(:) = 0._dp - WHERE (is_naturalveg) - delta(:) = cover_fract(:) - natural_veg(:) - cover_fract(:) = MIN(cover_fract(:),natural_veg(:)) - END WHERE - - ! Due to the pasture rule, in cells with pastures actual grass fractions are - ! disproportionately smaller than potential grass fractions. The relative - ! scaling in scale_cover_fract can lead to slightly greater fractions of the - ! remaining natural vegetation types if called for cover_fract (in comparison - ! to scale_cover_fract calls for natural_veg). - ! Thus calls to scale_cover_fract can distroy the harmonization just achieved. - ! We thus have to assure here, that no further calls of scale_cover_fract are - ! needed. - ! We add the missmatch (actual natural vegetation fraction is slightly - ! greater than the potential fraction) to the dominant natural grass types. - - DO i = 1, ntiles - IF (delta(i) > 0._dp) THEN - IF (cover_fract(veg_c3grass) > cover_fract(veg_c4grass)) THEN - cover_fract(veg_c3grass) = cover_fract(veg_c3grass) + delta(i) - ELSE - cover_fract(veg_c4grass) = cover_fract(veg_c4grass) + delta(i) - END IF - END IF - END DO - -END SUBROUTINE harmonize_fractions - -!------------------------------------------------------------------------------ -SUBROUTINE scale_cover_fract (ntiles, is_naturalveg, glac, cover_fract) -!------------------------------------------------------------------------------ -! -! !DESCRIPTION: -! -! Rescaling of cover fractions to assure that -! - the sum of cover fractions is one -! - all non-glacier grid cells have at least a minimum vegetated fraction -! -! This is not a copy of the current jsbach routine in mo_land_surface. -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - IMPLICIT NONE -! -! !INPUT PARAMETERS: -! - INTEGER, INTENT(in) :: ntiles ! number of tiles - INTEGER, INTENT(in) :: glac ! glacier flag (1:glacier) - LOGICAL, INTENT(in) :: is_naturalveg(ntiles) ! flag for natural vegetation -! -! !IN- and OUTPUT PARAMETERS: -! - REAL(dp), INTENT(inout) :: cover_fract(ntiles) ! vegetated fraction - -! !LOCAL VARIABLES: -! - INTEGER :: i, iter - INTEGER :: niter ! number of iterations needed - INTEGER :: nsparce ! number of PFTs with a vegetated fraction of less then small_fract - INTEGER :: nsparce_anthro ! number of non natural PFTs with a vegetated fraction < small_fract - INTEGER :: nnatural ! number natural PFTs - REAL(dp) :: sum_fract ! sum of all cover fractions - REAL(dp) :: excluded_fract ! sum of all cover fractions - -!------------------------------------------------------------------------------ - - ! cover fractions of glacier points have already been set in calc_cover_fract - - IF (glac == 1) RETURN - - ! Make sure, crop and pasture have a cover fraction of at least small_fract - - WHERE (.NOT. is_naturalveg) - cover_fract(:) = MAX(small_fract,cover_fract(:)) - END WHERE - - ! If there is a tile reserved for glaciers, it's fractions need to be 0 on non glacier points - - IF (glacier_tile /= -1) THEN - cover_fract(glacier_tile) = 0._dp - END IF - - ! Crops and pastures only need to be scaled if their total fraction is greater than - ! 1-nnatural*small_fract. - - excluded_fract = SUM(cover_fract(:), MASK = .NOT. is_naturalveg) - nnatural = 0 - nsparce_anthro = 0 - DO i = 1, ntiles - IF (is_naturalveg(i) .AND. glacier_tile /= i) THEN - nnatural = nnatural + 1 - END IF - IF (.NOT. is_naturalveg(i) .AND. cover_fract(i) <= small_fract .AND. glacier_tile /= i) THEN - nsparce_anthro = nsparce_anthro + 1 - END IF - END DO - IF (excluded_fract > 1._dp - REAL(nnatural+nsparce_anthro,dp)*small_fract) THEN - WHERE (.NOT. is_naturalveg .AND. cover_fract(:) > small_fract) - cover_fract(:) = cover_fract(:) * (1._dp - REAL(nnatural+nsparce_anthro,dp)*small_fract) & - / (excluded_fract-REAL(nsparce_anthro,dp)*small_fract) - - END WHERE - END IF - - ! Scale the natural vegetation that there is a minimum cover fraction of small_fract on all - ! tiles and the total cover fraction is 1. - - niter = ntiles ! to assure binary identical fractions whether or not - IF (glacier_tile /= -1) niter = niter - 1 ! a glacier tile is used, the niter has to be fix. - DO iter = 1, niter - - sum_fract = 0._dp - excluded_fract = 0._dp - nsparce = 0 - - DO i = 1,ntiles - IF (cover_fract(i) > small_fract .AND. is_naturalveg(i)) THEN - sum_fract = sum_fract + cover_fract(i) - ELSE IF (is_naturalveg(i)) THEN - nsparce = nsparce + 1 - ELSE - excluded_fract = excluded_fract + cover_fract(i) - END IF - END DO - DO i = 1,ntiles - IF (cover_fract(i) > small_fract .AND. is_naturalveg(i)) THEN - cover_fract(i) = cover_fract(i) * (1._dp - excluded_fract - REAL(nsparce,dp)*small_fract) / sum_fract - ELSE IF (glacier_tile == i) THEN - cover_fract(i) = 0._dp - ELSE IF (is_naturalveg(i)) THEN - cover_fract(i) = small_fract - ELSE - cover_fract(i) = MAX(small_fract,cover_fract(i)) - END IF - END DO - - END DO - - IF (ANY(cover_fract(:) < small_fract) .AND. glacier_tile == -1) THEN - WRITE(*,*) 'cover_fract still smaller ', small_fract, ' after ', niter, ' iterations:', & - MINVAL(cover_fract(:)), ' (tile: ', MINLOC(cover_fract(:)), ')' - STOP 1 - END IF - - IF (SUM(cover_fract(:)) > 1._dp + REAL(ntiles,dp)*EPSILON(1._dp) .OR. & - SUM(cover_fract(:)) < 1._dp - REAL(ntiles,dp)*EPSILON(1._dp)) THEN - WRITE(*,*) 'SUM(cover_fract) differs from 1: ', SUM(cover_fract(:)) - STOP 1 - END IF - -END SUBROUTINE scale_cover_fract - -!------------------------------------------------------------------------------ -SUBROUTINE put_lct_attributes(ncout, varid) -!------------------------------------------------------------------------------ -! -! Write attributes for land cover types -! -!------------------------------------------------------------------------------ - USE mo_vegparams - IMPLICIT NONE - include 'netcdf.inc' - - !-- INTENT(in) - INTEGER, INTENT(IN) :: ncout, varid - - !-- INTENT(out) - - !-- LOCAL - INTEGER :: stat - CHARACTER(5) :: attnam -!------------------------------------------------------------------------------ - - stat = nf_put_att_text(ncout,varid,'long_name',15,'land cover type') - CALL hdlerr(stat,'put_lct_attributes: long_name') - stat = nf_put_att_text(ncout,varid,'units',1,'1') - CALL hdlerr(stat,'put_lct_attributes: units') - - IF (lct_glacier /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_glacier - stat = nf_put_att_text(ncout,varid,attnam, 7,'glacier') - CALL hdlerr(stat,'put_lct_attributes: lct_glacier') - END IF - IF (lct_tropical_evergreen /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_tropical_evergreen - stat = nf_put_att_text(ncout,varid,attnam,28,'tropical broadleaf evergreen') - CALL hdlerr(stat,'put_lct_attributes: lct_tropical_evergreen') - END IF - IF (lct_tropical_deciduous /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_tropical_deciduous - stat = nf_put_att_text(ncout,varid,attnam,28,'tropical broadleaf deciduous') - CALL hdlerr(stat,'put_lct_attributes: lct_tropical_deciduous') - END IF - IF (lct_extratrop_evergreen /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_extratrop_evergreen - stat = nf_put_att_text(ncout,varid,attnam,24,'extra-tropical evergreen') - CALL hdlerr(stat,'put_lct_attributes: lct_extratrop_evergreen') - END IF - IF (lct_extratrop_deciduous /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_extratrop_deciduous - stat = nf_put_att_text(ncout,varid,attnam,24,'extra-tropical deciduous') - CALL hdlerr(stat,'put_lct_attributes: lct_extratrop_deciduous') - END IF - IF (lct_temperate_broadl_evergreen /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_temperate_broadl_evergreen - stat = nf_put_att_text(ncout,varid,attnam,29,'temperate broadleaf evergreen') - CALL hdlerr(stat,'put_lct_attributes: lct_temperate_broadl_evergreen') - END IF - IF (lct_temperate_broadl_deciduous /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_temperate_broadl_deciduous - stat = nf_put_att_text(ncout,varid,attnam,29,'temperate broadleaf deciduous') - CALL hdlerr(stat,'put_lct_attributes: lct_temperate_broadl_deciduous') - END IF - IF (lct_evergreen_conifer /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_evergreen_conifer - stat = nf_put_att_text(ncout,varid,attnam,20,'evergreen coniferous') - CALL hdlerr(stat,'put_lct_attributes: lct_evergreen_conifer') - END IF - IF (lct_deciduous_conifer /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_deciduous_conifer - stat = nf_put_att_text(ncout,varid,attnam,20,'deciduous coniferous') - CALL hdlerr(stat,'put_lct_attributes: lct_deciduous_conifer') - END IF - IF (lct_raingreen_shrub /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_raingreen_shrub - stat = nf_put_att_text(ncout,varid,attnam,16,'raingreen shrubs') - CALL hdlerr(stat,'put_lct_attributes: lct_raingreen_shrub') - END IF - IF (lct_deciduous_shrub /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_deciduous_shrub - stat = nf_put_att_text(ncout,varid,attnam,16,'deciduous shrubs') - CALL hdlerr(stat,'put_lct_attributes: lct_deciduous_shrub') - END IF - IF (lct_c3grass /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c3grass - stat = nf_put_att_text(ncout,varid,attnam, 8,'C3 grass') - CALL hdlerr(stat,'put_lct_attributes: lct_c3grass') - END IF - IF (lct_c4grass /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c4grass - stat = nf_put_att_text(ncout,varid,attnam, 8,'C4 grass') - CALL hdlerr(stat,'put_lct_attributes: lct_c4gras') - END IF - IF (lct_c3pasture /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c3pasture - stat = nf_put_att_text(ncout,varid,attnam,10,'C3 pasture') - CALL hdlerr(stat,'put_lct_attributes: lct_c3pasture') - END IF - IF (lct_c4pasture /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c4pasture - stat = nf_put_att_text(ncout,varid,attnam,10,'C4 pasture') - CALL hdlerr(stat,'put_lct_attributes: lct_c4pasture') - END IF - IF (lct_tundra /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_tundra - stat = nf_put_att_text(ncout,varid,attnam, 6,'tundra') - CALL hdlerr(stat,'put_lct_attributes: lct_tundra') - END IF - IF (lct_swamp /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_swamp - stat = nf_put_att_text(ncout,varid,attnam, 5,'swamp') - CALL hdlerr(stat,'put_lct_attributes: lct_swamp') - END IF - IF (lct_crop /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_crop - stat = nf_put_att_text(ncout,varid,attnam, 5,'crops') - CALL hdlerr(stat,'put_lct_attributes: lct_crop') - END IF - IF (lct_c3crop /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c3crop - stat = nf_put_att_text(ncout,varid,attnam, 8,'C3 crops') - CALL hdlerr(stat,'put_lct_attributes: lct_c3crop') - END IF - IF (lct_c4crop /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c4crop - stat = nf_put_att_text(ncout,varid,attnam, 8,'C4 crops') - CALL hdlerr(stat,'put_lct_attributes: lct_c4crop') - END IF - -END SUBROUTINE put_lct_attributes - -!------------------------------------------------------------------------------ -SUBROUTINE gauaw (pa, pw, nlat, api) -!------------------------------------------------------------------------------ - !-- copied from echam - - ! Description: - ! - ! Compute abscissas and weights for Gaussian integration. - ! - USE mo_kinds - IMPLICIT NONE - - INTEGER :: nlat - REAL(dp) :: pa(nlat), pw(nlat) - REAL(dp) :: api - - REAL(dp), PARAMETER :: epsil = EPSILON(0.0_dp) - INTEGER, PARAMETER :: itemax = 20 - - INTEGER :: iter, ins2, isym, jn, jgl - REAL(dp) :: za, zw, z, zan - REAL(dp) :: zk, zkm1, zkm2, zx, zxn, zldn, zmod - - ! Intrinsic functions - INTRINSIC ABS, COS, MOD, TAN - - ins2 = nlat/2+MOD(nlat,2) - - DO jgl = 1, ins2 - z = REAL(4 * jgl - 1) * api / REAL(4 * nlat + 2) - pa(jgl) = COS(z + 1._dp / (TAN(z) * REAL(8 * nlat**2))) - END DO - - DO jgl = 1, ins2 - - za = pa(jgl) - - DO iter = 1, itemax+1 - zk = 0._dp - - zkm2 = 1._dp - zkm1 = za - zx = za - DO jn = 2, nlat - zk = (REAL(2 * jn - 1) * zx * zkm1 - REAL(jn - 1) * zkm2) / REAL(jn) - zkm2 = zkm1 - zkm1 = zk - END DO - zkm1 = zkm2 - zldn = (REAL(nlat) * (zkm1 - zx * zk)) / (1._dp - zx * zx) - zmod = -zk / zldn - zxn = zx + zmod - zan = zxn - - zkm2 = 1._dp - zkm1 = zxn - zx = zxn - DO jn = 2,nlat - zk = (REAL(2 * jn - 1) * zx * zkm1 - REAL(jn - 1) * zkm2) / REAL(jn) - zkm2 = zkm1 - zkm1 = zk - END DO - zkm1 = zkm2 - zw = (1._dp - zx * zx) / (REAL(nlat * nlat) * zkm1 * zkm1) - za = zan - IF (ABS(zmod) <= epsil) EXIT - END DO - - pa(jgl) = zan - pw(jgl) = 2._dp * zw - - ENDDO - - DO jgl = 1, nlat/2 - isym = nlat - jgl + 1 - pa(isym) = -pa(jgl) - pw(isym) = pw(jgl) - ENDDO - -END SUBROUTINE gauaw - -!------------------------------------------------------------------------------ -SUBROUTINE extrap(nlon, nlat, lon, lat, mask, missval, method, val) -!------------------------------------------------------------------------------ -! Extrapolation to grid cells with missing values -! -! extrapolation methods (argument method): -! -! nneigh: use value of the nearest neighbor only -! mean: distance weighted mean of neighboring cells -! modal: modal value of neighboring cells, ignoring the distance. This -! only works for integers (technically defined as real). -! -! search for neighbors takes place in a square around the grid cell, with the -! radius being increased until valid neighbors are found. -! This is not optimal for large radii and/or high latitudes, as diagonal -! neighbors in a greater distance might be taken into account while closer -! cells to the east and west might not. -! -!------------------------------------------------------------------------------ - USE mo_kinds - IMPLICIT NONE - - INTEGER, INTENT(in) :: nlon, nlat ! dimensions - REAL(dp), INTENT(in) :: lon(nlon), lat(nlat) ! longitudes, latitudes - REAL(dp), INTENT(in) :: mask(nlon,nlat) ! land sea /glacier mask - REAL(dp), INTENT(in) :: missval ! value for missing data - CHARACTER(*), INTENT(in) :: method ! extrapolation method: nneigh, mean, modal - REAL(dp), INTENT(inout) :: val(nlon,nlat) ! array to be extrapolated - - REAL(dp), PARAMETER :: deg2rad = 1.74532925199432957692e-2 ! Degree to rad: 2pi/360 - - INTEGER :: i, j ! looping index of global grid - INTEGER :: ip, im, jp, jm, ii, jj - INTEGER :: ni, nj ! looping index on neighbors array - INTEGER :: m ! iteration counter - INTEGER :: mmax ! maximum number of iterations - INTEGER :: mini, maxi ! minimum, maximum value - INTEGER :: nval ! number of different values - INTEGER :: loc(2) ! location of nearest neighbor - LOGICAL :: filled ! flag to indicate if gap is filled - REAL(dp) :: x1, y1, z1, x2, y2, z2 ! x,y,z-coordinates - REAL(dp) :: dx ! distance - REAL(dp) :: lon_ctl, lat_ctl ! coordinates of missing cell - REAL(dp) :: lon_nbr, lat_nbr ! coordinates of neighboring cell - REAL(dp) :: sum_dist ! sum of distances of the neighbors - REAL(dp) :: val_new(nlon,nlat) ! filled array (no missing values on land) - REAL(dp), ALLOCATABLE :: neighbours_val(:,:) ! value on neighbors array - REAL(dp), ALLOCATABLE :: neighbours_lon(:,:) ! corresponding longitude - REAL(dp), ALLOCATABLE :: neighbours_lat(:,:) ! corresponding latitude - REAL(dp), ALLOCATABLE :: neighbours_dist(:,:) ! distance of the neighbor - REAL(dp), ALLOCATABLE :: count_values(:) ! array to count different values - - DO i = 1, nlon - DO j = 1, nlat - - ! gap on non-glacier land grid cell - IF (mask(i,j) > 0._dp .AND. val(i,j) == missval) THEN - - ! check neighboring grid cells - - ! initializations - ip = i - im = i - jp = j - jm = j - - m=1 - mmax = nlat ! maximum number of iterations - filled = .FALSE. - - sum_dist = 0._dp - - DO WHILE (.NOT. filled) - - ip = ip+1 - im = im-1 - jp = MIN(jp+1, nlat) - jm = MAX(jm-1, 1) - - ALLOCATE(neighbours_val(ip-im+1,jp-jm+1)) - ALLOCATE(neighbours_lon(ip-im+1,jp-jm+1)) - ALLOCATE(neighbours_lat(ip-im+1,jp-jm+1)) - ALLOCATE(neighbours_dist(ip-im+1,jp-jm+1)) - - DO ni = 1, ip-im+1 ! index on neighbors array - DO nj = 1, jp-jm+1 - ii = im + ni - 1 ! index on global grid - jj = jm + nj - 1 - - IF (ii <= 0) ii = ii + nlon - IF (ii > nlon) ii = ii - nlon - - neighbours_lon(ni,nj) = lon(ii) - neighbours_lat(ni,nj) = lat(jj) - neighbours_val(ni,nj) = val(ii,jj) - END DO - END DO - - IF ( ANY(neighbours_val(:,:) /= missval) ) THEN - SELECT CASE (method) - CASE ('modal') - mini = NINT(MINVAL(neighbours_val(:,:), MASK=neighbours_val(:,:)/=missval)) - maxi = NINT(MAXVAL(neighbours_val(:,:), MASK=neighbours_val(:,:)/=missval)) - ALLOCATE (count_values(maxi-mini+1)) - count_values(:) = 0 - DO nval = mini, maxi - DO ni = 1, ip-im+1 - DO nj = 1, jp-jm+1 ! index on neighbors array - IF (NINT(neighbours_val(ni,nj)) == nval) & - count_values(nval-mini+1) = count_values(nval-mini+1) + 1 - END DO - END DO - END DO - val_new(i,j) = MAXLOC(count_values(:), DIM=1) + mini - 1 - DEALLOCATE (count_values) - - CASE ('nneigh', 'mean') - lon_ctl = lon(i) * deg2rad ! central longitude [rad] - lat_ctl = lat(j) * deg2rad ! central latitude [rad] - - DO nj = 1, jp-jm+1 ! index on neighbors array - DO ni = 1, ip-im+1 - - IF (neighbours_val(ni,nj) /= missval) THEN - - lon_nbr = neighbours_lon(ni,nj) * deg2rad ! lon of neighbor [rad] - lat_nbr = neighbours_lat(ni,nj) * deg2rad ! lat of neighbor [rad] - - ! Transformation to x,y,z-coordinates - - x1 = cos(lat_ctl)*cos(lon_ctl) - y1 = cos(lat_ctl)*sin(lon_ctl) - z1 = sin(lat_ctl) - - x2 = cos(lat_nbr)*cos(lon_nbr) - y2 = cos(lat_nbr)*sin(lon_nbr) - z2 = sin(lat_nbr) - - ! direct distance - dx = SQRT((x2-x1)**2 + (y2-y1)**2 + (z2-z1)**2) - - ! distance along the surface - dx = 2*ASIN(dx/2) - - neighbours_dist(ni,nj) = dx - sum_dist = sum_dist + neighbours_dist(ni,nj) - ELSE - neighbours_dist(ni,nj) = 0._dp - END IF - END DO - END DO - IF (method == 'nneigh') THEN - loc(:) = MINLOC(neighbours_dist(:,:), MASK=neighbours_dist(:,:) /= 0._dp) - val_new(i,j) = neighbours_val(loc(1),loc(2)) - ELSE IF (method == 'mean') THEN - val_new(i,j) = SUM(neighbours_val(:,:) * neighbours_dist(:,:)/sum_dist) - END IF - - CASE default - CALL hdlerr(1, "extrapolation method not supported") - END SELECT - filled = .TRUE. - - ELSE - IF (m >= mmax) CALL hdlerr(1, "Not enough iterations for extrapolation") - m = m + 1 - END IF - - DEALLOCATE(neighbours_val) - DEALLOCATE(neighbours_lon) - DEALLOCATE(neighbours_lat) - DEALLOCATE(neighbours_dist) - - END DO - ELSE - IF (mask(i,j) == 0._dp) THEN - val_new(i,j) = 0._dp - ELSE - val_new(i,j) = val(i,j) - END IF - END IF - END DO - END DO - val(:,:)=val_new(:,:) - -END SUBROUTINE extrap - -!------------------------------------------------------------------------------ -SUBROUTINE open_file(info, infile, ncin, ret_stat) -!------------------------------------------------------------------------------ -! -! Routine to open a netcdf file as read only input file -! -!------------------------------------------------------------------------------ - IMPLICIT NONE - - include 'netcdf.inc' - - !-- INTENT(in) - CHARACTER*100, INTENT(IN) :: infile - LOGICAL, INTENT(IN) :: info - - !-- INTENT(out) - INTEGER, INTENT(OUT) :: ncin - INTEGER, INTENT(OUT), OPTIONAL :: ret_stat - - !-- LOCAL - INTEGER :: stat -!------------------------------------------------------------------------------ - - stat=nf_open(infile, NF_NOWRITE, ncin) - IF (PRESENT(ret_stat) .AND. stat /= NF_NOERR) THEN - ret_stat = stat - RETURN - ENDIF - CALL hdlerr(stat,'opening file '//infile) - IF (info) WRITE(*,*) ' File ', TRIM(infile),' opened' - -END SUBROUTINE open_file - -!------------------------------------------------------------------------------ -SUBROUTINE check_dimensions (varname, ncin, varid, nlon, nlat, ntiles, nlct, & - nvegtyp, nsoil, ntime) -!------------------------------------------------------------------------------ -! -! Routine to find dimensions of an input variable and to compare them with the -! dimensions defined in the output file -! -!------------------------------------------------------------------------------ - IMPLICIT NONE - - include 'netcdf.inc' - - !-- INTENT(in) - CHARACTER*30, INTENT(in) :: varname - INTEGER, INTENT(in) :: ncin, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime - - - !-- INTENT(out) - INTEGER, INTENT(out) :: varid - -!-- LOCAL - INTEGER :: stat, len, dim, ndims - INTEGER, ALLOCATABLE :: dimids(:) - CHARACTER*30 :: dimname -!------------------------------------------------------------------------------ - - stat=nf_inq_varid(ncin, varname, varid) - CALL hdlerr(stat,'check_dimensions: inq. varid of '//varname) - - stat=nf_inq_varndims(ncin, varid, ndims) - CALL hdlerr(stat,'check_dimensions: inq. ndims of '//varname) - - ALLOCATE(dimids(ndims)) - stat=nf_inq_vardimid(ncin, varid, dimids(:)) - CALL hdlerr(stat,'check_dimensions: inq. dimids of '//varname) - - DO dim=1,ndims - stat=nf_inq_dim(ncin, dimids(dim), dimname, len) - CALL hdlerr(stat,'check_dimensions: inq. dim of '//varname) - IF (dimname == 'lon') THEN - IF (nlon /= len) WRITE (*,*) 'Dimension error: nlon=',nlon,' len=', len - ELSE IF (dimname == 'lat') THEN - IF (nlat /= len) WRITE (*,*) 'Dimension error: nlat=',nlat,' len=', len - ELSE IF (dimname == 'level') THEN - IF (1 /= len) WRITE (*,*) 'Dimension error: nlevel=', 1,' len=', len - ELSE IF (dimname == 'lct') THEN - IF (nlct /= len) WRITE (*,*) 'Dimension error: nlct=',nlct,' len=', len - ELSE IF (dimname == 'ntiles') THEN - IF (ntiles /= len) WRITE (*,*) 'Dimension error: ntiles=',ntiles,' len=', len - ELSE IF (dimname == 'soillev') THEN - IF (nsoil /= len) WRITE (*,*) 'Dimension error: soillev=',nsoil,' len=', len - ELSE IF (dimname == 'time') THEN - IF (ntime /= len .AND. len /= 1) & - WRITE (*,*) 'Dimension error: ntime=',ntime,' len=', len - ELSE IF (dimname == 'vegtype') THEN - IF (len /= nvegtyp) WRITE (*,*) & - 'Dimension error: nvegtyp=', nvegtyp, ' len=', len - ELSE - WRITE (*,*) 'Unexpected dimension: ', dimname,' of ',varname - END IF - END DO - DEALLOCATE(dimids) - -END SUBROUTINE check_dimensions - -!------------------------------------------------------------------------------ -SUBROUTINE get_missval (ncid, varid, missval) -!------------------------------------------------------------------------------ -! -! Routine to find out the missing value of an input file variable -! -!------------------------------------------------------------------------------ - USE mo_kinds - IMPLICIT NONE - include 'netcdf.inc' - - !-- INTENT(in) - INTEGER, INTENT(in) :: ncid, varid - - !-- INTENT(out) - REAL(dp), INTENT(out) :: missval - - !-- LOCAL - INTEGER :: stat -!------------------------------------------------------------------------------ - - stat = nf_get_att_double(ncid, varid, "_FillValue", missval) - CALL hdlerr(stat,'get_missval: no missing value available') - -END SUBROUTINE get_missval - -!------------------------------------------------------------------------------ -SUBROUTINE define_var(ncin, ncout, varname_in, varname_out, outdimids, missval) -!------------------------------------------------------------------------------ -! -! Routine to define an output variable that had been read from another -! netcdf file. Attributes and dimensions are copied. -! -!------------------------------------------------------------------------------ - USE mo_kinds - - IMPLICIT NONE - - include 'netcdf.inc' - - !-- INTENT(in) - CHARACTER*30, INTENT(in) :: varname_in, varname_out - INTEGER, INTENT(in) :: ncin, ncout - INTEGER, INTENT(in) :: outdimids(6) - REAL(dp), INTENT(out), OPTIONAL :: missval - - !-- LOCAL - LOGICAL :: dimlon, dimlat, dimtil, dimlct, dimnsoil, dimtim - INTEGER :: stat, dim, att - INTEGER :: varid_in, varid_out, type, natts - INTEGER :: ndims_in, ndims_out - INTEGER, ALLOCATABLE :: dimids_in(:), dimids_out(:) - CHARACTER*30 :: dimname, attname - REAL(dp) :: miss -!------------------------------------------------------------------------------ - stat=nf_inq_varid(ncin, varname_in, varid_in) - CALL hdlerr(stat,'define_var: inq. varid of '//varname_in) - - stat=nf_inq_varndims(ncin, varid_in, ndims_in) - CALL hdlerr(stat,'define_var: inq. ndims of '//varname_in) - ALLOCATE(dimids_in(ndims_in)) - stat=nf_inq_vardimid(ncin, varid_in, dimids_in(:)) - CALL hdlerr(stat,'define_var: inq. dimids of '//varname_in) - - ndims_out=0 - dimlon = .FALSE. - dimlat = .FALSE. - dimtil = .FALSE. - dimlct = .FALSE. - dimtim = .FALSE. - dimnsoil = .FALSE. - - DO dim=1,ndims_in - stat=nf_inq_dimname(ncin, dimids_in(dim), dimname) - CALL hdlerr(stat,'define_var: dimname of '//varname_in) - IF (dimname == 'lon') THEN - dimlon = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'lat') THEN - dimlat = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'ntiles') THEN - dimtil = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'time') THEN - dimtim = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'lct') THEN - dimlct = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'nsoil') THEN - dimnsoil = .TRUE. - ndims_out = ndims_out + 1 - ELSE - WRITE(*,*) "New dimension: "//dimname - END IF - END DO - - ALLOCATE(dimids_out(ndims_out)) - IF (ndims_out == 1) THEN - IF (dimlon) dimids_out(1:1) = (/outdimids(1)/) - IF (dimlat) dimids_out(1:1) = (/outdimids(2)/) - IF (dimtil) dimids_out(1:1) = (/outdimids(3)/) - IF (dimlct) dimids_out(1:1) = (/outdimids(4)/) - IF (dimtim) dimids_out(1:1) = (/outdimids(5)/) - IF (dimnsoil) dimids_out(1:1) = (/outdimids(6)/) - ELSE IF (ndims_out == 2) THEN - dimids_out(1:2) = (/outdimids(1),outdimids(2)/) - ELSE IF (ndims_out == 3) THEN - IF (dimtil) dimids_out(1:3) = outdimids((/1,2,3/)) - IF (dimlct) dimids_out(1:3) = outdimids((/1,2,4/)) - IF (dimnsoil) dimids_out(1:3) = outdimids((/1,2,5/)) - IF (dimtim) dimids_out(1:3) = outdimids((/1,2,6/)) - ELSE IF (ndims_out == 4) THEN - IF (dimtil) dimids_out(1:4) = (/outdimids(1),outdimids(2),outdimids(3),outdimids(5)/) - IF (dimlct) dimids_out(1:4) = (/outdimids(1),outdimids(2),outdimids(4),outdimids(5)/) - ELSE - WRITE(*,*) "WARNING: No more than four dimensions expected" - END IF - - stat=nf_inq_vartype(ncin, varid_in, type) - CALL hdlerr(stat,'define_var: inq. type of '//varname_in) - stat=nf_inq_varnatts(ncin, varid_in, natts) - CALL hdlerr(stat,'define_var: inq. natts of '//varname_in) - - stat=nf_def_var(ncout, varname_out, type, ndims_out, dimids_out, varid_out) - CALL hdlerr(stat,'define_var: defining var '//varname_out) - DO att=1,natts - stat = nf_inq_attname(ncin, varid_in, att, attname) - CALL hdlerr(stat,'define_var: attname of '//varname_in) - stat = nf_copy_att(ncin, varid_in, attname, ncout,varid_out) - CALL hdlerr(stat,'define_var: copy attribute '//attname) - IF (attname == "_FillValue") THEN - stat = nf_get_att_double(ncin, varid_in, attname, miss) - CALL hdlerr(stat,'get missing value of: '//varname_in) - ENDIF - END DO - IF (PRESENT(missval)) missval = miss - - DEALLOCATE(dimids_in) - DEALLOCATE(dimids_out) - -END SUBROUTINE define_var - -!------------------------------------------------------------------------------ -SUBROUTINE define_var_new(ncout, varname, ndims, outdimids) -!------------------------------------------------------------------------------ -! -! Routine to define an output variable that had not been read from an other -! netcdf file. -! -!------------------------------------------------------------------------------ - IMPLICIT NONE - include 'netcdf.inc' - - !-- INTENT(in) - CHARACTER*30, INTENT(in) :: varname - INTEGER, INTENT(in) :: ncout, ndims - INTEGER, INTENT(in) :: outdimids(ndims) - - !-- LOCAL - INTEGER :: stat, varid - INTEGER, ALLOCATABLE :: dimids(:) -!------------------------------------------------------------------------------ - - ALLOCATE(dimids(ndims)) - IF (ndims == 2) THEN - dimids(1:2) = (/outdimids(1),outdimids(2)/) - ELSE IF (ndims == 3) THEN - dimids(1:3) = (/outdimids(1),outdimids(2),outdimids(3)/) - ELSE - WRITE(*,*) 'Only 2 or 3 dimensions supported so far' - END IF - - stat=nf_def_var(ncout, varname, NF_DOUBLE, ndims, dimids, varid) - CALL hdlerr(stat,'define_var_new: defining var '//varname) - DEALLOCATE(dimids) - - ! define attributes - - IF (varname == 'slm') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 19, 'land sea mask') - CALL hdlerr(stat,'define_var_new: put slm long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put slm units') - - ELSE IF (varname == 'cover_fract') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 19, 'land cover fraction') - CALL hdlerr(stat,'define_var_new: put cover_fract long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put cover_fract units') - - ELSE IF (varname == 'cover_type') THEN - CALL put_lct_attributes(ncout, varid) - - ELSE IF (varname == 'veg_ratio_max') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 27, 'maximum vegetation fraction') - CALL hdlerr(stat,'define_var_new: put veg_ratio_max long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put veg_ratio_max units') - - ELSE IF (varname == 'albedo_veg_vis') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 38, & - 'vegetation albedo in the visible range') - CALL hdlerr(stat,'define_var_new: put albedo_veg_vis long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put albedo_veg_vis units') - - ELSE IF (varname == 'albedo_veg_nir') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 28, 'vegetation albedo in the NIR') - CALL hdlerr(stat,'define_var_new: put albedo_veg_nir long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put albedo_veg_nir units') - - ELSE IF (varname == 'albedo_soil_vis') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 32, 'soil albedo in the visible range') - CALL hdlerr(stat,'define_var_new: put albedo_soil_vis long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put albedo_soil_vis units') - - ELSE IF (varname == 'albedo_soil_nir') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 22, 'soil albedo in the NIR') - CALL hdlerr(stat,'define_var_new: put albedo_soil_nir long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put albedo_soil_nir units') - - ELSE IF (varname == 'roughness_length_oro') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 33, 'roughness_length due to orography') - CALL hdlerr(stat,'define_var_new: put roughness_length_oro long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put roughness_length_oro units') - - ELSE IF (varname == 'natural_veg') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 30, 'natural (potential) vegetation') - CALL hdlerr(stat,'define_var_new: put natural_veg long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put natural_veg units') - - ELSE IF (varname == 'soil_depth') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 10, 'soil depth') - CALL hdlerr(stat,'define_var_new: put soil_depth long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put soil_depth units') - - ELSE IF (varname == 'soil_porosity') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 14, 'soil porosity') - CALL hdlerr(stat,'define_var_new: put soil_porosity long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put soil_porosity units') - - ELSE IF (varname == 'pore_size_index') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 20, 'soil pore size index') - CALL hdlerr(stat,'define_var_new: put pore_size_index long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put pore_size_index units') - - ELSE IF (varname == 'soil_field_cap') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 19, 'soil field capacity') - CALL hdlerr(stat,'define_var_new: put soil_field_cap long_name') - stat = nf_put_att_text(ncout, varid, 'units', 4, 'mm-1') - CALL hdlerr(stat,'define_var_new: put soil_field_cap units') - - ELSE IF (varname == 'heat_capacity') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 25, 'heat capacity of dry soil') - CALL hdlerr(stat,'define_var_new: put heat_capacity long_name') - stat = nf_put_att_text(ncout, varid, 'units', 7, 'Jm-3K-1') - CALL hdlerr(stat,'define_var_new: put heat_capacity units') - - ELSE IF (varname == 'heat_conductivity') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 29, 'heat conductivity of dry soil') - CALL hdlerr(stat,'define_var_new: put heat_conductivity long_name') - stat = nf_put_att_text(ncout, varid, 'units', 10, 'Jm-1s-1K-1') - CALL hdlerr(stat,'define_var_new: put heat_conductivity units') - - ELSE IF (varname == 'moisture_pot') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 34, 'saturated matrix potential of soil') - CALL hdlerr(stat,'define_var_new: put moisture_pot long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put moisture_pot units') - - ELSE IF (varname == 'hyd_cond_sat') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 19, 'saturated hydraulic conductivity') - CALL hdlerr(stat,'define_var_new: put hyd_cond_sat long_name') - stat = nf_put_att_text(ncout, varid, 'units', 4, 'ms-1') - CALL hdlerr(stat,'define_var_new: put hyd_cond_sat units') - - ELSE IF (varname == 'wilting_point') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 39, 'Volumetric soil permanent wilting point') - CALL hdlerr(stat,'define_var_new: put wilting_point long_name') - stat = nf_put_att_text(ncout, varid, 'units', 4, 'mm-1') - CALL hdlerr(stat,'define_var_new: put wilting_point units') - - ELSE IF (varname == 'bclapp') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 31, 'Clapp and Hornberger b exponent') - CALL hdlerr(stat,'define_var_new: put bclapp long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put bclapp units') - - ELSE IF (varname == 'root_depth') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 13, 'rooting depth') - CALL hdlerr(stat,'define_var_new: put root_depth long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put root_depth units') - - ELSE IF (varname == 'layer_moist') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 37, 'initial moisture for multilayer soils') - CALL hdlerr(stat,'define_var_new: put layer_moist long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put layer_moist units') - - ENDIF - -END SUBROUTINE define_var_new - -!------------------------------------------------------------------------------ -SUBROUTINE set_global_attributes(ncout, year_ct, year_cf, res_oce, res_atm, & - nlct, ntiles, nsoil, lcouple, ldynveg, lc3c4crop, lpasture, lread_pasture, & - lpasture_rule, desert_only, grass_only, woods_only, ignore_measurements, & - echam_fractional, maxmoist_version, pasture_tag, masks_file, svn_url, svn_rev) -!------------------------------------------------------------------------------ -! -! Routine to set global attributes -! -!------------------------------------------------------------------------------ - IMPLICIT NONE - include 'netcdf.inc' - - !-- INTENT(in) - INTEGER, INTENT(in) :: ncout - INTEGER, INTENT(in) :: nlct, ntiles, nsoil - INTEGER, INTENT(in) :: year_ct, year_cf - CHARACTER(8), INTENT(in) :: res_oce, res_atm, maxmoist_version, pasture_tag - LOGICAL, INTENT(in) :: lcouple, desert_only, grass_only, woods_only - LOGICAL, INTENT(in) :: ldynveg, lc3c4crop, lpasture, lread_pasture, lpasture_rule - LOGICAL, INTENT(in) :: echam_fractional, ignore_measurements - CHARACTER(100), INTENT(in) :: masks_file - CHARACTER(*), INTENT(in) :: svn_url, svn_rev - - !-- LOCAL - INTEGER :: stat - CHARACTER(8) :: date - CHARACTER(10) :: time - CHARACTER(400) :: comment, history, references, configuration - CHARACTER(120) :: url, rev - -!------------------------------------------------------------------------------ - - stat = nf_put_att_text(ncout, NF_GLOBAL, 'title', 31, & - 'initial surface data for JSBACH') - CALL hdlerr(stat,'set_global_attributes: title') - - stat = nf_put_att_text(ncout, NF_GLOBAL, 'institution', 54, & - 'Max Planck Institute for Meteorology, Hamburg, Germany') - CALL hdlerr(stat,'set_global_attributes: institution') - - stat = nf_put_att_text(ncout, NF_GLOBAL, 'Conventions', 6, 'CF-1.0') - CALL hdlerr(stat,'set_global_attributes: Conventions') - - stat = nf_put_att_int(ncout, NF_GLOBAL, 'refyear_for_cover_types', NF_INT, 1, year_ct ) - CALL hdlerr(stat,'set_global_attributes: year_ct') - - stat = nf_put_att_int(ncout, NF_GLOBAL, 'refyear_for_cover_fractions', NF_INT, 1, year_cf ) - CALL hdlerr(stat,'set_global_attributes: year_cf') - - stat = nf_put_att_text(ncout, NF_GLOBAL, 'spherical_truncation', LEN_TRIM(res_atm), TRIM(res_atm)) - CALL hdlerr(stat,'set_global_attributes: spherical_truncation') - - stat = nf_put_att_int(ncout, NF_GLOBAL, 'nlct', NF_INT, 1, nlct) - CALL hdlerr(stat,'set_global_attributes: nlct') - - WRITE (configuration,'(a,i2,a,i2.1,a)') TRIM(res_atm)//TRIM(res_oce)//' ', ntiles, 'tiles ', nsoil, 'layers' - stat = nf_put_att_text(ncout, NF_GLOBAL, 'configuration', LEN_TRIM(configuration), TRIM(configuration)) - CALL hdlerr(stat,'set_global_attributes: configuration') - - IF (lcouple) THEN - comment = 'setup for an experiment with ocean model: grid '//TRIM(res_oce) - ELSE - comment = 'setup for an experiment without ocean model' - END IF - IF (desert_only) THEN - comment = TRIM(comment)//CHAR(10)//'desert_only: all land has desert conditions' - ELSE IF (grass_only) THEN - comment = TRIM(comment)//CHAR(10)//'grass_only: all land covered by grass' - ELSE IF (woods_only) THEN - comment = TRIM(comment)//CHAR(10)//'woods_only: all land covered by woods' - END IF - IF (ignore_measurements) THEN - comment = TRIM(comment)//CHAR(10)//'ignore_measurements: cover fractions only depend on latitude' - END IF - IF (ldynveg) THEN - comment = TRIM(comment)//CHAR(10)//'setup for runs with dynamic vegetation' - ELSE - comment = TRIM(comment)//CHAR(10)//'setup for runs without dynamic vegetation' - END IF - IF (lc3c4crop) THEN - comment = TRIM(comment)//CHAR(10)//'C3 and C4 crops distinguished' - ELSE - comment = TRIM(comment)//CHAR(10)//'C3 and C4 crops not distinguished' - END IF - IF (lpasture) THEN - comment = TRIM(comment)//CHAR(10)//'pastures distinguished from crops' - ELSE - comment = TRIM(comment)//CHAR(10)//'pastures not distinguished form crops' - END IF - IF (lread_pasture) THEN - SELECT CASE (TRIM(pasture_tag)) - CASE ('LUH') - comment = TRIM(comment)//CHAR(10)// & - 'crop and pasture fractions calculated from LUH harmonized land use data '// & - 'generated for CMIP5' - CASE ('LUH2v2h') - comment = TRIM(comment)//CHAR(10)// & - 'crop and pasture fractions calculated from LUH2 v2h Release (10/14/16)' & - //CHAR(10)//'crop cover types calculated from 1961 to 2005 average of FAO data' - CASE DEFAULT - comment = TRIM(comment)//CHAR(10)// & - 'crop and pasture fractions from '//(TRIM(pasture_tag)) - END SELECT - END IF - IF (lpasture_rule) THEN - comment = TRIM(comment)//CHAR(10)//'pasture rule applied' - END IF - IF (echam_fractional) THEN - comment = TRIM(comment)//CHAR(10)//'setup for ECHAM with fractional land sea mask' - END IF - IF (maxmoist_version == 'LSP3') THEN - comment = TRIM(comment)//CHAR(10)//'maximum soil moisture from LSP3 (Stacke 2013) ' - ELSE IF (maxmoist_version == 'LSP2') THEN - comment = TRIM(comment)//CHAR(10)//'maximum soil moisture from LSP2 (as in echam5) ' - END IF - IF (TRIM(masks_file) /= 'default') THEN - comment = TRIM(comment)//CHAR(10)//'land sea, glacier and lake masks read from file: ' & - //TRIM(masks_file) - END IF - stat = nf_put_att_text(ncout, NF_GLOBAL, 'comment', LEN_TRIM(comment), TRIM(comment)) - CALL hdlerr(stat,'set_global_attributes: comment') - - CALL DATE_AND_TIME(date,time) - url=svn_url(11:LEN_TRIM(svn_url)-2) - rev=svn_rev(2:LEN_TRIM(svn_rev)-2) - history = date(1:4)//'-'//date(5:6)//'-'//date(7:8)//' ' & - //time(1:2)//':'//time(3:4)//' : created with ' & - //CHAR(10)//TRIM(url)//CHAR(10)//TRIM(rev) - stat = nf_put_att_text(ncout, NF_GLOBAL, 'history', LEN_TRIM(history), TRIM(history)) - CALL hdlerr(stat,'set_global_attributes: history') - - - references = 'Hagemann, S. (2002): An improved land surface parameter ' & - //CHAR(10)//' dataset for global and regional climate models, ' & - //CHAR(10)//' Max Planck Institute for Meteorology, Report 336' & - //CHAR(10)//'Pongratz, J. et al. (2008), A reconstruction of global ' & - //CHAR(10)//' agricultural areas and land cover for the last millennium, '& - //CHAR(10)//' Global Biogeochem. Cycles, 22, GB3018, doi:10.1029/2007GB003153.' - stat = nf_put_att_text(ncout, NF_GLOBAL, 'references', LEN_TRIM(references), TRIM(references)) - CALL hdlerr(stat,'set_global_attributes: references') - - -END SUBROUTINE set_global_attributes - -!------------------------------------------------------------------------------ -SUBROUTINE hdlerr(stat,string) -!------------------------------------------------------------------------------ -! -! Routine to handle netcdf errors -! -!------------------------------------------------------------------------------ - - IMPLICIT NONE - - include 'netcdf.inc' - -! INTENT(in) - INTEGER, INTENT(in) :: stat - CHARACTER*(*), INTENT(in) :: string - -!------------------------------------------------------------------------------ - - IF (stat /= NF_NOERR) THEN - WRITE (6,*) '--------' - WRITE (6,*) ' ERROR: ', string - WRITE (6,*) '--------' - STOP 1 - END IF - -END SUBROUTINE hdlerr -!------------------------------------------------------------------------------ diff --git a/couplings/coupling_dual-hemisphere/utils/jsbach_init_file.ksh b/couplings/coupling_dual-hemisphere/utils/jsbach_init_file.ksh deleted file mode 100755 index c8b37d167..000000000 --- a/couplings/coupling_dual-hemisphere/utils/jsbach_init_file.ksh +++ /dev/null @@ -1,209 +0,0 @@ -#!/bin/ksh -#------------------------------------------------------------------------------ -# Script to compile and run jsbach_init_file.f90 -# For more information read the header of jsbach_init_file.f90. -# -# The script is usually called by create_input_cosmos.ksh, were several -# variables are exported (interactive=false). -# Alternatively, it can be run interactively (interactive=true), to just create -# a specific initial file for jsbach. -# -# To generate a series of vegetation cover maps for runs with landcover change, -# the script needs to be called interactivly with landcover_series=true -# -# Veronika Gayler -# Stiig Wilkenskjeld, 2012-01: Added variables for 5 layer soil scheme -#------------------------------------------------------------------------------ -# -# !NOTE FOR USAGE ON MISTRAL: MAKE SURE TO LOAD THE MODULE 'NAG' PRIOR TO -# EXECUTION OF THIS SCRIPT, OR THE PREDEFINED COMPILER (nagfor) WILL NOT BE -# FOUND! -# Christian Stepanek, 20.04.2016 -# -#------------------------------------------------------------------------------ -# Updates to this script so it is suitable for iterative coupling. -# * Throws away unneeded library definition variables. -# * Turns echam input files into passable arguments. -# -# Paul Gierz, 15.08.2018 -#------------------------------------------------------------------------------ - -set -e - -# Variables that need to be defined if the sript is used interctively. -# If called from create_input_cosmos.ksh these variables are exported. -# -res_atm=T63 # horizontal grid resopution -res_oce=GR15 # ocean model grid (for a coupled setup) - -ntiles=11 # number of jsbach tiles - -dynveg=true # setup for dynamic vegetation -c3c4crop=true # differentiate between C3 and C4 crops -cmip5_pasture=true # use landuse maps for pastures and crops - -year_ct=1850 # year the cover_types are derived from -year_cf=1850 # year cover fractions are derived from - -landcover_series=false # generate a series of files with cover_types of - # year_ct and fractions from year_cf to year_cf2 -year_cf2=1859 # only used with landcover_series - -echam_fractional=false # initial file for echam runs with fractional - # land sea mask -# TODO: Replace this with a ${POOL_DIR}, which should be defined by esm-runscripts... -pool=/work/ollie/pool/ECHAM6/T63 # directories with echam input data -pool_land=/work/ollie/pool/JSBACH/prepare/T63 -srcdir=./ - -# TODO: Something that copies prog from utils here - -if [[ -f ${prog} ]]; then - #------------------------------------------------------------------------------ - # prepare the namelist - #------------------------------------------------------------------------------ - - [[ ${res_oce} = "" ]] && lcouple=.false. || lcouple=.true. - [[ ${dynveg} = true ]] && ldynveg=.true. || ldynveg=.false. - [[ ${c3c4crop} = true ]] && lc3c4crop=.true. || lc3c4crop=.false. - [[ ${cmip5_pasture} = true ]] && lcmip5_pasture=.true. || lcmip5_pasture=.false. - - if [[ ${ntiles} -eq 11 || ${dynveg} = true ]]; then - lpasture=.true. - else - lpasture=.false. - fi - - desert_only=.false. # setup for a desert-only experiment - grass_only=.false. # setup for a grass-only experiment - woods_only=.false. # setup for a woods-only experiment - - cat > namelist < LUH_states_${res_atm}.nc - fi - cdo selyear,${year_cf} LUH_states_${res_atm}.nc \ - LUH_states_${year_cf}_${res_atm}.nc - fi - - ln -sf ${pool_land}/soil_parameters_${res_atm}.nc . - - #------------------------------------------------------------------------------ - # run the program - #------------------------------------------------------------------------------ - echo "Run ${prog}..." - chmod 755 ${prog} - - yr=${year_cf} - [[ ${landcover_series} = true ]] || year_cf2=${year_cf} - while [[ ${yr} -le ${year_cf2} ]]; do - sed "s/year_cf=.*/year_cf=${yr}/" namelist > namelist.tmp - mv namelist.tmp namelist - ./${prog} - (( yr = yr + 1 )) - done - - #------------------------------------------------------------------------------ - # clean up - #------------------------------------------------------------------------------ - if [[ $? -eq 0 ]]; then - rm namelist - rm ${res_atm}${res_oce}_jan_surf.nc - rm ${res_atm}${res_oce}_VGRATCLIM.nc - rm ${res_atm}${res_oce}_VLTCLIM.nc - rm ${res_atm}_TSLCLIM2.nc - rm vegtype_${year_cf}_${res_atm}gauss_pa14.nc - if [[ ${year_cf} != ${year_ct} ]]; then - rm vegtype_${year_ct}_${res_atm}gauss_pa14.nc - fi - rm vegmax_6_${res_atm}.lola - rm ${res_atm}_topo_75.lola - rm albedo_${res_atm}.lola - rm C3C4_mask_${res_atm}gauss.nc - rm potveg_${res_atm}.nc - if [[ ${c3c4crop} = true ]]; then - rm C3C4_crop_${res_atm}.nc - fi - if [[ ${cmip5_pasture} = true ]]; then - rm LUH_states_${res_atm}.nc - rm LUH_states_${year_cf}_${res_atm}.nc - fi - [[ -f mo_kinds.mod ]] && rm mo_kinds.mod - [[ -f mo_vegparams.mod ]] && rm mo_vegparams.mod - rm -f 5soillayers_${res_atm}.nc soil_parameters_${res_atm}.nc - else - echo "error in ${prog}" - exit 1 - fi -else - echo "${prog} could not be created" - exit 1 -fi - -ofile=jsbach_T63GR15_11tiles_5layers_Lev_21ka_noTOPO_xzhang.nc -mv jsbach_T63GR15_11tiles_5layers_1850.nc ${ofile} diff --git a/couplings/coupling_dual-hemisphere/utils/pack.f90 b/couplings/coupling_dual-hemisphere/utils/pack.f90 deleted file mode 100644 index c61637a72..000000000 --- a/couplings/coupling_dual-hemisphere/utils/pack.f90 +++ /dev/null @@ -1,253 +0,0 @@ -!------------------------------------------------------------------------------ -! -! program reading an unpacked array and a corresponding 2d-mask and writes the -! packed array -! -! Compilation: -! -!linux-x64: -! module load nag -! nagfor -colour -nan -gline -O0 -C=all -w=uep pack.f90 -o pack -I/sw/jessie-x64/netcdf_fortran-4.4.2-static-nag60/include -L/sw/jessie-x64/netcdf_fortran-4.4.2-static-nag60/lib -lnetcdff -L/sw/jessie-x64/netcdf-4.3.3.1-static-gccsys/lib/ -lnetcdf -L/sw/jessie-x64/hdf5-1.8.16-static-gccsys/lib -lhdf5_hl -lhdf5 -ldl -L/sw/jessie-x64/szip-2.1-static-gccsys/lib -lsz -lz - -!mistral: -! module load nag -! export LD_LIBRARY_PATH="/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib:/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib:/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib" -! -! nagfor -colour '-maxcontin=100' '-wmismatch=define_var_new,nf_get_var_double,nf_copy_att,nf_get_var_real,nf_put_var_double,nf_def_var,nf_put_vara_double,dgemm,nfmpi_def_dim,nfmpi_put_vara_double,nfmpi_def_var' '-C=all' -g -gline -nan '-w=uep' -o pack ./pack.f90 -I/sw/rhel6-x64/netcdf/netcdf_fortran-4.4.2-static-nag60/include -L/sw/rhel6-x64/netcdf/netcdf_fortran-4.4.2-static-nag60/lib -lnetcdff -L/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib -lnetcdf -L/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib -lhdf5_hl -lhdf5 -ldl -L/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib -lsz -L/usr/lib64/lib -lz -ldl -lm -lnuma -Wl,--export-dynamic -lrt -lnsl -lutil -lm -ldl -!------------------------------------------------------------------------------ -PROGRAM pack_array - - IMPLICIT NONE - INCLUDE 'netcdf.inc' - - INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307) - INTEGER :: i, j, nlon, nlat, ntiles, nland, nsoil, nnlon, nnlat - INTEGER :: stat, ncid, ncin, varid, landid, tileid, soilid, varndims, idtile, idland, idsoil - INTEGER, ALLOCATABLE :: vardimids(:) - - REAL(dp), ALLOCATABLE :: packed1d(:) - REAL(dp), ALLOCATABLE :: packed2d(:,:) - REAL(dp), ALLOCATABLE :: packed3d(:,:,:) - REAL(dp), ALLOCATABLE :: unpacked2d(:,:) - REAL(dp), ALLOCATABLE :: unpacked3d(:,:,:) - REAL(dp), ALLOCATABLE :: unpacked4d(:,:,:,:) - REAL(dp), ALLOCATABLE :: landpoints(:) - REAL(dp), ALLOCATABLE :: tiles(:) - REAL(dp), ALLOCATABLE :: rmask(:,:) - LOGICAL, ALLOCATABLE :: lmask(:,:) - - CHARACTER*100 :: array_name, mask_name, tile_name, soil_name - - PRINT*, 'enter array file name (without .nc)' - READ*, array_name - PRINT*, 'enter mask file name (without .nc)' - READ*, mask_name - - !-- read land sea mask from mask file (array and file have the same names) - - stat = nf_open(TRIM(mask_name)//'.nc',NF_NOWRITE, ncin) - CALL hdlerr(stat) - stat = nf_inq_varid(ncin,mask_name,varid) - CALL hdlerr(stat) - - stat = nf_inq_varndims(ncin,varid,varndims) - CALL hdlerr(stat) - ALLOCATE(vardimids(varndims)) - stat = nf_inq_vardimid(ncin,varid,vardimids) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncin,vardimids(1),nlon) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncin,vardimids(2),nlat) - CALL hdlerr(stat) - DEALLOCATE(vardimids) - ALLOCATE(rmask(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,rmask) - CALL hdlerr(stat) - - !-- read unpacked array from file (array and file have the same names) - - stat = nf_open(TRIM(array_name)//'.nc',NF_NOWRITE,ncid) - CALL hdlerr(stat) - stat = nf_inq_varid(ncid,array_name,varid) - CALL hdlerr(stat) - - stat = nf_inq_varndims(ncid,varid,varndims) - CALL hdlerr(stat) - ALLOCATE(vardimids(varndims)) - stat = nf_inq_vardimid(ncid,varid,vardimids) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncid,vardimids(1),nnlon) - CALL hdlerr(stat) - IF (nnlon /= nlon) PRINT*, 'Dimensions of mask and data files do not match: ', nlon, nnlon - stat = nf_inq_dimlen(ncid,vardimids(2),nnlat) - CALL hdlerr(stat) - IF (nnlat /= nlat) PRINT*, 'Dimensions of mask and data files do not match: ', nlat, nnlat - IF (varndims > 2) THEN - stat = nf_inq_dimlen(ncid,vardimids(3),ntiles) - CALL hdlerr(stat) - stat = nf_inq_dimname(ncid,vardimids(3),tile_name) - CALL hdlerr(stat) - END IF - IF (varndims > 3) THEN - stat = nf_inq_dimlen(ncid,vardimids(4),nsoil) - CALL hdlerr(stat) - stat = nf_inq_dimname(ncid,vardimids(4),soil_name) - CALL hdlerr(stat) - END IF - DEALLOCATE(vardimids) - - nland=SUM(rmask(:,:)) - IF (varndims == 2) THEN - ALLOCATE(unpacked2d(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,unpacked2d) - CALL hdlerr(stat) - ELSE IF (varndims == 3) THEN - ALLOCATE(unpacked3d(nlon,nlat,ntiles)) - stat = nf_get_var_double(ncid,varid,unpacked3d) - CALL hdlerr(stat) - ELSE IF (varndims == 4) THEN - ALLOCATE(unpacked4d(nlon,nlat,ntiles,nsoil)) - stat = nf_get_var_double(ncid,varid,unpacked4d) - CALL hdlerr(stat) - ELSE - STOP ('maximum number of dimensions is 4!') - END IF - stat = nf_close(ncid) - CALL hdlerr(stat) - - !-- pack the array - - ALLOCATE(lmask(nlon,nlat)) - WHERE (rmask == 1._dp) - lmask = .TRUE. - ELSEWHERE - lmask = .FALSE. - ENDWHERE - - IF (varndims == 2) THEN - ALLOCATE(packed1d(nland)) - packed1d(:) = PACK(unpacked2d(:,:), MASK=lmask(:,:)) - ELSE IF (varndims == 3) THEN - ALLOCATE(packed2d(nland,ntiles)) - DO i = 1, ntiles - packed2d(:,i) = PACK(unpacked3d(:,:,i), MASK=lmask(:,:)) - END DO - ELSE IF (varndims == 4) THEN - ALLOCATE(packed3d(nland,ntiles,nsoil)) - DO j = 1, nsoil - DO i = 1, ntiles - packed3d(:,i,j) = PACK(unpacked4d(:,:,i,j), MASK=lmask(:,:)) - END DO - END DO - END IF - - !-- write the output file - - !-- dimensions - stat = nf_create('1d_'//TRIM(array_name)//'.nc',NF_CLOBBER,ncid) - CALL hdlerr(stat) - stat = nf_def_dim(ncid, 'landpoint', nland, idland) - CALL hdlerr(stat) - IF (varndims > 2) THEN - stat = nf_def_dim(ncid, tile_name, ntiles, idtile) - CALL hdlerr(stat) - END IF - IF (varndims > 3) THEN - stat = nf_def_dim(ncid, soil_name, nsoil, idsoil) - CALL hdlerr(stat) - END IF - - stat = nf_def_var(ncid, 'landpoint', NF_DOUBLE, 1, (/idland/), landid) - CALL hdlerr(stat) - IF (varndims > 2) THEN - stat = nf_def_var(ncid, tile_name, NF_DOUBLE, 1, (/idtile/), tileid) - CALL hdlerr(stat) - END IF - IF (varndims > 3) THEN - stat = nf_def_var(ncid, soil_name, NF_DOUBLE, 1, (/idsoil/), soilid) - CALL hdlerr(stat) - END IF - - IF (varndims == 2) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 1, (/idland/), varid) - CALL hdlerr(stat) - ELSE IF (varndims == 3) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 2, (/idland,idtile/), varid) - CALL hdlerr(stat) - ELSE IF (varndims == 4) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 3, (/idland,idtile,idsoil/), varid) - CALL hdlerr(stat) - END IF - stat = nf_enddef(ncid) - CALL hdlerr(stat) - - !-- dimension variables - ALLOCATE(landpoints(nland)) - DO i = 1, nland - landpoints(i)=i - END DO - stat = nf_put_var_double(ncid,landid,landpoints) - DEALLOCATE(landpoints) - CALL hdlerr(stat) - IF (varndims > 2) THEN - ALLOCATE(tiles(ntiles)) - DO i = 1, ntiles - tiles(i)=i - END DO - stat = nf_put_var_double(ncid,tileid,tiles) - CALL hdlerr(stat) - DEALLOCATE(tiles) - END IF - - !-- packed data array - IF (varndims == 2) THEN - stat = nf_put_var_double(ncid,varid,packed1d) - CALL hdlerr(stat) - ELSE IF (varndims == 3) THEN - stat = nf_put_var_double(ncid,varid,packed2d) - CALL hdlerr(stat) - ELSE IF (varndims == 4) THEN - stat = nf_put_var_double(ncid,varid,packed3d) - CALL hdlerr(stat) - END IF - stat = nf_close(ncid) - CALL hdlerr(stat) - stat = nf_close(ncin) - CALL hdlerr(stat) - - DEALLOCATE(rmask, lmask) - IF (varndims == 2) THEN - DEALLOCATE(packed1d, unpacked2d) - ELSE IF (varndims == 3) THEN - DEALLOCATE(packed2d, unpacked3d) - ELSE IF (varndims == 4) THEN - DEALLOCATE(packed3d, unpacked4d) - END IF - -END PROGRAM pack_array - -!------------------------------------------------------------------------------ -! -! Routine to handle netcdf errors -! -!------------------------------------------------------------------------------ -SUBROUTINE hdlerr(stat) - - IMPLICIT NONE - - include 'netcdf.inc' - -! INTENT(in) - INTEGER, INTENT(in) :: stat - -!------------------------------------------------------------------------------ - - IF (stat /= NF_NOERR) THEN - WRITE (6,*) '--------' - WRITE (6,*) ' ERROR: ', nf_strerror(stat) - WRITE (6,*) '--------' - STOP - END IF - -END SUBROUTINE hdlerr -!------------------------------------------------------------------------------ diff --git a/couplings/coupling_dual-hemisphere/utils/pack_file.ksh b/couplings/coupling_dual-hemisphere/utils/pack_file.ksh deleted file mode 100755 index 62d33bdb6..000000000 --- a/couplings/coupling_dual-hemisphere/utils/pack_file.ksh +++ /dev/null @@ -1,120 +0,0 @@ -#!/bin/ksh -#------------------------------------------------------------------------------ -# Script to re-pack all variables of an unpacked jsbach restart file. -# to be used in combination with unpack_file.ksh to e.g. modify the some -# arrays of the restart file -# -# Veronika Gayler, August 2014 -#------------------------------------------------------------------------------ -set -e - -restart=$1 # file with unpacked (lon/lat) data -maskfile=$2 # file with corresponding land sea mask -#maskfile=/pool/data/JSBACH/T63/jsbach_T63GR15_11tiles_1850.nc -maskname=slm # variable name of the land sea mask in maskfile - -#------------------------------------------------------------------------------ -. ${MODULESHOME}/init/ksh -module load nco || true -module unload cdo -if [[ $(uname -n | cut -c1-6) == mlogin || $(uname -n | cut -c1-9) == mistralpp || $(uname -n) == m????? ]]; then - module load cdo/1.7.2-magicsxx-gcc48 - export LD_LIBRARY_PATH="/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib:/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib:/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib" -else - #module load cdo/1.7.2-gccsys - module load cdo #/1.7.2 -fi -cdo="cdo -b 64 -s" -#------------------------------------------------------------------------------ - -if [[ ${restart} = "" ]]; then - echo " ERROR: " - echo " you need to define the name of the file with unpacked data" - echo " and a file containing the corresponding land sea mask" - exit 1 -fi - -restartfile=${restart##*/} -[[ ${restartfile} = ${restart} ]] && restart=./${restart} -restartdir=${restart%/*}; cd ${restartdir}; restartdir=$(pwd) -scriptdir=${0%/*} #; cd ${scriptdir}/..; scriptdir=$(pwd) -script=$(basename $0) - -if [[ ! -f ./pack ]]; then - echo " ERROR: " - echo " The program 'pack' is missing." - echo " Compile /contrib/pack.f90 and place the executable in this " - echo " directory. Instructions are given in the program header." - exit 1 -fi - -# data processing -#----------------- - -cd ${restartdir} -[[ -f 1d_${restartfile} ]] && rm 1d_${restartfile} -${cdo} -selvar,${maskname} ${maskfile} ${maskname}.nc - -# start restart file with (2d) land sea mask; -h: suppress history - -ncks -A -h --no_abc -v ${maskname} ${maskname}.nc 1d_${restartfile} -ncrename -h -v ${maskname},'landseamask' 1d_${restartfile} 1> /dev/null - -# 'cdo showvar' does not work for variables with more than three dimensiones -variables=$(ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '(') - -for var in ${variables}; do - { - # extract specific variable; -a: suppress alphabetical order of variables and dimensions - ncks -O --no_abc -v ${var} ${restartfile} ${var}.nc - case ${var} in - lon | lat ) - echo "${script}: ignoring ${var}: not needed in restart file" - ;; - landseamask | disch | awfre ) - echo "${script}: ${var} should not be packed" - cp ${var}.nc 1d_${var}.nc - ;; - vct_a | vct_b ) - echo "${script}: ${var} cannot be packed" - cp ${var}.nc 1d_${var}.nc - ;; - * ) - echo "${script}: ${var}" - ${scriptdir}/pack < global_atts.$$ -#nlines=$(cat global_atts.$$ | wc -l) -#for (( l = 1; l <= $nlines; l++ )); do -# glatt=$(cat global_atts.$$ | head -$l | tail -1) -# name=$(echo ${glatt} | cut -f4 -d' ' | cut -f 1 -d,) -# type=$(echo ${glatt} | cut -f8 -d' ' | cut -c 4 | tr "A-Z" "a-z") -# value=$(echo ${glatt} | cut -f3 -d= ) -# [[ ${value} = "" ]] && value=' ' -# ncatted -h -a ${name},global,a,${type},"${value}" 1d_${restartfile} -#done -#rm global_atts.$$ -#ncatted -h -a history,global,a,c," $(date): pack_file.ksh ${restartfile}; " 1d_${restartfile} - diff --git a/couplings/coupling_dual-hemisphere/utils/rotate_mesh.py b/couplings/coupling_dual-hemisphere/utils/rotate_mesh.py deleted file mode 100644 index 6258812c1..000000000 --- a/couplings/coupling_dual-hemisphere/utils/rotate_mesh.py +++ /dev/null @@ -1,68 +0,0 @@ -import random -import numpy as np -import xarray as xr -import pandas as pd -import sys -import math -import os -from tqdm import tqdm -from datetime import datetime -from numpy.linalg import inv - -mesh_path = sys.argv[1] -opath = sys.argv[2] -nod2d_file = os.path.join(mesh_path, "nod2d.out") - -def _generate_rotation_matrix(): - alphaEuler=50 - betaEuler=15 - gammaEuler=-90 - - al = np.radians(alphaEuler) - be = np.radians(betaEuler) - ga = np.radians(gammaEuler) - - rotate_matrix = np.zeros((3,3)) - rotate_matrix[0,0]=np.cos(ga)*np.cos(al)-np.sin(ga)*np.cos(be)*np.sin(al) - rotate_matrix[0,1]=np.cos(ga)*np.sin(al)+np.sin(ga)*np.cos(be)*np.cos(al) - rotate_matrix[0,2]=np.sin(ga)*np.sin(be) - rotate_matrix[1,0]=-np.sin(ga)*np.cos(al)-np.cos(ga)*np.cos(be)*np.sin(al) - rotate_matrix[1,1]=-np.sin(ga)*np.sin(al)+np.cos(ga)*np.cos(be)*np.cos(al) - rotate_matrix[1,2]=np.cos(ga)*np.sin(be) - rotate_matrix[2,0]=np.sin(be)*np.sin(al) - rotate_matrix[2,1]=-np.sin(be)*np.cos(al) - rotate_matrix[2,2]=np.cos(be) - - return rotate_matrix - -def _r2g(lon_r, lat_r): - A = _generate_rotation_matrix() - A_ = inv(A) - - lon_ = np.radians(lon_r) - lat_ = np.radians(lat_r) - - v_ = np.zeros((3,1)) - v_[0]=np.cos(lat_)*np.cos(lon_) - v_[1]=np.cos(lat_)*np.sin(lon_) - v_[2]=np.sin(lat_) - vr = np.dot(A_, v_) - - lon_g = np.degrees(math.atan2(vr[1], vr[0])) - lat_g = np.degrees(math.asin(vr[2])) - return lon_g, lat_g - -def _back_rotate(): - r2g_v = np.vectorize(_r2g, excluded="A") - - with open(nod2d_file, 'r') as csvfile: - nodes = pd.read_csv(csvfile, header=None, sep=r'\s* \s*', skiprows=1, engine='python') - #nodes.drop(nodes.index[0], inplace=True) - nodes.columns = ['index', 'lon', 'lat', 'mask'] - [lon_tmp, lat_tmp] = r2g_v(np.array(nodes['lon'].values[:], dtype=float).transpose(), - np.array(nodes['lat'].values[:], dtype=float).transpose()) - nodes['lon'] = lon_tmp - nodes['lat'] = lat_tmp - nodes.to_csv(os.path.join(opath, "nod2d.out"), sep=' ', header=[str(len(nodes)), "", "", ""], index=False) - -_back_rotate() diff --git a/couplings/coupling_dual-hemisphere/utils/unpack.f90 b/couplings/coupling_dual-hemisphere/utils/unpack.f90 deleted file mode 100644 index 85dd2d470..000000000 --- a/couplings/coupling_dual-hemisphere/utils/unpack.f90 +++ /dev/null @@ -1,238 +0,0 @@ -!------------------------------------------------------------------------------ -! -! program reading a packed array and a corresponding 2d-mask and writes the unpacked array -! -! Compilation -! -! linux-x64: -! module load nag -! nagfor -colour -nan -gline -O0 -C=all -w=uep unpack.f90 -o unpack -I/sw/jessie-x64/netcdf_fortran-4.4.2-static-nag60/include -L/sw/jessie-x64/netcdf_fortran-4.4.2-static-nag60/lib -lnetcdff -L/sw/jessie-x64/netcdf-4.3.3.1-static-gccsys/lib/ -lnetcdf -L/sw/jessie-x64/hdf5-1.8.16-static-gccsys/lib -lhdf5_hl -lhdf5 -ldl -L/sw/jessie-x64/szip-2.1-static-gccsys/lib -lsz -lz -! -! mistral: -! module load nag -! export LD_LIBRARY_PATH="/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib:/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib:/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib" -! -! nagfor -colour '-maxcontin=100' '-wmismatch=define_var_new,nf_get_var_double,nf_copy_att,nf_get_var_real,nf_put_var_double,nf_def_var,nf_put_vara_double,dgemm,nfmpi_def_dim,nfmpi_put_vara_double,nfmpi_def_var' '-C=all' -g -gline -nan '-w=uep' -o unpack ./unpack.f90 -I/sw/rhel6-x64/netcdf/netcdf_fortran-4.4.2-static-nag60/include -L/sw/rhel6-x64/netcdf/netcdf_fortran-4.4.2-static-nag60/lib -lnetcdff -L/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib -lnetcdf -L/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib -lhdf5_hl -lhdf5 -ldl -L/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib -lsz -L/usr/lib64/lib -lz -ldl -lm -lnuma -Wl,--export-dynamic -lrt -lnsl -lutil -lm -ldl -!------------------------------------------------------------------------------ -PROGRAM unpack_array - - IMPLICIT NONE - INCLUDE 'netcdf.inc' - - INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307) - REAL(dp), PARAMETER :: missval=NF_FILL_DOUBLE - INTEGER :: i, j, nlon, nlat, ntiles, nland, nsoil - INTEGER :: stat, ncid, ncin, varid, lonid, latid, varndims, idlon, idlat, idtile, idsoil - INTEGER, ALLOCATABLE :: vardimids(:) - - REAL(dp), ALLOCATABLE :: packed1d(:) - REAL(dp), ALLOCATABLE :: packed2d(:,:) - REAL(dp), ALLOCATABLE :: packed3d(:,:,:) - REAL(dp), ALLOCATABLE :: unpacked2d(:,:) - REAL(dp), ALLOCATABLE :: unpacked3d(:,:,:) - REAL(dp), ALLOCATABLE :: unpacked4d(:,:,:,:) - REAL(dp), ALLOCATABLE :: rmask(:,:) - REAL(dp), ALLOCATABLE :: lon(:) - REAL(dp), ALLOCATABLE :: lat(:) - LOGICAL, ALLOCATABLE :: lmask(:,:) - - CHARACTER*100 :: array_name, mask_name, tile_name, soil_name - - !PRINT*, 'enter array file name (without .nc)' - READ*, array_name - !PRINT*, 'enter mask file name (without .nc)' - READ*, mask_name - !PRINT*, 'Got:', array_name, 'and', 'mask_name' - !-- read land sea mask from mask file (array and file have the same names) - - stat = nf_open(TRIM(mask_name)//'.nc',NF_NOWRITE, ncin) - CALL hdlerr(stat) - stat = nf_inq_varid(ncin,mask_name,varid) - CALL hdlerr(stat) - - stat = nf_inq_varndims(ncin,varid,varndims) - CALL hdlerr(stat) - ALLOCATE(vardimids(varndims)) - stat = nf_inq_vardimid(ncin,varid,vardimids) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncin,vardimids(1),nlon) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncin,vardimids(2),nlat) - CALL hdlerr(stat) - DEALLOCATE(vardimids) - ALLOCATE(rmask(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,rmask) - CALL hdlerr(stat) - - !-- read packed array from file (array and file have the same names) - - stat = nf_open(TRIM(array_name)//'.nc',NF_NOWRITE,ncid) - CALL hdlerr(stat) - stat = nf_inq_varid(ncid,array_name,varid) - CALL hdlerr(stat) - - stat = nf_inq_varndims(ncid,varid,varndims) - CALL hdlerr(stat) - ALLOCATE(vardimids(varndims)) - stat = nf_inq_vardimid(ncid,varid,vardimids) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncid,vardimids(1),nland) - CALL hdlerr(stat) - IF (varndims > 1) THEN - stat = nf_inq_dimlen(ncid,vardimids(2),ntiles) - CALL hdlerr(stat) - stat = nf_inq_dimname(ncid,vardimids(2),tile_name) - CALL hdlerr(stat) - END IF - IF (varndims > 2) THEN - stat = nf_inq_dimlen(ncid,vardimids(3),nsoil) - CALL hdlerr(stat) - stat = nf_inq_dimname(ncid,vardimids(3),soil_name) - CALL hdlerr(stat) - END IF - DEALLOCATE(vardimids) - - IF (varndims == 1) THEN - ALLOCATE(packed1d(nland)) - stat = nf_get_var_double(ncid,varid,packed1d) - CALL hdlerr(stat) - ELSE IF (varndims == 2) THEN - ALLOCATE(packed2d(nland,ntiles)) - stat = nf_get_var_double(ncid,varid,packed2d) - CALL hdlerr(stat) - ELSE - ALLOCATE(packed3d(nland,ntiles,nsoil)) - stat = nf_get_var_double(ncid,varid,packed3d) - CALL hdlerr(stat) - END IF - stat = nf_close(ncid) - CALL hdlerr(stat) - - !-- unpack the array - - ALLOCATE(lmask(nlon,nlat)) - WHERE (rmask == 1._dp) - lmask = .TRUE. - ELSEWHERE - lmask = .FALSE. - ENDWHERE - - IF (varndims == 1) THEN - ALLOCATE(unpacked2d(nlon,nlat)) - unpacked2d(:,:) = UNPACK(packed1d(:), MASK=lmask(:,:), FIELD=missval) - ELSE IF (varndims == 2) THEN - ALLOCATE(unpacked3d(nlon,nlat,ntiles)) - DO i = 1, ntiles - unpacked3d(:,:,i) = UNPACK(packed2d(:,i), MASK=lmask(:,:), FIELD=missval) - END DO - ELSE - ALLOCATE(unpacked4d(nlon,nlat,ntiles,nsoil)) - DO j = 1, nsoil - DO i = 1, ntiles - unpacked4d(:,:,i,j) = UNPACK(packed3d(:,i,j), MASK=lmask(:,:), FIELD=missval) - END DO - END DO - END IF - - !-- write the output file - - stat = nf_inq_varid(ncin,'lon',lonid) - CALL hdlerr(stat) - ALLOCATE(lon(nlon)) - stat = nf_get_var_double(ncin,lonid,lon) - CALL hdlerr(stat) - stat = nf_inq_varid(ncin,'lat',latid) - CALL hdlerr(stat) - ALLOCATE(lat(nlat)) - stat = nf_get_var_double(ncin,latid,lat) - CALL hdlerr(stat) - - stat = nf_create('2d_'//TRIM(array_name)//'.nc',NF_CLOBBER,ncid) - CALL hdlerr(stat) - stat = nf_def_dim(ncid, 'lon', nlon, idlon) - CALL hdlerr(stat) - stat = nf_def_dim(ncid, 'lat', nlat, idlat) - CALL hdlerr(stat) - IF (varndims > 1) THEN - stat = nf_def_dim(ncid, tile_name, ntiles, idtile) - CALL hdlerr(stat) - END IF - IF (varndims > 2) THEN - stat = nf_def_dim(ncid, soil_name, nsoil, idsoil) - CALL hdlerr(stat) - END IF - stat = nf_def_var(ncid, 'lon', NF_DOUBLE, 1, (/idlon/), lonid) - CALL hdlerr(stat) - stat = nf_def_var(ncid, 'lat', NF_DOUBLE, 1, (/idlat/), latid) - CALL hdlerr(stat) - IF (varndims == 1) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 2, (/idlon,idlat/), varid) - CALL hdlerr(stat) - ELSE IF (varndims == 2) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 3, (/idlon,idlat,idtile/), varid) - CALL hdlerr(stat) - ELSE - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 4, (/idlon,idlat,idtile,idsoil/), varid) - CALL hdlerr(stat) - END IF - stat = nf_put_att_double(ncid, varid, '_FillValue', NF_DOUBLE, 1, missval) - CALL hdlerr(stat) - - stat = nf_enddef(ncid) - CALL hdlerr(stat) - - stat = nf_put_var_double(ncid,lonid,lon) - CALL hdlerr(stat) - stat = nf_put_var_double(ncid,latid,lat) - CALL hdlerr(stat) - IF (varndims == 1) THEN - stat = nf_put_var_double(ncid,varid,unpacked2d) - CALL hdlerr(stat) - ELSE IF (varndims == 2) THEN - stat = nf_put_var_double(ncid,varid,unpacked3d) - CALL hdlerr(stat) - ELSE - stat = nf_put_var_double(ncid,varid,unpacked4d) - CALL hdlerr(stat) - END IF - stat = nf_close(ncid) - CALL hdlerr(stat) - stat = nf_close(ncin) - CALL hdlerr(stat) - - DEALLOCATE(rmask, lmask, lon, lat) - IF (varndims == 1) THEN - DEALLOCATE(packed1d, unpacked2d) - ELSE IF (varndims == 2) THEN - DEALLOCATE(packed2d, unpacked3d) - ELSE - DEALLOCATE(packed3d, unpacked4d) - END IF - -END PROGRAM unpack_array - -!------------------------------------------------------------------------------ -! -! Routine to handle netcdf errors -! -!------------------------------------------------------------------------------ -SUBROUTINE hdlerr(stat) - - IMPLICIT NONE - - include 'netcdf.inc' - -! INTENT(in) - INTEGER, INTENT(in) :: stat - -!------------------------------------------------------------------------------ - - IF (stat /= NF_NOERR) THEN - WRITE (6,*) '--------' - WRITE (6,*) ' ERROR: ', nf_strerror(stat) - WRITE (6,*) '--------' - STOP - END IF - -END SUBROUTINE hdlerr -!------------------------------------------------------------------------------ diff --git a/couplings/coupling_dual-hemisphere/utils/unpack_file.ksh b/couplings/coupling_dual-hemisphere/utils/unpack_file.ksh deleted file mode 100755 index e8dc5a7c8..000000000 --- a/couplings/coupling_dual-hemisphere/utils/unpack_file.ksh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/ksh -#------------------------------------------------------------------------------ -# Script to unpack all variables of a jsbach restart file. -# -# Veronika Gayler, June 2013 -#------------------------------------------------------------------------------ -set -e - -restart=$1 # file with packed data -maskfile=$2 # file with corresponding land sea mask -# maskfile=/pool/data/JSBACH/T63/jsbach_T63GR15_11tiles_1850.nc -maskname=slm # variable name of the land sea mask in maskfile - -#------------------------------------------------------------------------------ -. ${MODULESHOME}/init/ksh -module load nco || true -module unload cdo || true -if [[ $(uname -n | cut -c1-6) == mlogin || $(uname -n | cut -c1-9) == mistralpp || $(uname -n) == m????? ]]; then - module load cdo/1.7.2-magicsxx-gcc48 - export LD_LIBRARY_PATH="/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib:/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib:/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib" -else - #module load cdo/1.7.2-gccsys - module load cdo #/1.7.2 -fi -#------------------------------------------------------------------------------ - -if [[ ${restart} = "" ]]; then - echo " ERROR: " - echo " you need to define the name of the file with packed data" - echo " and a file containing the corresponding land sea mask" - exit 1 -fi - -restartfile=${restart##*/} -[[ ${restartfile} = ${restart} ]] && restart=./${restart} -mydir=$(pwd) -restartdir=${restart%/*}; cd ${restartdir}; restartdir=$(pwd) -cd ${mydir} -scriptdir=${0%/*} #; cd ${scriptdir}/..; scriptdir=$(pwd) -script=$(basename $0) - -if [[ ! -f ./unpack ]]; then - echo " ERROR: " - echo " The program 'unpack' is missing." - echo " Compile /contrib/unpack.f90 and place the executable in this " - echo " directory. Instructions are given in the program header." - exit 1 -fi - -# data processing -#----------------- - -cd ${restartdir} -[[ -f 2d_${restartfile} ]] && rm 2d_${restartfile} -cdo -s -selvar,${maskname} ${maskfile} ${maskname}.nc - -variables=$(cdo -s showvar ${restartfile}) -for var in ${variables}; do - { - echo "${script}: ${var}" - ncks -O -v ${var} ${restartfile} ${var}.nc - case ${var} in - landseamask | disch | awfre ) - echo "${script}: copying ${var}: already on lat lon grid" - ln -fs ${var}.nc 2d_${var}.nc - ;; - vct_a | vct_b ) - echo "${script}: copying ${var}: no landpoint dimension" - ln -fs ${var}.nc 2d_${var}.nc - ;; - *) - ${scriptdir}/unpack < global_atts.$$ -#nlines=$(cat global_atts.$$ | wc -l) -#for (( l = 1; l <= $nlines; l++ )); do -# glatt=$(cat global_atts.$$ | head -$l | tail -1) -# name=$(echo ${glatt} | cut -f4 -d' ' | cut -f 1 -d,) -# type=$(echo ${glatt} | cut -f8 -d' ' | cut -c 4 | tr "A-Z" "a-z") -# value=$(echo ${glatt} | cut -f3 -d= ) -# [[ ${value} = "" ]] && value=' ' -# ncatted -h -a ${name},global,a,${type},"${value}" 2d_${restartfile} -#done -#rm global_atts.$$ -ncatted -h -a history,global,a,c," $(date): unpack_file.ksh ${restartfile}; " 2d_${restartfile} -echo "All done with ${script}: Output is $(pwd)/2d_${restartfile}" diff --git a/couplings/dEBM/install_debm.sh b/couplings/dEBM/install_debm.sh deleted file mode 100755 index def132a62..000000000 --- a/couplings/dEBM/install_debm.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -MACHINE=$1 - -if [[ ${MACHINE} == "albedo" ]]; then - module load nco/5.0.1 netcdf-fortran/4.5.4-intel2021.6.0 - module load intel-oneapi-compilers/2022.1.0 - fortran_compiler=ifort #gfortran - nc_config=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/bin/nf-config - export NETCDF_LIB=$($nc_config --flibs) - export NETCDF_INC=$($nc_config --includedir) - NETCDFFROOT=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz - export PATH=${NETCDFFROOT}:${NETCDFFROOT}/include:${NETCDFFROOT}/lib:$PATH - export LD_LIBRARY_PATH=${NETCDFFROOT}/lib:${NETCDFROOT}/lib:$LD_LIBRARY_PATH -elif [[ ${MACHINE} == "levante" ]]; then - module load nco/5.0.6-gcc-11.2.0 intel-oneapi-compilers/2022.0.1-gcc-11.2.0 - module load intel-oneapi-mkl/2022.0.1-gcc-11.2.0 openmpi/4.1.2-intel-2021.5.0 netcdf-fortran/4.5.3-openmpi-4.1.2-intel-2021.5.0 - nc_config=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/bin/nf-config - export NETCDF_LIB=$($nc_config --flibs) - export NETCDF_INC=$($nc_config --includedir) - NETCDFFROOT=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/ - export PATH=${NETCDFFROOT}:${NETCDFFROOT}/include:${NETCDFFROOT}/lib:$PATH - export LD_LIBRARY_PATH=${NETCDFFROOT}/lib:${NETCDFROOT}/lib:$LD_LIBRARY_PATH -else - echo " * Unknown machine! No installation possible" - exit -fi - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -cd ${thisdir}/Fortran/ - -make diff --git a/couplings/dEBM/namelist.debm b/couplings/dEBM/namelist.debm deleted file mode 100644 index 28fd03884..000000000 --- a/couplings/dEBM/namelist.debm +++ /dev/null @@ -1,40 +0,0 @@ -&runctl -lresume=.false. ! if restart, read snow height from 'restart_debm.nc' - ! .false. by default -use_shortwave_radiation_TOA=.true. ! if incorporate top incoming shortwave -use_mask=.false. ! ice mask -debug_switch=.true. ! debug option - ! .false. by default -debug_lon=241 ! if debug_switch=.true. -debug_lat=107 ! debug grid point(debug_lon,debug_lat,debug_mon,debug_year) -debug_mon=7 ! will be print during simulation -debug_year=1 -/ - -&debm -filename_in='input/Amon_AWI-ESM-1-1-LR_historical_r1i1p1f1_gn_dEBM_1951_5km.nc' ! input filename - -precipitation_varname='precip' -temperature_varname='temp2' -shortwave_radiation_downward_varname='swd' -shortwave_radiation_TOA_varname='srad0d' -cloud_cover_varname='aclcov' -emissivity_varname='emiss' -!transmissivity_varname='tau' -mapping_varname='thk' -longitude_varname='lon' -latitude_varname='lat' -time_varname='time' - -hydmth_str = 10 ! the beginning of the hydrological year, also start month for snow height integration - ! October for Northern Hemisphere - ! April Southern Hemisphere -stddev=3.5 ! constant standard deviation -obliquity=23.446 ! obliquity -cloud_bias=0.155 ! cloud bias -Ans = .845 ! Albedo for new snow -Ads = .73 ! Albedo for dry snow -Aws = .55 ! Albedo for wet snow -tau_cs = .75 ! expected clear sky transmissivity -residual = 0 ! residual heat flux (e.g. due to flux into the ice sheet -/ diff --git a/couplings/echam/coupling_echam2ice.functions b/couplings/echam/coupling_echam2ice.functions deleted file mode 100644 index d65d54ebf..000000000 --- a/couplings/echam/coupling_echam2ice.functions +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/ksh -## @file -## @author Dr. Paul Gierz -## @author Alfred Wegener Institute for Polar and Marine Research -## @author Bremerhaven, Germany -## -## @brief Functions for preparing `ECHAM6` output for use with a generic ice sheet model - -# Here, variables which control the program flow are "declared", even if they are defined in other files -## @var ECHAM_TO_ISM_multiyear_mean -## Controls whether or not a multi-year mean is made from `atmosphere_file_for_ice.nc` -## Originally defined in ::echam_after_last_run_in_chunk -export ECHAM_TO_ISM_multiyear_mean - -##@var ECHAM_TO_ISM_atmosphere_forcing -## Controls whether `ECHAM6` output is used to prepare a forcing file for a generic ice sheet model. -## Originally defined in ::echam_after_last_run_in_chunk -export ECHAM_TO_ISM_atmosphere_forcing - -## @fn echam2ice() -## @brief Container for all functionality of `ECHAM6` to a generic ice sheet -## -## This function contains all functions needed to gather standard `ECHAM6` output for use with a -## generic ice sheet model. The following steps are preformed: -## 1. Generation of forcing -## 2. Preparing a grid description for later use with `cdo remap` -## 3. Preparing a file describing the names `ECHAM6` uses for its variables -## -## The variable #ECHAM_TO_ISM_atmosphere_forcing must be set to `1` -## for this function to be called (This is the default value). -## -## (Re)-initializes an empty file in `COUPLE_DIR` to store standard error of cdo output (for cleaner logs) -echam2ice() { - echo " ==================================================================" - echo " *** S T A R T I N G echam2ice *** "; echo - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - . ${FUNCTION_PATH}/../general/general_helpers.functions - - :> ${COUPLE_DIR}/cdo_stderr_echam2ice - iterative_coupling_echam6_ice_make_forcing - iterative_coupling_echam6_ice_write_grid - iterative_coupling_echam6_ice_write_names - - echo "*** build dynamic link of ${RESTART_DIR_echam}/restart_${EXP_ID}_echam_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}.nc" - ln -sf ${RESTART_DIR_echam}/restart_${EXP_ID}_echam_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}.nc ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc - - for STREAM in jsbach veg - do - rfile_1=${RESTART_DIR_jsbach}/restart_${EXP_ID}_${STREAM}_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}.nc - rfile_2=${RESTART_DIR_jsbach}/restart_${EXP_ID}_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}_${STREAM}.nc - if [ -f ${rfile_1} ]; then - ln -sf ${rfile_1} ${RESTART_DIR_jsbach}/restart_${EXP_ID}_${STREAM}.nc - elif [ -f ${rfile_2} ]; then - ln -sf ${rfile_2} ${RESTART_DIR_jsbach}/restart_${EXP_ID}_${STREAM}.nc - else - echo " * no ${rfile_1} or ${rfile_2} found ..." - exit - fi - done - - echo " *** F I N I S E D echam2ice *** " - echo " ==================================================================" -} - - -## @fn iterative_coupling_echam6_ice_make_forcing() -## @brief Container for all functionality to prepare forcing -## -## Preforms the following steps: -## 1. Constructs an input list of files from which the `ECHAM6` output will be extracted -## 2. Selects relevant variables from these files -## 3. Concatenates files to single file for further manipulation -## 4. Generates a multiyear mean, if `ECHAM_TO_ISM_multiyear_mean` is `1` -## 5. Adds `atmosphere_file_for_ice.nc` to the couple directory via `add_to`. -iterative_coupling_echam6_ice_make_forcing() { - echo " Preparing echam6 file for processing in an ice sheet model..." - - ECHAM_TO_ISM_multiyear_mean=${ECHAM_TO_ISM_multiyear_mean:-1} - - echam_ice_construct_input_list - echam_ice_select_relevant_variables - echam_ice_concatenate_files - if [ "x${ECHAM_TO_ISM_multiyear_mean}" == "x1" ]; then - echam_ice_generate_multiyear_mean - fi - #add_to $(pwd)/atmosphere_file_for_ice.nc atmosphere_file_for_ice.nc couple - cp $(pwd)/atmosphere_file_for_ice.nc ${COUPLE_DIR}/atmosphere_file_for_ice.nc - - echo; echo " ...done."; echo -} - -## @fn iterative_coupling_echam6_ice_write_grid() -## @brief Writes grids via `cdo griddes` -## -## Uses `cdo griddes` to determine the atmosphere grid information in the file `atmosphere.griddes`. -## Adds this to the couple directory. -iterative_coupling_echam6_ice_write_grid() { - echo " Writing echam6 grid description to generic atmosphere.griddes..." - - echo ""; echo " * generating griddes" - ${cdo} -s griddes atmosphere_file_for_ice.nc > atmosphere.griddes 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - #add_to $(pwd)/atmosphere.griddes atmosphere.griddes couple - cp $(pwd)/atmosphere.griddes ${COUPLE_DIR}/atmosphere.griddes - - echo; echo " ...done."; echo -} - -## @fn iterative_coupling_echam6_ice_write_names() -## @brief Writes names and units of atmospheric variables to `atmosphere_names_for_ice.dat` -## -## (Re)-initializes an empty file atmosphere_names_for_ice.dat -## @note This function currently only generates names useful for the `PISM` mass-ablation scheme PDD! -iterative_coupling_echam6_ice_write_names() { - echo " Writing echam6 names and units for use with generic atmosphere_file_for_ice.nc" - - :> atmosphere_names_for_ice.dat - echo ""; echo " * temperature below firn" - echo "atmosphere_name_temperature_below_firn=tsurf" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_temperature=K" >> atmosphere_names_for_ice.dat - echo ""; echo " * temperature" - echo "atmosphere_name_temperature=temp2" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_temperature=K" >> atmosphere_names_for_ice.dat - echo ""; echo " * precipitation" - echo "atmosphere_name_precipitation=aprt" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_precipitation=kg/m2/s" >> atmosphere_names_for_ice.dat - echo ""; echo " * elevation" - echo "atmosphere_name_elevation=orog" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_elevation=m" >> atmosphere_names_for_ice.dat - echo ""; echo " * shortwave downward radiation" - echo "atmosphere_name_shortwave=swd" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_shortwave=W/m2" >> atmosphere_names_for_ice.dat - echo ""; echo " * emissivity" - echo "atmosphere_name_emissivity=emiss" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_emissivity=frac" >> atmosphere_names_for_ice.dat - echo ""; echo " * wind speed" - echo "atmosphere_name_wind=uv" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_wind=m/s" >> atmosphere_names_for_ice.dat - #echo ""; echo " * longwave downward radiation" - #echo "atmosphere_name_longwave=lwd" >> atmosphere_names_for_ice.dat - #echo "atmosphere_units_longwave=W/m2" >> atmosphere_names_for_ice.dat - echo ""; echo " * cloud cover" - echo "atmosphere_name_cloud_cover=cc" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_cloud_cover=frac" >> atmosphere_names_for_ice.dat - echo ""; echo " * spec. humidity@2m" - echo "atmosphere_name_humidity=q2m" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_humidity=frac" >> atmosphere_names_for_ice.dat - echo ""; echo " * atm. transmissivity" - echo "atmosphere_name_transmissivity=tau" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_transmissivity=frac" >> atmosphere_names_for_ice.dat - echo ""; echo " * TOA shortwave downward radiation" - echo "atmosphere_name_TOAshortwave=TOAswd" >> atmosphere_names_for_ice.dat - echo "atmosphere_units_TOAshortwave=W/m2" >> atmosphere_names_for_ice.dat - #add_to $(pwd)/atmosphere_names_for_ice.dat atmosphere_names_for_ice.dat couple - cp $(pwd)/atmosphere_names_for_ice.dat ${COUPLE_DIR}/atmosphere_names_for_ice.dat - - echo; echo " ...done."; echo -} - -## @fn echam_ice_construct_input_list() -## @brief constructs the list of input files -## -## By using a parsed version of `CHUNK_END_DATE_echam` and `number_of_years_for_forcing`, -## this constructs a list of files which match: -## `${DATA_DIR_echam}/${EXP_ID}_echam6_echam_${year}${month}.grb` -## -## @warning Construction of the input list is **directly** dependent on the formatting of `ECHAM6` -## output filenames. **A change in the convention of output filenames will break this function.** -echam_ice_construct_input_list() { - echo ""; echo " * constructing input list" - - CHUNK_END_YEAR_echam=$(date -d "${CHUNK_END_DATE_echam:?Missing_var}" +%Y) - CHUNK_END_MONTH_echam=$(date -d "${CHUNK_END_DATE_echam:?Missing_var}" +%m) - CHUNK_END_DAY_echam=$(date -d "${CHUNK_END_DATE_echam:?Missing_var}" +%d) - - test_if_set CHUNK_END_YEAR_echam - number_of_years_for_forcing=${number_of_years_for_forcing:-1} - start_year_couple=$(( CHUNK_END_YEAR_echam - number_of_years_for_forcing + 1 )) - end_year_couple=${CHUNK_END_YEAR_echam} - echam6_file_list_for_ice="" - for year in $(seq $start_year_couple $end_year_couple ); do - for month in $(seq -f "%02g" 1 12); do - if [ -f "${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_ism" ]; then - current_file="${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_ism" - elif [ -f "${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_echam" ]; then - current_file="${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_echam" - else - echo ""; echo " FILE ${DATA_DIR_echam}/${EXP_ID}_${year}${month}.01_echam not found! " - exit 42 - fi - echam6_file_list_for_ice="$echam6_file_list_for_ice $current_file" - done - done - -} - -## @fn echam_ice_select_relevant_variables() -## @brief Cuts out orography, precipitation, and 2-m air temperature from `ECHAM6` output. -## -## Selects variables `geosp`, `aprl`, `aprc`, `temp2` 'sradsu', 'srads', -# 'trads'. 'tradsu' and 'aclcov' from files in `echam6_file_list_for_ice` -## In the output, `aprt` = `aprl` + `aprc`, and `orog`=`geosp`/9.81, -# 'swd'= 'srads'-'sradsu' and 'lwd'= 'trads'-'tradsu' -## -## @todo This function needs to be more flexible and also select variables needed for different -## mass balance schemes, e.g. an EBM. -echam_ice_select_relevant_variables() { - echo ""; echo " * selecting relevant variables" - - processed_echam6_file_list_for_ice="" - - if [[ "x${oro_update_var}" == "xgeosp" ]]; then - for file in ${echam6_file_list_for_ice}; do - filename=$(basename $file) - ${cdo} -s -f nc \ - -expr,"orog=geosp/9.81; aprt=aprl+aprc; temp2=temp2; tsurf=tsurf; swd=srads-sradsu; cc=aclcov; \ - emiss=(trads-tradsu)/(5.6703744e-8*temp2^4); \ - tau=((srad0d<5)? 0.5 : ((srads-sradsu)/srad0d)); TOAswd=srad0d; q2m=q2m; - uv=(u10^2+v10^2)^(1/2)" \ - -setcodetab,${file}.codes \ - -selcode,169,167,143,142,144,129,176,204,177,205,164,184,54,165,166 \ - $file \ - "${filename%.*}"_for_ice.nc 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - #-expr,"temp2=temp2; orog=geosp/9.81; aprt=aprl+aprc; swd=srads-sradsu; lwd=trads-tradsu; cc=aclcov" \ - #-setcodetab,echam \ - #-selcode,169,143,142,129,176,204,177,205,164 \ - - processed_echam6_file_list_for_ice="$processed_echam6_file_list_for_ice ${filename%.*}_for_ice.nc" - done - else - for file in ${echam6_file_list_for_ice}; do - filename=$(basename $file) - ${cdo} -s -f nc \ - -expr,"aprt=aprl+aprc; temp2=temp2; tsurf=tsurf; swd=srads-sradsu; cc=aclcov; \ - emiss=(trads-tradsu)/(5.6703744e-8*temp2^4); \ - tau=((srad0d<5)? 0.5 : ((srads-sradsu)/srad0d)); TOAswd=srad0d; q2m=q2m; - uv=(u10^2+v10^2)^(1/2)" \ - -setcodetab,${file}.codes \ - -selcode,169,167,143,142,144,129,176,204,177,205,164,184,54,165,166 \ - $file \ - "${filename%.*}"_for_ice.nc 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - #-expr,"temp2=temp2; orog=geosp/9.81; aprt=aprl+aprc; swd=srads-sradsu; lwd=trads-tradsu; cc=aclcov" \ - #-setcodetab,echam \ - #-selcode,169,143,142,129,176,204,177,205,164 \ - processed_echam6_file_list_for_ice="$processed_echam6_file_list_for_ice ${filename%.*}_for_ice.nc" - done - fi - unset echam6_file_list_for_ice -} - -## @fn echam_ice_concatenate_files() -## @brief Combines files from `processed_echam6_file_list_for_ice` -## -## Combines all files in the `processed_echam6_file_list_for_ice` to a file `atmosphere_file_for_ice.nc`, -## and removes the individual files. -echam_ice_concatenate_files() { - echo ""; echo " * concatenating files" - - test -f atmosphere_file_for_ice.nc && rm atmosphere_file_for_ice.nc - ${cdo} -s cat ${processed_echam6_file_list_for_ice} atmosphere_file_for_ice.nc 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - if [[ ! "x${oro_update_var}" == "xgeosp" ]]; then - - latest_restart_file="${RESTART_DIR_echam}/restart_${EXP_ID}_echam_${END_YEAR_echam}${END_MONTH_echam}${END_DAY_echam}.nc" - echo " * latest_restart_file=${latest_restart_file}" - - cdo -s chname,oromea,orog -selname,oromea ${latest_restart_file} orog_tmp - ncks -A -v orog orog_tmp atmosphere_file_for_ice.nc 2>> ${COUPLE_DIR}/nco_stderr_echam2ice - rm orog_tmp - fi - - #rm ${processed_echam6_file_list_for_ice} - unset processed_echam6_file_list_for_ice -} - -## @fn echam_ice_generate_multiyear_mean() -## @brief Makes a multiyear mean of `atmosphere_file_for_ice.nc` -## -## If the switch #ECHAM_TO_ISM_multiyear_mean is set to `1`, a multi-year monthly mean of `atmosphere_file_for_ice.nc` is made. -echam_ice_generate_multiyear_mean() { - echo ""; echo " * making multi-year monthly mean" - - ################################## - CHUNK_END_YEAR_echam=$(date -d "${CHUNK_END_DATE_echam:?Missing_var}" +%Y) - CHUNK_START_YEAR_echam=$(date -d "${CHUNK_START_DATE_echam:?Missing_var}" +%Y) - - start_year_couple=$(( CHUNK_START_YEAR_echam + 1 )) - echo "* select years from ${start_year_couple} to ${CHUNK_END_YEAR_echam} " - ################################## - - ################################### - ## LA: choose minimum temperature - #echo ""; echo " * selcting year with minimum summer temp2 over NA" - #${cdo} -s -yearmean -selmon,4,5,6 -selname,temp2 atmosphere_file_for_ice.nc tmp - #${cdo} -s -sellonlatbox,-100,-55,40,60 tmp tmp2 - #${cdo} -s -fldmean tmp2 tmp3 - #${cdo} -s -eq -timmin tmp3 tmp3 tmp4 - #${cdo} -s -remapnn,${COUPLE_DIR}/atmosphere.griddes tmp4 tmp5 - #${cdo} -s -splityear tmp5 year - #${cdo} -s -splityear atmosphere_file_for_ice.nc atm.year - - ##for YEAR in $(CHUNK_START_YEAR_echam..CHUNK_END_YEAR_echam) - #for YEAR in $(seq ${CHUNK_START_YEAR_echam} 1 ${CHUNK_END_YEAR_echam}) - #do - # echo ""; echo " * processing year ${YEAR}" - # ${cdo} -s -ifthen year${YEAR}.nc atm.year${YEAR}.nc tmp.year${YEAR}.nc - #done - #${cdo} -s -ymonsum -cat "tmp.year*.nc" tmp.final - #mv tmp.final atmosphere_file_for_ice.nc - ##rm tmp tmp2 tmp3 tmp4 tmp5 atm.year* year* tmp.year* - ################################### - - ${cdo} -s -ymonmean -selyear,${start_year_couple}/${CHUNK_END_YEAR_echam} atmosphere_file_for_ice.nc tmp 2>> ${COUPLE_DIR}/cdo_stderr_echam2ice - mv -f tmp atmosphere_file_for_ice.nc -} - -# emacs: -*- mode: shell; -# vim: expandtab copyindent preserveindent softtabstop=0 shiftwidth=4 tabstop=4 -# -- last line diff --git a/couplings/echam/coupling_ice2echam.functions b/couplings/echam/coupling_ice2echam.functions deleted file mode 100644 index b2451607d..000000000 --- a/couplings/echam/coupling_ice2echam.functions +++ /dev/null @@ -1,1425 +0,0 @@ -#!/usr/bin/ksh - -## @fn ice2echam() -ice2echam() { - echo " ==================================================================" - echo " *** S T A R T I N G ice2echam *** "; echo - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - ISM_TO_ECHAM_update_orography=${ISM_TO_ECHAM_update_orography:-1} - ISM_TO_ECHAM_update_glacial_mask=${ISM_TO_ECHAM_update_glacial_mask:-1} - ISM_TO_ECHAM_update_land_runoff=${ISM_TO_ECHAM_update_land_runoff:-1} - HOSING_CORRECTION=${HOSING_CORRECTION:-0} - - :> nco_stderr_ice2echam; :> cdo_stderr_ice2echam - - counter=0 - COUNT_MAX=60 - while [ ${counter} -lt ${COUNT_MAX} ] - do - echo " * inside while loop " - if [ -f ${COUPLE_DIR}/ice_file_for_atmosphere.nc ]; then - break - fi - - echo; echo " * File ${COUPLE_DIR}/ice_file_for_atmosphere.nc not found. Waiting for 10 seconds ..." - sleep 10 - counter=$((counter+1)) - done - - read_names ice atmosphere - define_echam_names - if [ "$ISM_TO_ECHAM_update_glacial_mask" -eq 1 ]; then - iterative_coupling_ice_echam6_update_glacial_mask - fi - if [ "$ISM_TO_ECHAM_update_orography" -eq 1 ]; then - iterative_coupling_ice_echam6_update_orography - fi - if [ "$ISM_TO_ECHAM_update_land_runoff" -eq 1 ]; then - iterative_coupling_ice_echam6_update_land_runoff - fi - - echo " *** F I N I S H E D ice2echam *** " - echo " ==================================================================" -} - -## @fn define_echam_names() -define_echam_names() { - echam_glacial_mask_name=glac -} - -## @fn iterative_coupling_ice_echam6_update_orography() -iterative_coupling_ice_echam6_update_orography() { - echo " Updating orography and gravity wave drag parameterization in echam6" - update_orography_select_field - if [ "$MACHINE" == "levante" ]; then - hi_res_init_oro="/pool/data/ECHAM5/T511/T511_jan_surf.nc" - fi - if [ -f ${hi_res_init_oro} ] - then - regrid_to_echam ${COUPLE_DIR}/ice_orog_difference.nc remapbil T511 - regrid_to_echam ${COUPLE_DIR}/ice_orog_difference.nc remapbil - update_orography_apply_orography_anomaly_high_res - update_orography_prepare_calnoro_high_res - else - regrid_to_echam ${COUPLE_DIR}/ice_orog_difference.nc remapbil - update_orography_apply_orography_anomaly - update_orography_prepare_calnoro - fi - update_orography_run_calnoro - update_orography_generate_target_orography_file - #set_in_jsbach_restart_file elevation ${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc OROMEA unpack - update_orography_set_namelist_modifications_next_echam_run - echo; echo " ...done."; echo -} - -## @fn iterative_coupling_ice_echam6_update_glacial_mask() -iterative_coupling_ice_echam6_update_glacial_mask() { - echo " Updating Glacial Mask in echam6" - set_glacial_mask_select_field - set_glacial_mask_echam_restart_file $ifile - if [ -d ${COUPLE_DIR}/jsbach_init_file_modifications ]; then - rm -rf ${COUPLE_DIR}/jsbach_init_file_modifications - fi - mkdir ${COUPLE_DIR}/jsbach_init_file_modifications - here=$(pwd) - cd ${COUPLE_DIR}/jsbach_init_file_modifications - set_glacial_mask_echam_make_dummy_jan_surf - set_glacial_mask_jsbach_update_init_file - cd $here - rm -rf ${COUPLE_DIR}/jsbach_init_file_modifications - set_glacial_mask_jsbach_update_restart_jsbach - set_glacial_mask_jsbach_update_restart_veg - echo; echo " ...done."; echo -} - -## @fn iterative_coupling_ice_echam6_update_land_runoff() -iterative_coupling_ice_echam6_update_land_runoff() { - echo " Setting Glacial Runoff for incorporation in HD-Model via oasis3-mct" - update_land_runoff_select_glacial_discharge - regrid_to_echam ${COUPLE_DIR}/ice_discharge.nc - update_land_runoff_fill_missing - if [ "x${HOSING_CORRECTION}" == "x1" ]; then - echo; echo " * Correcting freshwater input by hosing " - distribute_total_discharge_over_ocean - else - echo; echo " * NOT correcting freshwater input by hosing " - fi - update_land_runoff_prepare_for_oasis - update_land_runoff_set_namcouple_override - update_land_runoff_set_namelist_modifications_next_echam_run - update_land_runoff_set_namelist_modifications_next_jsbach_run - echo; echo " ...done."; echo -} - -## @fn update_orography_select_field() -update_orography_select_field() { - echo; echo " * selecting orography difference over ice run" - cdo -s selvar,${ice_orography_difference_name} \ - ${COUPLE_DIR}/ice_file_for_atmosphere.nc \ - ${COUPLE_DIR}/ice_orog_difference.nc - rmlist="$rmlist ${COUPLE_DIR}/ice_orog_difference.nc" -} - -update_orography_from_martins_script() { -cdo -L -remapbil,${RES_echam}grid / - ${COUPLE_DIR}/ice_orog_difference_T511grid.nc / - ${COUPLE_DIR}/ice_orog_difference_${RES_echam}grid.nc -#cdo -L -setmisstoc,0. -ifthen slf.nc ${COUPLE_DIR}/ice_orog_difference_${RES_echam}grid.nc dummy.nc -#mv dummy.nc ${COUPLE_DIR}/ice_orog_difference_${RES_echam}grid.nc -ECHAM_g=9.80665 -if [ -L ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc ]; then - rfile=$(readlink ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc) -else - rfile=${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc -fi -cdo -L -sp2gp -gp2sp -add -selvar,GEOSP ${rfile} -mulc,${ECHAM_g} / - ${COUPLE_DIR}/ice_orog_difference_${RES_echam}grid.nc / - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc -mv geosp.nc ${output_dir}/input/echam6/GEOSP_${paleo_time}_${RES_echam}.nc -} - -update_oromea_from_martins_script() { -ofile=${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc - -cdo -L -remapnn,r720x360 -setgrid,T511grid -selvar,OROMEA ${hi_res_init_oro} oromea_pi_r720x360.nc -cdo -L -remapnn,r720x360 ${COUPLE_DIR}/ice_orog_difference_T511grid.nc anom_topo_r720x360.nc -#cdo -L -setmisstoc,0. -ifthen -remapnn,r720x360grid slf.nc anom_topo_r720x360.nc dummy.nc -#mv dummy.nc anom_topo_r720x360.nc -cdo -L -add oromea_pi_r720x360.nc anom_topo_r720x360.nc oromea_r720x360.nc -cdo -L -mul oromea_r720x360.nc -gtc,0. oromea_r720x360.nc dummy.nc; mv dummy.nc oromea_r720x360.nc -CALNORO_RES=${echam_res:1:3} # use defined ECHAM6 grid resolution for calnoro -cp oromea_r720x360.nc topodata.nc -echo ${CALNORO_RES} | ${calnoro_dir}/calnoro -cdo -L -s -f nc -setgrid,${echam_res}grid -invertlat sso_par_fil.srv calnoro_output.nc -cdo -L -chvar,var51,OROMEA,var52,OROSTD,var53,OROSIG,var54,OROGAM,var55,OROTHE,var56,OROPIC,var57,OROVAL calnoro_output.nc ${ofile} -cdo -L -mul -selvar,OROMEA ${ofile} -gtc,0. -selvar,OROMEA ${ofile} oromea.tmp -# save geosp and oro-xxx in different files. why oromea from original file @PG? -cdo -L -replace ${ofile} oromea.tmp dummy.nc; mv dummy.nc ${ofile} -rm oromea.tmp -rm oromea_pi_r720x360.nc anom_topo_r720x360.nc oromea_r720x360.nc topodata.nc sso_par_fil.srv calnoro_output.nc -} - - -## @fn update_orography_apply_orography_anomaly_high_res() -update_orography_apply_orography_anomaly_high_res() { - echo; echo " * applying surface height changes to high-resolution echam topography" - ifile=${COUPLE_DIR}/ice_orog_difference_T511grid.nc - ofile=${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc - ncrename -v ${ice_orography_difference_name},oromea $ifile - cdo -s -setmisstoc,0 $ifile tmp; mv tmp $ifile - if [[ -f ${ofile} ]] - then - rfile=${ofile} - ncks -O -v oromea $rfile tmp_oromea - else - rfile=${hi_res_init_oro} - ncks -O -v OROMEA $rfile tmp_oromea - ncrename -v OROMEA,oromea tmp_oromea - fi - change_lonlat $ifile oromea - # LA: need to backup echam6_new_orography_before_calnoro!!! - ncbo -O --operation=add $ifile tmp_oromea $ofile 2>> nco_stderr_ice2echam - - update_orography_apply_orography_anomaly -} - -## @fn update_orography_apply_orography_anomaly() -update_orography_apply_orography_anomaly() { - echo; echo " * applying surface height changes to low-resolution echam topography" - ifile=${COUPLE_DIR}/ice_orog_difference_${RES_echam}grid.nc - ofile=${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc - ncrename -v ${ice_orography_difference_name},oromea $ifile - cdo -s -setmisstoc,0 $ifile tmp; mv tmp $ifile - if [ -L ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc ]; then - rfile=$(readlink ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc) - else - rfile=${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc - fi - ncks -O -v oromea $rfile tmp_oromea - change_lonlat $ifile oromea - ncbo -O --operation=add $ifile tmp_oromea $ofile 2>> nco_stderr_ice2echam -} - -## @fn update_orography_prepare_calnoro_high_res() -update_orography_prepare_calnoro_high_res() { - echo; echo " * preparing for external program CALNORO" - ifile=${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc - ofile=topodata.nc - cdo -s -P 28 \ - -remapnn,r720x360 \ - -setgrid,T511grid \ - -chname,oromea,OROMEA \ - $ifile \ - $ofile 2>>cdo_stderr_ice2echam -} - -## @fn update_orography_prepare_calnoro() -update_orography_prepare_calnoro() { - echo; echo " * preparing for external program CALNORO" - ifile=${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc - ofile=topodata.nc - cdo -s -P 28 \ - -remapnn,r720x360 \ - -setgrid,${RES_echam}grid \ - -chname,oromea,OROMEA \ - $ifile \ - $ofile 2>>cdo_stderr_ice2echam -} - -## @fn update_orography_run_calnoro() -update_orography_run_calnoro() { - echo; echo " * running CALNORO" - ofile=${COUPLE_DIR}/calnoro_output.nc - if [ ! -f calnoro ]; then - if [ ! -f ${FUNCTION_PATH}/../utils/calnoro ]; then - if [ -f ${FUNCTION_PATH}/../utils/install_calnoro.sh ]; then - echo " install_calnoro.sh found. Running installation ..." - currentdir=$(pwd) - cd ${FUNCTION_PATH}/../utils/ - ./install_calnoro.sh ${MACHINE} - cd ${currentdir} - cp ${FUNCTION_PATH}/../utils/calnoro . - else - echo " !!! FATAL ERROR: Compiled external utility CALNORO not found" - echo " !!! Looking in: ${FUNCTION_PATH}/../utils/" - echo " !!! FATAL ERROR: Please compile this program using the install_calnoro.sh script!" - exit 42 - fi - else - cp ${FUNCTION_PATH}/../utils/calnoro . - fi - fi - # Make sure dimension order is correct: - change_lonlat topodata.nc OROMEA - - module list - if [ "$MACHINE" == "levante" ]; then - export LD_LIBRARY_PATH=/sw/spack-levante/netcdf-fortran-4.5.3-jlxcfz/lib/:$LD_LIBRARY_PATH - elif [ "$MACHINE" == "albedo" ]; then - export LD_LIBRARY_PATH=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/lib/:$LD_LIBRARY_PATH - tmp_mods=$( module list -t | tail -n +2 ) - module purge - fi - - echo ${RES_echam/T/} | ./calnoro > ${COUPLE_DIR}/calnoro_stdout_stderr 2>&1 - - if [ "$MACHINE" == "albedo" ]; then - module load $tmp_mods - fi - - cdo -s -f nc -setgrid,$RES_echam -invertlat sso_par_fil.srv $ofile 2>>cdo_stderr_ice2echam - #rm sso_par_fil.srv topodata.nc -} - -## @fn update_orography_generate_target_orography_file() -update_orography_generate_target_orography_file() { - echo; echo " * generating target orography file for linear stepwise change of echam6 orography" - ifile=${COUPLE_DIR}/calnoro_output.nc - ofile=${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc - - typeset -A orography_names - orography_names[var51]=OROMEA - orography_names[var52]=OROSTD - orography_names[var53]=OROSIG - orography_names[var54]=OROGAM - orography_names[var55]=OROTHE - orography_names[var56]=OROPIC - orography_names[var57]=OROVAL - - for varname in "${!orography_names[@]}"; do - ncrename -v ${varname},${orography_names[$varname]} ${ifile} tmp; mv tmp ${ifile} - done - - ## Ensure that we use the OROMEA from the "raw" PISM-corrected orography, - ## not what is given from the calnoro program - - - ############################################################ - # Define the method for orography update (oro_update_mod): - # 1: use low-resolution reference; take all sub-grid scale parameters from CALNORO; take GEOSP from low-res input - # 2: use low-resolution reference; take all sub-grid scale parameters from CALNORO; take OROMEA and GEOSP from low-res input - # (like it has been done before) - # 3: use high-resolution reference; take all sub-grid scale parameterds from CALNORO; take OROMEA and GEOSP from high-res input - # 4: update orography but keep sub-grid scale parameters from unit.24 - # 5: update orography but change sub-grid scale parameters only in ice domain where ice mask or change of ice mask (ice loss/ice gain) - - if [ "x${oro_update_mod}" == "x1" ]; then # according to Martins script: OROMEA from calnoro; GEOSP from input - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - elif [ "x${oro_update_mod}" == "x2" ]; then # old coupling scheme: OROMEA and GEOSP from low-res input - cdo -s -replace \ - ${ifile} \ - -chname,oromea,OROMEA -remapnn,${RES_echam}grid ${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc \ - tmp 2>>cdo_stderr_ice2echam - mv tmp ${ifile} - - # Take the GEOSP field from the "raw" PISM-corrected orography, and not - # what is given from the calnoro program - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_low_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - elif [ "x${oro_update_mod}" == "x3" ]; then # new coupling scheme: OROMEA and GEOSP from high-res input - cdo -s -replace \ - ${ifile} \ - -chname,oromea,OROMEA -remapnn,${RES_echam}grid ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - tmp 2>>cdo_stderr_ice2echam - mv tmp ${ifile} - - # Take the GEOSP field from the "raw" PISM-corrected orography, and not - # what is given from the calnoro program - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - # - elif [ "x${oro_update_mod}" == "x4" ]; then # new coupling scheme: OROMEA and GEOSP from high-res input but overwrite with unit.24 sub-grid parameters - cdo -s -replace \ - ${ifile} \ - -chname,oromea,OROMEA -remapnn,${RES_echam}grid ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - tmp 2>>cdo_stderr_ice2echam - mv tmp ${ifile} - - # Take the GEOSP field from the "raw" PISM-corrected orography, and not - # what is given from the calnoro program - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - - cdo -s replace ${ofile} ${INIT_DIR_echam}/unit.24 tmp_replace; mv tmp_replace ${ofile} - # - - elif [ "x${oro_update_mod}" == "x5" ]; then # masked: new coupling scheme: OROMEA and GEOSP from high-res input - cdo -s -replace \ - ${ifile} \ - -chname,oromea,OROMEA -remapnn,${RES_echam}grid ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - tmp 2>>cdo_stderr_ice2echam - mv tmp ${ifile} - - # Take the GEOSP field from the "raw" PISM-corrected orography, and not - # what is given from the calnoro program - - ECHAM_g=9.80665 - cdo -s -sp2gp -gp2sp -mulc,${ECHAM_g} -chname,oromea,GEOSP \ - -remapnn,${RES_echam}grid \ - ${COUPLE_DIR}/echam6_new_orography_before_calnoro_high_res.nc \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc 2>>cdo_stderr_ice2echam - - # Make sure dimension order is correct: - change_lonlat ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc GEOSP - - cdo -s -O merge \ - ${ifile} \ - ${COUPLE_DIR}/echam6_new_GEOSP_for_target_orog.nc \ - ${ofile} 2>>cdo_stderr_ice2echam - - if [ -L ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc ]; then - rfile=$(readlink ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc) - else - rfile=${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc - fi - - cdo -s -ifthen ${COUPLE_DIR}/ice_domain_current_T63grid.nc -gtc,0 \ - -add ${COUPLE_DIR}/ice_mask_current_T63grid.nc -selname,GLAC ${INIT_DIR_echam}/unit.24 \ #${COUPLE_DIR}/ice_mask_before_T63grid.nc \ - ${COUPLE_DIR}/mask_oro_update.nc -# cdo -s selname,glac ${rfile} ${COUPLE_DIR}/ice_mask_before_T63grid.nc - for VAR in "OROMEA" "OROSTD" "OROSIG" "OROGAM" "OROTHE" "OROPIC" "OROVAL" - do - cdo -s ifthenelse -setmisstoc,0 ${COUPLE_DIR}/mask_oro_update.nc \ - -selname,${VAR} ${ofile} \ - -selname,${VAR} ${INIT_DIR_echam}/unit.24 ${VAR}.orotmp - - done - cdo -s merge *.orotmp ORO_merged #; mv ORO_merged ${ofile}; rm *.orotmp - cdo -s replace ${ofile} ORO_merged tmp; mv tmp ${ofile} - # - fi - ############################################################ - ln -sf ${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${COUPLE_DIR}/latest_target_orography.nc - # Destroy# the time dimension; just in case - #if ncdump -h# $ofile | grep -q "time"; then - # ncwa -a time $ofile tmp; mv tmp $ofile - #fi - echo; echo -e "\t\t- finished with target orography generation" -} - -## @fn update_orography_set_namelist_modifications_next_echam_run() -update_orography_set_namelist_modifications_next_echam_run() { - echam_variable_modify_file=${COUPLE_DIR}/echam_namelist_switches_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - echo; echo " * setting echam variables for update ororgapy to be read from file in next run" - echo " - echam_variable_modify_file=$echam_variable_modify_file" - if [ ! -s $echam_variable_modify_file ]; then - :> $echam_variable_modify_file - fi - echo "submodelctl___lupdate_orog___nml_entry=.TRUE." >> $echam_variable_modify_file - echo "submodelctl___lupdate_orog___nml_file=namelist.echam" >> $echam_variable_modify_file - add_to ${echam_variable_modify_file} echam_namelist_switches.dat config echam -} - -## @fn set_glacial_mask_select_field() -set_glacial_mask_select_field() { - echo; echo " * selecting glacial mask" - cdo \ - -selvar,${ice_glacial_mask_name} \ - ${COUPLE_DIR}/ice_file_for_atmosphere.nc \ - ${COUPLE_DIR}/ice_mask_current.nc 2>> cdo_stderr_ice2echam - mv ${COUPLE_DIR}/ice_mask_current.nc tmp - ncdump tmp | sed 's/byte/float/g' | ncgen -o tmp.nc; mv tmp.nc tmp - mv tmp ${COUPLE_DIR}/ice_mask_current.nc - rmlist="$rmlist ${COUPLE_DIR}/ice_mask_current.nc" - -} - -## @fn set_glacial_mask_echam_restart_file() -set_glacial_mask_echam_restart_file() { - if [ -L ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc ]; then - ECHAM_RESTART_FILE=$(readlink ${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc) - else - ECHAM_RESTART_FILE=${RESTART_DIR_echam}/restart_${EXP_ID}_echam.nc - fi - ifile=${COUPLE_DIR}/ice_mask_current.nc - dfile=${COUPLE_DIR}/ice_domain_current.nc - cdo -s setrtoc,0,1,1 $ifile $dfile - - echo; echo " * Setting ice mask in: $ECHAM_RESTART_FILE" - echo " from: $ifile" - echo " using region: $dfile" - - # Define the entire area where pism is defined: - ncrename -v ${ice_glacial_mask_name},ice_mask $ifile - ncrename -v ${ice_glacial_mask_name},ice_domain $dfile - - regrid_to_echam $ifile - regrid_to_echam $dfile - - ifile=${ifile%.*}_${RES_echam}grid.nc - dfile=${dfile%.*}_${RES_echam}grid.nc - - cdo -s -setmisstoc,0 $ifile tmp 2>> cdo_stderr_ice2echam; mv tmp $ifile - cdo -s -gec,${ECHAM_GLACIAL_THRESHOLD} $ifile tmp 2>> cdo_stderr_ice2echam; mv tmp $ifile # PG: Ensure the mask is binary after regridding. - - change_lonlat $ifile ice_mask - change_lonlat $dfile ice_domain - - # Restrict the ice mask on the echam grid to only be valid where echam land - cdo -s -setmisstoc,0 -ifthen -selvar,slm $ECHAM_RESTART_FILE $ifile tmp 2>> cdo_stderr_ice2echam; mv tmp $ifile - - cp $ECHAM_RESTART_FILE ${ECHAM_RESTART_FILE%.*}_backup_before_glacial_mask_replacement.nc - cp $ECHAM_RESTART_FILE echam_with_ice_mask.nc - - echo " - Preforming replacement" - - cdo -s -selvar,glac ${ECHAM_RESTART_FILE} just_glac.nc 2>> cdo_stderr_ice2echam - cdo -s -ifthenelse -setmisstoc,0 $dfile -chname,ice_mask,glac $ifile just_glac.nc just_glac_new.nc 2>> cdo_stderr_ice2echam - - ncdump just_glac_new.nc | sed s/int/double/g | ncgen -o tmp; mv tmp just_glac_new.nc - # This multipliation transforms "float" into "double" - ncap=${ncap:-ncap2} - $ncap -s "glac=glac*1.0000000000000;" \ - just_glac_new.nc \ - just_glac_new.tmp.nc - ncks -A just_glac_new.tmp.nc echam_with_ice_mask.nc - - #mv echam_with_ice_mask.nc ${ECHAM_RESTART_FILE} - ncatted -O -a history_of_appended_files,global,d,, echam_with_ice_mask.nc tmp.restart - ncatted -O -a history,global,d,, tmp.restart ${ECHAM_RESTART_FILE} - ncrename -v ice_mask,glac $ifile - rm just_glac_new.nc - rm just_glac_new.tmp.nc -} - -## @fn set_glacial_mask_echam_make_dummy_jan_surf() -set_glacial_mask_echam_make_dummy_jan_surf() { - echo; echo " * Generating a dummy unit.24 file with new ice orography and mask" - # Generates a dummy unit.24 file by modifying a copy of the - # The echam restart file has already been modified with the "correct" - # glacial mask", construct a dummy one from the restart - #CLEANUP cp ${BASE_DIR}/${EXP_ID}/awicm/input/echam/unit.24 dummy_jan_surf.nc - cp ${INIT_DIR_echam}/unit.24 dummy_jan_surf.nc - # Fix Lu: --------------------------- - if [[ ${DOMAIN_pism} == "nhem" ]]; then - cdo setclonlatbox,0,0,360,0,90 -selvar,GLAC dummy_jan_surf.nc tmp - cdo -replace dummy_jan_surf.nc tmp dummy_jan_surf.nc2 - mv dummy_jan_surf.nc2 dummy_jan_surf.nc - rm tmp - fi - # Fix Lu: --------------------------- - cdo -s replace dummy_jan_surf.nc \ - ${COUPLE_DIR}/target_orography_echam6_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - tmp && mv tmp dummy_jan_surf.nc - # Fix Albedo where there are glaciers: - #echam_albedo_on_glaciers=0.7 - echam_albedo_on_glaciers=${ECHAM_ALBEDO_ON_GLACIERS} - cdo -s \ - -setmisstoc,${echam_albedo_on_glaciers} -setrtomiss,-1,2 \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc - cdo -s \ - -selvar,ALB dummy_jan_surf.nc input_if_mask_false.nc - cdo -s -ifthenelse \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc \ - input_if_mask_false.nc \ - dummy_jan_surf_ALB.nc - cdo -s replace \ - dummy_jan_surf.nc \ - -chname,${echam_glacial_mask_name},ALB dummy_jan_surf_ALB.nc \ - tmp; mv tmp dummy_jan_surf.nc - - # Fix lakes where there are glaciers - cdo -s \ - -setrtoc,0,1,0 -selvar,ALAKE dummy_jan_surf.nc input_if_mask_true.nc - cdo -s \ - -selvar,ALAKE dummy_jan_surf.nc input_if_mask_false.nc - cdo -s -ifthenelse \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc \ - input_if_mask_false.nc \ - dummy_jan_surf_ALAKE.nc - cdo -s replace \ - dummy_jan_surf.nc \ - dummy_jan_surf_ALAKE.nc tmp #-chname,${echam_glacial_mask_name},ALAKE dummy_jan_surf_ALAKE.nc \ - mv tmp dummy_jan_surf.nc - - cdo -s \ - -setmisstoc,1 -setrtomiss,-1,2 \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc - cdo -s \ - -selvar,GLAC dummy_jan_surf.nc input_if_mask_false.nc - - cdo -s -ifthenelse \ - ${COUPLE_DIR}/ice_mask_current_${RES_echam}grid.nc \ - input_if_mask_true.nc \ - input_if_mask_false.nc \ - dummy_jan_surf_GLAC.nc - - cdo -s replace \ - dummy_jan_surf.nc \ - -chname,${echam_glacial_mask_name},GLAC dummy_jan_surf_GLAC.nc \ - tmp; mv tmp dummy_jan_surf.nc -} - -## @fn set_glacial_mask_jsbach_update_init_file() -set_glacial_mask_jsbach_update_init_file() { - echo; echo " * Generating a new JSBACH init file with updated land cover types" - # Get the Program and required .mod files - if [ -f ${FUNCTION_PATH}/../utils/jsbach_init_file ]; then - cp ${FUNCTION_PATH}/../utils/jsbach_init_file . - elif [ -f ${FUNCTION_PATH}/../utils/install_jsbach_init_file.sh ]; then - echo " install_jsbach_init_file.sh found. Running installation ..." - currentdir=$(pwd) - cd ${FUNCTION_PATH}/../utils/ - ./install_jsbach_init_file.sh ${MACHINE} - cd ${currentdir} - cp -v ${FUNCTION_PATH}/../utils/jsbach_init_file . - else - echo -e "\t\t E R O R R --- binary missing, don't know how to proceed" - exit - fi - cp ${FUNCTION_PATH}/../utils/_build/mo_kinds.mod . - cp ${FUNCTION_PATH}/../utils/_build/mo_vegparams.mod . - cleanup_list="$cleanup_list jsbach_init_file mo_kinds.mod mo_vegparams.mod" - # Here we place a slimmed-down version of the Veronika Gayler script: - res_atm=${RES_echam} - res_oce=GENERIC - ntiles=11 # number of jsbach tiles - - dynveg=true # setup for dynamic vegetation - c3c4crop=true # differentiate between C3 and C4 crops - - lpasture=true # distinguish pastures from grasses - read_pasture=LUH2v2h # LUH: read pastures and crops from LUH states as in CMIP5 - # LUH2v2h: read pastures and crops from LUH2 states as in CMIP6 - # false: no separate input file for crops and pastures - pasture_rule=true # allocate pastures primarily on grass lands - - year_ct=1850 # year the cover_types are derived from - year_cf=1850 # year cover fractions are derived from - - landcover_series=false # generate a series of files with cover_types of - # year_ct and fractions from year_cf to year_cf2 - year_cf2=1859 # only used with landcover_series - - echam_fractional=false # initial file for echam runs with fractional - # land sea mask - masks_file=default # file with land sea mask (default: use echam land sea mask) - - mv dummy_jan_surf.nc ${RES_echam}${res_oce}_jan_surf.nc - echo " - Using unit.24 (jan surf) file: ${RES_echam}GENERIC_jan_surf.nc" - echo " --> (This is the dummy file after ice update)" - ln -sf ${INIT_DIR_echam}/unit.91 ${res_atm}${res_oce}_VGRATCLIM.nc - echo " - Using unit.91 (VGRATCLIM) file: ${INIT_DIR_echam}/unit.91" - ln -sf ${INIT_DIR_echam}/unit.90 ${res_atm}${res_oce}_VLTCLIM.nc - echo " - Using unit.90 (VLTCLIM) file: ${INIT_DIR_echam}/unit.90" - - cleanup_list="$cleanup_list ${RES_echam}_jan_surf.nc" - - pool=${POOL_DIR_echam}/ECHAM6/${RES_echam} - pool_land=${POOL_DIR_jsbach}/JSBACH/prepare/${RES_echam} - #------------------------------------------------------------------------------ - # prepare the namelist - #------------------------------------------------------------------------------ - - [[ ${res_oce} = "" ]] && lcouple=.false. || lcouple=.true. - [[ ${dynveg} = true ]] && ldynveg=.true. || ldynveg=.false. - [[ ${c3c4crop} = true ]] && lc3c4crop=.true. || lc3c4crop=.false. - [[ ${read_pasture} != false ]] && lread_pasture=.true. || lread_pasture=.false. - [[ ${landcover_series} = false ]] && year_cf2=${year_cf} - - desert_only=.false. # setup for a desert-only experiment - grass_only=.false. # setup for a grass-only experiment - woods_only=.false. # setup for a woods-only experiment - - cat > namelist < ${COUPLE_DIR}/jsbach_init_file_stdout_stderr 2>&1 - if [[ $? -eq 0 ]]; then - echo -e "\t\t - ...finished with external program jsbach_init_file!" - else - echo "error in jsbach_init_file" - exit 1 - fi - # BUG: How do we know what the output file is called? - mv jsbach_T63GENERIC_11tiles_5layers_1850_dynveg.nc \ - ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc - echo :> ${COUPLE_DIR}/jsbach_init_override_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - - ############################################################################ - # LA UPDATE - ln -sf ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${COUPLE_DIR}/latest_jsbach_init_file.nc - #cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${WORK_DIR}/jsbach.nc - ############################################################################ - - echo "LAND_BOUNDARY_CONDITIONS_jsbach=${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc" > ${COUPLE_DIR}/jsbach_init_override_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - add_to ${COUPLE_DIR}/jsbach_init_override_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat jsbach_init_override.dat config jsbach -} - -set_glacial_mask_jsbach_update_restart_jsbach() { - echo; echo " * updating land cover fractions in jsbach restart file >>jsbach<<" - echo -e "\t\t- Making a temporary directory to work in" - startdir=$(pwd) - if [ -d ${COUPLE_DIR}/update_land_cover_fractions ]; then - # Throw away the temporary working directory from last time to - # avoid merge problems in the next coupling iteration: - rm -rf ${COUPLE_DIR}/update_land_cover_fractions - fi - mkdir -p ${COUPLE_DIR}/update_land_cover_fractions; cd ${COUPLE_DIR}/update_land_cover_fractions - echo -e "\t\t- determining where the glacial mask has advanced and retreated" - echo -e "\t\t- New JSBACH Init File: ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc" - echo -e "\t\t- Old JSBACH Init File: ${FORCING_DIR_jsbach}/jsbach.nc" - cdo -s -sub \ - -selvar,glac ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - -selvar,glac ${FORCING_DIR_jsbach}/jsbach.nc \ - ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc 2>> ${COUPLE_DIR}/update_land_cover_fractions/cdo_stderr_ice2echam - - # Make two masks: one for glacial retreat, and one for glacial advance - cdo -s gtc,0 ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc - cdo -s gtc,0 -mulc,-1 ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc - sum_new_glaciers=$(cdo -s -output -fldsum -gtc,0 ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc | tr -d "[:blank:]") - sum_new_land=$(cdo -s -output -fldsum -gtc,0 -mulc,-1 ${COUPLE_DIR}/update_land_cover_fractions/jsbach_glac_diff.nc | tr -d "[:blank:]") - echo -e "\t\t- Total number of new glacial cells: >>>$sum_new_glaciers<<<" - echo -e "\t\t- Total number of new deglacial cells: >>>$sum_new_land<<<" - - if [[ $sum_new_glaciers -eq 0 ]] && [[ $sum_new_land -eq 0 ]]; then - echo -e "\t\t- >>>INFO<<< No new land or new glaciers, this routine will be skipped..." - newest_jsbach_restart_file=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc) - ln -sf ${newest_jsbach_restart_file} ${COUPLE_DIR}/latest_jsbach_restart_file.nc - return - fi - - newest_jsbach_restart_file=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc) - # Make a backup copy - #cp $(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc) ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach_backup_$(date +%Y%m%d%H%M%S).nc - cp ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach_backup_$(date +%Y%m%d%H%M%S).nc - echo -e "\t\t- Unpacking JSBACH restart file: $newest_jsbach_restart_file" - # Ensure that the unpack binary is here: - if [ ! -f unpack ]; then - if [ -f ${FUNCTION_PATH}/../utils/unpack ]; then - #cp -v ${FUNCTION_PATH}/../utils/unpack ${COUPLE_DIR}/ - cp -v ${FUNCTION_PATH}/../utils/unpack . - elif [ -f ${FUNCTION_PATH}/../utils/install_jsbach_pack_unpack.sh ]; then - echo " install_jsbach_pack_unpack.sh found. Running installation ..." - currentdir=$(pwd) - cd ${FUNCTION_PATH}/../utils/ - ./install_jsbach_pack_unpack.sh ${MACHINE} - cd ${currentdir} - #cp -v ${FUNCTION_PATH}/../utils/unpack ${COUPLE_DIR}/ - cp -v ${FUNCTION_PATH}/../utils/unpack . - else - echo -e "\t\t E R O R R --- unpack binary missing, don't know how to proceed" - exit - fi - fi - - echo " *** unpack binary found here: $(pwd) " 2>&1 > ${COUPLE_DIR}/unpack_script_stdout_stderr - - # Copy the files here: - cp ${newest_jsbach_restart_file} ./ - cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ./ - echo -e "\t\t- Running unpack binary with arguments:" - echo -e "\t\t- Script: ${FUNCTION_PATH}/../utils/unpack_file.ksh" - echo -e "\t\t- Restart File: $(basename ${newest_jsbach_restart_file})" - echo -e "\t\t- Mask file: $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc)" - echo "$(module list)" - ${FUNCTION_PATH}/../utils/unpack_file.ksh \ - $(basename $newest_jsbach_restart_file) \ - $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc) \ - 2>&1 > ${COUPLE_DIR}/unpack_script_stdout_stderr - - echo -e "\t\t- Listing files after program execution:" - ls -ratl - restartfile=2d_$(basename ${newest_jsbach_restart_file}) - # 'cdo showvar' does not work for variables with more than three dimensiones - echo "ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '('" - variables=$(ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '(') - echo $variables - - # Rename the "tiles" dimension to "time", since cdo can only handle 4D - # variables if one is called time. This will be corrected again below - ncrename -O -d tiles,time 2d_$(basename ${newest_jsbach_restart_file}) - for var in ${variables}; do - ncks -O --no_abc \ - -v ${var} \ - 2d_$(basename ${newest_jsbach_restart_file}) \ - 2d_restart_${EXP_ID}_jsbach_${var}.nc - - if [ ! -f 2d_restart_${EXP_ID}_jsbach_${var}.nc ]; then - echo -e "\t\t !!! WARNING !!! -- no file for ${var}" - echo -e "\t\t continue loop" - continue - fi - - # Keep the directory clean: make one directory for each variable: - here=$(pwd); mkdir -p ${var}; mv 2d_restart_${EXP_ID}_jsbach_${var}.nc ${var}; cd ${var} - echo -e "\t\t- Updating JSBACH restart file -- ${var}\n" - case ${var} in - cover_fract | cover_fract_pot | veg_ratio) - echo -e "\t\t- Need to set correct cover fractions for retreating and advancing glaciers for $var" - # Split to all the land tiles - # - # NOTE: We use splitrec because we need to - # split fake "timesteps" and not "layers" since - # cdo can't handle 4D without time...remember - # that tiles was renamed to time above. - cdo -s splitrec 2d_restart_${EXP_ID}_jsbach_${var}.nc 2d_restart_${EXP_ID}_jsbach_${var}_tile - mergelist="" - for tile in $(ls 2d_restart_${EXP_ID}_jsbach_${var}_tile0000??.nc); do - case ${tile} in - 2d_restart_${EXP_ID}_jsbach_${var}_tile000001.nc ) - echo -e "\t\t Glacier landpoints for ${var} on ${tile}" - # New glaciers must have exactly 1 or keep the old value - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - ${tile} \ - ${tile}.tmp - # New land must get 1e-10 or keep the old value - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - -mulc,1e-10 ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - ${tile}.tmp \ - ${tile} - - ;; - 2d_restart_${EXP_ID}_jsbach_${var}_tile000007.nc ) - echo -e "\t\t Tundra for ${var} on ${tile}" - # New Glaciers need to be exactly 0 everywhere except on tile 1 - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - -mulc,0 ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - ${tile} \ - ${tile}.tmp - # New land gets the maximum allowed value - # NOTE: This is only valid for 11 tiles!! - # BUG(?): What about the negative values that appear here? - cdo -s -subc,1e-9 \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - ${tile}_maxveg.nc - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - ${tile}_maxveg.nc \ - ${tile}.tmp \ - ${tile} - ;; - *) - echo -e "\t\t Nothing special for ${var} on ${tile}" - # New glacial tiles get exactly 0 - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - -mulc,0 ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - ${tile} ${tile}.tmp - # New land cells get 1e-10: smallest allowed minium - cdo -s -ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - -mulc,1e-10 ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - ${tile}.tmp \ - ${tile} - ;; - esac - # Add the fake time axis after the case - # statement, since the ifthenelse - # clause might do strange things with - # the time axis otherwise: - tile_number=$(echo $tile | rev | cut -d_ -f1 | rev | sed s/tile// | sed s/\.nc//) - cdo -settaxis,${tile_number}-01-01,00:00:00 $tile ${tile}.time; mv ${tile}.time ${tile} - mergelist="$mergelist $tile" - done - cdo -s -O mergetime $mergelist ${var}.tmp - # Ensure the name is correct - cdo -s setvar,$var ${var}.tmp 2d_restart_${EXP_ID}_jsbach_${var}.nc - ;; - soil_moisture) - echo -e "\t\t- Need to change soil moisture for $var" - ;; - layer_moisture) - echo -e "\t\t- Need to change layer moisture for $var" - # NOTE: The layer moisture can't exceed the - # holding capacity, which changes under (new) - # glacier cells. Since the glacial mask was - # used to construct the jsbach.nc forcing file, - # we use those values for new glacial cells: - # - # NOTE 2: the layer moisture variable is called - # layer_moist in jsbach init file, not layer - # moisture. Therefore, the setvar command needs - # to rename it - cdo -s -setvar,${var} -ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_non_glaciers.nc \ - -selvar,layer_moist ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - 2d_restart_${EXP_ID}_jsbach_${var}.nc 2d_restart_${EXP_ID}_jsbach_${var}.tmp - cdo -s -setvar,${var} -ifthenelse \ - ${COUPLE_DIR}/update_land_cover_fractions/new_glaciers.nc \ - -selvar,layer_moist ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - 2d_restart_${EXP_ID}_jsbach_${var}.tmp 2d_restart_${EXP_ID}_jsbach_${var}.nc - ;; - esac - cd $here - done - mergelist="" - for var in ${variables}; do - ncrename -d .time,tiles ${var}/2d_restart_${EXP_ID}_jsbach_${var}.nc 2>&1 >> ${COUPLE_DIR}/nco_stderr_ice2echam - mergelist="$mergelist ${var}/2d_restart_${EXP_ID}_jsbach_${var}.nc" - done - echo -e "\t\t- Creating merge list" - # For debugging: - #echo "Done constructing merge list and renaming time to tiles, these files will be merged" - #for f in $mergelist; do - # ls -l $f - #done - # Merge with ncks, since cdo has issues: - echo -e "\t\t- Merging with ncks, as cdo has problems" - ofile=2d_restart_${EXP_ID}_jsbach_merged.nc - for f in $mergelist; do - ncks -A -h $f $ofile - done - echo -e "\t\t- Done merging, now we need to fix the tiles dimension to be limited again rather than unlimited" - # Turn "tiles" back to a limited dimension: - ncks --fix_rec_dmn tiles $ofile -o tmp; mv tmp $ofile - echo -e "\t\t- Finished with modification of variables, now we need to repack" - - # Ensure that the pack binary is here: - if [ ! -f pack ]; then - #if [ -f ${FUNCTION_PATH}..//utils/_build/pack ]; then - # cp -v ${FUNCTION_PATH}..//utils/_build/pack . - if [ -f ${FUNCTION_PATH}/../utils/pack ]; then - cp -v ${FUNCTION_PATH}/../utils/pack . - else - echo -e "\t\t E R O R R --- pack binary missing, don't know how to proceed" - exit - fi - fi - # Copy the files here: - cp ${newest_jsbach_restart_file} . - cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc . - echo -e "\t\t- Running pack binary with arguments:" - echo -e "\t\t- Script: ${FUNCTION_PATH}/../utils/pack_file.ksh" - echo -e "\t\t- Restart File: $(readlink -f ${ofile})" - echo -e "\t\t- Mask file: $(readlink -f ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc)" - echo -e "\n\t\t - NOTE: Errors with >VARDIMIDS (value 2) is out of range (1:1)< can be ignored (maybe?)" - ${FUNCTION_PATH}/../utils/pack_file.ksh \ - $(basename $ofile) \ - $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc) - - echo -e "\t\t- Listing files after program execution:" - ls -ratl - - mv 1d_$(basename $ofile) ${newest_jsbach_restart_file} - ln -sf ${newest_jsbach_restart_file} ${COUPLE_DIR}/latest_jsbach_restart_file.nc - # Go back to the previous directory - cd ${startdir} -} - -set_glacial_mask_jsbach_update_restart_veg() { - echo; echo " * updating active and bare plant fractions in jsbach restart file >>veg<<" - echo -e "\t\t- Making a temporary directory to work in" - startdir=$(pwd) - if [ -d ${COUPLE_DIR}/update_veg ]; then - # Throw away the temporary working directory from last time to - # avoid merge problems in the next coupling iteration: - rm -rf ${COUPLE_DIR}/update_veg - fi - mkdir -p ${COUPLE_DIR}/update_veg; cd ${COUPLE_DIR}/update_veg - - # TODO: This next block is repeated code, it should be made it's own function - echo -e "\t\t- determining where the glacial mask has advanced and retreated" - echo -e "\t\t- New JSBACH Init File: ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc" - echo -e "\t\t- Old JSBACH Init File: $(readlink ${FORCING_DIR_jsbach}/jsbach.nc)" - cdo -s -selvar,glac -sub \ - ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc \ - ${FORCING_DIR_jsbach}/jsbach.nc \ - ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc 2>> ${COUPLE_DIR}/update_veg/cdo_stderr_ice2echam - # Make two masks: one for glacial retreat, and one for glacial advance - cdo -s gtc,0 ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc ${COUPLE_DIR}/update_veg/new_glaciers.nc - cdo -s gtc,0 -mulc,-1 ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc ${COUPLE_DIR}/update_veg/new_non_glaciers.nc - sum_new_glaciers=$(cdo -s -output -fldsum -gtc,0 ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc | tr -d "[:blank:]") - sum_new_land=$(cdo -s -output -fldsum -gtc,0 -mulc,-1 ${COUPLE_DIR}/update_veg/jsbach_glac_diff.nc | tr -d "[:blank:]") - echo -e "\t\t- Total number of new glacial cells: >>>$sum_new_glaciers<<<" - echo -e "\t\t- Total number of new deglacial cells: >>>$sum_new_land<<<" - - if [[ $sum_new_glaciers -eq 0 ]] && [[ $sum_new_land -eq 0 ]]; then - echo -e "\t\t- >>>INFO<<< No new land or new glaciers, this routine will be skipped..." - newest_jsbach_restart_file=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg.nc) - ln -sf ${newest_jsbach_restart_file} ${COUPLE_DIR}/latest_veg_restart_file.nc - return - fi - - newest_jsbach_restart_file=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg.nc) - # Make a backup copy - cp ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg.nc ${RESTART_DIR_jsbach}/restart_${EXP_ID}_veg_backup_$(date +%Y%m%d%H%M%S).nc - echo -e "\t\t- Unpacking JSBACH restart file: $newest_jsbach_restart_file" - # Ensure that the unpack binary is here: - if [ ! -f unpack ]; then - #if [ -f ${FUNCTION_PATH}..//utils/_build/unpack ]; then - # cp -v ${FUNCTION_PATH}..//utils/_build/unpack ./ - if [ -f ${FUNCTION_PATH}/../utils/unpack ]; then - cp -v ${FUNCTION_PATH}/../utils/unpack ./ - else - echo -e "\t\t E R O R R --- unpack binary missing, don't know how to proceed" - exit - fi - fi - # Copy the files here: - cp ${newest_jsbach_restart_file} ./ - cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ./ - echo -e "\t\t- Running unpack binary with arguments:" - echo -e "\t\t- Script: ${FUNCTION_PATH}/../utils/unpack_file.ksh" - echo -e "\t\t- Restart File: $(basename ${newest_jsbach_restart_file})" - echo -e "\t\t- Mask file: $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc)" - ${FUNCTION_PATH}/../utils/unpack_file.ksh \ - $(basename $newest_jsbach_restart_file) \ - $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc) \ - 2>&1 > ${COUPLE_DIR}/unpack_veg_script_stdout_stderr - - echo -e "\t\t- Listing files after program execution:" - ls -ratl - restartfile=2d_$(basename ${newest_jsbach_restart_file}) - # 'cdo showvar' does not work for variables with more than three dimensiones - echo "ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '('" - variables=$(ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '(') - echo $variables - - for var in ${variables}; do - ncks -O --no_abc \ - -v ${var} \ - 2d_$(basename ${newest_jsbach_restart_file}) \ - 2d_restart_${EXP_ID}_veg_${var}.nc - - # The following can be turned into an exit if needed: - if [ ! -f 2d_restart_${EXP_ID}_veg_${var}.nc ]; then - echo -e "\t\t !!! WARNING !!! -- no file for ${var}" - echo -e "\t\t continue loop" - continue - fi - - # Keep the directory clean: make one directory for each variable: - here=$(pwd); mkdir -p ${var}; mv 2d_restart_${EXP_ID}_veg_${var}.nc ${var}; cd ${var} - echo -e "\t\t- Updating JSBACH restart file -- ${var}\n" - case ${var} in - bare_fpc ) - # For bare fpc, we need the fraction of "bare" under glaciers to be 1 - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_veg/new_glaciers.nc \ - ${COUPLE_DIR}/update_veg/new_glaciers.nc \ - 2d_restart_${EXP_ID}_veg_${var}.nc \ - 2d_restart_${EXP_ID}_veg_${var}.tmp - # Over newly deglaciated tiles, we put 95% bare soil - cdo -s ifthenelse \ - ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - -mulc,0.95 ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - 2d_restart_${EXP_ID}_veg_${var}.tmp \ - 2d_restart_${EXP_ID}_veg_${var}.nc - cdo -s -setvar,$var 2d_restart_${EXP_ID}_veg_${var}.nc ${var}.tmp - mv ${var}.tmp 2d_restart_${EXP_ID}_veg_${var}.nc - ;; - act_fpc ) - # NOTE: No correction is applied under - # new_glaciers, this is automatically taken - # care of by JSBACH internally. - # - # For active plant cover fraction, we put 0 on - # all tiles except tundra (tile 7) which gets - # 5%. - # - # Split up the levels - cdo -s splitlevel 2d_restart_${EXP_ID}_veg_${var}.nc 2d_restart_${EXP_ID}_veg_${var}_tile - mergelist="" - for tile in $(ls 2d_restart_${EXP_ID}_veg_${var}_tile0000??.nc); do - # NOTE: The period before the old - # dimension name, sfc, indicates - # optional presence of the dimension - # (ncrename -d renames dimensions). It - # seems as if the variable sometimes - # has the correct dimension name tiles - # (or maybe my test case was incorrect - # and had the dimension name sfc). To - # overcome this, we simply ensure that - # if sfc is the dimension name, it - # should be renamed to tiles, and if - # this is already the case, do nothing: - ncrename -d .sfc,tiles $tile - case ${tile} in - 2d_restart_${EXP_ID}_veg_${var}_tile000007.nc ) - echo -e "\t\t- Setting 5% initial cover of tundra for new deglacial cells" - # For the tundra tile - cdo -v -setvar,$var -ifthenelse \ - ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - -mulc,0.05 ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - 2d_restart_${EXP_ID}_veg_${var}_tile000007.nc \ - 2d_restart_${EXP_ID}_veg_${var}_tile000007.tmp - mv 2d_restart_${EXP_ID}_veg_${var}_tile000007.tmp 2d_restart_${EXP_ID}_veg_${var}_tile000007.nc - ;; - * ) - # For all other tiles: - cdo -s -setvar,$var -ifthenelse \ - ${COUPLE_DIR}/update_veg/new_non_glaciers.nc \ - -mulc,0.0 ${COUPLE_DIR}/update_veg/new_glaciers.nc \ - ${tile} ${tile}.tmp - mv ${tile}.tmp ${tile} - ;; - esac - mergelist="$mergelist $tile" - done - mkdir pre_merge - cp $mergelist pre_merge - echo -e "\t\t >>> PG DEBUG: Command for merging will be: cdo -v -O merge $mergelist ${var}.tmp" - echo -e "\t\t >>> PG DEBUG: The files in merglist ($mergelist) have been copied here:" - echo -e "\t\t >>> PG DEBUG: pre_merge -- directory contents:" - ls -ratlh pre_merge - cdo -v -O merge $mergelist ${var}.tmp - mv -v ${var}.tmp 2d_restart_${EXP_ID}_veg_${var}.nc - # NOTE: Same as above...not sure why this is needed twice?? - ncrename -d .sfc,tiles 2d_restart_${EXP_ID}_veg_${var}.nc - ;; - esac - cd $here - done - mergelist="" - for var in ${variables}; do - mergelist="$mergelist ${var}/2d_restart_${EXP_ID}_veg_${var}.nc" - done - echo -e "\t\t- Creating merge list" - # For debugging: - #echo "Done constructing merge list and renaming time to tiles, these files will be merged" - #for f in $mergelist; do - # ls -l $f - #done - # Merge with ncks, since cdo has issues: - echo -e "\t\t- Merging with ncks, as cdo has problems" - ofile=2d_restart_${EXP_ID}_veg_merged.nc - for f in $mergelist; do - ncks -A -h $f $ofile - done - echo -e "\t\t- Finished with modification of variables, now we need to repack" - # Ensure that the pack binary is here: - if [ ! -f pack ]; then - if [ -f ${FUNCTION_PATH}/../utils/pack ]; then - cp -v ${FUNCTION_PATH}/../utils/pack . - else - echo -e "\t\t E R O R R --- pack binary missing, don't know how to proceed" - exit - fi - fi - # Copy the files here: - cp ${newest_jsbach_restart_file} . - cp ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc . - echo -e "\t\t- Running pack binary with arguments:" - echo -e "\t\t- Script: ${FUNCTION_PATH}/../utils/pack_file.ksh" - echo -e "\t\t- Restart File: $(readlink -f ${ofile})" - echo -e "\t\t- Mask file: $(readlink -f ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc)" - echo -e "\n\t\t - NOTE: Errors with >VARDIMIDS (value 2) is out of range (1:1)< can be ignored (maybe?)" - ${FUNCTION_PATH}/../utils/pack_file.ksh \ - $(basename $ofile) \ - $(basename ${COUPLE_DIR}/jsbach_init_file_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc) - - echo -e "\t\t- Listing files after program execution:" - ls -ratl - - mv 1d_$(basename $ofile) ${newest_jsbach_restart_file} - ln -sf ${newest_jsbach_restart_file} ${COUPLE_DIR}/latest_veg_restart_file.nc - # Go back to the previous directory - cd ${startdir} -} -## @fn update_land_runoff_select_glacial_discharge() -update_land_runoff_select_glacial_discharge() { - echo; echo " * selecting glacial discharge from ice_file_for_atmosphere.nc" - cdo -s -selvar,${ice_mass_loss_varname} ${COUPLE_DIR}/ice_file_for_atmosphere.nc ${COUPLE_DIR}/ice_discharge.nc -} - - -## @fn update_land_runoff_fill_missing() -update_land_runoff_fill_missing() { - echo; echo " * filling non-pism areas with 0" - ifile=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.nc - ofile=${COUPLE_DIR}/gfw_atmo.nc - change_lonlat $ifile $ice_mass_loss_varname - # multiply by -1 to get signs correct (in ice sheet, ice mass gain is positive, loss is negative - # in the atmosphere, loss should be positive, gain should be negative) - # PG: Fix for way too much water: - # Divide by minus 1000; oasis gives m/s to FESOM, not kg/m2/s. - cdo -s mulc,-1 -divc,1000 -setmisstoc,0 $ifile $ofile -} - -distribute_total_discharge_over_ocean() { -# echo; echo " * integrate discharge over echam grid" - ifile1=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.nc - ifile2=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.gridarea.nc -# ofile=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.fldsum.nc - cdo -s gridarea ${ifile1} ${ifile2} -# cdo -s fldsum -mul ${ifile1} ${ifile2} ${ofile} - CELL_AREA_FESOM_FILE=${CELL_AREA_FESOM_FILE:-"fesom.mesh.diag.nc"} - echo; echo " * Start apply_hosing_correction.py with: $ifile1 $ifile2 ${MESH_PATH_FESOM}/${CELL_AREA_FESOM_FILE} ${HOSING_FILE_LANDICE_LOSS} " - module load python3 - echo " * HOSING_FILE_LANDICE_LOSS = ${HOSING_FILE_LANDICE_LOSS}" - if [ -f "${HOSING_FILE_LANDICE_LOSS}/landice_yearly_mass_loss.out" ]; then - rm ${HOSING_FILE_LANDICE_LOSS}/landice_yearly_mass_loss.out - fi - - python ${FUNCTION_PATH}/../utils/apply_hosing_correction.py "$ifile1" "$ifile2" "${MESH_PATH_FESOM}/${CELL_AREA_FESOM_FILE}" "${HOSING_FILE_LANDICE_LOSS}" - module unload python3 - echo; echo " * Finished apply_hosing_correction.py " -# -# -# ifile=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.fldsum.nc -# ofile=${COUPLE_DIR}/ice_discharge_${RES_echam}grid.fldsum.flux.nc -# echo; echo " * evenly spread discharge over ocean with total node area = ${TOTAL_NODE_AREA}" -# cdo -f divc,${TOTAL_NODE_AREA} ${ifile} ${ofile} -# TOTAL_DISCHARGE=$( ncdump ${ofile} | awk '/total_ice_mass_loss_flux =/{getline; print}' | tr -d ";" | xargs ) -# -# echo; echo " * write to ${HOSING_FILE_LANDICE_LOSS}"i -# echo 1 > ${HOSING_FILE_LANDICE_LOSS} -# echo ${TOTAL_DISCHARGE} >> ${HOSING_FILE_LANDICE_LOSS} -} - -## @fn update_land_runoff_prepare_for_oasis() -update_land_runoff_prepare_for_oasis() { - echo; echo " * preparing file for oasis" - ifile=${COUPLE_DIR}/gfw_atmo.nc - ofile=${COUPLE_DIR}/gfw_atmo_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc - ncrename -v total_ice_mass_loss_flux,gfw_atmo $ifile tmp; mv tmp $ifile - ncrename -d lon,nx $ifile tmp; mv tmp $ifile - ncrename -d lat,ny $ifile tmp; mv tmp $ifile - ncks -A ${FUNCTION_PATH}/../utils/axis_366.nc $ifile - ncpdq -a time,ny,nx $ifile tmp; mv tmp $ifile - mv $ifile $ofile - cp ${COUPLE_DIR}/gfw_atmo_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${WORK_DIR}/gfw_atmo.nc - ln -sf ${COUPLE_DIR}/gfw_atmo_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.nc ${COUPLE_DIR}/latest_gfw_atmo.nc -} - -## @fn update_land_runoff_set_namcouple_override() -update_land_runoff_set_namcouple_override() { - echo; echo " * making a file with instructions to override namcouple" - switch_file=${COUPLE_DIR}/namcouple_override_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - echo "" > $switch_file - echo oasis3mct_add_general_info_to_namcouple 12 2 fesom echam6 \$RUNTIME_awicm >> $switch_file -} - -## @fn update_land_runoff_set_namelist_modifications_next_echam_run() -update_land_runoff_set_namelist_modifications_next_echam_run() { - echam_variable_modify_file=${COUPLE_DIR}/echam_namelist_switches_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - echo; echo " * setting echam variables for land runoff to be read from file in next run" - echo " - echam_variable_modify_file=$echam_variable_modify_file" - if [ ! -s $echam_variable_modify_file ]; then - :> $echam_variable_modify_file - fi - echo "lgfw=1" > ${COUPLE_DIR}/oasis3mct_config_switches.dat - # BUG: Moved to the function below due to bad logic in echam.functions - # add_to ${echam_variable_modify_file} echam_namelist_switches.dat config echam - add_to ${COUPLE_DIR}/oasis3mct_config_switches.dat oasis3mct_config_switches.dat config oasis3mct -} - -## @fn update_land_runoff_set_namelist_modifications_next_jsbach_run() -update_land_runoff_set_namelist_modifications_next_jsbach_run() { - jsbach_variable_modify_file=${COUPLE_DIR}/jsbach_namelist_switches_${CHUNK_START_DATE_echam}-${CHUNK_END_DATE_echam}.dat - echo; echo " * setting jsbach variables for land runoff to be read from file in next run" - echo " - jsbach_variable_modify_file=$jsbach_variable_modify_file" - if [ ! -s $jsbach_variable_modify_file ]; then - :> $jsbach_variable_modify_file - fi - echo "submodelctl___lgfw___nml_entry=.TRUE." >> $jsbach_variable_modify_file - # Yes, this is correct below: we want to modify the ECHAM namelist, but - # need it to connect to JSBACH: - echo "submodelctl___lgfw___nml_file=namelist.echam" >> $jsbach_variable_modify_file - echo "hydrology_ctl___lgfw___nml_entry=.TRUE." >> $jsbach_variable_modify_file - echo "hydrology_ctl___lgfw___nml_file=namelist.jsbach" >> $jsbach_variable_modify_file - add_to ${jsbach_variable_modify_file} jsbach_namelist_switches.dat config jsbach -} - -## @fn regrid_to_echam() -regrid_to_echam() { - FILENAME=$1 - remapper=$2 - RES=${3:-${RES_echam}} - if [[ "x$remapper" == "x" ]]; then - remapper=remapcon2 - fi - echo " - regridding $FILENAME to echam ${RES} grid with $remapper" - cdo -s -P 28 \ - -$remapper,${RES}grid \ - -setgrid,${COUPLE_DIR}/ice.griddes \ - $FILENAME ${FILENAME%.*}_${RES}grid.nc -} - -## @fn set_in_jsbach_restart_file() -set_in_jsbach_restart_file() { - TARGET_VARNAME=$1 - SOURCE_FILENAME=$2 - SOURCE_VARNAME=$3 - unpack=$4 - RESTART_FILE=$(readlink ${RESTART_DIR_jsbach}/restart_${EXP_ID}_jsbach.nc) - echo " * replacing: $TARGET_VARNAME " - echo " in: $RESTART_FILE " - echo " from: $SOURCE_VARNAME " - echo " in: $SOURCE_FILENAME" - if [ ! -z $unpack ]; then - echo " - with unpacking from landpoint grid to latlon grid" - python ${FUNCTION_PATH}/../utils/unpack_jsbach.py $TARGET_VARNAME $RESTART_FILE - ################################################################################ - # $ cdo -h replace - # NAME - # replace - Replace variables - # - # SYNOPSIS - # replace infile1 infile2 outfile - # - # DESCRIPTION - # The replace operator replaces variables in infile1 by variables from infile2 and write - # the result to outfile. Both input datasets need to have the same number of timesteps. - ################################################################################ - cdo -s replace \ - ${TARGET_VARNAME}_lonlat_grid.nc \ - -chname,${SOURCE_VARNAME},${TARGET_VARNAME} \ - -selvar,${SOURCE_VARNAME} ${SOURCE_FILENAME} \ - ${TARGET_VARNAME}_lonlat_grid_replaced.nc - echo " - and repacking from latlon grid to landpoint grid" - # FIXME: The next line is probably wrong, or incomplete. - python ${FUNCTION_PATH}/../utils/pack_jsbach.py ${TARGET_VARNAME} ${TARGET_VARNAME}_lonlat_grid_replaced.nc ${RESTART_FILE} - else - cdo -s replace \ - ${RESTART_FILE} \ - -chname,${SOURCE_VARNAME},${TARGET_VARNAME} \ - -selvar,${SOURCE_VARNAME} ${SOURCE_FILENAME} \ - tmp - cp ${RESTART_FILE} ${RESTART_FILE%.*}_backup_before_replace_${TARGET_VARNAME}_$(date +%Y%m%d%H%M%S).nc - mv tmp ${RESTART_FILE} - fi -} - -## @fn change_lonlat() -change_lonlat() { - file=$1 - varname=$2 - if ncdump -h $file | grep "${varname}" | grep -q "lon, lat"; then - echo " - changing lat/lon dimension order for $varname in $file" - ncpdq -a lat,lon $file tmp; mv tmp $file 2>> nco_stderr_ice2echam - fi -} diff --git a/couplings/echam/env_echam.py b/couplings/echam/env_echam.py deleted file mode 100644 index 637342e90..000000000 --- a/couplings/echam/env_echam.py +++ /dev/null @@ -1,49 +0,0 @@ -def prepare_environment(config): - environment_dict = { - "ICE_TO_ECHAM": int(config["general"]["first_run_in_chunk"]), - "ECHAM_TO_ICE": int(config["general"]["last_run_in_chunk"]), - "ECHAM_TO_ISM_multiyear_mean": int(config["echam"].get("multi_year_mean", 1)), - "ISM_TO_ECHAM_update_orography": 1, - "ISM_TO_ECHAM_update_glacial_mask": int(config["echam"].get("update_glacial_mask", True).__bool__()), - "ISM_TO_ECHAM_update_land_runoff": 1, - "COUPLE_DIR": config["general"]["experiment_couple_dir"], - "RES_echam": config["echam"]["resolution"], - "EXP_ID": config["general"]["command_line_config"]["expid"], - "RESTART_DIR_echam": config["echam"]["experiment_restart_out_dir"], - "DATA_DIR_echam": config["echam"]["experiment_outdata_dir"], - "INIT_DIR_echam": config["echam"]["experiment_input_dir"], - "WORK_DIR": config["general"]["thisrun_work_dir"], - "number_of_years_for_forcing": config["model1"]["chunk_size"], - "CHUNK_START_DATE_echam": config["general"]["chunk_start_date"], - "CHUNK_END_DATE_echam": config["general"]["chunk_end_date"], - "END_YEAR_echam": config["general"]["chunk_end_date"].syear, - "END_MONTH_echam": config["general"]["chunk_end_date"].smonth, - "END_DAY_echam": config["general"]["chunk_end_date"].sday, - "FUNCTION_PATH": config["echam"]["workflow"]["subjobs"]["couple_in"]["script_dir"], - "FORCING_DIR_jsbach": config["jsbach"]["experiment_input_dir"], - "RESTART_DIR_jsbach": config["jsbach"]["experiment_restart_out_dir"], - "POOL_DIR_jsbach": config["computer"]["pool_dir"], - "POOL_DIR_echam": config["computer"]["pool_dir"], - "MACHINE": config["computer"]["name"], - "MESH_PATH_FESOM": config["fesom"]["mesh_dir"], - "HOSING_FILE_LANDICE_LOSS": config["fesom"].get("fwf_path", config["general"]["experiment_couple_dir"]), - "HOSING_CORRECTION": int(config["echam"].get("hosing_correction", False).__bool__()), # LA: Not needed anymore with Lu's ECHAM gfw fix - "CELL_AREA_FESOM_FILE": config["fesom"].get("fesom_cell_area_file", "fesom.mesh.diag.nc"), - "ECHAM_ALBEDO_ON_GLACIERS": config["echam"].get("albedo_on_glaciers", 0.7), - "ECHAM_GLACIAL_THRESHOLD": config["echam"].get("glacial_threshold", 0.5), - "oro_update_mod": config["echam"].get("oro_update_mod", 2), - "oro_update_var": config["echam"].get("oro_update_var", "geosp"), - } - - #if environment_dict["ADD_UNCHANGED_ICE"] == False: - # environment_dict["ADD_UNCHANGED_ICE"] = 0 - #elif environment_dict["ADD_UNCHANGED_ICE"] == True: - # environment_dict["ADD_UNCHANGED_ICE"] = 1 - - - print(environment_dict) - return environment_dict - - - - diff --git a/couplings/fesom/coupling_fesom2ice.functions b/couplings/fesom/coupling_fesom2ice.functions deleted file mode 100644 index c5fd26fcc..000000000 --- a/couplings/fesom/coupling_fesom2ice.functions +++ /dev/null @@ -1,756 +0,0 @@ -#!/usr/bin/ksh - -function fesom2ice { - FESOM_TO_ISM_ocean_forcing=${FESOM_TO_ISM_ocean_forcing:-0} - echo " *** S T A R T I N G fesom2ice *** " - echo " LA DEBUG: MESH_PATH=${MESH_DIR_fesom}" - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - echo " Starting coupling_fesom2ice.functions ...." - echo "FESOM_TO_ISM_ocean_forcing=${FESOM_TO_ISM_ocean_forcing}" - - export FileName_depth4levels_FESOM=depth_axis_fesom.nc - iter_coup_interact_method_oce2ice=${iter_coup_interact_method_oce2ice:-} - - iterative_coupling_fesom1x_ice_make_forcing - iterative_coupling_fesom1x_ice_write_grid - iterative_coupling_fesom1x_ice_write_names - - for file in ${cleanup_list} ; do test -f $file && rm $file ; done - unset cleanup_list file -} - -function iterative_coupling_fesom1x_ice_make_forcing { - echo "Preparing fesom1x file for processing in an ice sheet model..." - - FESOM_TO_ISM_multiyear_mean=${FESOM_TO_ISM_multiyear_mean:-1} - FESOM_TO_ISM_total_mean=${FESOM_TO_ISM_total_mean:-1} - - fesom_ice_construct_input_list - fesom_ice_select_relevant_variables - # Come from special FESOM grid to i(lon,lat),j(lon,lat),depth grid - fesom_ice_fesom_build_grid_with_lonlat_depth - fesom_ice_concatenate_files - if [ "x${FESOM_TO_ISM_multiyear_mean:-0}" == "x1" ] ; then - fesom_ice_generate_multiyear_mean - fi - if [ "x${FESOM_TO_ISM_total_mean:-0}" == "x1" ] ; then - fesom_ice_generate_total_mean - fi - - # Since depth array "depth(level)" is lost after each CDO - # command (because the vertical dimension is "level"), we have - # to add the depth array as very last command. - # To keep the "depth" and allow CDO to use this information, - # we have to rename the dimension "level" against "depth" as well. - # Hence use "fesom_ice_rename_level2depth_add_depth" and not - # "fesom_ice_add_depth", because the latter does not work as - # wanted. - # - # These selections of `$iter_coup_interact_method_oce2ice` - # could lead to enormous main memory request, if we use many - # time step. Therefore we collapse the data file into one - # single time step . - if [ "${iter_coup_interact_method_oce2ice}" == "MIXED" -o \ - "${iter_coup_interact_method_oce2ice}" == "TS_RESCALED2FLUX" -o \ - "${iter_coup_interact_method_oce2ice}" == "TEMPSALT2FLUX" -o \ - "${iter_coup_interact_method_oce2ice}" == "TEMP2FLUX" -o \ - "${iter_coup_interact_method_oce2ice}" == "OCEANTEMP" ] ; then - FESOM_TO_ISM_total_mean=1 - fi - - fesom_ice_construct_input_list - fesom_ice_select_relevant_variables - # Come from special FESOM grid to i(lon,lat),j(lon,lat),depth grid - fesom_ice_fesom_build_grid_with_lonlat_depth - fesom_ice_concatenate_files - if [ "x${FESOM_TO_ISM_multiyear_mean}" == "x1" ] ; then - fesom_ice_generate_multiyear_mean - fi - if [ "x${FESOM_TO_ISM_total_mean}" == "x1" ] ; then - fesom_ice_generate_total_mean - fi - - # Since depth array "depth(level)" is lost after each CDO - # command (because the vertical dimension is "level"), we have - # to add the depth array as very last command. - # To keep the "depth" and allow CDO to use this information, - # we have to rename the dimension "level" against "depth" as well. - # Hence use "fesom_ice_rename_level2depth_add_depth" and not - # "fesom_ice_add_depth", because the latter does not work as - # wanted. - # - # Adding the depth works only for z-coordinates - # - if [ -f ${FileName_depth4levels_FESOM} ] ; then - cp ocean_file_for_ice.nc ocean_file_for_ice.before_add_depth.nc - fesom_ice_rename_level2depth_add_depth ${FileName_depth4levels_FESOM} ocean_file_for_ice.nc - cleanup_list="${cleanup_list} $(pwd)/ocean_file_for_ice.before_add_depth.nc" - fi - - #add_to $(pwd)/ocean_file_for_ice.nc ocean_file_for_ice.nc couple - cp $(pwd)/ocean_file_for_ice.nc ${COUPLE_DIR}/ocean_file_for_ice.nc - - if [ "${MACHINE}" == "albedo" ]; then - module unload python - module load python - fi - - echo " ...done." -} - -function iterative_coupling_fesom1x_ice_write_grid { - echo "Writing fesom1x grid description to generic ocean.griddes..." - echo ""; echo " * generating griddes" - NEW_OCE2ICE_GRID=$(build_grid_des ocean_file_for_ice.nc ocean.griddes couple) - export NEW_OCE2ICE_GRID - cp $(pwd)/ocean.griddes ${COUPLE_DIR}/ocean.griddes - - echo "....done." -} - -function iterative_coupling_fesom1x_ice_write_names { - echo "Writing fesom1x names and units for use with generic ocean_file_for_ice.nc" - :> ocean_names_for_ice.dat - echo ""; echo " * temperature" - echo "ocean_name_pot_temperature=temp" >> ocean_names_for_ice.dat - echo "ocean_units_pot_temperature=degC" >> ocean_names_for_ice.dat - echo ""; echo " * salinity" - echo "ocean_name_salinity=salt" >> ocean_names_for_ice.dat - # Since "psu" is not a standard unit, we use "g/kg", which follows the newest definitions - #echo "ocean_units_salinity=psu" >> ocean_names_for_ice.dat - echo "ocean_units_salinity=g/kg" >> ocean_names_for_ice.dat - echo ""; echo " * ice base depth" - echo "ocean_name_ice_base_depth=basedepth" >> ocean_names_for_ice.dat - echo "ocean_units_ice_base_depth=m" >> ocean_names_for_ice.dat - - echo ""; echo " * top/surface tempeature" - echo "ocean_name_pot_temperature_z0=Tsurf" >> ocean_names_for_ice.dat - echo "ocean_units_pot_temperature_z0=degC" >> ocean_names_for_ice.dat - - echo ""; echo " * top/surface salinity" - echo "ocean_name_salinity_z0=Ssurf" >> ocean_names_for_ice.dat - echo "ocean_units_salinity_z0=g/kg" >> ocean_names_for_ice.dat - - echo ""; echo " * top-of-ocean heat flux" - echo "ocean_name_heatflux_z0=fh" >> ocean_names_for_ice.dat - echo "ocean_units_heatflux_z0=W/m2/s" >> ocean_names_for_ice.dat - - echo ""; echo " * top-of-ocean freshwater flux" - echo "ocean_name_fwflux_z0=fw" >> ocean_names_for_ice.dat - echo "ocean_units_fwflux_z0=kg/m2" >> ocean_names_for_ice.dat - - echo ""; echo " * iteration counter" - echo "ocean_name_iter=iter" >> ocean_names_for_ice.dat - echo "ocean_units_iter=1" >> ocean_names_for_ice.dat - - #add_to $(pwd)/ocean_names_for_ice.dat ocean_names_for_ice.dat couple - cp $(pwd)/ocean_names_for_ice.dat ${COUPLE_DIR}/ocean_names_for_ice.dat - echo " ...done." -} - -function fesom_ice_construct_input_list { - echo ""; echo " * constructing input list" - - export CHUNK_END_YEAR_fesom=$(date -d "${CHUNK_END_DATE_fesom:?'Missing variable'}" +%Y) - export CHUNK_END_MONTH_fesom=$(date -d "${CHUNK_END_DATE_fesom:?'Missing variable'}" +%m) - export CHUNK_END_DAY_fesom=$(date -d "${CHUNK_END_DATE_fesom:?'Missing variable'}" +%d) - - number_of_years_for_forcing=${number_of_years_for_forcing:-1} - start_year_couple=$(( CHUNK_END_YEAR_fesom - number_of_years_for_forcing + 1 )) - end_year_couple=${CHUNK_END_YEAR_fesom} - fesom1x_raw_file3D_T_list_for_ice="" - fesom1x_raw_file3D_S_list_for_ice="" - fesom1x_raw_file2D_list_for_ice="" - fesom1x_raw_file2Dstatic_list_for_ice="" - - # - # Standard (monthly) 3dimensional+time FESOM output - # - - for year in $(seq $start_year_couple $end_year_couple ); do - month=01 - #for month in $(seq -f "%02g" 1 12); do - day=01 - variable=temp - current_file=${DATA_DIR_fesom}/${variable}.fesom.${year}.nc - if [ -f $current_file ] ; then - fesom1x_raw_file3D_T_list_for_ice="$fesom1x_raw_file3D_T_list_for_ice $current_file" - else - echo " - Missing 3D fesom file ${current_file}" - echo " S T O P 1 (coupling_fesom2ice.functions::fesom_ice_construct_input_list)" ; exit 1 - fi - - variable=salt - current_file=${DATA_DIR_fesom}/${variable}.fesom.${year}.nc - if [ -f $current_file ] ; then - fesom1x_raw_file3D_S_list_for_ice="$fesom1x_raw_file3D_S_list_for_ice $current_file" - else - echo " - Missing 3D fesom file ${current_file}" - echo " S T O P 2 (coupling_fesom2ice.functions::fesom_ice_construct_input_list)" ; exit 2 - fi - #done - done - -# TODO Activate this part once Ozgur's fesom is ready (allow STOP & exit) - # - # Special 2dimensional+time FESOM output - # - # -- SST, SSS, fluxes through surface - for year in $(seq $start_year_couple $end_year_couple ); do - month=01 - day=01 - current_file=${DATA_DIR_fesom}/${EXP_ID}.${year}.pism.nc - if [ -f $current_file ] ; then - fesom1x_raw_file2D_list_for_ice="$fesom1x_raw_file2D_list_for_ice $current_file" - else - echo " - Missing 2D fesom file ${current_file}" -# echo " S T O P 3 (coupling_fesom2ice.functions::fesom_ice_construct_input_list)" ; exit 3 - fi - #done - done - -# TODO Activate this part once Ozgur's fesom is ready (allow STOP & exit) - # - # Special 2dimensional FESOM output - # - # -- basal ice depth/ice draft - for year in $(seq $start_year_couple $end_year_couple ); do - month=01 - #for month in $(seq -f "%02g" 1 12); do - day=01 - current_file=${DATA_DIR_fesom}/${EXP_ID}.initial.mesh.diag.nc - if [ -f $current_file ] ; then - fesom1x_raw_file2Dstatic_list_for_ice="$fesom1x_raw_file2Dstatic_list_for_ice $current_file" - else - echo " - Missing 2D static fesom file ${current_file}" -# echo " S T O P 4 (coupling_fesom2ice.functions::fesom_ice_construct_input_list)" ; exit 4 - fi - #done - done - - unset variable year month #current_file start_year_couple end_year_couple -} - -function fesom_ice_select_relevant_variables { - echo ""; echo " * selecting relevant variables" - fesom1x_file3D_T_list_for_ice="" - fesom1x_file3D_S_list_for_ice="" - fesom1x_file2D_list_for_ice="" - fesom1x_file2Dstatic_list_for_ice="" - - variable=temp - for file in ${fesom1x_raw_file3D_T_list_for_ice} ; do - echo -n " - >${variable}< from ${file}" - filename=$(basename $file) - output="${filename%.*}"_var4ice.nc - ${cdo} -s -f nc monmean $file $output - fesom1x_file3D_T_list_for_ice="$fesom1x_file3D_T_list_for_ice ${output}" - echo " : STILL alive" - done - - variable=salt - for file in ${fesom1x_raw_file3D_S_list_for_ice} ; do - echo -n " - >${variable}< from ${file}" - filename=$(basename $file) - output="${filename%.*}"_var4ice.nc - ${cdo} -s -f nc monmean $file $output - fesom1x_file3D_S_list_for_ice="$fesom1x_file3D_S_list_for_ice ${output}" - echo " : STILL alive" - done - - variable="2dim-fields" - for file in ${fesom1x_raw_file2D_list_for_ice} ; do - echo -n " - >${variable}< from ${file}" - filename=$(basename $file) - output="${filename%.*}"_var4ice.nc - ${cdo} -s -f nc monmean $file $output - fesom1x_file2D_list_for_ice="$fesom1x_file2D_list_for_ice ${output}" - echo " : STILL alive" - done - - variable="static 2dim-fields" - for file in ${fesom1x_raw_file2Dstatic_list_for_ice} ; do - echo -n " - >${variable}< from ${file}" - filename=$(basename $file) - output="${filename%.*}"_var4ice.nc - cp $file $output #${cdo} -s -f nc selvar,XXX,YYY,ZZZ $file $output - fesom1x_file2D_list_for_ice="$fesom1x_file2D_list_for_ice ${output}" - echo " : STILL alive" - done - - # - # Do NOT delete the raw files! - # - - unset output filename - unset fesom1x_raw_file3D_T_list_for_ice fesom1x_raw_file2D_list_for_ice - unset fesom1x_raw_file3D_S_list_for_ice fesom1x_raw_file2Dstatic_list_for_ice -} - -function fesom_ice_fesom_build_grid_with_lonlat_depth { - # Come from special FESOM grid to i(lon,lat),j(lon,lat),depth grid - if [ "${MACHINE}" == "levante" ]; then - #module unload python3 - module load python3 - fi - echo ""; echo " * build files on propper grid with longitude, latitude, and depth" - echo ""; echo " * using python version $(python --version)" - - pyfesom_script=${FUNCTION_PATH:-${FPATH}}/../utils/fesom_scalar_array_to_LonLat.py - if [ ! -f $pyfesom_script ] ; then - echo " - Missing pyfesom_script ${pyfesom_script}" - echo " S T O P 5 (coupling_fesom2ice.functions::fesom_ice_fesom_build_grid_with_lonlat_depth)" ; exit 5 - fi - - # Path of PYFESOM installation - PYFESOM_PATH=${PYFESOM_PATH:-${FUNCTION_PATH}/pyfesom} - CMOCEAN_PATH=${CMOCEAN_PATH:-${FUNCTION_PATH}/cmocean} - for dir in ${PYFESOM_PATH} ${CMOCEAN_PATH} ; do - base_dir=$(basename $dir) - echo -n " - $base_dir" - if [ ! -d $base_dir ] ; then - echo " - create link" - ln -s $dir - else - echo " - exists in $(pwd)" - fi - done - - processed_fesom1x_file3D_T_list_for_ice="" - processed_fesom1x_file3D_S_list_for_ice="" - processed_fesom1x_file2D_list_for_ice="" - processed_fesom1x_file2Dstatic_list_for_ice="" - -# -------------------------------------------------------- -# -# HOT fix, part 1/2 -# - echo "=====## ---------------------------------------------------------------" - echo " ## HOT fix for the python2 (needed for pyfesom) vs python3 problem" - node_name=$(hostname) - echo " ## Check for computer/node name '${node_name}'" - FLAG_SWITCHED_PYTHON=0 - case ${node_name} in - prod-[0-9]*) - FLAG_SWITCHED_PYTHON=1 - module_python3="python3" - module_python2="python" - ;; - ollie[0-1]) - FLAG_SWITCHED_PYTHON=1 - module_python3="python3" - module_python2="python" - ;; - fat-*[0-9]|fat[0-9]) - FLAG_SWITCHED_PYTHON=1 - module_python3="python3" - module_python2="python" - ;; - xfat*) - FLAG_SWITCHED_PYTHON=1 - module_python3="python3" - module_python2="python" - ;; - m[0-9]*[0-9]) - # Mistral has compute nodes named m-number(several times) - FLAG_SWITCHED_PYTHON=1 - module_python3="python/3.5.2" - module_python2="python/2.7.12" - ;; - mlogin[0-9]*) - # Mistral has compute nodes named m-number(several times) - FLAG_SWITCHED_PYTHON=1 - module_python3="python/3.5.2" - module_python2="python/2.7.12" - ;; - *) - echo " ## Nothing defined for computer '$(hostname)'" - ;; - esac - FLAG_SWITCHED_PYTHON=0 - if [ ${FLAG_SWITCHED_PYTHON} -eq 1 ] ; then - echo " ## ACTIVATE HOT fix for the ${module_python2} vs ${module_python3} problem" - echo "--------- module output --- begin" - module unload ${module_python3} - module load ${module_python2} - echo "--------- module output --- end" - echo " ## unload ${module_python3} and load ${module_python2} : ${node_name}" - else - echo " ## Do not activate HOT fix" - echo "=====## ---------------------------------------------------------------" - fi - - # Several things might be needed for pyfesom. If it isn't installed; - # get it - for required_python_external in xarray joblib cmocean seawater; do - python -c "import $required_python_external" \ - || pip install --user ${required_python_external} \ - && echo -e "\t\t - Using existing ${required_python_external} for python" - done -# -------------------------------------------------------- - - # ------------------------------------------------ - # - # Determine if grid is rotated and how much - # - # See issue #83 : - # [...] from now on all new meshes will be in geographical - # coordinates and old meshes will be converted - # accordingly. This means force_rotation=.FALSE. and - # rotated_grid=.true. will be the fixed options - # - # ==> related code is placed at the end of this file - # - if [ "${MACHINE}" == "albedo" ]; then - module unload python - module load python/3.9.12 - fi - - variable=temp - for file in ${fesom1x_file3D_T_list_for_ice} ; do - filename=$(basename $file) ; logfile=${filename}.${variable}.log - output="${filename%.*}"_goodgrid.nc - - echo -n " - >${variable}< from ${file}" - python $pyfesom_script ${FESOM_MESH_SWITCHES} \ - --FESOM_PATH $DATA_DIR_fesom \ - --FESOM_VARIABLE $variable \ - --FESOM_MESH ${MESH_DIR_fesom} \ - --FESOM_YEARS $start_year_couple $end_year_couple \ - --FESOM_MESH_ROTATED ${MESH_ROTATED_fesom} \ - --FESOM_OUTPUT $output > $logfile - echo " : STILL alive" - - test_file_or_exit $output 6 - processed_fesom1x_file3D_T_list_for_ice="$processed_fesom1x_file3D_T_list_for_ice ${output}" - done - - variable=salt - for file in ${fesom1x_file3D_S_list_for_ice} ; do - filename=$(basename $file) ; logfile=${filename}.${variable}.log - output="${filename%.*}"_goodgrid.nc - - echo -n " - >${variable}< from ${file}" - python $pyfesom_script ${FESOM_MESH_SWITCHES} \ - --FESOM_PATH $DATA_DIR_fesom \ - --FESOM_VARIABLE $variable \ - --FESOM_MESH ${MESH_DIR_fesom} \ - --FESOM_YEARS $start_year_couple $end_year_couple \ - --FESOM_MESH_ROTATED ${MESH_ROTATED_fesom} \ - --FESOM_OUTPUT $output > $logfile - echo " : STILL alive" - - test_file_or_exit $output 7 - processed_fesom1x_file3D_S_list_for_ice="$processed_fesom1x_file3D_S_list_for_ice ${output}" - done - - for file in ${fesom1x_file2D_list_for_ice} ; do - filename=$(basename $file) - output="${filename%.*}"_goodgrid.nc - - ic=0 - for variable in Tsurf Ssurf fh fw ; do - ic=$(( ic + 1 )) - - logfile=${filename}.${variable}.log - input=$file - if [[ "x${variable}" =~ x[q,w]net ]] ; then - echo " + ${variable} set to zero outside of ice fesom ice shelves" - # Set heat and freshwater/mass fluxes to - # zero outside of the ice shelf region - filename=$(echo $fesom1x_file2Dstatic_list_for_ice | cut -d' ' -f1) - test_file_or_exit $filename 8 - input=tmp_cavity_flag_extended - $cdo -O ifthen -selvar,cavity_flag_extended $filename \ - -selvar,${variable} $file $input - fi - - echo -n " - >${variable}< from ${file}" - result_file=tmp_file_$(printf "%04i" $ic)__${variable} - python $pyfesom_script ${FESOM_MESH_SWITCHES} \ - --FESOM_PATH $DATA_DIR_fesom \ - --FESOM_VARIABLE $variable \ - --FESOM_MESH ${MESH_DIR_fesom} \ - --FESOM_YEARS $start_year_couple $end_year_couple \ - --FESOM_MESH_ROTATED ${MESH_ROTATED_fesom} \ - --FESOM_OUTPUT $output > $logfile - echo " : STILL alive" - - test_file_or_exit $result_file 9 - done - $cdo -f nc cat tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* ${output} - - ncks -Av iter tmp_file_0001__[A-Z,a-z]* ${output} && \ - rm tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* - - processed_fesom1x_file2D_list_for_ice="$processed_fesom1x_file2D_list_for_ice ${output}" - done - - for file in ${fesom1x_file2Dstatic_list_for_ice} ; do - filename=$(basename $file) - output="${filename%.*}"_goodgrid.nc - - ic=0 -# TODO: Wait for OG code for cavities in standard FESOM -#TODO : variable names of 1) cavitity mask (extend) -# 2) depth of ice base (top depth of top ocean layer) - for variable in cavity_flag_extended fld ; do - ic=$(( ic + 1 )) - - logfile=${filename}.${variable}.log - echo -n " - >${variable}< from ${file}" - result_file=tmp_file_$(printf "%04i" $ic)__${variable} - python $pyfesom_script ${FESOM_MESH_SWITCHES} \ - --FESOM_PATH $DATA_DIR_fesom \ - --FESOM_VARIABLE $variable \ - --FESOM_MESH ${MESH_DIR_fesom} \ - --FESOM_YEARS $start_year_couple $end_year_couple \ - --FESOM_MESH_ROTATED ${MESH_ROTATED_fesom} \ - --FESOM_OUTPUT $output > $logfile - echo " : STILL alive" - - test_file_or_exit $result_file 10 - done - $cdo -f nc cat tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* ${output} \ - && rm tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* - - processed_fesom1x_file2Dstatic_list_for_ice="$processed_fesom1x_file2Dstatic_list_for_ice ${output}" - done - - if [ 1 -eq 1 ] ; then - # Clean up and discard intermediate temporary files - for file in tmp_cavity_flag_extended $result_file \ - ${fesom1x_file3D_T_list_for_ice} \ - ${fesom1x_file2D_list_for_ice} \ - ${fesom1x_file3D_S_list_for_ice} \ - ${fesom1x_file2Dstatic_list_for_ice} - do - if [ -f $file ] ; then - cleanup_list="${cleanup_list} $(pwd)/$(basename ${file})" - fi - done - rm -f tmp_file_[0-9][0-9][0-9][0-9]__[A-Z,a-z]* - fi - -# -------------------------------------------------------- -# -# HOT fix, part 2/2 -# - if [ ${FLAG_SWITCHED_PYTHON} -eq 1 ] ; then - echo " ## DEactivate HOT fix for the ${module_python2} vs ${module_python3} problem" - echo " ## unload ${module_python2} and load ${module_python3}" - echo " ## HOT fix for the ${module_python2} (needed for pyfesom) vs ${module_python3} problem" - echo " ## Check computer name" - echo "--------- module output --- begin" - module unload ${module_python2} - module load ${module_python3} - echo "--------- module output --- end" - echo "=====## ---------------------------------------------------------------" - FLAG_SWITCHED_PYTHON=0 - fi -# -------------------------------------------------------- - - unset dir file filename input logfile output result_file - unset fesom1x_file3D_T_list_for_ice fesom1x_file2D_list_for_ice - unset fesom1x_file3D_S_list_for_ice fesom1x_file2Dstatic_list_for_ice - unset FLAG_SWITCHED_PYTHON FESOM_MESH_SWITCHES -} - -function fesom_ice_concatenate_files { - echo ""; echo " * concatenating files" - # New cdo versions sometimes do not allow to overwrite files for - # "collective" commands. Hence delete existing old output file - [[ -f temp.tmp.nc ]] && rm temp.tmp.nc - [[ -f salt.tmp.nc ]] && rm salt.tmp.nc - [[ -f ocean_file_for_ice.nc ]] && rm ocean_file_for_ice.nc - ${cdo} -s ensmean ${processed_fesom1x_file3D_T_list_for_ice} temp.tmp.nc - ${cdo} -s ensmean ${processed_fesom1x_file3D_S_list_for_ice} salt.tmp.nc - ${cdo} -s merge temp.tmp.nc salt.tmp.nc ocean_file_for_ice.nc - #${cdo} -s merge \ - # ${processed_fesom1x_file3D_T_list_for_ice} \ - # ${processed_fesom1x_file3D_S_list_for_ice} \ - # ${processed_fesom1x_file2D_list_for_ice} \ - # ${processed_fesom1x_file2Dstatic_list_for_ice} \ - # ocean_file_for_ice.nc - _flag_extract_depth=1 - # Extract depth axis and Clean up temporary files - for file in \ - ${processed_fesom1x_file3D_T_list_for_ice} \ - ${processed_fesom1x_file3D_S_list_for_ice} \ - ${processed_fesom1x_file2D_list_for_ice} \ - ${processed_fesom1x_file2Dstatic_list_for_ice} - do - if [ -f $file ] ; then - if [ ${_flag_extract_depth} -ne 0 ] ; then - # Shall we add the depth axis (discarded above during merge/cat) - varname_depth="depth" - echo " - extract depth variable >${varname_depth}< axis from >>${file}<<" - - if [ ! -f ${FileName_depth4levels_FESOM} ] ; then - ncks -v ${varname_depth} ${file} ${FileName_depth4levels_FESOM} \ - || echo " ****** FAILED extracting >${varname_depth}< *****" \ - && _flag_extract_depth=0 # Preventing further attempts adding "depth" -# TODO : compute layer bounds and add them also - fi - fi - - if [ 0 -eq 1 ] ; then - cleanup_list="${cleanup_list} $(pwd)/$(basename ${file})" - #OR rm $file - fi - fi - done - - unset _flag_extract_depth file - unset processed_fesom1x_file3D_T_list_for_ice processed_fesom1x_file2D_list_for_ice - unset processed_fesom1x_file3D_S_list_for_ice processed_fesom1x_file2Dstatic_list_for_ice -} - - -function fesom_ice_rename_level2depth_add_depth { - _file_depth=$1 - _file_data=$2 - echo ""; echo " * Rename dimension level and add depth axis >>${_file_depth}<< to >>${_file_data}<<" - if [ $# -lt 2 ] ; then - echo " not enought input variables in coupling_fesom2ice.functions::fesom_ice_rename_level2depth_add_depth" - echo " S T O P 11" - exit 11 - fi - test_file_or_exit ${_file_depth} 12 - test_file_or_exit ${_file_data} 13 - - # Since depth(level) and level is the vertical dimension, the - # "depth" is not recognized by just adding the "depth". As a - # consequence "cdo vertlevel,150/500" does not work as expected. - - # - # REPLACE 'level' with real 'depth' values - # - # Step 1 : rename dimension "level" into "depth" - # - echo $(module list) - ncrename -d level,depth -v level,depth ${_file_data} - #ncrename -d level,depth ${_file_data} - ncatted -a axis,depth,o,c,'Z' ${_file_data} - - # - # Step 2 : Modified depth/level file comparable to the data file - # - _file_depth_level=${_file_depth}.level2depth - if [ ! -f ${_file_depth_level} ] ; then - if [ 1 -eq 0 ] ; then - # This does not work, because we have a missmatch of - # number types between "float" and "double". At the end - # the below added reasonable depth values (via ncks -A) - # are converted into ridiculous large numbers without - # meaning. - # Therefore we first have to convert the depth type - # "float" into "double" and then add this depth. - ncrename -d level,depth ${_file_depth} ${_file_depth_level} - ncatted -a axis,level,d,, \ - -a axis,depth,o,c,'Z' \ - ${_file_depth_level} - else - # As before - ncrename -d level,depth ${_file_depth} ${_file_depth_level}.tmp1 - #ncrename -d level,depth ${_file_depth_level}.tmp1 - ncatted -a axis,level,d,, \ - -a axis,depth,c,c,'Z' \ - ${_file_depth_level}.tmp1 - - # This multipliation transforms "float" into "double" - ncap=${ncap:-ncap2} - $ncap -s "depth=depth*1.0000000000000;" \ - ${_file_depth_level}.tmp1 \ - ${_file_depth_level}.tmp2 - - # Repair the broken meta-data information for depth and - # get the final $_file_depth_level - ncatted \ - -a long_name,depth,o,c,"depth" \ - -a units,depth,o,c,"m" \ - -a description,depth,o,c,"depth below sea level" \ - -a positive,depth,o,c,"down" \ - ${_file_depth_level}.tmp2 \ - ${_file_depth_level} - - # Cleanup - rm -f ${_file_depth_level}.tmp1 ${_file_depth_level}.tmp2 - fi - fi - - # - # Step 3 : Overwrite former "level" values with real "depth" - # - ncks -A ${_file_depth_level} ${_file_data} - - unset _file_data _file_depth _file_depth_level -} - -function fesom_ice_add_depth { - _file_depth=$1 - _file_data=$2 - echo ""; echo " * Adding depth axis >>${_file_depth}<< to >>${_file_data}<<" - if [ $# -lt 2 ] ; then - echo " not enought input variables in coupling_fesom2ice.functions::fesom_ice_add_depth" - echo " S T O P 11" - exit 11 - fi - test_file_or_exit ${_file_depth} 12 - test_file_or_exit ${_file_data} 13 - - #--> This depth is not recognized since depth(level) and - # level is the vertical dimension and, hence, the command - # "cdo vertlevel,150/500" does not work as expected - ncks -A ${_file_depth} ${_file_data} - - unset _file_data _file_depth -} - - -function fesom_ice_generate_multiyear_mean { - input=ocean_file_for_ice.nc - echo ""; echo " * making multi-year monthly mean >>${input}<<" - - bakfile=ocean_file_for_ice.before_ymonmean.nc - test_file_or_exit $input 14 - mv $input $bakfile - - for __var in $($cdo -s showvar ${bakfile} ) - do - $cdo ymonmean -selvar,${__var} ${bakfile} ${input}.TMP_FIX_$$.${__var} - done - $cdo -O merge ${input}.TMP_FIX_$$.* ${input} && rm ${input}.TMP_FIX_$$.* - - $cdo showvar ${input} - #add_to $(pwd)/${bakfile} ${bakfile} couple - cp $(pwd)/${bakfile} ${COUPLE_DIR}/${bakfile} - cleanup_list="${cleanup_list} $(pwd)/${bakfile}" - - unset __var -} - -function fesom_ice_generate_total_mean { - input=ocean_file_for_ice.nc - echo ""; echo " * making total mean >>${input}<<" - - bakfile=ocean_file_for_ice.before_totalmean.nc - test_file_or_exit $input 15 - mv $input $bakfile - if [ 1 -eq 1 ] ; then - ${cdo} timmean $bakfile $input - else - ncwa -a time $bakfile $input - fi - - #add_to $(pwd)/${bakfile} ${bakfile} couple - cp $(pwd)/${bakfile} ${COUPLE_DIR}/${bakfile} - cleanup_list="${cleanup_list} $(pwd)/${bakfile}" - - unset bakfile -} - -# -- last line diff --git a/couplings/fesom/coupling_ice2fesom.functions b/couplings/fesom/coupling_ice2fesom.functions deleted file mode 100644 index ae4e3f0ef..000000000 --- a/couplings/fesom/coupling_ice2fesom.functions +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/ksh - -function ice2fesom { - echo " *** S T A R T I N G ice2fesom ***)" - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - . ${FUNCTION_PATH}/../pism/coupling_ocean2pism.functions - - echo "ICE_TO_FESOM=${ICE_TO_FESOM:-0}" - if [[ "x$ICE_TO_FESOM" == "x0" ]]; then - echo " NOT generating ice forcing for ocean model" - echo " since ICE_TO_FESOM=${ICE_TO_FESOM}" - return - else - echo " Only generating iceberg forcing so far ..." - iterative_coupling_pism_ocean_prepare_ocean_icebergmodel_forcing - return - fi - - # - # ==> if [[ $ICE_TO_FESOM -ge 1 ]]; then - # - # ice2fesom - # 4) Remap/Regrid to FESOM grid - # 5) FESOM Names - # - CHUNK_DATE_TAG_awicm="${CHUNK_START_DATE_awicm}-${CHUNK_END_DATE_awicm}" - - INTERPOL_TYPE_OCE=${INTERPOL_TYPE_OCE:-"dis"} #Standard=dis : "bil" "con" "dis" "nn" - - WEIGHTS_ICE2OCE=${WEIGHTS_ICE2OCE:-weights_ice2oce.${INTERPOL_TYPE_OCE}.nc} - GRIDDES_OCE=${GRIDDES_OCE:-ocean.griddes} - OCEAN_PISM_FORCING_FILE="pism_forcing4ocean_verXXXX.${INTERPOL_TYPE_OCE}.${CHUNK_DATE_TAG_awicm}.nc" - COMBINED_OUTPUT=ice_file_at_ocean.combined.nc - - - iterative_coupling_ice_fesom1x_write_names - - read_names ice fesom - save_griddes ocean - - NOCOLOR='\033[0m' - GREEN='\033[32m' - - echo "Grid method (ocean) : ${iter_coup_regrid_method_ice2oce}" - echo -e " --> Grid method >>> ${GREEN}${iter_coup_regrid_method_ice2oce}${NOCOLOR} <<< ocean" - case $iter_coup_regrid_method_ice2oce in - "INTERPOLATE"|"REMAP") - iterative_coupling_ice_ocean_regrid_interpolate - ;; - "EXTRAPOLATE") - iterative_coupling_ice_ocean_regrid_interpolate - iterative_coupling_ice_ocean_regrid_extrapolate - ;; - "NONE") - # Ocean and ice sheet grid are identical !! - INTERPOL_TYPE_OCE=none - iterative_coupling_ice_ocean_regrid_none - ;; - *) - echo " UNKNOWN regrid method selected!" - echo " Known: INTERPOLATE = REMAP, EXTRAPOLATE, NONE" - echo " S T O P 2" - exit 2 - esac - - for file in ${cleanup_list} ; do test -f $file && rm $file ; done - unset cleanup_list file - unset NOCOLOR GREEN - - echo " ...done." -} - - - -function iterative_coupling_ice_fesom1x_write_names { - echo "Writing fesom1x input names and units for use with generic ocean_file_for_ice.nc" - :> ice_names_for_fesom.dat - - # - # FESOM names - # - echo ""; echo " * freshwater flux" - echo "fesom_name_freshwater_flux=wnet" >> ice_names_for_fesom.dat - echo "fesom_units_freshwater_flux=W/m2" >> ice_names_for_fesom.dat - - echo ""; echo " * heat flux" - echo "fesom_name_heat_flux=qnet" >> ice_names_for_fesom.dat - #echo "fesom_units_heat_flux=kg/m2/s" >> ice_names_for_fesom.dat - echo "fesom_units_heat_flux=m" >> ice_names_for_fesom.dat - - echo ""; echo " * basal ice shelf temperature gradient" - echo "fesom_name_temperature_gradient=dTdz" >> ice_names_for_fesom.dat - echo "fesom_unit_temperature_gradient=K/m" >> ice_names_for_fesom.dat - - echo ""; echo " * landmask" - echo "fesom_name_landmask=mask" >> ice_names_for_fesom.dat - echo "fesom_units_landmask=1" >> ice_names_for_fesom.dat - - echo ""; echo " * oceanmask" - echo "fesom_name_oceanmask=mask" >> ice_names_for_fesom.dat - echo "fesom_units_oceanmask=1" >> ice_names_for_fesom.dat - - echo ""; echo " * iceshelfmask" - echo "fesom_name_iceshelfmask=mask" >> ice_names_for_fesom.dat - echo "fesom_units_iceshelfmask=1" >> ice_names_for_fesom.dat - - add_to $(pwd)/ice_names_for_fesom.dat ice_names_for_fesom.dat couple - echo " ...done." - -} - -# -# Regrid: Interpolation and extrapolation -# -function iterative_coupling_ice_ocean_regrid_interpolate { - echo " * Interpolate GCM forcing..." - - ierr=20 - for file in ${GRIDDES_OCE:?Missing variable} ${COMBINED_OUTPUT:?Missing variable} ; do - ierr=$(( ierr + 1 )) - test_file_or_exit $file $ierr #ierr=++20 - done - - build_weights4remap \ - ${COMBINED_OUTPUT:?Missing variable} \ - ${GRIDDES_OCE:?Missing variable} \ - ${WEIGHTS_ICE2OCE:?Missing variable} \ - ${INTERPOL_TYPE_OCE:?Missing variable} \ - couple - test_file_or_exit $WEIGHTS_ICE2OCE 29 - - echo " => remap,$GRIDDES_OCE,$WEIGHTS_ICE2OCE" - $cdo remap,$GRIDDES_OCE,$WEIGHTS_ICE2OCE \ - ${COMBINED_OUTPUT} \ - ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc - - cleanup_list="${cleanup_list} $(pwd)/${COMBINED_OUTPUT}" -} - - -function iterative_coupling_ice_ocean_regrid_extrapolate { - # - # This has to be called after the interpolation, because after the - # interpolation we have landpoints that does not exist in the - # FESOM ocean grid - regrid_pism_ocean_extrapolate_misstoc=${regrid_pism_ocean_extrapolate_misstoc:-0} - iterative_coupling_pism_ocean_regrid_extra_type=${iterative_coupling_pism_ocean_regrid_extra_type:-setmisstoc} - echo " * Extrapolate GCM forcing with method >>${iterative_coupling_pism_ocean_regrid_extra_type}<< ..." - - _cdo_flag=$( return_allowed_cdo_miss_replace_flags ${iterative_coupling_pism_ocean_regrid_extra_type} ${regrid_pism_ocean_extrapolate_misstoc} ) - - _tmp_file=ice_file_at_ocean.${INTERPOL_TYPE_OCE}_before_extrapolation.nc - mv ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc ${_tmp_file} - - $cdo $_cdo_flag ${_tmp_file} \ - ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc - - echo " ... done" - cleanup_list="${cleanup_list} $(pwd)/${_tmp_file}" - unset _cdo_flag _tmp_file -} - - -function iterative_coupling_ice_ocean_regrid_none { - echo " * Grid-identical GCM forcing (no interpolation)..." - - test_file_or_exit ${COMBINED_OUTPUT} 10 - - mv ${COMBINED_OUTPUT} \ - ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc - - cleanup_list="${cleanup_list} $(pwd)/${COMBINED_OUTPUT}" -} - - -function iterative_coupling_ice_fesom_rename_vars { - echo " * Set final FESOM variable names..." - - test_file_or_exit ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc 11 - - ncrename \ - -v .wnet,${fesom_name_freshwater_flux} \ - -v .qnet,${fesom_name_heat_flux} \ - -v .dTdz,${fesom_name_temperature_gradient} \ - -v .landmask,${fesom_name_landmask} \ - -v .oceanmask,${fesom_name_oceanmask} \ - -v .iceshelfmask,${fesom_name_iceshelfmask} \ - ice_file_at_ocean.${INTERPOL_TYPE_OCE}.nc \ - ${OCEAN_PISM_FORCING_FILE} - - cleanup_list="${cleanup_list} $(pwd)/ice_file_for_ocean.${INTERPOL_TYPE_OCE}.nc" -} - -######################################################################## -######################################################################## -# Lars Ackermann 07.09.2020 -######################################################################## -function iterative_coupling_pism_ocean_prepare_ocean_icebergmodel_forcing { - # iceberg coupling LA - #latest_pism_output=${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${YR0_pism}${M0_pism}${D0_pism}-${END_YEAR_pism}${END_MONTH_pism}${END_DAY_pism}.nc - - counter=0 - COUNT_MAX=12 - while [ ${counter} -lt ${COUNT_MAX} ] - do - echo " * inside while loop " - if [ -f ${COUPLE_DIR}/../outdata/pism/latest_ex_file_pism.nc ]; then - break - fi - - echo; echo " * File ${COUPLE_DIR}/../outdata/pism/latest_ex_file_pism.nc not found. Waiting for 10 seconds ..." - sleep 10 - counter=$((counter+1)) - done - - latest_pism_output=${COUPLE_DIR}/../outdata/pism//latest_ex_file_pism.nc - if [[ -f ${latest_pism_output} ]]; then - pism_discharge_file=${COUPLE_DIR}/../outdata/pism/latest_ex_file_pism.nc - #pism_discharge_file=${latest_pism_output} - elif [[ -f ${SPINUP_FILE_pism} ]]; then - pism_discharge_file=${SPINUP_FILE_pism} - fi - - echo "CHUNK_SIZE_pism_standalone: ${CHUNK_SIZE_pism_standalone}" - echo "COUPLE_DIR: ${COUPLE_DIR}" - echo "PISM_DISCHARGE_FILE: ${pism_discharge_file}" - - cdo -s -timmean -selname,tendency_of_ice_amount_due_to_discharge \ - -setgrid,${COUPLE_DIR}/ice.griddes ${pism_discharge_file} ${COUPLE_DIR}/latest_discharge.nc - - use_icesheet_coupling=1 -} - -############################################################################ -############################################################################ - - -# -- last line diff --git a/couplings/fesom/env_fesom.py b/couplings/fesom/env_fesom.py deleted file mode 100644 index 0f62376b7..000000000 --- a/couplings/fesom/env_fesom.py +++ /dev/null @@ -1,57 +0,0 @@ -def prepare_environment(config): - environment_dict = { - "ICE_TO_FESOM": int(config["fesom"].get("use_icebergs", False).__bool__()), - "FESOM_TO_ICE": int(config["general"]["first_run_in_chunk"]), - "MESH_DIR_fesom": config["fesom"]["mesh_dir"], - "MESH_ROTATED_fesom": config["fesom"]["mesh_rotated"], - "DATA_DIR_fesom": config["fesom"]["experiment_outdata_dir"], - "COUPLE_DIR": config["general"]["experiment_couple_dir"], - "number_of_years_for_forcing": config["model1"]["chunk_size"], - "CHUNK_SIZE_pism_standalone": config["model2"]["chunk_size"], - "CHUNK_START_DATE_fesom": config["general"]["chunk_start_date"], - "CHUNK_END_DATE_fesom": config["general"]["chunk_end_date"], - "FUNCTION_PATH": config["fesom"]["workflow"]["subjobs"]["couple_in"]["script_dir"], - "PYFESOM_PATH": "/pf/a/a270124/pyfesom2/", - "EXP_ID": config["general"]["command_line_config"]["expid"], - "iter_coup_regrid_method_ice2oce": "INTERPOLATE", - #"BASIN_FILE": config["fesom"].get("basin_file"), - "MACHINE": config["computer"]["name"], - "ICEBERG_DIR": config["fesom"].get("iceberg_dir", ""), - - #"FESOM_GRID_input": config["fesom"]["grid_input"], - #"solidearth_ice_thickness_file":( - # config["general"]["experiment_couple_dir"] + - # "/ice_thickness.nc" - # ), - #"ADD_UNCHANGED_ICE": config["vilma"].get("add_unchanged_ice", False), - #"EISLASTFILE_vilma": ( - # config["vilma"]["experiment_input_dir"] + - # "/" + - # config["vilma"]["eislastfile"] - # ), - #"RUN_NUMBER_vilma": config["general"]["run_number"], - #"RUN_DATE_STAMP": config["general"]["run_datestamp"], - #"LAST_RUN_DATE_STAMP": config["general"]["last_run_datestamp"], - #"INITIAL_YEAR_vilma": config["general"]["initial_date"].syear, - #"NYEAR_vilma_standalone": config["general"]["nyear"], - #"FINAL_YEAR_vilma": config["general"]["final_date"].syear, - #"EISLASTCONF_vilma":( - # config["vilma"]["experiment_config_dir"] + - # "/inp/" + - # config["vilma"]["eislastconf"] - # ) - - } - - #if environment_dict["ADD_UNCHANGED_ICE"] == False: - # environment_dict["ADD_UNCHANGED_ICE"] = 0 - #elif environment_dict["ADD_UNCHANGED_ICE"] == True: - # environment_dict["ADD_UNCHANGED_ICE"] = 1 - - - print(environment_dict) - return environment_dict - - - - diff --git a/couplings/general/coupling_general.functions b/couplings/general/coupling_general.functions deleted file mode 100644 index 4818a2e42..000000000 --- a/couplings/general/coupling_general.functions +++ /dev/null @@ -1,447 +0,0 @@ -#!/usr/bin/ksh - -module load nco -. ${FUNCTION_PATH}/../general/general_lists.functions - -cdo=cdo - -function read_names { - model_from=$1 - model_to=$2 - echo "*** COUPLE_DIR = ${COUPLE_DIR} ***" - if [ -f ${COUPLE_DIR}/${model_from}_names_for_${model_to}.dat ]; then - namefile=${COUPLE_DIR}/${model_from}_names_for_${model_to}.dat - elif [ -f ${model_from}_names_for_${model_to}.dat ]; then - namefile=${model_from}_names_for_${model_to}.dat - else - echo "Could not find ${COUPLE_DIR}/${model_from}_names_for_${model_to}.dat" - exit 42 - fi - echo; echo -e "\t\t* Reading ${model_from} variable names for ${model_to}" - source ${namefile} -} - -function test_file_or_exit { - # Checks if the file exists and exit if file is missing - # Call: test_file_or_exit FILENAME (ExitCode) - # Christian Rodehacke, AWI, 2018-09-04 - __file=$1 - __error_code=$2 - if [ ! -f ${__file:-/DiesenFileNamenSeheIchSehrSelten_Oder_Fragezeichen} ] ; then - echo " Missing file >>${__file}<< in $(pwd)" - echo " S T O P ${__error_code:-998}" - exit ${__error_code:-998} - fi - - unset __file __error_code -} - -# ---------------------------------------------------------- -# -# CDO (Climate Data Operator) specific functions -# -function build_grid_des { - # Build grid description file (cdo griddes) for provided - # input or use existing older file if both are identical - # Call: build_grid_des InputData, GridDesFileName (TargetDir) (RestartDir) (Var2SelectGrid) - # Christian Rodehacke, AWI, 2018-10-15 - _source_file=$1 - _griddes_file=$2 - _target_dir=$3 - _restart_dir=$4 - _var2grid=$5 - - test_file_or_exit $_source_file - if [ "x${_var2grid}" != "x" ] ; then - $cdo -s griddes -selvar,${_var2grid} $_source_file > $_griddes_file - else - $cdo -s griddes $_source_file > $_griddes_file - fi - - _restart_griddes_file=${_restart_dir}/$_griddes_file - - _new_grid_flag=1 - if [ -f $_restart_griddes_file ] ; then - if [ "x$(diff $griddes_file $_restart_griddes_file)" == "x" ] ; then - # Identical grid description - _new_grid_flag=0 - fi - fi - - if [ "x${_target_dir}" != "x" ] ; then - if [ $_new_grid_flag -ge 1 ] ; then - add_to $(pwd)/$griddes_file $_griddes_file $_target_dir - else - add_to $_restart_dir/$_griddes_file $_griddes_file $_target_dir - fi - fi - - unset _griddes_file _restart_dir _restart_griddes_file _source_file _target_dir - return ${_new_grid_flag} -} - - -function build_weights4remap { - # Build remapping weights (cdo griddes) for provided input - # or use existing restart weights of it exists - # Call: build_grid_des InputData, GridDesFileName WeightFileName RemapType (TargetDir) (RestartDir) (VariableSelection) - # Christian Rodehacke, 2018-09-05 - _source_file=$1 - _griddes_file=$2 - _weight_file=$3 - _remap_type=$4 - _target_dir=$5 - _restart_dir=$6 - _selvar2regrid=$7 - - _restart_weight_file=${_restart_dir}/$_weight_file - - if [ -f $_restart_weight_file ] ; then - echo " - Reuse restart weight file $_restart_weight_file" - use_weight_file=$_restart_weight_file - else - echo " - Compute new weight file >>${_weight_file}<< based on >>${_source_file}<<" - test_file_or_exit $_source_file - test_file_or_exit $_griddes_file - - check_allowed_cdo_remap_flag ${_remap_type} - - if [ "x${vars2regrid}" == "x" ] ; then - $cdo -s gen${_remap_type},${_griddes_file} \ - -seltimestep,1 $_source_file \ - $_weight_file - else - $cdo -s gen${_remap_type},${_griddes_file} \ - -selvar,${_selvar2regrid} -seltimestep,1 $_source_file \ - $_weight_file - fi - use_weight_file=$(pwd)/$_weight_file - - if [ "x${_restart_dir}" != "x" ] ; then - add_to $use_weight_file $_weight_file $(basename ${_restart_dir}) - fi - fi - - if [ "x${_target_dir}" != "x" ] ; then - add_to $use_weight_file $_weight_file $_target_dir - fi - - unset _griddes_file _restart_dir _remap_type _restart_weight_file - unset _selvar2regrid _source_file _target_dir use_weight_file _weight_file -} - - -function check_allowed_cdo_remap_flag { - # Check allowed remapping type flags in the frame work - # of the here used script environment - # Call: check_allowed_cdo_remap_flag RemapType - # Christian Rodehacke, 2018-09-05 - __remap_type=$1 - case ${__remap_type} in - bil) - echo " - Remapping ${__remap_type} : bilinear (for curvelinear grid)" - ;; - bic) - echo " - Remapping ${__remap_type} : bicubic (for curvelinear grid)" - ;; - nn) - echo " - Remapping ${__remap_type} : nearest neighbor (any grid)" - ;; - dis) - echo " - Remapping ${__remap_type} : distance-weighted average (any grid)" - ;; - con) - echo " - Remapping ${__remap_type} : First order conservative (requires corner points)" - ;; - ycon) - echo " - Remapping ${__remap_type} : First order conservative, YAC (requires corner points)" - ;; - con2) - echo " - Remapping ${__remap_type} : Second order conservative (requires corner points)" - ;; - laf) - echo " - Remapping ${__remap_type} : largest area fraction (for spherical grid)" - ;; - *) - echo " UNKNOWN remapping <<${__remap_type}>>" - echo " Known: bil, bic, nn, dis, con, ycon, con2, laf" - echo " S T O P 1" - exit 1 - ;; - esac - unset __remap_type -} - - -function return_allowed_cdo_miss_replace_flags { - # Determine allowd filling missing values flags - # Call: return_allowed_cdo_miss_replace_flags ReplaceType - # Christian Rodehacke, 2018-09-10 - - _fill_type=$1 - _regrid_extra_misstoc=$2 - - case ${_fill_type} in - setmisstoc) - # missing to constant value - #echo " - Set miss to constant ${_regrid_extra_misstoc:-0} (any grid)" - _cdo_flag=${_fill_type},${_regrid_extra_misstoc:-0} - ;; - fillmiss2) - #echo " - Fillmiss2 (any grid)" - # cdo "strip"-like filling - _cdo_flag=${_fill_type} - ;; - setmisstodis) - # distance - #echo " - distance-weighted average values (any grid)" - _cdo_flag=${_fill_type} - ;; - setmisstonn) - # neigherst neigbour - #echo " - nearest neighbor values (any grid)" - _cdo_flag=${_fill_type} - ;; - *) - echo " UNKNOWN extrapolation type <<${_fill_type}>>" - echo " Known: setmisstoc, fillmiss2, setmisstodis, setmisstonn" - echo " S T O P 2" - exit 2 - ;; - esac - - echo "${_cdo_flag[@]}" -} - -# ---------------------------------------------------------- -# -# PISM specific functions -# - -function pism_coupler_to_esm_runsscripts_syntax { - # Transform PISM command line coupler options into esm-runscript syntax - # Call: pism_coupler_to_esm_runsscripts_syntax "-ocean given" - # Christian Rodehacke, 2018-09-17 - - echo "pism_set_coupler__$(echo $* | tr -s '-' '_' | tr -s ' ' '=' )" -} - -function pism_forcing_to_esm_runsscripts_syntax { - # Transform PISM command line forcing file options into esm-runscript syntax - # Call: pism_forcing_to_esm_runsscripts_syntax "-ocean given" - # Christian Rodehacke, 2018-09-17 - _arg1=$(echo $1 | sed s/_file//g | tr -s '-' '_') - _arg2=$2 - - echo "pism_set_forcing_file__$(echo $_arg1 $_arg2 | tr -s ' ' '=')" - unset _arg1 _arg2 -} - - - - - -function get_units4pism_version { - # Resolve the units for provided variables and PISM version - # Call: get_units4pism_version VariableName PISMVersionString - # Christian Rodehacke, 2018-09-10 - - # NOTE: Please keep alphabetic order of variable names in each - # section. This helps maintaining this function - - __varname=$1 - __ver_pism_string=$2 - - __units="IDoNotKnowThisDummyUnit" - - case ${__ver_pism_string:--0.1} in - "0.0") - # TEMPLATE - case ${__varname} in - # - # Atmosphere/Surface forcing related variables - # - - # - # Ocean forcing related variables - # - - # - # Miscellaneous - # - topg) - __units="meter" - ;; - # - # UKNOWN - # - *) - echo "NOT DEFINED VARIABLE >${__varname}< for PISM version >${__ver_pism_string}<" - echo " You may have changed the pism version, which requires different variables and units" - echo "Please adjust function >get_units4pism_version<" - echo " S T O P 999" - exit 999 - ;; - esac - ;; - - "0.7") - case ${__varname} in - # - # Atmosphere/Surface forcing related variables - # - air_temp) - __units="Kelvin" - ;; - air_temp_std) - __units="Kelvin" - ;; - climatic_mass_balance) - __units="kg m-2 s-1" - ;; - ice_surface_temperature) - __units="Kelvin" - ;; - precipitation) - #__units="mm day-1" #Ice equivalent - __units="m second-1" #Ice equivalent - ;; - #snow_depth) - # __units="" - # ;; - surface_altitude) - __units="meter" - ;; - # - # Ocean forcing related variables - # - salinity_ocean) - __units="g kg-1" - ;; - shelfbmassflux) - __units="kg m-2 s-1" - ;; - shelfbtemp) - __units="degC" - ;; - theta_ocean) - __units="degC" - ;; - theta_ocean_ref) - __units="degC" - ;; - # - # Miscellaneous - # - topg) - __units="meter" - ;; - # - # UKNOWN - # - *) - echo "NOT DEFINED VARIABLE >${__varname}< for PISM version >${__ver_pism_string}<" - echo " You may have changed the pism version, which requires different variables and units" - echo "Please adjust function >get_units4pism_version<" - echo " S T O P 10" - exit 10 - ;; - esac - ;; - "1.0" | "1.1" | "1.2") - case ${__varname} in - # - # Atmosphere/Surface forcing related variables - # - air_temp) - __units="Kelvin" - ;; - air_temp_std) - __units="Kelvin" - ;; - climatic_mass_balance) - __units="kg m-2 s-1" - ;; - ice_surface_temperature) - __units="Kelvin" - ;; - precipitation) - __units="kg m-2 second-1" - ;; - # - # Ocean forcing related variables - # - salinity_ocean) - __units="g kg-1" - ;; - shelfbmassflux) - __units="kg m-2 s-1" - ;; - shelfbtemp) - __units="degC" - ;; - theta_ocean) - __units="degC" - ;; - theta_ocean_ref) - __units="degC" - ;; - # - # Miscellaneous - # - topg) - __units="meter" - ;; - # - # UKNOWN - # - *) - echo "NOT DEFINED VARIABLE >${__varname}< for PISM version >${__ver_pism_string}<" - echo " You may have changed the pism version, which requires different variables and units" - echo "Please adjust function >get_units4pism_version<" - echo " S T O P 11" - exit 11 - ;; - esac - ;; - *) - echo "NOT DEFINED PISM version >${__ver_pism_string}<" - echo "Please adjust function >get_units4pism_version<" - echo " S T O P 99" - exit 99 - ;; - esac - - echo "${__units[@]}" - - unset __units __varname __ver_pism_string -} - -function iterative_coupling_pism_regrid_add_xy_array { - _file_name_add_xy=$1 - _model=${2:-"generic"} - - echo; echo -e "\t\t* x- and y-array to 'pism' ${_model} forcing file >>${_file_name_add_xy}<<" - - test_file_or_exit $_file_name_add_xy 10 - - if [ 1 -eq 0 ] ; then - # Problems with float vs double: does not work as expected when using directly: "ncks -A .." - PISM_GRID_XY_FILE=${POOL_DIR_pism}/grids/${DOMAIN_pism}/pismr_${DOMAIN_pism}_${RES_pism}_xy.nc - else - # This is the standard case: generate both float and double files, just in case something strange happens - INITIAL_FILE_pism=${POOL_DIR_pism}/grids/${DOMAIN_pism}/pismr_${DOMAIN_pism}_${RES_pism}_xy.nc - PISM_GRID_xy_file_double=${PISM_GRID_xy_file_double:-xy_file_double.$(basename ${INITIAL_FILE_pism})} - PISM_GRID_xy_file_float=${PISM_GRID_xy_file_float:-xy_file_float.$(basename ${INITIAL_FILE_pism})} - pism_helpers_create_xy_axis ${INITIAL_FILE_pism} ${PISM_GRID_xy_file_double} ${PISM_GRID_xy_file_float} - - PISM_GRID_XY_FILE=${PISM_GRID_xy_file_double} - fi - - test_file_or_exit $PISM_GRID_XY_FILE 11 - - ncrename -v .x,x_org_$$ -v .y,y_org_$$ $_file_name_add_xy && \ - ncks -A -v x,y $PISM_GRID_XY_FILE $_file_name_add_xy - - unset _file_name_add_xy _model -} diff --git a/couplings/general/general_helpers.functions b/couplings/general/general_helpers.functions deleted file mode 100644 index a1441ba5a..000000000 --- a/couplings/general/general_helpers.functions +++ /dev/null @@ -1,478 +0,0 @@ -#!/usr/bin/ksh - - -mecho() -{ - mecho_level=${mecho_level:-1} - this_level=0 - mecho_string="" - if [[ x"${verbose}" = x1 ]] - then - while (( $this_level < $mecho_level )) - do - mecho_string="---"${mecho_string} - this_level=$((this_level + 1)) - done - echo "${mecho_string}> $@" >> $dumpfile - fi - unset mecho_string this_level -} - -becho() -{ - echo " $@" - mecho " $@" -} - -bline() -{ - becho "==================================================================" -} - - -line() -{ - echo " ==================================================================" -} - - -headline() -{ - echo; echo - echo " ${1}..." - line -} - -bheadline() -{ - becho; becho - becho " ${1}..." - bline -} - - -output_changed_vars() -{ - changedvars=`comm -13 <(sort < $DUMP_DIR/oldvars_${ID}_${mecho_level}_$1.txt) <(sort < $DUMP_DIR/newvars_${ID}_${mecho_level}_$1.txt) \ - | sed '/LINENO/d' \ - | sed '/SECONDS/d' \ - | sed '/RANDOM=/d' ` - printf '%s\n' "$changedvars" | while IFS= read -r line - do - mecho "$line" - done - unset line changedvars -} - -run_formatted() -{ - mecho_level=$((mecho_level + 1)) - ID=${JOB_ID:-$$} - #DUMP_DIR=$WORKING_DIR - $set > $DUMP_DIR/oldvars_${ID}_${mecho_level}_$1.txt - eval $@ - $set > $DUMP_DIR/newvars_${ID}_${mecho_level}_$1.txt - output_changed_vars $1 - rm $DUMP_DIR/oldvars_${ID}_${mecho_level}_$1.txt $DUMP_DIR/newvars_${ID}_${mecho_level}_$1.txt - mecho_level=$((mecho_level - 1)) -} - -call_or_exit() -{ - function_exists_or_exit $1 - run_formatted $@ -} - -var_set() -{ - varname=$1 - re='^[0-9]+$' - - eval $varname=\${${varname}:-ERR} - eval varvalue=\$${varname} - - if [[ "x${varvalue}" = "xERR" ]] - then - echo "0" - else - echo "1" - fi - unset varname varvalue re -} - - - -cond_merge() -{ - if [[ -e $2 ]]; then - echo "about to merge $1 and $2" - cdo merge $1 $2 tempout_cond_merge; mv tempout_cond_merge $2; rm $1 - echo "done" - else - mv $1 $2 - fi -} - - - -test_if_set() -{ - varname=$1 - re='^[0-9]+$' - - eval $varname=\${${varname}:-ERR} - eval varvalue=\$${varname} - - if [[ "x${varvalue}" = "xERR" ]] - then - echo "${varname} not set!" - exit 42 - fi - unset varname varvalue re -} - -test_if_number() -{ - varname=$1 - re='^[0-9]+$' - - eval varvalue=\$${varname} - - if [[ ! ${varvalue} =~ $re ]] - then - echo "${varname} not a number!" - exit 42 - fi - unset varname varvalue re -} - -test_if_set_and_number() -{ - test_if_set $1 - test_if_number $1 -} - -function_exists_or_exit() -{ - if ! [[ "`type $1 2>/dev/null`" ]] - then - echo Function $1 not found. - exit 1 - fi -} - -call_if_exists() -{ - if [[ "`type $1 2>/dev/null`" ]] - then - if ! [[ "${@#*pass_down}" = $@ ]]; then - mecho Calling $@... - fi - run_formatted $@ - fi -} - -calc_date() -{ - typeset command="$1" - shift - command calc_date $command -c 1 "$@" - unset command -} - -get_file_names() -{ - typeset pattern="$1" - shift - echo $(printf " $pattern" "$@") - unset pattern -} - -time_merge() -{ - typeset out="$1" - typeset tmp=$(dirname $out)/.$(basename $out) - shift - cat "$@" > $tmp && mv $tmp $out - unset out tmp -} - - - -pass_down_vars() -{ - searchname=$1 - replacename=$2 - mecho Passing down vars from $1 to $2: - list_of_all_vars=`set | awk -v pat="${searchname}\$" ' BEGIN { FS = "=" } ; $1 ~ pat {print $1}'` - for variable in $list_of_all_vars - do - newvar=`echo $variable | sed s/${searchname}/${replacename}/` - eval testvar=\${${newvar}:-ERR} - if [[ "x${testvar}" = "xERR" ]] - then - eval ${newvar}=\$${variable} - fi - done - unset list_of_all_vars replacename searchname newvar testvar variable -} - - -general_execute() -{ - call_if_exists general_$1 - - call_if_exists ${setup_name}_user_$1 - call_if_exists ${setup_name}_$1 - call_if_exists ${setup_name}_USER_$1 - call_if_exists ${setup_name}_pass_down - - for model in $coupled_setup_component_list - do - call_if_exists ${model}_user_$1 - call_if_exists ${model}_$1 - call_if_exists ${model}_USER_$1 - call_if_exists ${model}_pass_down - done -} - - -double_loop() { - - nolastbit=0 - critsize=10000 - verbose=0 # [0,1,2]; only debuggin; must equal 0 for model run - - template=$1 - if [[ "x$verbose" == "x1" ]]; then - echo "template=$template" - fi - len_temp=`printf '%s' "$template" | awk '{ print length($0) }'` - if [[ $verbose = 1 ]]; then - echo "len_temp=$len_temp" - fi - - location1=`awk -v a="${template}" -v b="SUBSTREAM1" 'BEGIN{print index(a,b)}'` - location2=`awk -v a="${template}" -v b="SUBSTREAM2" 'BEGIN{print index(a,b)}'` - if [[ $verbose = 1 ]]; then - echo "location1=$location1" - fi - if [[ $verbose = 1 ]]; then - echo "location2=$location2" - fi - - if [[ $location1 -lt $location2 ]]; then - loc1=$location1 - loc2=$location2 - else - loc1=$location2 - loc2=$location1 - fi - if [[ $verbose = 1 ]]; then - echo "loc1=$loc1" - fi - if [[ $verbose = 1 ]]; then - echo "loc2=$loc2" - fi - - start_pre=0 - len_pre=$(( loc1 - 1 )) - if [[ $verbose = 1 ]]; then - echo "len_pre=$len_pre" - fi - prefix=`printf '%s' "$template" | awk -v start="$start_pre" -v len="$len_pre" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "prefix=$prefix" - fi - - start_mid=$(( loc1 + 10 )) - if [[ $verbose = 1 ]]; then - echo "start_mid=$start_mid" - fi - len_mid=$(( loc2 - start_mid )) - if [[ $verbose = 1 ]]; then - echo "len_mid=$len_mid" - fi - middle=`printf '%s' "$template" | awk -v start="$start_mid" -v len="$len_mid" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "middle=$middle" - fi - - start_end=$((loc2 + 10)) - if [[ $verbose = 1 ]]; then - echo "start_end=$start_end" - fi - len_end=$((len_temp - start_end + 1)) - if [[ $verbose = 1 ]]; then - echo "len_end=$len_end" - fi - lastbit=`printf '%s' "$template" | awk -v start="$start_end" -v len="$len_end" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "lastbit=$lastbit" - fi - if [[ "x${lastbit}" == "x" ]]; then - nolastbit=1 - fi - if [[ $verbose = 1 ]]; then - echo "nolastbit=$nolastbit" - fi - - substreams1=""; substreams2=""; list_of_files="" - firstline=1 - - searchtemplate="`echo $template | sed 's/SUBSTREAM1/*/' | sed 's/SUBSTREAM2/*/' `" - if [[ $verbose = 1 ]]; then - echo "searchtemplate=$searchtemplate" - $(ls $searchtemplate) - fi - if files=$(ls $searchtemplate 2>/dev/null); then - for file in $files; do - if [[ $verbose = 1 ]]; then - echo "file =$file" - fi - len_file=`printf '%s' "$file" | awk '{ print length($0) }'` - if [[ $verbose = 1 ]]; then - echo "len_file=$len_file" - fi - - file_tmp=${file:$len_pre:$len_file} - if [[ $verbose = 1 ]]; then - echo "file_tmp=$file_tmp" - fi - start_mid=`awk -v a="$file_tmp" -v b="${middle}" 'BEGIN{print index(a,b)}'` - if [[ $verbose = 1 ]]; then - echo "start_mid=$start_mid" - fi - start_mid=$(( start_mid + len_pre )) - if [[ $verbose = 1 ]]; then - echo "start_mid=$start_mid" - fi - if [[ "${nolastbit}" == 0 ]]; then - start_end=`awk -v a="$file" -v b="${lastbit}" 'BEGIN{print index(a,b)}'` - else - start_end=$(( len_file + 1 )) - fi - if [[ $verbose = 1 ]]; then - echo "start_end=$start_end" - fi - - sub1_start=$loc1 - if [[ $verbose = 1 ]]; then - echo "sub1_start=$sub1_start" - fi - sub1_len=$(( start_mid - sub1_start )) - if [[ $verbose = 1 ]]; then - echo "sub1_len=$sub1_len" - fi - sub1=`printf '%s' "$file" | awk -v start="${sub1_start}" -v len="${sub1_len}" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "sub1=$sub1" - fi - - sub2_start=$((start_mid + len_mid )) - if [[ $verbose = 1 ]]; then - echo "sub2_start=$sub2_start" - fi - sub2_len=$((start_end - sub2_start)) - if [[ $verbose = 1 ]]; then - echo "sub2_len=$sub2_len" - fi - sub2=`printf '%s' "$file" | awk -v start="${sub2_start}" -v len="${sub2_len}" '{print substr ($0, start, len)}'` - if [[ $verbose = 1 ]]; then - echo "sub2=$sub2" - fi - - if [[ $location1 -lt $location2 ]]; then - substream1=${sub1} - substream2=${sub2} - else - substream1=${sub2} - substream2=${sub1} - fi - if [[ $verbose = 1 ]]; then - echo "substream1=$substream1" - fi - if [[ $verbose = 1 ]]; then - echo "substream2=$substream2" - fi - - found=0 - for stream in $substreams1; do - if [[ $verbose = 1 ]]; then - echo "prefix=$prefix" - fi - if [[ "x${stream}" = "x${substream1}" ]]; then - found=1 - fi - done - if [[ "x$found" = "x0" ]]; then - substreams1="${substreams1} $substream1" - fi - if [[ $verbose = 1 ]]; then - echo "substreams1=$substreams1" - fi - found=0 - for stream in $substreams2; do - if [[ $verbose = 1 ]]; then - echo "stream=$stream" - fi - if [[ "x${stream}" = "x${substream2}" ]]; then - found=1 - fi - done - if [[ "x$found" = "x0" ]]; then - substreams2="${substreams2} $substream2" - fi - if [[ $verbose = 1 ]]; then - echo "substreams2=$substreams2" - fi - done - - for substream1 in $substreams1; do - if [[ $verbose = 2 ]]; then - echo "substream1=$substream1" - fi - for substream2 in $substreams2; do - if [[ $verbose = 2 ]]; then - echo "substream2=$substream2" - fi - file=`echo $template | sed "s/SUBSTREAM1/${substream1}/" | sed "s/SUBSTREAM2/${substream2}/" ` - if [[ $verbose = 2 ]]; then - echo "file=$file" - fi - if found=$(ls $file 2>/dev/null); then - filesize=$(stat -c%s "$file") - if [[ ("$filesize" > "$critsize") ]]; then - if [[ "x$firstline" = "x1" ]]; then - list_of_files=$(printf "$file $substream1 $substream2") - just_the_files=$(printf "$file") - just_the_substreams1=$(printf "$substream1") - just_the_substreams2=$(printf "$substream2") - firstline=0 - else - list_of_files=$(printf "$list_of_files\n $file $substream1 $substream2") - just_the_files=$(printf "$just_the_files\n $file") - just_the_substreams1=$(printf "$just_the_substreams1\n $substream1") - just_the_substreams2=$(printf "$just_the_substreams1\n $substream2") - fi - fi - fi - done - done - fi - if [[ "${firstline}" = "1" ]]; then - echo "firstline=$firstline exit" - exit 21 - else - printf "$list_of_files" - fi -} - -forall_models_and_filetypes() -{ - for model in ${setup_name} $coupled_setup_component_list; do - for filetype in $autofiletypes; do - call_if_exists $@ $model ${filetype} - done - done -} diff --git a/couplings/general/general_lists.functions b/couplings/general/general_lists.functions deleted file mode 100644 index f6747408e..000000000 --- a/couplings/general/general_lists.functions +++ /dev/null @@ -1,324 +0,0 @@ -#!/bin/ksh -l - - - -assemble_total_list() { - totallistname=$1_TOTAL_$2_FILES - inlistname=$1_$3_$2_FILES - - eval totallist=\$\{${totallistname}\} - eval inlist=\$\{${inlistname}\} - - incounter=1 - for inentry in $inlist; do - case $incounter in - 1) - incounter=2 - infrom=$inentry - ;; - 2) - incounter=3 - totalcounter=1 - into=$inentry - alreadyexists=0 - for totalentry in $totallist; do - case $totalcounter in - 1) - totalcounter=2 - ;; - 2) - totalcounter=3 - if [[ "x${into}" = "x${totalentry}" ]]; then - alreadyexists=1 - break - fi - ;; - 3) totalcounter=1 - ;; - esac - done - ;; - 3) - incounter=1 - inwarning=$inentry - if [[ "x${alreadyexists}" = "x0" ]]; then - if ! [[ "x$3" = "xDEFAULT" ]]; then - echo " $infrom $into $inwarning" - fi - totallist="${totallist} $infrom $into $inwarning" - fi - esac - done - eval ${totallistname}=\"${totallist}\" - - unset $inlistname - unset totallistname inlistname totallist inlist incounter inentry infrom into totalcounter alreadyexists totalentry -} - - - -general_get_file_info() { - echo " ==================================================================" - for model in ${setup_name} $coupled_setup_component_list; do - for filetype in $autofiletypes; do - call_if_exists ${model}_prepare_${filetype} - done - echo " ==================================================================" - done -} - -general_assemble_file_info() { - for model in ${setup_name} $coupled_setup_component_list; do - for filetype in $autofiletypes; do - typeset -u ft_uc; ft_uc=${filetype} - list_of_all_vars=`set | awk -v pat="${model}_.*_${ft_uc}_FILES" ' BEGIN { FS = "=" } ; $1 ~ pat {print $1}'` - default=0 - for var in $list_of_all_vars - do - name=`echo $var | cut -d_ -f2` - case $name in - DEFAULT ) - default=1 - ;; - * ) - echo " Processing user defined file list $var" - call_if_exists assemble_total_list $model ${ft_uc} $name - ;; - esac - done - if [[ "x${default}" = "x1" ]]; then - call_if_exists assemble_total_list $model ${ft_uc} DEFAULT - fi - done - done -} - - -add_to() { - datatype=${3:-${filetype}} - thismodel=${4:-${model}} - withwarning=${5:-warn} - - if [[ "x${datatype}" = "xno_warning" ]]; then - withwarning="no_warning"; datatype=${filetype} - fi - if [[ "x${thismodel}" = "xno_warning" ]]; then - withwarning="no_warning"; thismodel=${model} - fi - - typeset -u dt_uc; dt_uc=${datatype} - from=$1 - to=$2 - listname=${thismodel}_DEFAULT_${dt_uc}_FILES - eval list=\$\{${listname}\} - eval $listname=\"$list $from $to $withwarning\" - - unset list to from datatype dt_uc thismodel listname -} - -add_file() { - add_to $@ -} - -remove_old_setups_and_missings() { - pd_model=$1 - datatype=$2 - typeset -u dt_uc; dt_uc=${datatype} - eval list=\$\{${pd_model}_TOTAL_${dt_uc}_FILES\} - eval destdir=\$\{${dt_uc}_DIR_${pd_model}\} - - eval thisdate=\$\{START_DATE_${pd_model}\} - setupfile=$destdir/${pd_model}_${datatype}_setup_${thisdate}.txt - missingfile=$destdir/${pd_model}_${datatype}_missing_${thisdate}.txt - - if [[ -e $setupfile ]]; then - $rm $setupfile >> $dumpfile - fi - if [[ -e $missingfile ]]; then - $rm $missingfile >> $dumpfile - fi -} - - -general_remove_old_files() { - forall_models_and_filetypes remove_old_setups_and_missings - if [[ -e $totalsetupfile ]]; then - $rm $totalsetupfile >> $dumpfile - fi - if [[ -e $totalmissingfile ]]; then - $rm $totalmissingfile >> $dumpfile - fi - -} - -prepare_data() -{ - pd_model=$1 - datatype=$2 - typeset -u dt_uc; dt_uc=${datatype} - eval list=\$\{${pd_model}_TOTAL_${dt_uc}_FILES\} - eval destdir=\$\{${dt_uc}_DIR_${pd_model}\} - - eval run_number=\$\{RUN_NUMBER_${pd_model}\} - eval thisdate=\$\{START_DATE_${pd_model}\} - eval thisenddate=\$\{END_DATE_${pd_model}\} - copy=1 - create_softlink=0 - - eval lresume=\$\{LRESUME_${pd_model}\} - - if [[ "x${lresume}" = "x0" && "x${dt_uc}" = "xRESTART_IN" ]]; then - echo " Restart files not needed for initial runs for ${pd_model} (LRESUME_${pd_model}=$lresume), skipping..." - else - cp_bckp=${cp} - case $datatype in - init | exe | restart_in ) - if [[ ! "x${run_number}" = "x1" ]]; then - copy=0 - fi - ;; - output | restart_out ) - cp="mv" - create_softlink=1 - ;; - esac - - if [[ "x${before_simulation}" = "x1" ]]; then - setupfile=$destdir/${model}_${datatype}_setup_${thisdate}.txt - else - setupfile=$destdir/${model}_${datatype}_results_${enddate}.txt - fi - missingfile=$destdir/${model}_${datatype}_missing_${thisdate}.txt - - counter=1 - for entry in $list; do - case $counter in - 1) - counter=2 - from=$entry - filename=`basename $from` - ;; - 2) - counter=3 - to=$entry - todir=`dirname $to` - toname=`basename $to` - if ! [[ "x$todir" = "x." ]]; then - mkdir -p ${destdir}/$todir - todir=${todir}/ - else - todir="" - fi - ;; - 3) - counter=1 - warning=$entry - - if [[ "x${copy}" = "x1" ]]; then - if [[ -e $from ]]; then - if [[ ! "x${filename}" = "x${toname}" ]]; then - [[ -e ${destdir}/${to} ]] && rm -rf ${destdir}/${to} - echo "$from -> $to" >> $setupfile - else - echo "$from -> ${todir}$filename" >> $setupfile - fi - [[ -e ${destdir}/${todir}${filename} ]] && rm -rf ${destdir}/${todir}${filename} - ${cp} ${from} ${destdir}/${todir}${filename} >> $dumpfile - [[ "x${create_softlink}" = "x1" ]] && ln -svf ${destdir}/${todir}${filename} ${from} >> $dumpfile - else - if ! [[ "x${warning}" = "xno_warning" ]]; then - if [[ ! "x${filename}" = "x${toname}" ]]; then - echo "$from -> $to" >> $missingfile - else - echo "$from -> ${todir}$filename" >> $missingfile - fi - fi - fi - if [[ ! "x${filename}" = "x${toname}" ]]; then - ${ln} ${destdir}/${todir}${filename} ${destdir}/${to} 2>/dev/null >> $dumpfile - fi - - fi - esac - done - - if [[ -e $setupfile ]]; then - if [[ "x${before_simulation}" = "x1" ]]; then - echo "SETUP used for $model $datatype for run starting at ${thisdate}:" >> $totalsetupfile - else - echo "RESULTS obtained for $model $datatype for run ending at ${enddate}:" >> $totalsetupfile - fi - cat $setupfile >> $totalsetupfile - echo >> $totalsetupfile - fi - if [[ -e $missingfile ]]; then - echo "WARNING: THESE FILES WERE MISSING for $model $datatype for run starting at ${thisdate}:" >> $totalmissingfile - cat $missingfile >> $totalmissingfile - echo >> $totalmissingfile - fi - cp=$cp_bckp - fi - unset cp_bckp datatype dt_uc list create_softlink from to destdir filename missingfile setupfile entry thisdate - unset pd_model run_number counter -} - - - -prepare_work() -{ - pw_model=$1 - datatype=$2 - typeset -u dt_uc; dt_uc=${datatype} - eval list=\$\{${model}_TOTAL_${dt_uc}_FILES\} - eval destdir=\$\{${dt_uc}_DIR_${model}\} - eval lresume=\$\{LRESUME_${pw_model}\} - counter=1 - for entry in $list; do - case $counter in - 1) - counter=2 - ;; - 2) - counter=3 - to=$entry - todir=`dirname $to` - toname=`basename $to` - if ! [[ "x$todir" = "x." ]]; then - mkdir -p ${WORK_DIR}/$todir - todir=${todir}/ - else - todir="" - fi - ;; - 3) - counter=1 - case $datatype in - forcing | init | exe | config) - if [[ -e ${destdir}/${to} ]]; then - ${ln} ${destdir}/${to} ${WORK_DIR}/${to} >> $dumpfile - if [[ "x$dt_uc" = "xCONFIG" ]]; then - echo " ${to}:" - echo "===========================================================================================================" - if [[ "x${to##*.}" == "xnc" ]]; then - ncdump -h ${WORK_DIR}/${to}|grep -v "_doc ="|grep -v "_option ="|grep -v "_type ="|grep -v "_choices =" - else - cat ${WORK_DIR}/${to} - fi - echo; echo "===========================================================================================================" - fi - fi - ;; - restart_in) - if [[ "x${lresume}" = "x1" ]]; then - [[ -e ${destdir}/${toname} ]] && ${cp} ${destdir}/${toname} ${WORK_DIR}/${todir}$toname >> $dumpfile - fi - ;; - *) - ;; - esac - esac - done - unset ${model}_TOTAL_${dt_uc}_FILES - unset pw_model datatype dt_uc list to destdir entry counter -} - diff --git a/couplings/general/pism_helpers.functions b/couplings/general/pism_helpers.functions deleted file mode 100644 index d72445922..000000000 --- a/couplings/general/pism_helpers.functions +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/ksh - -pism_helpers_create_xy_axis() { - # Build xy-file from PISM initial file - # If we produce input files for PISM, the horizontal axis have to - # be the dimension/arrays "x" and "y". These shall hold the grid - # dimension as distance and correct meta data. We obtain these - # from a PISM initial/restart file. - # Since using "ncks" to add these with the wrong numerical type - # (eg. float vs double), you could be rediculous wrong - # values. Hence we produce two versions, one with "float" and one - # with "double" arrays. - # Call: pism_helpers_create_xy_axis PISMInitFile (XY_FileName_double) (XY_FileName_float) (RestartDir) - # Christian Rodehacke, AWI, 2018-09-20 - _pism_init_file=$1 - _xy_file_double=$2 - _xy_file_float=$3 - _restart_dir=$4 - - test_file_or_exit $_pism_init_file 11 - - _xy_double=${_xy_file_double:-xy_file_double.$(basename $_pism_init_file)} - _xy_float=${_xy_file_float:-xy_file_float.$(basename $_pism_init_file)} - - if [ "x${_restart_dir}" != "x" ] ; then - _xy_restart_double=${_restart_dir:-.}/${_xy_double} - _xy_restart_float=${_restart_dir:-.}/${_xy_float} - else - _xy_restart_double=${_xy_double} - _xy_restart_float=${_xy_float} - fi - - echo " - xy-files: " - echo " double >${_xy_double}<" - echo " float >${_xy_float}< " - echo " extracted from >>${_pism_init_file}<<" - - _flag_compute_xy=0 - _flag_new_double_file=0 - _flag_new_float_file=0 - # If any of the wanted or restart files is missing, we set the flag - for _file in $_xy_double $_xy_float $_xy_restart_double $_xy_restart_float ; do - test ! -f $_file && _flag_compute_xy=$(( _flag_compute_xy + 1 )) - done - - if [ $_flag_compute_xy -gt 0 ] ; then - if [ ! -f ${_xy_double} ] ; then - if [ "x${_restart_dir}" != "x" ] ; then - # If Restart exists, use it - if [ -f ${_xy_restart_double} ] ; then - cp ${_xy_restart_double} ${_xy_double} - fi - fi - if [ ! -f ${_xy_double} ] ; then - # xy-file still not present: build it - #ncks -v x,y,.mapping ${_pism_init_file} ${_xy_double} && \ - echo "_pism_init_file = ${_pism_init_file}" - echo "_xy_double = ${_xy_double}" - ncks -v x,y ${_pism_init_file} ${_xy_double} && \ - ncatted \ - -a standard_name,x,c,c,"projection_x_coordinate" \ - -a standard_name,y,c,c,"projection_y_coordinate" \ - -a units,x,c,c,"m" -a axis,x,c,c,"X" \ - -a units,y,c,c,"m" -a axis,y,c,c,"Y" \ - ${_xy_double} - _flag_new_double_file=1 - fi - fi - - if [ ! -f ${_xy_float} ] ; then - if [ "x${_restart_dir}" != "x" ] ; then - # If Restart exists, use it - if [ -f ${_xy_restart_float} ] ; then - cp ${_xy_restart_float} ${_xy_float} - fi - fi - if [ ! -f ${_xy_float} ] ; then - # xy-file still not present: build it - ncdump ${_xy_double} | sed 's/double /float /g' | ncgen -o ${_xy_float} - #ncatted \ - # -a standard_name,x,c,c,"projection_x_coordinate" \ - # -a standard_name,y,c,c,"projection_y_coordinate" \ - # -a units,x,c,c,"m" -a axis,x,c,c,"X" \ - # -a units,y,c,c,"m" -a axis,y,c,c,"Y" \ - # ${_xy_float} - fi - fi - fi - - if [ "x${_restart_dir}" != "x" ] ; then - if [ $_flag_new_double_file -ge 1 ] ; then - add_to $(pwd)/$_xy_double $_xy_double $_restart_dir - fi - if [ $_flag_new_float_file -ge 1 ] ; then - add_to $(pwd)/$_xy_float $_xy_float $_restart_dir - fi - fi - - unset _pism_init_file _xy_file_double _xy_file_float _restart_dir - unset _flag_compute_xy _flag_new_double_file _flag_new_float_file - unset _file _restart_xy_double _restart_xy_float _xy_double _xy_float -} - -# -- last line diff --git a/couplings/mpiom/coupling_ice2mpiom.functions b/couplings/mpiom/coupling_ice2mpiom.functions deleted file mode 100644 index e69de29bb..000000000 diff --git a/couplings/mpiom/coupling_mpiom2ice.functions b/couplings/mpiom/coupling_mpiom2ice.functions deleted file mode 100644 index e69de29bb..000000000 diff --git a/couplings/pism/coupling_atmosphere2pism.functions b/couplings/pism/coupling_atmosphere2pism.functions deleted file mode 100644 index cc9472549..000000000 --- a/couplings/pism/coupling_atmosphere2pism.functions +++ /dev/null @@ -1,2098 +0,0 @@ -#!/bin/ksh -## @file -## @author Dr. Paul Gierz -## @author Alfred Wegener Institute for Polar and Marine Research -## @author Bremerhaven, Germany -## -## @brief Functions for preparing a generic atmosphere output for use with the `PISM` ice sheet model. -## -## NOTES and TODO for this file: -## * [ ] Unify name structure, it's a bit messy right now. -## * [ ] Unset all local variables to keep the global namespace clean (sort-of done, could be better). -## * [ ] Get the abstraction levels figured out correctly. We really want 1 -## function to do 1 thing (and only 1 thing) - - -################################################################################ -################################################################################ -# T O P L E V E L :: Calls all other functions -################################################################################ -################################################################################ - - -## @fn atmosphere2pism() -## @brief -## The top-level container which is called if the -## logical switch `ACM_TO_PISM=1` is set. -## -## This is the top-level container which is called if the -## logical switch `ACM_TO_PISM` is set. In this case, the -## following steps are performed: -## -## 1. Variable names as provided by the atmosphere model are read, -## so that they may be easily renamed to correct `PISM` names. -## 2. The `PISM` target grid description is generated or copied to -## the working directory. -## 3. atmospheric forcing is regridded from the original source -## grid (defined by `atmosphere.griddes`) to `PISM` model grid -## defined by `ice.griddes`. The regridding occurs based upon -## the value of `iterative_coupling_atmosphere_pism_regrid_method` -## 4. An approriate `PISM` forcing is generated. In this step, -## variables are renamed to conform to `PISM` standards, and a -## file is generated which will pass approrpriate command flags -## to the `PISM` run. -## 5. Temporary files are removed from the working directory. -## -## Variables Used: -## -## @var bool ACM_TO_PISM -## @var ic_atm2pism_regrid_method -## @var ic_atm2pism_ablation_method -## -## Variables Assigned: -## -## @var INTERPOL_TYPE_ATM :: "bil" -## @var WEIGHTS_ATM2ICE :: weights_atm2ice.${INTERPOL_TYPE_ATM}.nc -## @var GRIDDES_ICE :: ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes -## @var GRIDDES_ATM :: -## @var ic_atm2pism_regrid_method :: The method which will be used to get -## from the general atmosphere grid to the `PISM` grid. Default value is -## "INTERPOLATE", which specifies bilinear interpolation. Choices are: -## -## 1. DOWNSCALE: Performs bilinear interpolation and then applies -## lapse-rate and atmospheric desertification corrections -## 2. INTERPOLATE: Just bilinear interpolation -## 3. REMAP: Just conservative remapping -## -## Given a different option, the function will exit -## -## @var ic_atm2pism_ablation_method :: Which method should be used to get -## from atmospheric information to a surface mass balance. Default value is "PDD", -## which prepares files and `PISM` options for a positive-degree day ablation -## scheme. Current choices are: -## -## 1. PDD: Prepares files/flags for the positive degree day scheme -## 2. DEBM: Prepares files/flags for the diurnal energy balance model (see here: REF to Uta) -## 3. EBM: Prepares files/flags for the SEMIC energy balance model (see here: REF Mario) -atmosphere2pism() { - echo -e "\t\t==================================================================" - echo -e "\t\t*** S T A R T I N G atmosphere2pism *** "; echo - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/general_helpers.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - which cdo - echo -e "\t\t---> Preparing to couple generic atmosphere to specific ice sheet model PISM" - ic_atm2pism_prepare - - iterative_coupling_atmosphere_pism_regrid_method=${iterative_coupling_atmosphere_pism_regrid_method:-DOWNSCALE} - bool_atm2pism_regrid_dyn_downscaling=${bool_atm2pism_regrid_dyn_downscaling:-0} - echo -e "\t\t--> Regrid method >>> ${GREEN}${iterative_coupling_atmosphere_pism_regrid_method}${NOCOLOR} <<<" - case $iterative_coupling_atmosphere_pism_regrid_method in - "DYN_DOWNSCALE") - bool_atm2pism_regrid_dyn_downscaling=1 - ic_atm2pism_regrid_dyn_downscale - ;; - "DOWNSCALE") - ic_atm2pism_regrid_downscale - ;; - "INTERPOLATE") - ic_atm2pism_regrid_interpolate - ;; - "REMAP") - ic_atm2pism_regrid_remap - ;; - *) - echo "Unknown regrid method selected!" - echo "Known options: DOWNSCALE, INTERPOLATE, REMAP" - exit 1 - ;; - esac - - iterative_coupling_atmosphere_pism_ablation_method=${iterative_coupling_atmosphere_pism_ablation_method:-PDD} - echo -e "\t\t--> Ablation method >>> ${GREEN}${iterative_coupling_atmosphere_pism_ablation_method}${NOCOLOR} <<<" - case $iterative_coupling_atmosphere_pism_ablation_method in - "PDD") - ic_atm2pism_ablation_pdd - latest_atmo_file=${COUPLE_DIR}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - ;; - "DEBM") - ic_atm2pism_ablation_debm - latest_atmo_file=${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - ;; - "EBM") - ic_atm2pism_ablation_ebm - ;; - *) - echo "Unknown mass balance selected!" - echo "Known options: PDD, DEBM, EBM" - exit 2 - ;; - esac - - echo -e "\t\t---> Tidying up after coupling generic atmosphere to specific ice sheet model PISM" - ic_atm2pism_finish_up - - max_retry=12 - retry=0 - sleep 10 # Minimum time for st_new.sh to finish - - ln -sf ${latest_atmo_file} ${COUPLE_DIR}/latest_atmo_forcing_file.nc - - while [ ${retry} -lt ${max_retry} ]; do - if [ -f ${COUPLE_DIR}/latest_atmo_forcing_file.nc ]; then - break # call results.sh outside loop - else - (( retry = retry + 1 )) - sleep 1 - fi - done - if [ ! -f ${COUPLE_DIR}/latest_atmo_forcing_file.nc ]; then - echo "Something wrong after waiting for 120 seconds!" - fi - echo -e "\t\t*** F I N I S H E D atmosphere2pism *** " - echo -e "\t\t==================================================================" -} - -################################################################################ -################################################################################ -# P R E P A R E :: Does all the preperation steps: sets variables, reads names -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_prepare() -## @brief Calls functions for preperation -## -## Prefix of called functions: ic_atm2pism_prepare (if not defined elsewhere) -## -## 1. Defines useful constants -## 2. Reads names of variables and units which are in the atmosphere_file_for_ice.nc -## 3. Saves PISM grid description to COUPLE_DIR for use when regridding -## 4. Cleans up missing values out of the atmosphere_file_for_ice -ic_atm2pism_prepare() { - echo; echo -e "\t\tPreparing to recieve atmosphere..." - ic_atm2pism_prepare_define_constants - read_names atmosphere ice - ic_atm2pism_prepare_save_griddes - ic_atm2pism_prepare_clean_missing_values - echo; echo -e "\t\t...done."; echo -} - - -################################################################################ -################################################################################ -# R E G R I D D I N G :: Wraps up functions down downscaling, interpolating, usw. -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_downscale() -## @brief Calls functions for downscaling GCM forcing -## -## Prefix of called functions: ic_atm2pism_regrid_downscale -## -## 1. Splits names into individual files for each atmospheric variable -## 2. Generates an elevation anomaly between the low resolution and high resolution grid -## 3. Downscales temperature -## 4. Downscales precipitation -ic_atm2pism_regrid_dyn_downscale() { - echo; echo -e "\t\tDynamically downscaling atmosphere forcing..." - ic_atm2pism_regrid_dyn_downscale_split_names - ic_atm2pism_regrid_dyn_downscale_generate_elevation_difference - ic_atm2pism_regrid_dyn_downscale_temperature - ic_atm2pism_regrid_dyn_downscale_temperature_below_firn - ic_atm2pism_regrid_dyn_downscale_precipitation - ic_atm2pism_regrid_dyn_downscale_shortwave_downward_radiation - ic_atm2pism_regrid_dyn_downscale_TOAshortwave - ic_atm2pism_regrid_dyn_downscale_humidity - ic_atm2pism_regrid_dyn_downscale_emissivity - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - ic_atm2pism_regrid_dyn_downscale_wind - fi - ic_atm2pism_regrid_dyn_downscale_cloud_cover - ic_atm2pism_regrid_dyn_downscale_transmissivity - - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_regrid_downscale() -## @brief Calls functions for downscaling GCM forcing -## -## Prefix of called functions: ic_atm2pism_regrid_downscale -## -# temperature_varname = 'air_temp' -# shortwave_radiation_downward_varname = 'swd' -# TOA_shortwave_varname = 'TOAswd' -# humidity_varname = 'q2m' -# emissivity_varname = 'emiss' -# cloud_cover_varname = 'cc' -# transmissivity_varname = 'tau' -## 1. Splits names into individual files for each atmospheric variable -## 2. Generates an elevation anomaly between the low resolution and high resolution grid -## 3. Downscales temperature -## 4. Downscales precipitation -ic_atm2pism_regrid_downscale() { - echo; echo -e "\t\tDownscaling atmosphere forcing..." - ic_atm2pism_regrid_downscale_split_names - ic_atm2pism_regrid_downscale_generate_elevation_difference - ic_atm2pism_regrid_downscale_temperature - ic_atm2pism_regrid_downscale_temperature_below_firn - ic_atm2pism_regrid_downscale_precipitation - ic_atm2pism_regrid_downscale_shortwave_downward_radiation - ic_atm2pism_regrid_downscale_TOAshortwave - ic_atm2pism_regrid_downscale_humidity - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - ic_atm2pism_regrid_downscale_wind - fi - ic_atm2pism_regrid_downscale_emissivity - ic_atm2pism_regrid_downscale_cloud_cover - ic_atm2pism_regrid_downscale_transmissivity - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_regrid_interpolate() -## @brief Interpolates temperature and precipitation biliniearly -## -## Prefix of called functions: ic_atm2pism_regrid_interpolate -## -## Uses `cdo -P 8 remapbil` to interpolate atmospheric fields to the `PISM` grid. -ic_atm2pism_regrid_interpolate() { - echo; echo -e "\t\tInterpolating atmosphere forcing..." - ic_atm2pism_regrid_interpolate_temperature - ic_atm2pism_regrid_interpolate_temperature_below_firn - ic_atm2pism_regrid_interpolate_precipitation - ic_atm2pism_regrid_interpolate_shortwave_downward_radiation - ic_atm2pism_regrid_interpolate_TOAshortwave - ic_atm2pism_regrid_interpolate_humidity - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - ic_atm2pism_regrid_interpolate_wind - fi - ic_atm2pism_regrid_interpolate_emissivity - ic_atm2pism_regrid_interpolate_cloud_cover - ic_atm2pism_regrid_interpolate_transmissivity - - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_regrid_remap() -## @brief Conservative remapping of atmospheric fields -## -## Uses `cdo remapcon` to conservatively remap to the `PISM` grid -ic_atm2pism_regrid_remap() { - echo; echo -e "\t\tRemapping atmosphere forcing..." - ic_atm2pism_regrid_remap_temperature - ic_atm2pism_regrid_remap_temperature_below_firn - ic_atm2pism_regrid_remap_precipitation - ic_atm2pism_regrid_remap_shortwave_downward_radiation - ic_atm2pism_regrid_remap_TOAshortwave - ic_atm2pism_regrid_remap_humidity - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - ic_atm2pism_regrid_remap_wind - fi - ic_atm2pism_regrid_remap_emissivity - ic_atm2pism_regrid_remap_cloud_cover - ic_atm2pism_regrid_remap_transmissivity - echo; echo -e "\t\t...done."; echo -} - - -################################################################################ -################################################################################ -# A B L A T I O N :: Wraps up functions for PDD, DEBM, and SEMIC -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_ablation_pdd() -ic_atm2pism_ablation_pdd() { - echo; echo -e "\t\tSetting up SMB scheme PDD..." - ic_atm2pism_ablation_pdd_make_atmosphere_forcing - # TODO(PG): consistent names - iterative_coupling_pism_regrid_add_xy_array \ - ${COUPLE_DIR}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - "atmosphere" - ic_atm2pism_ablation_pdd_set_options_atmo_given - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_ablation_debm() -ic_atm2pism_ablation_debm() { - echo; echo -e "\t\tSetting up SMB scheme DEBM..." - ic_atm2debm_ablation_debm_make_forcing - ic_atm2debm_ablation_debm_run - ic_debm2pism_ablation_debm_make_surface_forcing - ic_debm2pism_ablation_debm_set_options_surface_given - echo; echo -e "\t\t...done."; echo -} - - -## @fn ic_atm2pism_ablation_ebm() -ic_atm2pism_ablation_ebm() { - echo; echo -e "\t\tSetting up SMB scheme EBM (SEMIC)..." - # NOTE: Not yet implemented. Turning this one will break... - ic_atm2semic_ablation_ebm_make_forcing - ic_atm2semic_ablation_ebm_run - ic_semic2pism_ablation_ebm_make_surface_forcing - ic_semic2pism_set_options_surface_given - echo; echo -e "\t\t...done."; echo -} - -################################################################################ -################################################################################ -# F I N I S H :: Does all the clean up steps -################################################################################ -################################################################################ - - -ic_atm2pism_finish_up() { - for file in ${cleanup_list}; do - if [ -f ${file} ]; then - rm ${file} - fi - done -} - - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for preparing -################################################################################ -################################################################################ - - -ic_atm2pism_prepare_define_constants() { - echo; echo -e "\t\t* Defining constants" - INTERPOL_TYPE_ATM="bil" #"bil" "con" "dis" "nn" - WEIGHTS_ATM2ICE=weights_atm2ice.${INTERPOL_TYPE_ATM}.nc - GRIDDES_ICE=${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes - GRIDDES_ATM=atmosphere.griddes - - NOCOLOR='\033[0m' - GREEN='\033[32m' - RED='\033[31m' -} - - -## @fn ic_atm2pism_prepare_save_griddes() -## @brief -## Saves grid description for a ice sheet -## -## Saves a ice.griddes file in the `COUPLE_DIR` of your experiment. By default, -## tries to copy from the `POOL_DIR_pism` -ic_atm2pism_prepare_save_griddes() { - if [ ! -f ${COUPLE_DIR}/ice.griddes ]; then - echo; echo -e "\t\t* Saving ice.griddes" - if [ -f ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes ]; then - cp ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - ${COUPLE_DIR}/ice.griddes - else - echo " Was Looking for: ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes" - echo "Could not find griddes file, exiting..." - exit 3 - fi - else - echo; echo -e "\t\t* File ice.griddes is in place" - fi -} - - -ic_atm2pism_prepare_clean_missing_values() { - # Determine if there are any missing values in the - # atmosphere_file_for_ice, and issue a warning. They will be all set to - # 0, but this might have unintended side-effects - echo; echo -e "\t\t* Cleaning up missing values from atmosphere_file_for_ice.nc (If any are found)" - - missing_value_filler=0 - variables_in_atmosphere_file_for_ice=$(cdo -s vardes ${COUPLE_DIR}/atmosphere_file_for_ice.nc | tr -s ' ' | awk '{print $2}') - echo " * variables_in_atmosphere_file_for_ice=${variables_in_atmosphere_file_for_ice}" - cdo -s splitvar ${COUPLE_DIR}/atmosphere_file_for_ice.nc ${COUPLE_DIR}/atmosphere_file_for_ice_ - for var in ${variables_in_atmosphere_file_for_ice}; do - current_min=$(cdo -s \ - -output \ - -timmin \ - -fldmin \ - -selvar,$var \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - | tr -s ' ' \ - | awk '{print $NF}') - current_max=$(cdo -s \ - -output \ - -timmax \ - -fldmax \ - -selvar,$var \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - | tr -s ' ' \ - | awk '{print $NF}') - if [ "x$debug_ic_atm2pism_clean_missing_values" == "x1" ]; then - echo -e "\t\t @ DEBUG: The variable ${var} has current_min=${current_min} and current_max=${current_max}" - fi - number_of_missing_values=$(cdo -s \ - -output \ - -timsum \ - -fldsum \ - -setmisstoc,1 \ - -setrtoc,${current_min},${current_max},0 \ - -selvar,$var \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - | tr -s ' ' \ - | awk '{print $NF}') - echo "number_of_missing_values = ${number_of_missing_values}" - if [ "x$number_of_missing_values" != "x0" ]; then - echo -e "\t\t!!! ${RED}W A R N I N G${NOCOLOR}: The variable ${var} has ${number_of_missing_values} missing values." - echo -e "\t\t!!! ${RED}W A R N I N G${NOCOLOR}: These are being set to $missing_value_filler" - cdo -s \ - -setmisstoc,${missing_value_filler} \ - ${COUPLE_DIR}/atmosphere_file_for_ice_${var}.nc \ - tmp - mv tmp ${COUPLE_DIR}/atmosphere_file_for_ice_${var}.nc - fi - merge_list="$merge_list ${COUPLE_DIR}/atmosphere_file_for_ice_${var}.nc" - done - cdo -s -O merge $merge_list ${COUPLE_DIR}/atmosphere_file_for_ice.nc -} - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for dynamic downscaling -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_downscale_split_names() -## @brief -## Splits names **and** regrids via `INTERPOL_TYPE_ATM` -## -## Using the `INTERPOL_TYPE_ATM`, weights are generated for remapping, and -## then used to remap `atmosphere_file_for_ice.nc`. -## Variable names are split into seperate files for further processing. -## Error output of the cdo commant is dumped in `cdo_stderr_atm2pism`. -## -## After regridding, all files matching variable names in `cdo vardes atmosphere_file_for_ice` are added to the `cleanup_list` -ic_atm2pism_regrid_dyn_downscale_split_names() { - ic_atm2pism_regrid_downscale_split_names -} - -## @fn ic_atm2pism_regrid_downscale_generate_elevation_difference() -## @brief -## Calculates `evel_hi` minus `elev_lo`. -## -## Using the `INPUT_FILE_pism` variable `usurf` as high resolution orography, the differnce to the low resolution orography is calculed. -## -## @pre -## Assumes that a variable `atmosphere_name_elevation` is present in the `atmosphere_file_for_ice.nc` -ic_atm2pism_regrid_dyn_downscale_generate_elevation_difference() { - echo ""; echo " * calculating elevation difference" - echo "*** INPUT_FILE_pism = ${INPUT_FILE_pism} ***" - if [ -z ${INPUT_FILE_pism} ]; then - echo "Oh no, help. please don't use unusual operators like -z" - exit 5 - fi - #INPUT_FILE_NAME_BASE_pism=$(basename ${INPUT_FILE_pism:?Missing variable}) - INPUT_FILE_NAME_BASE_pism=${INPUT_FILE_pism} - if ${cdo} -L -s vardes ${INPUT_FILE_pism} 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism | grep -q usurf; then - echo ""; echo " * using INPUT_FILE_pism = ${INPUT_FILE_pism}" - elev_hi_file="${INPUT_FILE_NAME_BASE_pism%.*}"_usurf.nc - ${cdo} -s -selvar,usurf ${INPUT_FILE_pism} usurf.tmp.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - ${cdo} -s -seltimestep,-1 usurf.tmp.nc ${COUPLE_DIR}/elev_hi.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - #${cdo} -s -seltimestep,-1 -selvar,usurf ${INPUT_FILE_pism} ${COUPLE_DIR}/${elev_hi_file} 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - else - elev_hi_file="${INPUT_FILE_NAME_BASE_pism%.*}"_thk_plus_topg.nc - ${cdo} -s -setrtoc,-10000,0,0 \ - -add \ - -selvar,thk ${INPUT_FILE_pism} \ - -selvar,topg ${INPUT_FILE_pism} \ - ${COUPLE_DIR}/${elev_hi_file} 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - ncrename -v thk,usurf ${COUPLE_DIR}/${elev_hi_file} ${COUPLE_DIR}/elev_hi.nc - fi - cp ${COUPLE_DIR}/elev_hi.nc ${COUPLE_DIR}/elev_hi_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - #mv $elev_hi_file ${COUPLE_DIR}/elev_hi.nc - cp ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_elevation}.nc ${COUPLE_DIR}/elev_lo.nc - ncrename -v $atmosphere_name_elevation,usurf ${COUPLE_DIR}/elev_lo.nc ${COUPLE_DIR}/tmp.nc - cp ${COUPLE_DIR}/tmp.nc ${COUPLE_DIR}/elev_lo.nc - - ${cdo} -s sub ${COUPLE_DIR}/elev_hi.nc ${COUPLE_DIR}/elev_lo.nc ${COUPLE_DIR}/elev_hi_minus_lo.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - ncrename -v $atmosphere_name_elevation,usurf ${COUPLE_DIR}/elev_lo.nc ${COUPLE_DIR}/tmp.nc - cdo settbounds,1mon -setreftime,1850-01-01,00:00:00 -setunit,m tmp.nc surface_altitude_coarse_resolution.nc - - cleanup_list="$cleanup_list ${COUPLE_DIR}/elev_hi.nc ${COUPLE_DIR}/elev_lo.nc ${COUPLE_DIR}/elev_hi_minus_lo.nc" -} - -ic_atm2pism_regrid_dyn_downscale_temperature_below_firn() { - echo""; echo -e "\t\t* dynamical downscaling temperature below firn" - echo -e "\t\t- falling back to bilinear interpolation for temperature!" - echo -e "\t\t- PISM will internally apply lapse rates to this field!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc ${COUPLE_DIR}/temperature_below_firn.nc -} - -ic_atm2pism_regrid_dyn_downscale_temperature() { - echo""; echo -e "\t\t* dynamical downscaling temperature" - echo -e "\t\t- falling back to bilinear interpolation for temperature!" - echo -e "\t\t- PISM will internally apply lapse rates to this field!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc ${COUPLE_DIR}/temperature.nc -} - -ic_atm2pism_regrid_dyn_downscale_precipitation() { - echo""; echo -e "\t\t* dynamical downscaling precipitation" - echo -e "\t\t- falling back to bilinear interpolation for precipitation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc ${COUPLE_DIR}/precipitation.nc -} - -ic_atm2pism_regrid_dyn_downscale_shortwave_downward_radiation() { - echo""; echo -e "\t\t* downscaling shortwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for SW radiation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_shortwave}.nc ${COUPLE_DIR}/shortwave_down.nc -} - -ic_atm2pism_regrid_dyn_downscale_TOAshortwave() { - echo""; echo -e "\t\t* downscaling TOA shortwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for SW radiation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_TOAshortwave}.nc ${COUPLE_DIR}/TOAshortwave.nc -} - -ic_atm2pism_regrid_dyn_downscale_humidity() { - echo""; echo -e "\t\t* downscaling TOA shortwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_humidity}.nc ${COUPLE_DIR}/humidity.nc -} -ic_atm2pism_regrid_dyn_downscale_longwave_downward_radiation() { - echo""; echo -e "\t\t* downscaling longwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for LW radiation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_longwave}.nc ${COUPLE_DIR}/longwave_down.nc -} -ic_atm2pism_regrid_dyn_downscale_emissivity() { - echo""; echo -e "\t\t* downscaling atm. emissivity" - echo -e "\t\t- falling back to bilinear interpolation for LW radiation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_emissivity}.nc ${COUPLE_DIR}/emissivity.nc -} -ic_atm2pism_regrid_dyn_downscale_wind() { - echo""; echo -e "\t\t* downscaling wind velocities" - echo -e "\t\t- falling back to bilinear interpolation for wind velocities!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_wind}.nc ${COUPLE_DIR}/uv.nc -} -ic_atm2pism_regrid_dyn_downscale_cloud_cover() { - echo""; echo -e "\t\t* downscaling cloud cover" - echo -e "\t\t- falling back to bilinear interpolation for cloud cover!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_cloud_cover}.nc ${COUPLE_DIR}/cloud_cover.nc -} - -ic_atm2pism_regrid_dyn_downscale_transmissivity() { - echo""; echo -e "\t\t* downscaling transmissivity" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_transmissivity}.nc ${COUPLE_DIR}/transmissivity.nc -} -################################################################################ -################################################################################ -# D E T A I L S :: Steps for downscaling -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_downscale_split_names() -## @brief -## Splits names **and** regrids via `INTERPOL_TYPE_ATM` -## -## Using the `INTERPOL_TYPE_ATM`, weights are generated for remapping, and -## then used to remap `atmosphere_file_for_ice.nc`. -## Variable names are split into seperate files for further processing. -## Error output of the cdo commant is dumped in `cdo_stderr_atm2pism`. -## -## After regridding, all files matching variable names in `cdo vardes atmosphere_file_for_ice` are added to the `cleanup_list` -ic_atm2pism_regrid_downscale_split_names() { - echo; echo " * spliting names and regridding via ${INTERPOL_TYPE_ATM}" - - # Umbau wegen dieser Fehlermeldungen - #* spliting names and regridding via remapbil - #cdo(2) remapbil (Abort): Bilinear/bicubic interpolation doesn't support unstructured source grids! - #cdo: posixio.c:660: px_get: Assertion `pxp->bf_refcount <= 0' failed. - # - #/tmp/slurmd/job2388013/slurm_script[73]: eval[73]: eval[73]: eval[393]: atmosphere2pism[12]: ic_atm2pism_regrid_downscale[65]: regrid_downscale_split_names: line 342: 92036: Abort(coredump) - - if [ 1 -eq 0 ] ; then - # IF CDO does not recognize the grid, you activate this mode - # section and it may solve the problem - - VAR4REMAP=$( $cdo -s showvar ../couple/atmosphere_file_for_ice.nc | awk '{print $1}' ) - echo " Fix for missing information metadata information about longitude and latitude: 'lon lat'" - ncatted -a coordinates,${VAR4REMAP},c,c,'lon lat' ${COUPLE_DIR}/atmosphere_file_for_ice.nc - - build_weights4remap \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${GRIDDES_ICE:?Missing variable} \ - ${WEIGHTS_ATM2ICE:?Missing variable} \ - ${INTERPOL_TYPE_ATM:?Missing variable} \ - couple \ - dummy_restart_dir_weights \ - $VAR4REMAP - else - build_weights4remap \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${GRIDDES_ICE:?Missing variable} \ - ${WEIGHTS_ATM2ICE:?Missing variable} \ - ${INTERPOL_TYPE_ATM:?Missing variable} \ - couple - fi - - test_file_or_exit $WEIGHTS_ATM2ICE 4 - - $cdo -s -splitname \ - -remap,$GRIDDES_ICE,$WEIGHTS_ATM2ICE \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_ 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - ##atmosphere_file_at_ice.${INTERPOL_TYPE_ATM}.nc # && rm atmosphere_file_for_ice.nc - - for varname in $(cdo -s vardes ${COUPLE_DIR}/atmosphere_file_for_ice.nc | tr -s ' ' | awk -F ' ' '{print $2}'); do - cleanup_list="$cleanup_list ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${varname}.nc" - done -} - -## @fn ic_atm2pism_regrid_downscale_generate_elevation_difference() -## @brief -## Calculates `evel_hi` minus `elev_lo`. -## -## Using the `INPUT_FILE_pism` variable `usurf` as high resolution orography, -## the difference to the low resolution orography is calculated. -## -## @pre -## Assumes that a variable `atmosphere_name_elevation` is present in the `atmosphere_file_for_ice.nc` -ic_atm2pism_regrid_downscale_generate_elevation_difference() { - echo ""; echo " * calculating elevation difference" - echo "*** INPUT_FILE_pism = ${INPUT_FILE_pism} ***" - if [ -z ${INPUT_FILE_pism} ]; then - echo "Oh no, help." - exit 5 - fi - #INPUT_FILE_NAME_BASE_pism=$(basename ${INPUT_FILE_pism:?Missing variable}) - INPUT_FILE_NAME_BASE_pism=${INPUT_FILE_pism} - if ${cdo} -s vardes ${INPUT_FILE_pism} 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism | grep -q usurf; then - elev_hi_file="${INPUT_FILE_NAME_BASE_pism%.*}"_usurf.nc - ${cdo} -s -seltimestep,-1 ${INPUT_FILE_pism} usurf.tmp.nc - ${cdo} -s -selvar,usurf usurf.tmp.nc ${COUPLE_DIR}/${elev_hi_file} 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - else - #elev_hi_file="${INPUT_FILE_NAME_BASE_pism%.*}"_thk_plus_topg.nc - elev_hi_file=elev_hi.nc - echo "UKK2: elev_hi=" ${elev_hi_file} - echo " * LA DEBUG: INPUT_FILE_pism = ${INPUT_FILE_pism}" - echo " * LA DEBUG: INPUT_FILE_NAME_BASE_pism = ${INPUT_FILE_NAME_BASE_pism%.*}" - ${cdo} -s \ - -setrtoc,-10000,0,0 \ - -add \ - -selvar,thk ${INPUT_FILE_pism} \ - -selvar,topg ${INPUT_FILE_pism} \ - ${COUPLE_DIR}/${elev_hi_file} 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - fi - cp ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_elevation}.nc ${COUPLE_DIR}/elev_lo.nc - ${cdo} -s sub ${COUPLE_DIR}/elev_hi.nc ${COUPLE_DIR}/elev_lo.nc ${COUPLE_DIR}/elev_hi_minus_lo.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - #UKK generate elevation differences for desertification scheme - #the idea is to prevent that the ice sheet grows unlimited, if the HR (high res - #resolution) ice sheet exceeds the height of the LR ice sheet and gets too - #high precipitation rates, due to the lower topography in the LR atmosphere. - #this scheme is only active on HR heights >2000m. - ${cdo} -maxc,2000 ${COUPLE_DIR}/elev_hi.nc ${COUPLE_DIR}/elev_hi_2000.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - ${cdo} -maxc,2000 ${COUPLE_DIR}/elev_lo.nc ${COUPLE_DIR}/elev_lo_2000.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - ${cdo} -s -maxc,0 -sub ${COUPLE_DIR}/elev_hi_2000.nc ${COUPLE_DIR}/elev_lo_2000.nc ${COUPLE_DIR}/elev_hi_minus_lo_2000.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - -#UKK cleanup_list="$cleanup_list ${COUPLE_DIR}/elev_hi.nc ${COUPLE_DIR}/elev_lo.nc ${COUPLE_DIR}/elev_hi_minus_lo.nc usurf.tmp.nc" -} - -## @fn ic_atm2pism_regrid_downscale_temperature() -## @brief -## Downscales atmospheric temperature using a lapse-rate correction -## -## The following operation applies a spatially uniform, temporally constant lapse rate to the -## elevation difference and corrects the interpolated 2m temperature as: -## -## \f[ -## T_{downscaled} = T_{2m} + \Gamma \cdot \left(z_{hi} - z_{lo}\right) -## \f] -## Where: -## \f$ T_{downscaled} \f$ = Downscaled temperature (K) -## -## \f$ T_{2m} \f$ = 2m air temperature (K) -## -## \f$ \Gamma \f$ = Lapse rate (K/1000m) -## -## \f$ z_{hi} \f$ = High resolution orography (m) -## -## \f$ z_{lo} \f$ = Low resolution orography (m) -## -## The lapse-rate correction may be defined via `DOWNSCALING_LAPSE_RATE` -## (default value is -0.007) units of K/1000m. -## -## @note -## Downscaling of temperature can be explicitly turned **OFF** by setting `DOWNSCALE_TEMP` to a value not equal to 1. -## In this case, temperature information is instead generated via bilinear interpolation. -ic_atm2pism_regrid_downscale_temperature() { - DOWNSCALE_TEMP=${DOWNSCALE_TEMP:-1} - if [ "x${DOWNSCALE_TEMP}" == "x1" ]; then - echo ""; echo " * downscaling temperature" - DOWNSCALING_LAPSE_RATE=${DOWNSCALING_LAPSE_RATE:-"-0.005"} - if [ ${DOWNSCALING_LAPSE_RATE} -gt 0 ]; then - echo "YOUR DOWNSCALING LAPSE RATE IS POSITIVE!" - echo "IT WAS: $DOWNSCALING_LAPSE_RATE" - exit 6 - fi - echo " - Lapse rate applied was Γ=${DOWNSCALING_LAPSE_RATE} (K/km)" - cp ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc ${COUPLE_DIR}/uta_temp_before.nc - ${cdo} -s -f nc \ - -add ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc \ - -mulc,${DOWNSCALING_LAPSE_RATE} \ - ${COUPLE_DIR}/elev_hi_minus_lo.nc \ - ${COUPLE_DIR}/temp_hi.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - cp ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/uta_temp_after.nc - echo " - corrections applied (time mean of difference Hi-Res - Lo-Res) " - echo " fldmin: $(cdo -s -output -fldmin -timmean -sub ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc)" - echo " fldmean: $(cdo -s -output -fldmean -timmean -sub ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc)" - echo " fldmax: $(cdo -s -output -fldmax -timmean -sub ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc)" - mv ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/temperature.nc - else - echo ""; echo -e "\t\t* NOT downscaling temperature" - echo -e "\t\t- falling back to bilinear interpolation for temperature!" - # Take the already bilinearly interpolated file - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc ${COUPLE_DIR}/temperature.nc - fi -} - -ic_atm2pism_regrid_downscale_temperature_below_firn() { - DOWNSCALE_TEMP=${DOWNSCALE_TEMP:-1} - if [ "x${DOWNSCALE_TEMP}" == "x1" ]; then - echo ""; echo " * downscaling temperature_below_firn" - DOWNSCALING_LAPSE_RATE=${DOWNSCALING_LAPSE_RATE:-"-0.005"} #old value = -0.007 - if [ ${DOWNSCALING_LAPSE_RATE} -gt 0 ]; then - echo "YOUR DOWNSCALING LAPSE RATE IS POSITIVE!" - echo "IT WAS: $DOWNSCALING_LAPSE_RATE" - exit 6 - fi - echo " - Lapse rate applied was Γ=${DOWNSCALING_LAPSE_RATE} (K/km)" - ${cdo} -s -f nc \ - -add ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc \ - -mulc,${DOWNSCALING_LAPSE_RATE} \ - ${COUPLE_DIR}/elev_hi_minus_lo.nc \ - ${COUPLE_DIR}/temp_hi.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - echo " - corrections applied (time mean of difference Hi-Res - Lo-Res) " - echo " fldmin: $(cdo -s -output -fldmin -timmean -sub ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc)" - echo " fldmean: $(cdo -s -output -fldmean -timmean -sub ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc)" - echo " fldmax: $(cdo -s -output -fldmax -timmean -sub ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc)" - mv ${COUPLE_DIR}/temp_hi.nc ${COUPLE_DIR}/temperature_below_firn.nc - else - echo ""; echo -e "\t\t* NOT downscaling temperature_below_firn" - echo -e "\t\t- falling back to bilinear interpolation for temperature_below_firn!" - # Take the already bilinearly interpolated file - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature_below_firn}.nc ${COUPLE_DIR}/temperature_below_firn.nc - fi -} - -## @fn ic_atm2pism_regrid_downscale_precipitation() -## @brief -## Downscales atmospheric precipitaiton using temperature differences and a scaling factor \f$ \gamma \f$ -## -## The following is after Quiquet et al, The Cryosphere, 2012 -## https://www.the-cryosphere.net/6/999/2012/ -## -## \f[ -## P_{downscaled} = P_{lo} \cdot e^{\gamma \cdot (T_{hi} - T_{lo})} -## \f] -## -## The factor gamma is chosen after Huybrechts 2002, but is poorly constrained (see Charbit et al. 2002) -## UKK also it is not clear if it has the right sign and whether it is actually -## doing what we want it to do... -## AND maybe it is unfortunate that temperature and precip downscaling use -## parameters Gamma and gamma, IMO -## UKK!!! In case {DOWNSCALE_PRECIP} == desertification we use a desertif. scheme for -## elevations >2000m mostly following Ziemen et al, 2014. -## only difference: we only aply it if elev_hi > elev_lo... -ic_atm2pism_regrid_downscale_precipitation() { - DOWNSCALE_PRECIP=${DOWNSCALE_PRECIP:-1} - if [ "x${DOWNSCALE_PRECIP}" == "x1" ]; then - echo ""; echo -e "\t\t* downscaling precipitation" - # Now we do precipitation - gamma="-0.07" - echo -e "\t\t- factor γ=${gamma}" - echo -e "\t\t- P_downscaled = P * e ** (gamma * (T_downscaled - T_original))" - ${cdo} -s \ - -mul \ - ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc \ - -exp \ - -mulc,$gamma \ - -sub \ - ${COUPLE_DIR}/temperature.nc \ - ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc \ - ${COUPLE_DIR}/precip_hi.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - echo -e "\t\t- corrections applied (time mean of difference Hi-Res - Lo-Res) " - echo " fldmin: $(cdo -s -output -fldmin -timmean -sub ${COUPLE_DIR}/precip_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - echo " fldmean: $(cdo -s -output -fldmean -timmean -sub ${COUPLE_DIR}/precip_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - echo " fldmax: $(cdo -s -output -fldmax -timmean -sub ${COUPLE_DIR}/precip_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - mv ${COUPLE_DIR}/precip_hi.nc ${COUPLE_DIR}/precipitation.nc - if [ "x$backup_temperature" == "x1" ]; then - echo -e "\t\t Restoring interpolated temperature for use in atmo_given_file.nc" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_temperature}.nc ${COUPLE_DIR}/temperature.nc - DOWNSCALE_TEMP=0 - fi - elif [ "x${DOWNSCALE_PRECIP}" == "desertification" ]; then - echo ""; echo -e "\t\t* downscaling precipitation following desertification scheme -> Ziemen et al, 2014 " - # Now we do precipitation - gamma=${gamma:-"-0.00069315"} - echo -e "\t\t- factor γ=${gamma}" - echo -e "\t\t- P_downscaled = P * e ** (-gamma * max(0,(max(2000,Z_hi) - max(2000,Z_lo))))" - - ${cdo} -s \ - -mul \ - ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc \ - -exp \ - -mulc,$gamma \ - ${COUPLE_DIR}/elev_hi_minus_lo_2000.nc \ - ${COUPLE_DIR}/precip_hi.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - echo -e "\t\t- corrections applied (time mean of difference Hi-Res - Lo-Res) " - echo " fldmin: $(cdo -s -output -fldmin -timmean -sub ${COUPLE_DIR}/precip_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - echo " fldmean: $(cdo -s -output -fldmean -timmean -sub ${COUPLE_DIR}/precip_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - echo " fldmax: $(cdo -s -output -fldmax -timmean -sub ${COUPLE_DIR}/precip_hi.nc ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc)" - mv ${COUPLE_DIR}/precip_hi.nc ${COUPLE_DIR}/precipitation.nc - else - echo ""; echo -e "\t\t* NOT downscaling precipitation" - echo -e "\t\t- falling back to bilinear interpolation for precipitation!" - # Take the already bilinearly interpolated file - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_precipitation}.nc ${COUPLE_DIR}/precipitation.nc - fi -} - -ic_atm2pism_regrid_downscale_shortwave_downward_radiation() { - echo""; echo -e "\t\t* downscaling shortwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for SW radiation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_shortwave}.nc ${COUPLE_DIR}/shortwave_down.nc -} - -ic_atm2pism_regrid_downscale_longwave_downward_radiation() { - echo""; echo -e "\t\t* downscaling longwave downward radiation" - echo -e "\t\t- falling back to bilinear interpolation for LW radiation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_longwave}.nc ${COUPLE_DIR}/longwave_down.nc -} -ic_atm2pism_regrid_downscale_TOAshortwave() { - echo""; echo -e "\t\t* downscaling shortwave_radiation_TOA" - echo -e "\t\t- falling back to bilinear interpolation for LW radiation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_TOAshortwave}.nc ${COUPLE_DIR}/TOAshortwave.nc -} -ic_atm2pism_regrid_downscale_humidity() { - echo""; echo -e "\t\t* downscaling near_surface_humidity" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_humidity}.nc ${COUPLE_DIR}/humidity.nc -} -ic_atm2pism_regrid_downscale_emissivity() { - echo""; echo -e "\t\t* downscaling atm_emissivity" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_emissivity}.nc ${COUPLE_DIR}/emissivity.nc -} -ic_atm2pism_regrid_downscale_wind() { - echo""; echo -e "\t\t* downscaling wind" - echo -e "\t\t- falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_wind}.nc ${COUPLE_DIR}/uv.nc -} -ic_atm2pism_regrid_downscale_cloud_cover() { - echo""; echo -e "\t\t* downscaling cloud cover" - echo -e "\t\t- falling back to bilinear interpolation for cloud cover!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_cloud_cover}.nc ${COUPLE_DIR}/cloud_cover.nc -} -ic_atm2pism_regrid_downscale_transmissivity() { - echo""; echo -e "\t\t* downscaling transmissivity" - echo -e "\t\t- UKK falling back to bilinear interpolation!" - mv ${COUPLE_DIR}/atmosphere_file_for_ice_for_downscaling_${atmosphere_name_transmissivity}.nc ${COUPLE_DIR}/transmissivity.nc -} -################################################################################ -################################################################################ -# D E T A I L S :: Steps for bilinear interpolation -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_interpolate_temperature() -## @brief -## Interpolates temperature field bilinearly -## -## This uses `cdo remapbil` to bilinearly interpolate the atmospheric temperature to the ice grid. -## It is the fallback option if downscaling is only applied to precipitation. -ic_atm2pism_regrid_interpolate_temperature() { - atmosphere_file=${1:-${COUPLE_DIR}/atmosphere_file_for_ice.nc} - echo ""; echo -e "\t\t* Regridding temperature bilinearly from atmosphere_file_for_ice.nc" - - if [ "x$debug_ic_atm2pism_regrid_interpolate_temperature" == "x1" ]; then - echo -e "\t\t Command is:" - echo " ${cdo} -v -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_temperature} \ - ${atmosphere_file} ${COUPLE_DIR}/temperature.nc \ - 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism" - fi - - ${cdo} -s -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_temperature} \ - ${atmosphere_file} \ - ${COUPLE_DIR}/temperature.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_temperature_below_firn() { - atmosphere_file=${1:-${COUPLE_DIR}/atmosphere_file_for_ice.nc} - echo ""; echo -e "\t\t* Regridding temperature_below_firn bilinearly from atmosphere_file_for_ice.nc" - - if [ "x$debug_ic_atm2pism_regrid_interpolate_temperature_below_firn" == "x1" ]; then - echo -e "\t\t Command is:" - echo " ${cdo} -v -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_temperature_below_firn} \ - ${atmosphere_file} ${COUPLE_DIR}/temperature_below_firn.nc \ - 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism" - fi - - ${cdo} -s -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_temperature_below_firn} \ - ${atmosphere_file} \ - ${COUPLE_DIR}/temperature_below_firn.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -## @fn ic_atm2pism_regrid_interpolate_precipitation() -## @brief -## Interpolates atmospheric precipitation field bilinearly -## -## Uses `cdo remapbil` to interpolate precipitation biliniearly to the ice grid. -## This is the fallback option if downscaling only is applied to temperature. -ic_atm2pism_regrid_interpolate_precipitation() { - echo ""; echo -e "\t\t* Regridding precipitation bilinearly from atmosphere_file_for_ice.nc" - ${cdo} -v -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_precipitation} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/precipitation.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - - -ic_atm2pism_regrid_interpolate_shortwave_downward_radiation() { - echo ""; echo -e "\t\t* Regridding short-wave downward radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_shortwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/shortwave_down.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - - -ic_atm2pism_regrid_interpolate_longwave_downward_radiation() { - echo ""; echo -e "\t\t* Regridding long-wave downward radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_longwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/longwave_down.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} -ic_atm2pism_regrid_interpolate_TOAshortwave() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_TOAshortwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/TOAshortwave.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} -ic_atm2pism_regrid_interpolate_emissivity() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_emissivity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/emissivity.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} -ic_atm2pism_regrid_interpolate_wind() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_wind} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/uv.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_humidity() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_humidity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/humidity.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_transmissivity() { - echo ""; echo -e "\t\t* Regridding from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_transmissivity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/transmissivity.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_interpolate_cloud_cover() { - echo ""; echo -e "\t\t* Regridding cloud cover downward radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_cloud_cover} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/cloud_cover.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for conservative remapping -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_regrid_remap_temperature() -## @brief -## Conservative remapping for temperature to ice grid -ic_atm2pism_regrid_remap_temperature() { - echo ""; echo -e "\t\t* Regridding temperature conservatively from atmosphere_file_for_ice.nc" - ${cdo} -s -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_temperature} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/temperature.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_temperature_below_firn() { - echo ""; echo -e "\t\t* Regridding temperature_below_firn conservatively from atmosphere_file_for_ice.nc" - ${cdo} -s -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_temperature_below_firn} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/temperature_below_firn.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -## @fn ic_atm2pism_regrid_remap_precipitation() -## @brief -## Conservative remapping for precipitation to ice grid -ic_atm2pism_regrid_remap_precipitation() { - echo ""; echo -e "\t\t* Regridding precipitation conservatively from atmosphere_file_for_ice.nc" - ${cdo} -s -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_precipitation} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/precipitation.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_shortwave_downward_radiation() { - echo ""; echo -e "\t\t* Regridding short-wave downward radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_shortwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/shortwave_down.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - - -ic_atm2pism_regrid_remap_longwave_downward_radiation() { - echo ""; echo -e "\t\t* Regridding long-wave downward radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_longwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/longwave_down.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - -ic_atm2pism_regrid_remap_TOAshortwave() { - echo ""; echo -e "\t\t* Regridding TOA shortwave radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_TOAshortwave} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/TOAshortwave.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} -ic_atm2pism_regrid_remap_emissivity() { - echo ""; echo -e "\t\t* Regridding TOA shortwave radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_emissivity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/emissivity.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} -ic_atm2pism_regrid_remap_wind() { - echo ""; echo -e "\t\t* Regridding wind velocity from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_wind} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/uv.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} -ic_atm2pism_regrid_remap_humidity() { - echo ""; echo -e "\t\t* Regridding TOA shortwave radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_humidity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/humidity.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} -ic_atm2pism_regrid_remap_transmissivity() { - echo ""; echo -e "\t\t* Regridding TOA shortwave radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_transmissivity} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/transmissivity.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} -ic_atm2pism_regrid_remap_cloud_cover() { - echo ""; echo -e "\t\t* Regridding cloud cover downward radiation from atmosphere_file_for_ice.nc" - ${cdo} -f nc \ - -remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${atmosphere_name_cloud_cover} \ - ${COUPLE_DIR}/atmosphere_file_for_ice.nc \ - ${COUPLE_DIR}/cloud_cover.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for PDD -################################################################################ -################################################################################ - - -## @fn ic_atm2pism_make_atmosphere_forcing() -## @brief -## Sets correct temperature and precipitation units, adds a time axis -## -## Sets temperature and precipitation units and combines the files along with a time axis. -ic_atm2pism_ablation_pdd_make_atmosphere_forcing() { - echo; echo -e "\t\t* Generating atmo_given file with sensible metadata" - ic_atm2pism_ablation_pdd_set_temperature_units - ic_atm2pism_ablation_pdd_set_precipitation_units - ic_atm2pism_ablation_pdd_merge_preliminary_files - ic_atm2pism_ablation_pdd_set_time_axis -} - - -## @fn ic_atm2pism_ablation_pdd_set_temperature_units() -## @brief -## Sets metadata for air temperature when using an atmosphere given scheme in `PISM` -## -## Renames the variable read from atmosphere_name_temperature to air_temp -## -## @fixme This probably should be named atmo_given_set_temperature_metadata instead... -ic_atm2pism_ablation_pdd_set_temperature_units() { - echo -e "\t\t- setting temperature units and variable names" - ncrename \ - -v ${atmosphere_name_temperature},air_temp \ - ${COUPLE_DIR}/temperature.nc -} - - -## @fn ic_atm2pism_ablation_pdd_set_precipitation_units() -## @brief -## Sets metadata for precipitation when using an atmo given scheme in `PISM` -## -## If `$VERSION_pism` is specificed to 0.7, the precipitation field is rescaled to mm/day. -## Otherwise, in `$VERSION_pism` == 1.0 or 1.1, we can use `kg m-2 second-1`. -## File metadata and variable names are set according. -ic_atm2pism_ablation_pdd_set_precipitation_units() { - echo -e "\t\t- setting precipitation units and variable names" - test_if_set VERSION_pism - if [ "x$VERSION_pism" == "x0.7" ]; then - # FIXME(PG): This is currently very specific and assumes that - # the units coming out of the atmosphere model are kg/m2/s - # - # Divide by ice density and convert from kg/m^2s to mm/day ice equivalent - # Next step is skipped if we use pism1.0, then pism wants kg m-2 s-1 - ${cdo} -s \ - -mulc,3600 -mulc,24 -mulc,1000 -divc,910 \ - ${COUPLE_DIR}/precipitation.nc \ - tmp \ - 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism \ - && mv tmp ${COUPLE_DIR}/precipitation.nc - fi - ncrename \ - -v ${atmosphere_name_precipitation},precipitation \ - ${COUPLE_DIR}/precipitation.nc - case ${VERSION_pism:--0.1} in - "0.7") - ncatted \ - -a units,precipitation,o,c,"mm day-1" \ - ${COUPLE_DIR}/precipitation.nc \ - tmp - ;; - "1.0"|"1.1"|"1.2") - ncatted \ - -a units,precipitation,o,c,"kg m-2 second-1" \ - ${COUPLE_DIR}/precipitation.nc \ - tmp - ;; - *) - echo "Undefined pism version, exiting" - exit 7 - ;; - esac - mv tmp ${COUPLE_DIR}/precipitation.nc -} - - -ic_atm2pism_ablation_pdd_merge_preliminary_files() { - echo -e "\t\t- merging atmospheric temp and precip together" - ${cdo} -s -O \ - -merge \ - ${COUPLE_DIR}/precipitation.nc \ - ${COUPLE_DIR}/temperature.nc \ - ${COUPLE_DIR}/atmo_given_file.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism -} - - -## @fn ic_atm2pism_ablation_pdd_set_time_axis() -## @brief adds a time axis to a forcing file -## -## Uses a predefined time axis file to attach time bounds to an atmo_given file -## -## @fixme: This function currently does 360 days. This needs to be improved. -ic_atm2pism_ablation_pdd_set_time_axis() { - - echo -e "\t\t- appending time axis to forcing file >>${COUPLE_DIR}/atmo_given_file.nc<<" - # Determine how many timesteps we have and set time unit accordingly - nt=$(${cdo} -s ntime ${COUPLE_DIR}/atmo_given_file.nc) - if [ "x$nt" == "x1" ]; then - echo -e "\t\t- only ONE timestep given" - time_unit="year" - echo "Dont know what to do" - exit 8 - else - echo -e "\t\t- assuming MONTHLY MEANS (for now -- using 30 equivalent days per month)" - time_calendar="360_day" - fi - - ncatted \ - -a \ - bounds,time,o,c,"time_bnds" \ - -a \ - calendar,time,o,c,${time_calendar} \ - ${COUPLE_DIR}/atmo_given_file.nc tmp && mv tmp ${COUPLE_DIR}/atmo_given_file.nc - - ${FUNCTION_PATH}/../utils/CreateTimeAxisNC.bash ${nt} ${COUPLE_DIR}/time_axis_pism.nc 0 classic 365_day #${CHUNK_START_YEAR_pism} - #ncks -A ${POOL_DIR_pism}/time_axis/pismr_timeaxis_12_360day.nc ${COUPLE_DIR}/atmo_given_file.nc - ncks -A ${COUPLE_DIR}/time_axis_pism.nc ${COUPLE_DIR}/atmo_given_file.nc - #cdo -s settunits,days -settaxis,0000-01-01,00:00:00,1mon ${COUPLE_DIR}/atmo_given_file.nc tmp - #mv tmp ${COUPLE_DIR}/atmo_given_file.nc - - #FAILURE: ncks -A ${POOL_DIR_pism}/grids/${DOMAIN_pism}/pismr_${DOMAIN_pism}_${RES_pism}_xy.nc ${COUPLE_DIR}/atmo_given_file.nc - # Producesses unrealistic x-/y-arrays with a values like: -8.0e+51, 1.7e+161, 1.e-258 - - echo -e "\t\t- appending unique date-stamp to file name" - echo -e "\t\t- atmo_given_file.nc ---> atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc" - - mv ${COUPLE_DIR}/atmo_given_file.nc ${COUPLE_DIR}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - ln -fs ${COUPLE_DIR}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc ${COUPLE_DIR}/latest_atmo_given_file.nc - cleanup_list="${cleanup_list} ${COUPLE_DIR}/temperature.nc ${COUPLE_DIR}/precipitation.nc" -} - - -ic_atm2pism_ablation_pdd_set_options_atmo_given() { - echo; echo -e "\t\t* Generating files with option information for PISM" - pism_conf_file_list="${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat ${COUPLE_DIR}/pism_config_value_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat" - for pism_conf_file in $pism_conf_file_list; do - if [ ! -f $pism_conf_file ]; then - :> $pism_conf_file - fi - done - - if [ "x${bool_atm2pism_regrid_dyn_downscaling}" == "x1" ]; then - echo; echo -e "\t\t* Write options for dynamic downscaling" - - echo "pism_set_coupler___atmosphere=given,lapse_rate" >> \ - ${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - echo "pism_set_forcing_file___atmosphere_lapse_rate=${COUPLE_DIR}/surface_altitude_coarse_resolution.nc" >> \ - ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - else - echo "pism_set_coupler___atmosphere=given" >> \ - ${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - fi - - echo "pism_set_coupler___surface=pdd" \ - >> ${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - echo "pism_set_forcing_file___atmosphere_given=${COUPLE_DIR}/atmo_given_file_${CURRENT_YEAR_pism}-${END_YEAR_pism}.nc" \ - >> ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - number_of_timesteps_in_atmo_given_file=$(cdo -s \ - nyear \ - ${COUPLE_DIR}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc) - echo "pism_set_config_value_FORCE___atmosphere_given_period=${number_of_timesteps_in_atmo_given_file}" \ - >> ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - # ${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - # echo "pism_set_forcing_file___atmosphere_lapse_rate=${COUPLE_DIR}/surface_altitude_coarse_resolution.nc" >> \ - # ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - #else - # echo "pism_set_coupler___atmosphere=given" >> \ - # ${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - #fi - # - #echo "pism_set_coupler___surface=pdd" \ - #>> ${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - #echo "pism_set_forcing_file___atmosphere_given=${COUPLE_DIR}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc" \ - #>> ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - - #number_of_timesteps_in_atmo_given_file=$(cdo -s \ - # nyear \ - # ${COUPLE_DIR}/atmo_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc) - #echo "pism_set_config_value_FORCE___atmosphere_given_period=${number_of_timesteps_in_atmo_given_file}" \ - #>> ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat -} - - -################################################################################ -################################################################################ -# D E T A I L S :: Steps for DEBM -################################################################################ -################################################################################ -## @fn ic_atm2debm_make_forcing() -## @brief -## Prepares a forcing file for the Fortran implementation of the dEBM mass balance model -ic_atm2debm_ablation_debm_make_forcing() { - echo; echo -e "\t\t* Preparing forcing file from atmosphere_file_for_ice.nc for the dEBM Mass Balance Model" - ic_atm2debm_ablation_debm_make_forcing_set_temperature_units - ic_atm2debm_ablation_debm_make_forcing_set_temperature_below_firn_units - ic_atm2debm_ablation_debm_make_forcing_set_precipitation_units - ic_atm2debm_ablation_debm_make_forcing_set_cloud_cover_units - ic_atm2debm_ablation_debm_make_forcing_set_shortwave_units - ic_atm2debm_ablation_debm_make_forcing_set_longwave_units - ic_atm2debm_ablation_debm_make_forcing_set_TOAshortwave_units - ic_atm2debm_ablation_debm_make_forcing_set_emissivity_units - ic_atm2debm_ablation_debm_make_forcing_set_transmissivity_units - ic_atm2debm_ablation_debm_make_forcing_set_humidity_units - ic_atm2debm_ablation_debm_make_forcing_merge_preliminary_files -} - - -## @fn ic_atm2debm_run() -## @brief -## Downloads dEBM Fortran code, compile and create excute binary file -## Specific steps: -## -## 1) Generates namelists specific for the Fortran dEBM run -## 2) Downloads dEBM code and create dEBM execute binary file; this only do for the first time step -## 3) Run the Fortran version of the dEBM -ic_atm2debm_ablation_debm_run() { - echo; echo -e "\t\t* Running dEBM Model" - ic_atm2debm_ablation_debm_run_modify_nml - ic_atm2debm_ablation_debm_run_compile_binary - ic_atm2debm_ablation_debm_run_execute_binary -} - -## @fn ic_debm2pism_make_surface_forcing() -## @brief -## Sets the metadata and time axis needed for a surface given file which comes out of the dEBM model -## -## Specific steps: -## 1) Sets the temperature variable name -## 2) Converts temperature to Kelvin if needed -## 3) Sets the SMB variable name -## 4) Sets the SMB units to kg/m2/s (see pism-docs) -## 5) Merges results together -## 6) Sets a time axis -ic_debm2pism_ablation_debm_make_surface_forcing() { - echo; echo -e "\t\t* Generating a surface_given file with sensible names, units, and a time axis..." - ic_debm2pism_ablation_debm_make_surface_forcing_add_surface_temperature - ic_debm2pism_ablation_debm_make_surface_forcing_apply_mask - ic_debm2pism_ablation_debm_make_surface_forcing_set_temperature_varname_and_units - ic_debm2pism_ablation_debm_make_surface_forcing_set_smb_varname_and_units - ic_debm2pism_ablation_debm_make_surface_forcing_merge_preliminary_files - ic_debm2pism_ablation_debm_make_surface_forcing_set_time_axis -} - - -ic_atm2debm_ablation_debm_make_forcing_set_temperature_units() { - echo -e "\t\t- setting temperature units and variable names" - ncrename -v ${atmosphere_name_temperature},air_temp ${COUPLE_DIR}/temperature.nc - echo -e "\t\t- LA DEBUG: REDUCE_TEMP = ${REDUCE_TEMP}" - if [[ "x${REDUCE_TEMP}" == "x1" ]]; then - if [[ "x${REDUCE_TEMP_BY}" == "xanom" ]]; then - echo -e "\t\t- use bias correction from this file ${TEMP2_BIAS_FILE}" - - ${cdo} -s -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - ${TEMP2_BIAS_FILE} \ - ${COUPLE_DIR}/remapped.temp2bias_file.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - cdo -s -sub ${COUPLE_DIR}/temperature.nc ${COUPLE_DIR}/remapped.temp2bias_file.nc ${COUPLE_DIR}/temperature.tmp.nc - mv ${COUPLE_DIR}/temperature.tmp.nc ${COUPLE_DIR}/temperature.nc - else - echo -e "\t\t- reduce temperature of dEBM input artificially by ${REDUCE_TEMP_BY} K" - cdo -subc,${REDUCE_TEMP_BY} ${COUPLE_DIR}/temperature.nc ${COUPLE_DIR}/temperature.tmp.nc - mv ${COUPLE_DIR}/temperature.tmp.nc ${COUPLE_DIR}/temperature.nc - fi - fi - # Units skipped, although we need a way to ensure they are in Kelvin -} - - -ic_atm2debm_ablation_debm_make_forcing_set_temperature_below_firn_units() { - echo -e "\t\t- setting temperature below_firn units and variable names" - #LA: variable name stays the same - #ncrename -v ${atmosphere_name_temperature_below_firn},tsurf ${COUPLE_DIR}/temperature_below_firn.nc - # Units skipped, although we need a way to ensure they are in Kelvin -} - - -ic_atm2debm_ablation_debm_make_forcing_set_precipitation_units() { - echo -e "\t\t- setting precipitation units and variable names" - ncrename -v ${atmosphere_name_precipitation},precipitation ${COUPLE_DIR}/precipitation.nc - ncatted -a units,precipitation,o,c,"kg m-2 second-1" ${COUPLE_DIR}/precipitation.nc - echo -e "\t\t- LA DEBUG: Use anomaly coupling = ${PREC_ANOM}" - if [[ "x${PREC_ANOM}" == "x1" ]]; then - echo -e "\t\t- use bias correction from this file ${PREC_BIAS_FILE}" - - ${cdo} -s -f nc -P 8 \ - -remapbil,${COUPLE_DIR}/ice.griddes \ - ${PREC_BIAS_FILE} \ - ${COUPLE_DIR}/remapped.precbias_file.nc - ${cdo} -s -P 8 \ - -setmisstoc,0 - -ifthen -gtc,0 ${COUPLE_DIR}/remapped.precbias_file.nc - ${COUPLE_DIR}/remapped.precbias_file.nc tmp.nc - mv tmp.nc ${COUPLE_DIR}/remapped.precbias_file.nc - - ${COUPLE_DIR}/temperature.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - cdo -s -sub ${COUPLE_DIR}/precipitation.nc ${COUPLE_DIR}/remapped.precbias_file.nc ${COUPLE_DIR}/precipitation.tmp.nc - mv ${COUPLE_DIR}/precipitation.tmp.nc ${COUPLE_DIR}/precipitation.nc - fi -} - - -ic_atm2debm_ablation_debm_make_forcing_set_cloud_cover_units() { - echo -e "\t\t- NO CHANGES for clouds units and variable names" -} - - -ic_atm2debm_ablation_debm_make_forcing_set_shortwave_units() { - echo -e "\t\t- NO CHANGES for shortwave units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_TOAshortwave_units() { - echo -e "\t\t- NO CHANGES for TOAshortwave units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_emissivity_units() { - echo -e "\t\t- NO CHANGES for emissivity units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_transmissivity_units() { - echo -e "\t\t- NO UKK CHANGES for transmissivity units and variable names" - #ncrename -v ${atmosphere_name_transmissivity},tau ${COUPLE_DIR}/transmissivity.nc - #ncatted -a units,transmissivity,o,c,"" ${COUPLE_DIR}/transmissivity.nc -} - -ic_atm2debm_ablation_debm_make_forcing_set_humidity_units() { - echo -e "\t\t- NO CHANGES for humidity units and variable names" -} - -ic_atm2debm_ablation_debm_make_forcing_set_longwave_units() { - echo -e "\t\t- NO CHANGES for longwave units and variable names" -} - - -ic_atm2debm_ablation_debm_make_forcing_merge_preliminary_files() { - echo -e "\t\t- merging together atmospheric temperature, precip, cloud cover, SW and LW radiation" - if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - $cdo -s -O \ - -merge \ - ${COUPLE_DIR}/temperature.nc \ - ${COUPLE_DIR}/precipitation.nc \ - ${COUPLE_DIR}/cloud_cover.nc \ - ${COUPLE_DIR}/shortwave_down.nc \ - ${COUPLE_DIR}/TOAshortwave.nc \ - ${COUPLE_DIR}/emissivity.nc \ - ${COUPLE_DIR}/transmissivity.nc \ - ${COUPLE_DIR}/humidity.nc \ - ${COUPLE_DIR}/uv.nc \ - ${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - #${COUPLE_DIR}/uv.nc \ - else - $cdo -s -O \ - -merge \ - ${COUPLE_DIR}/temperature.nc \ - ${COUPLE_DIR}/precipitation.nc \ - ${COUPLE_DIR}/cloud_cover.nc \ - ${COUPLE_DIR}/shortwave_down.nc \ - ${COUPLE_DIR}/TOAshortwave.nc \ - ${COUPLE_DIR}/emissivity.nc \ - ${COUPLE_DIR}/transmissivity.nc \ - ${COUPLE_DIR}/humidity.nc \ - ${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - fi - echo -e "\t\t- UKK input_file_for_debm_" ${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism} - #${COUPLE_DIR}/temperature_below_firn.nc \ -} - - - - -## @fn ic_atm2pism_set_options_surface_given -## @brief -## Sets surface given options for the next PISM run -ic_debm2pism_ablation_debm_set_options_surface_given() { - pism_conf_file_list="${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat ${COUPLE_DIR}/pism_config_value_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat" - for pism_conf_file in $pism_conf_file_list; do - if [ ! -f $pism_conf_file ]; then - :> $pism_conf_file - fi - done - - echo "pism_set_coupler___surface=given" >> \ - ${COUPLE_DIR}/pism_coupler_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - echo "pism_set_forcing_file___surface_given=${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc" >> \ - ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat - echo "pism_set_config_value_FORCE___surface_given_period=$(cdo -s nyear ${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc)" \ - >> ${COUPLE_DIR}/pism_forcing_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.dat -} - - -ic_atm2debm_ablation_debm_run_modify_nml() { - PISM_GRID_FILE=${COUPLE_DIR}/ice.griddes - number_of_timesteps=$(cdo -s ntime ${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc) - - number_of_x_points=$(grep 'xsize' $PISM_GRID_FILE | head -n 1 | awk '{print $3}') - number_of_y_points=$(grep 'ysize' $PISM_GRID_FILE | head -n 1 | awk '{print $3}') - TMP=$( grep cobld $( ls -t ${COUPLE_DIR}/../run_*/work/namelist.echam | head -1 ) | sed 's/^[ \t]*//' ) - prefix="cobld = " - MY_OBLIQUITY=${TMP#"$prefix"} - obliquity_value=${MY_OBLIQUITY:-"23.441"} - - echo -e "\t\t- Generating namelist for dEBM Mass Balance Model" - echo -e "\t\t- Obliquity = ${obliquity_value}" - - # Plus ten points for Shan: variable names are actually variable. Sortof... - # UKK Paul, sometimes I don't understand you - -if [[ "x${DEBM_BETA}" == "xWIND" ]]; then - cat -> ${COUPLE_DIR}/namelist.debm << EOF -! This is the namelist file for model general configuration - -&runctl -lresume=.false. ! if restart, read snow height from 'restart_debm.nc' - ! .false. by default -use_shortwave_radiation_TOA=.true. ! if incorporate top incoming shortwave -use_mask=.false. ! ice mask -debug_switch=.true. ! debug option - ! .false. by default -debug_lon=241 ! if debug_switch=.true. -debug_lat=107 ! debug grid point(debug_lon,debug_lat,debug_mon,debug_year) -debug_mon=7 ! will be print during simulation -debug_year=1 -/ - -&debm -filename_in='${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc' - -precipitation_varname='precipitation' -temperature_varname='air_temp' -shortwave_radiation_downward_varname='swd' -shortwave_radiation_TOA_varname='TOAswd' -cloud_cover_varname='cc' -emissivity_varname='emiss' -transmissivity_varname='tau' -windvelocity_varname='uv' -mapping_varname='thk' -longitude_varname='lon' -latitude_varname='lat' -time_varname='time' - -hydmth_str = 10 ! the beginning of the hydrological year, also start month for snow height integration - ! October for Northern Hemisphere - ! April Southern Hemisphere -stddev=3.5 ! constant standard deviation -obliquity=${obliquity_value} -cloud_bias=0.155 ! cloud bias -Ans = .845 ! Albedo for new snow -Ads = .73 ! Albedo for dry snow -Aws = .55 ! Albedo for wet snow -tau_cs = .75 ! expected clear sky transmissivity -residual = 0 ! residual heat flux (e.g. due to flux into the ice sheet -/ -EOF -elif [[ "x${DEBM_BETA}" == "x999" ]]; then - cat -> ${COUPLE_DIR}/namelist.debm << EOF -! This is the namelist file for model general configuration - -&runctl -lresume=.false. ! if restart, read snow height from 'restart_debm.nc' - ! .false. by default -use_shortwave_radiation_TOA=.true. ! if incorporate top incoming shortwave -use_mask=.false. ! ice mask -debug_switch=.true. ! debug option - ! .false. by default -debug_lon=241 ! if debug_switch=.true. -debug_lat=107 ! debug grid point(debug_lon,debug_lat,debug_mon,debug_year) -debug_mon=7 ! will be print during simulation -debug_year=1 -/ - -&debm -filename_in='${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc' - -precipitation_varname='precipitation' -temperature_varname='air_temp' -shortwave_radiation_downward_varname='swd' -shortwave_radiation_TOA_varname='TOAswd' -cloud_cover_varname='cc' -emissivity_varname='emiss' -transmissivity_varname='tau' -mapping_varname='thk' -longitude_varname='lon' -latitude_varname='lat' -time_varname='time' - -hydmth_str = 10 ! the beginning of the hydrological year, also start month for snow height integration - ! October for Northern Hemisphere - ! April Southern Hemisphere -stddev=3.5 ! constant standard deviation -obliquity=${obliquity_value} -cloud_bias=0.155 ! cloud bias -Ans = .845 ! Albedo for new snow -Ads = .73 ! Albedo for dry snow -Aws = .55 ! Albedo for wet snow -tau_cs = .75 ! expected clear sky transmissivity -residual = 0 ! residual heat flux (e.g. due to flux into the ice sheet -/ -EOF -else - cat -> ${COUPLE_DIR}/namelist.debm << EOF -! This is the namelist file for model general configuration - -&runctl -lresume=.false. ! if restart, read snow height from 'restart_debm.nc' - ! .false. by default -use_shortwave_radiation_TOA=.true. ! if incorporate top incoming shortwave -use_mask=.false. ! ice mask -debug_switch=.true. ! debug option - ! .false. by default -debug_lon=241 ! if debug_switch=.true. -debug_lat=107 ! debug grid point(debug_lon,debug_lat,debug_mon,debug_year) -debug_mon=7 ! will be print during simulation -debug_year=1 -/ - -&debm -filename_in='${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc' -precipitation_varname='precipitation' -temperature_varname='air_temp' -shortwave_radiation_downward_varname='swd' -shortwave_radiation_TOA_varname='TOAswd' -cloud_cover_varname='cc' -emissivity_varname='emiss' -transmissivity_varname='tau' -mapping_varname='thk' -longitude_varname='lon' -latitude_varname='lat' -time_varname='time' -hydmth_str = 10 ! the beginning of the hydrological year, also start month for snow height integration - ! October for Northern Hemisphere - ! April Southern Hemisphere -stddev=3.5 ! constant standard deviation -obliquity=${obliquity_value} -beta_nml=${DEBM_BETA} -cloud_bias=0.155 ! cloud bias -Ans = .845 ! Albedo for new snow -Ads = .73 ! Albedo for dry snow -Aws = .55 ! Albedo for wet snow -tau_cs = .75 ! expected clear sky transmissivity -residual = 0 ! residual heat flux (e.g. due to flux into the ice sheet -/ -EOF -fi -# cat -> ${COUPLE_DIR}/namelist.debm << EOF -#& debm -# xlen = ${number_of_x_points} -# ylen = ${number_of_y_points} -# tlen = ${number_of_timesteps} -# filename_in = '${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc' -# precipitation_varname = 'precipitation' -# temperature_varname = 'air_temp' -# shortwave_radiation_downward_varname = 'swd' -# mapping_varname = 'orog' -# longitude_varname = 'lon' -# latitude_varname = 'lat' -# time_varname = 'time' -# stddev = 3.5 -# obliquity = ${obliquity_value} -# beta = ${DEBM_BETA} -#/ -#EOF - -echo -e "\t\t- Namelist used in this dEBM run was:" -cat ${COUPLE_DIR}/namelist.debm - -} - - -ic_atm2debm_ablation_debm_run_compile_binary() { - debug_compile_ic_atm2debm_binary=${debug_compile_ic_atm2debm_binary:-1} - # Get a user supplied version if available: - echo "*** DEBM_EXE = ${DEBM_EXE} ***" - if [ ! -z ${DEBM_EXE} ]; then - echo "*** Copy DEBM_EXE into ${COUPLE_DIR}" - cp ${DEBM_EXE} ${COUPLE_DIR}/dEBMmain - elif [ ! -z ${FUNCTION_PATH} ]; then - echo "*** Copy DEBM_EXE from ${FUNCTION_PATH} into ${COUPLE_DIR}" - cp ${FUNCTION_PATH}/dEBM/Fortran/dEBMmain ${COUPLE_DIR}/dEBMmain - fi - - # Clone Shan's fortran version if it's not already here: - if [ ! -f ${COUPLE_DIR}/dEBMmain ]; then - echo -e "\t\t- Couldn't find: ${COUPLE_DIR}/dEBMmain" - if [ ! -d ${COUPLE_DIR}/dEBM ]; then - echo -e "\t\t- Cloning dEBM" - git clone --quiet https://github.com/ukrebska/dEBM - fi - # compile it - current_dir=$(pwd) - cd ${FUNCTION_PATH} - ./install_debm.sh ${MACHINE} 2>> debm_compile_stdout_stderr - - if [ -f ${COUPLE_DIR}/dEBMmain ]; then - echo -e "\t\t * dEBM compilation was successful!" - else - echo -e "\t\t!!! F A T A L E R R O R !!! dEBM not successful. Aborting" - exit - fi - cp dEBMmain ${COUPLE_DIR} - cd $current_dir - fi -} - - -## @fn execute_ic_atm2debm_binary -## @brief -## Runs the Fortran version of the dEBM Mass Balance Model -## -## Note: -## 1) Also checks if the namelist and binary file exist -## 2) The stdout and stderr of dEBM are piped to -## ${COUPLE_DIR}/ic_atm2debm_stdout_stderr. If the program exits with an error code of -## non-zero, this stdout/stderr file is printed to the console. -ic_atm2debm_ablation_debm_run_execute_binary() { - echo -e "\t\t- Running DEBM Binary" - cd ${COUPLE_DIR} - DEBM_BINARY=dEBMmain - DEBM_NAMELIST=namelist.debm - required_files_to_run_dEBM="$DEBM_NAMELIST $DEBM_BINARY" - echo -e "\t\t! UKK required_files_to_run_dEBM=$DEBM_NAMELIST $DEBM_BINARY" - for required_file in $required_files_to_run_dEBM; do - required_file_exit_code=1 - if [ ! -f $required_file ]; then - echo -e "\t\t!!! F A T A L E R R O R !!! required file for dEBM $required_file could not befound, exiting" - exit $required_file_exit_code - fi - required_file_exit_code=$((required_file_exit_code + 1)) - done - - echo $(module list) > ${COUPLE_DIR}/module.list - echo "PATH=${PATH}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH}; NETCDFFROOT=${NETCDFFROOT}" - ./$DEBM_BINARY > debm_stdout_stderr 2>&1 || cat debm_stdout_stderr - cd - -} - - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_add_surface_temperature -## @brief -## generates a surface forcing that could passes down to PISM: dEBM output + air_temp -## dEBM ouput is generated from above functions -## air_temp is yearly mean air_temperature under zero degC calculated from echam output -ic_debm2pism_ablation_debm_make_surface_forcing_add_surface_temperature() { - echo -e "\t\t- Adding yearly-averaged atmospheric surface temperature to surface given file" - echo -e "\t\t NOTE: this serves as a first-order estimate for surface temperature below the firn layer" - cd ${COUPLE_DIR} - - debug_add_surface_temperature=${debug_add_surface_temperature:-0} - - if [ "x${debug_add_surface_temperature}" == "x1" ]; then - echo -e "\t\t@ DEBUG: Getting air temperature" - fi - # select air_temperature - #LA: change timmean to ymonmean - if [[ "x${MULTI_YEAR_MEAN_SMB}" == "x1" ]]; then - cdo -s \ - -ymonmean \ - -selvar,tsurf \ - ${COUPLE_DIR}/temperature_below_firn.nc \ - tmp0 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - #${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - else - cdo -s \ - -selvar,tsurf \ - ${COUPLE_DIR}/temperature_below_firn.nc \ - tmp0 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - #${COUPLE_DIR}/input_file_for_debm_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - fi - - if [ "x${debug_add_surface_temperature}" == "x1" ]; then - echo -e "\t\t@ DEBUG: Determining temperature scale Kelvin vs Celsius" - fi - - cdo -s \ - -setmisstoc,273.15 \ - -ifthen \ - -ltc,273.15 \ - tmp0 \ - tmp0 \ - tmp 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - cdo -s \ - -setmisstoc,273.15 \ - tmp \ - tmp1 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - - if [ "x${debug_add_surface_temperature}" == "x1" ]; then - echo -e "\t\t@ DEBUG: Duplicating array 12x" - fi - ## copy this array 12x so you have one for each month - cp tmp1 tmp12 - - cdo -s \ - -settaxis,${CHUNK_START_YEAR_pism}-01-16,23:55:55,1mon \ - tmp12 \ - ${COUPLE_DIR}/air_temp_copy.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - #rm tmp0 tmp tmp1 tmp6 tmp12 - rm tmp0 tmp tmp1 tmp12 - - if [ "x${debug_add_surface_temperature}" == "x1" ]; then - echo -e "\t\t@ DEBUG: Multi-year monthly means" - fi - # merge air_temp with debm output files - # & set time axies - # PG: Why is this set to noon on the year 1000? Does that have any reason? - if [[ "x${MULTI_YEAR_MEAN_SMB}" == "x1" ]]; then - cdo -s \ - -ymonmean \ - -settaxis,${CHUNK_START_YEAR_pism}-01-16,23:55:55,1mon \ - surface_mass_balance.nc \ - tmp 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - else - cdo -s \ - -settaxis,${CHUNK_START_YEAR_pism}-01-16,23:55:55,1mon \ - surface_mass_balance.nc \ - tmp 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - fi - - if [ "x${debug_add_surface_temperature}" == "x1" ]; then - echo -e "\t\t@ DEBUG: Merge and clean up" - fi - cdo -s -O \ - -merge \ - tmp \ - ${COUPLE_DIR}/air_temp_copy.nc \ - ${COUPLE_DIR}/smb.nc 2>> ${COUPLE_DIR}/cdo_stderr_atm2pism - rm tmp - cp ${COUPLE_DIR}/smb.nc ${COUPLE_DIR}/uta_smb.nc - cp ${COUPLE_DIR}/air_temp_copy.nc ${COUPLE_DIR}/uta_air_temp_copy.nc - cleanup_list="$cleanup_list ${COUPLE_DIR}/air_temp_copy.nc" - cd - -} - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_apply_mask -## @brief -## apply a mask for PISM surface forcing -## -## Specific steps: -## 1) creates a glacial mask -## for the first time step, users could specifiy DEBM_MASK_SOURCE_FILE -## then, fn will generate a glacial mask from PISM latest output -## 2) appply the above mask -ic_debm2pism_ablation_debm_make_surface_forcing_apply_mask() { - echo -e "\t\t- Applying a mask" - cd ${COUPLE_DIR} - # TODO/BUG (sxu): It looks like the mask we are getting is just 1 everywhere... is this correct? - - debug_apply_ic_atm2debm_mask=${debug_apply_ic_atm2debm_mask:-0} - # create glacial mask according to the latest output by setting mask.nc 2 3 —> 1; 4 —>0 - mask_file=mask.nc - if [ "x$RUN_NUMBER_pism" == "x1" ]; then - echo -e "\t\t- First run, you can specify to use DEBM_MASK_FILE to get the mask you want to use" - DEBM_MASK_FILE=${DEBM_MASK_FILE:-${POOL_DIR_pism}/masks/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_mask_${RES_pism}.nc} - else - cdo -f nc -selvar,mask ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc mask.nc - DEBM_MASK_FILE=mask.nc - fi - echo -e "\t\t- DEBM_MASK_FILE=${DEBM_MASK_FILE}" - cdo -s selvar,mask -seltimestep,-1 ${DEBM_MASK_FILE} tmp.mask.nc; mv tmp.mask.nc mask.nc 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - cdo -s -lec,3 mask.nc tmp 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - mv tmp ${mask_file} - - #if [[ "x${DEBM_BETA}" == "x999" ]]; then - # # apply mask - # #for var in SNH ME SMB RZ A air_temp; do - # for var in SNH ME SMB RZ A tsurf; do - # #cdo -s -f nc ifthen ${mask_file} -selvar,${var} smb.nc ${var} 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - # cdo -s -f nc -selvar,${var} smb.nc ${var} 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - # done - # #cdo -s -O merge SNH ME SMB RZ A air_temp surface_mass_balance_masked.nc 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - # cdo -s -O merge SNH ME SMB RZ A tsurf surface_mass_balance_masked.nc 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - - # cp surface_mass_balance_masked.nc ${COUPLE_DIR}/uta_surface_mass_balance_masked2.nc - # # TODO/BUG (sxu): For right now, Paul is just filling in any missing - # # values with a setmisstodis, maybe there is a better way to solve - # # this? - - # #cdo -s -O -setmisstodis surface_mass_balance_masked.nc tmp - - # # TODO(sxu) Not urgent, but we can use a cleanup list for this, that - # # way we can have a debug step print it out if anything needs to get - # # checked. - # # make clean - # #rm SNH ME SMB RZ A air_temp - # rm SNH ME SMB RZ A tsurf - # rm smb.nc - #else - # apply mask - for var in SNH ME SMB RZ A tsurf; do - cdo -s -f nc -selvar,${var} smb.nc ${var} 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - done - cdo -s -O merge SNH ME SMB RZ A tsurf surface_mass_balance_masked.nc 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - - cp ${COUPLE_DIR}/uta_smb.nc ${COUPLE_DIR}/uta_surface_mass_balance_masked3.nc - cdo -selvar,SNH,ME,SMB,RZ,A,tsurf ${COUPLE_DIR}/smb.nc ${COUPLE_DIR}/surface_mass_balance_masked.nc - - rm SNH ME SMB RZ A tsurf - rm smb.nc - #fi - if [ ! -f ${COUPLE_DIR}/${mask_file} ]; then - mv ${mask_file} ${COUPLE_DIR}/ - fi - if [ "x${debug_apply_ic_atm2debm_mask}" == "x1" ]; then - echo -e "\t\t@ DEBUG: Opening the results in ncview for you" - # Put this in the background, or it blocks the rest of the script - ncview surface_mass_balance_masked.nc & - fi - - cdo -splitname \ - surface_mass_balance_masked.nc \ - ${COUPLE_DIR}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_\ - 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - cd - -} - - - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_set_temperature_varname_and_units -## @brief -## ## Sets variables name that conform to PISM standards -## -## Sets air_temp to ice_surface_temp -ic_debm2pism_ablation_debm_make_surface_forcing_set_temperature_varname_and_units() { - echo -e "\t\t- Setting variable name and unit for temperature" - echo -e "\t\t- In surface_given variant, this corresponds to firn temperature" - - #debm_ice_temp_varname="air_temp" - debm_ice_temp_varname="tsurf" - pism_ice_temp_varname="ice_surface_temp" - ncrename \ - -v ${debm_ice_temp_varname},${pism_ice_temp_varname} \ - ${COUPLE_DIR}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_ice_temp_varname}.nc - # TODO(pg or shan): Unit check -} - - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_set_smb_varname_and_units -## @brief -## ## Sets variables name that conform to PISM standards -## -## Sets SMB to climatic_mass_balance -ic_debm2pism_ablation_debm_make_surface_forcing_set_smb_varname_and_units() { - echo -e "\t\t- Setting variable name and unit for SMB" - - debm_mass_balance_varname="SMB" - pism_mass_balance_varname="climatic_mass_balance" - ncrename \ - -v ${debm_mass_balance_varname},${pism_mass_balance_varname} \ - ${COUPLE_DIR}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_mass_balance_varname}.nc - ncatted -a \ - units,${pism_mass_balance_varname},o,c,"kg m-2 s-1" \ - ${COUPLE_DIR}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_mass_balance_varname}.nc \ - tmp_${debm_mass_balance_varname} - #cp tmp_${debm_mass_balance_varname} ${COUPLE_DIR}/uta_tmp_${debm_mass_balance_varname} - mv tmp_${debm_mass_balance_varname} \ - ${COUPLE_DIR}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_mass_balance_varname}.nc -} - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_merge_preliminary_files -## @brief -## merge temperature and surface mass balance -## -ic_debm2pism_ablation_debm_make_surface_forcing_merge_preliminary_files() { - echo -e "\t\t- Merging below-firn temperature and surface mass balance together!" - cdo -O merge \ - ${COUPLE_DIR}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_ice_temp_varname}.nc \ - ${COUPLE_DIR}/debm_output_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}_${debm_mass_balance_varname}.nc \ - ${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc \ - 1>> ${COUPLE_DIR}/cdo_stderr_atm2pism 2>&1 - #cp ${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc ${COUPLE_DIR}/uta_surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc -} - -## @fn ic_debm2pism_ablation_debm_make_surface_forcing_set_time_axis -## @brief -## adds a time axis to a forcing file -## -ic_debm2pism_ablation_debm_make_surface_forcing_set_time_axis() { - echo -e "\t\t- Adding a time axis" - - # Determine how many timesteps we have and set time unit accordingly - nt=$(${cdo} -s ntime ${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc) - if [ "x$nt" == "x1" ]; then - echo " - only ONE timestep given" - time_unit="year" - echo "Dont know what to do" - exit 8 - else - echo " - assuming MONTHLY MEANS (for now -- using 30 equivalent days per month)" - time_calendar="360_day" - fi - - #cp ${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc ${COUPLE_DIR}/uta_dummy.nc - ncatted \ - -a \ - bounds,time,o,c,"time_bnds" \ - -a \ - calendar,time,o,c,${time_calendar} \ - ${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc tmp_with_taxis \ - && mv tmp_with_taxis ${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - - ${FUNCTION_PATH}/../utils/CreateTimeAxisNC.bash ${nt} ${COUPLE_DIR}/time_axis_pism.nc 0 classic 365_day #${CHUNK_START_YEAR_pism} - ncks -A \ - ${COUPLE_DIR}/time_axis_pism.nc \ - ${COUPLE_DIR}/surface_given_file_${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}.nc - - #FAILURE: ncks -A ${POOL_DIR_pism}/grids/${DOMAIN_pism}/pismr_${DOMAIN_pism}_${RES_pism}_xy.nc ${COUPLE_DIR}/atmo_given_file.nc - # Producesses unrealistic x-/y-arrays with a values like: -8.0e+51, 1.7e+161, 1.e-258 - - # PG: Why was this necessary? - # iterative_coupling_pism_regrid_add_xy_array ${COUPLE_DIR}/atmo_given_file.nc "atmosphere" - # TODO: cleanup_list="${cleanup_list} ${COUPLE_DIR}/temperature.nc ${COUPLE_DIR}/precipitation.nc" - -} - - -################################################################################ -################################################################################ -# U T I L I T Y F U N C T I O N S -################################################################################ -################################################################################ -# NOTE: These probably should be moved to a general file. - - -## @fn cdo_verbosity() -## @brief -## Controls how verbose CDO should be. -cdo_verbosity() { - if [ "x$CDO_QUIET" == "x1" ]; then - cdo="cdo -s" - elif [ "x$CDO_VERBOSE" == "x1" ]; then - cdo="cdo -v" - else - cdo=cdo - fi -} diff --git a/couplings/pism/coupling_awiesm2pism.functions b/couplings/pism/coupling_awiesm2pism.functions deleted file mode 100644 index 3a19b5087..000000000 --- a/couplings/pism/coupling_awiesm2pism.functions +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/ksh -awiesm2pism() { - . ${FUNCTION_PATH}/coupling_atmosphere2pism.functions - . ${FUNCTION_PATH}/coupling_ocean2pism.functions - . ${FUNCTION_PATH}/../general/pism_helpers.functions - . ${FUNCTION_PATH}/../general/general_lists.functions - - if [ -f ${COUPLE_DIR}/latest_atmo_forcing_file.nc ]; then - rm ${COUPLE_DIR}/latest_atmo_forcing_file.nc - fi - - if [ -f ${COUPLE_DIR}/latest_ocean_forcing_file.nc ]; then - rm ${COUPLE_DIR}/latest_ocean_forcing_file.nc - fi - atmosphere2pism - ocean2pism -} diff --git a/couplings/pism/coupling_ocean2pism.functions b/couplings/pism/coupling_ocean2pism.functions deleted file mode 100644 index f46ba93fe..000000000 --- a/couplings/pism/coupling_ocean2pism.functions +++ /dev/null @@ -1,926 +0,0 @@ -#!/usr/bin/ksh - -function ocean2pism { - echo " *** S T A R T I N G ocean2pism *** (PISM version ${VERSION_pism})" - - echo $(module list) - . ${FUNCTION_PATH}/../general/coupling_general.functions - . ${FUNCTION_PATH}/../general/general_lists.functions - - #CHUNK_DATE_TAG_pism="${CHUNK_START_DATE_pism}-${CHUNK_END_DATE_pism}" - CHUNK_DATE_TAG_pism="${CURRENT_YEAR_pism}-${END_YEAR_pism}" - - INTERPOL_TYPE_OCE=${INTERPOL_TYPE_OCE:-"dis"} #Standard=dis : "bil" "con" "dis" "nn", "bil" doesn't work for FESOM - WEIGHTS_OCE2ICE=${WEIGHTS_OCE2ICE:-weights_oce2ice.${INTERPOL_TYPE_OCE}.nc} - GRIDDES_ICE=${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes - GRIDDES_OCE=${GRIDDES_OCE:-ocean.griddes} - PISM_OCEAN_FORCING_FILE=${COUPLE_DIR}/"ocean_forcing4pism_ver${VERSION_pism}.${INTERPOL_TYPE_OCE}.${CHUNK_DATE_TAG_pism}.nc" - - OCEAN_3EQN_ICE_FORCE_PY_SCRIPT=${FUNCTION_PATH:-${FPATH}}/ocean_3eqn_ismforce.py - - PISM_OCEAN_SWITCH="" - PISM_OCEAN_FILE_SWITCH="" - - iter_coup_regrid_method_oce2ice=${iter_coup_regrid_method_oce2ice:-EXTRAPOLATE} - iter_coup_interact_method_oce2ice=${iter_coup_interact_method_oce2ice:-OCEANTEMPSALT} - - read_names ocean ice - save_griddes ice - - NOCOLOR='\033[0m' - GREEN='\033[32m' - - echo "Interaction (ocean) : ${iter_coup_interact_method_oce2ice} (1/2)" - echo -e " --> Interaction >>> ${GREEN}${iter_coup_interact_method_oce2ice}${NOCOLOR} <<< ocean (Step 1/2: names)" - case $iter_coup_interact_method_oce2ice in - "DIRECT") - # - # Take DIRECTly the forcing coming from the ocean model - # - PISM_OCEAN_SWITCH="-ocean given" - PISM_OCEAN_FILE_SWITCH="-ocean_given_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_direct_forcing - ;; - "MIXED"|"TS_RESCALED2FLUX") - # - # Take directly the forcing coming from the ocean model - # and rescale it with `ocean_3eqn_iceforce.py` computed - # fluxes -- NOT YET IMPLEMENTED - # - PISM_OCEAN_SWITCH="-ocean given" - PISM_OCEAN_FILE_SWITCH="-ocean_given_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_mixed_forcing - ;; - "OCEANTEMP") - # - # Provide the ice sheet model (here PISM) the temperature - # 3dim field (constant in time) and the PISM computes the - # basal ice shelf conditions - # - PISM_OCEAN_SWITCH="-ocean o3d" - PISM_OCEAN_FILE_SWITCH="-ocean_o3d_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_temp_forcing - ;; - "OCEANTEMPSALT") - # - # Provide the ice sheet model (here PISM) the temperature - # and salinity 3dim fields (constant in time) and the PISM - # computes the basal ice shelf conditions - # - PISM_OCEAN_SWITCH="-ocean th" - PISM_OCEAN_FILE_SWITCH="-ocean_th_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_tempsalt_forcing - ;; - "PICO_OCEAN") - # - # Provide the ice sheet model temperature and salinity - # fields and PISM computes via the "PICO" submodel the - # ice shelf conditions - # - #PISM_OCEAN_SWITCH="-ocean pico -ocean.pico.continental_shelf_depth 700" - - PISM_OCEAN_SWITCH="-ocean pico" - PISM_OCEAN_FILE_SWITCH="-ocean_pico_file ${PISM_OCEAN_FORCING_FILE}" - PISM_OCEAN_PICO_BASINS_FILE=${PISM_OCEAN_PICO_BASINS_FILE:-${PISM_OCEAN_FORCING_FILE}} - echo " * Doing iterative_coupling_ocean_pism_prepare_ocean_tempsalt_forcing ..." - iterative_coupling_ocean_pism_prepare_ocean_tempsalt_forcing - echo " ...done." - - #echo " * Doing iterative_coupling_ocean_pism_prepare_pico_ocean_forcing ..." - #iterative_coupling_ocean_pism_prepare_pico_ocean_forcing ${PISM_OCEAN_PICO_BASINS_FILE} ${PISM_OCEAN_FORCING_FILE} - #echo " ...done." - ;; - "TEMP2FLUX") - # - # Use the python script `ocean_3eqn_iceforce.py` and - # compute the basal temporal evolving conditions based - # only on the 3dim oceanic temperature distribution - # - PISM_OCEAN_SWITCH="-ocean given" - PISM_OCEAN_FILE_SWITCH="-ocean_given_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_temp2flux_forcing - ;; - "TEMPSALT2FLUX") - # - # Use the python script `ocean_3eqn_iceforce.py` and - # compute the basal temporal evolving conditions based on - # 3dim oceanic temperature and salinity distributions - # - PISM_OCEAN_SWITCH="-ocean given" - PISM_OCEAN_FILE_SWITCH="-ocean_given_file ${PISM_OCEAN_FORCING_FILE}" - iterative_coupling_ocean_pism_prepare_ocean_tempsalt2flux_forcing - ;; - *) - echo " UNKNOWN mass balance selected!" - echo " Known: DIRECT, MIXED, OCEANTEMP, PICO_OCEAN, TEMP2FLUX, TEMPSALT2FLUX" - echo " S T O P 1" - exit 1 - esac - - echo "Grid method (ocean) : ${iter_coup_regrid_method_oce2ice}" - echo -e " --> Grid method >>> ${GREEN}${iter_coup_regrid_method_oce2ice}${NOCOLOR} <<< ocean" - case $iter_coup_regrid_method_oce2ice in - "INTERPOLATE"|"REMAP") - iterative_coupling_ocean_pism_regrid_interpolate - ;; - "EXTRAPOLATE") - iterative_coupling_ocean_pism_regrid_interpolate - iterative_coupling_ocean_pism_regrid_extrapolate - ;; - "NONE") - # Ocean and ice sheet grid are identical !! - INTERPOL_TYPE_OCE=none - SM_OCEAN_FORCING_FILE3 iterative_coupling_ocean_pism_regrid_none - ;; - *) - echo " UNKNOWN regrid method selected!" - echo " Known: INTERPOLATE = REMAP, EXTRAPOLATE, NONE" - echo " S T O P 2" - exit 2 - esac - - echo "Interaction (ocean) : ${iter_coup_interact_method_oce2ice} (2/2)" - echo -e " --> Interaction >>> ${GREEN}${iter_coup_interact_method_oce2ice}${NOCOLOR} <<< ocean (Step 2/2: final file)" - case $iter_coup_interact_method_oce2ice in - "DIRECT") - iterative_coupling_ocean_pism_compute_ocean_direct_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "MIXED"|"TS_RESCALED2FLUX") - iterative_coupling_ocean_pism_compute_ocean_mixed_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "OCEANTEMP") - iterative_coupling_ocean_pism_compute_ocean_temp_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "OCEANTEMPSALT") - iterative_coupling_ocean_pism_compute_ocean_tempsalt_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "PICO_OCEAN") - iterative_coupling_ocean_pism_compute_ocean_tempsalt_forcing ${PISM_OCEAN_FORCING_FILE} - PISM_OCEAN_PICO_BASINS_FILE=${PISM_OCEAN_PICO_BASINS_FILE:-${PISM_OCEAN_FORCING_FILE}} - echo " * Doing iterative_coupling_ocean_pism_prepare_pico_ocean_forcing ..." - iterative_coupling_ocean_pism_prepare_pico_ocean_forcing ${PISM_OCEAN_PICO_BASINS_FILE} ${PISM_OCEAN_FORCING_FILE} - echo " ...done." - ;; - "TEMP2FLUX") - iterative_coupling_ocean_pism_compute_ocean_temp2flux_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - "TEMPSALT2FLUX") - iterative_coupling_ocean_pism_compute_ocean_tempsalt2flux_forcing ${PISM_OCEAN_FORCING_FILE} - ;; - *) - echo " UNKNOWN mass balance selected!" - echo " Known: DIRECT, MIXED, OCEANTEMP, TEMP2FLUX, TEMPSALT2FLUX" - echo " S T O P 3" - exit 3 - esac - - #iterative_coupling_ocean_pism_set_options - iterative_coupling_ocean_pism_regrid_set_time_axis ${PISM_OCEAN_FORCING_FILE} - iterative_coupling_pism_regrid_add_xy_array ${PISM_OCEAN_FORCING_FILE} "ocean" - - ln -sf "${COUPLE_DIR}/ocean_forcing4pism_ver${VERSION_pism}.${INTERPOL_TYPE_OCE}.${CHUNK_DATE_TAG_pism}.nc" "${COUPLE_DIR}/latest_ocean_forcing_file.nc" - - for file in ${cleanup_list} ; do test -f $file && rm $file ; done - - unset cleanup_list file - - unset NOCOLOR GREEN - unset PISM_OCEAN_SWITCH PISM_OCEAN_FILE_SWITCH PISM_OCEAN_FORCING_FILE - - max_retry=12 - retry=0 - sleep 10 # Minimum time for st_new.sh to finish - - while [ ${retry} -lt ${max_retry} ]; do - if [ -f ${COUPLE_DIR}/latest_ocean_forcing_file.nc ]; then - break # call results.sh outside loop - else - (( retry = retry + 1 )) - sleep 1 - fi - done - if [ ! -f ${COUPLE_DIR}/latest_ocean_forcing_file.nc ]; then - echo "Something wrong after waiting for 120 seconds!" - fi - echo " ...done." -} - -function save_griddes { - model_type=$1 - if [ ! -f ${COUPLE_DIR}/${model_type}.griddes ]; then - echo "Saving ${model_type}.griddes" - if [ -f ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes ]; then - cp ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - ${COUPLE_DIR}/${model_type}.griddes - else - echo " Was Looking for: ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes" - echo "Could not find griddes file, exiting..." - echo " S T O P 4 (coupling_ocean2pism.functions::save_griddes)" - exit 4 - fi - else - echo "${model_type}.griddes is in place" - fi -} - - -# -# Compute actual forcing files : Convert variable names to pism names -# -function iterative_coupling_ocean_pism_prepare_ocean_direct_forcing { - echo "Preparing direct ocean forcing (${PISM_OCEAN_SWITCH:-Unknown}) file with sensible units..." - # PISM0.7 : shelfbtemp [degC], shelfbmassflux [kg m-2 s-1] -## $cdo -select,name=wnet,Tsurf - - # Rename all input variables - cdo_table_file=cdo_partable.txt - iterative_coupling_ocean_pism_fesom2pism_names $cdo_table_file - - # Extend the list: Delete not needed one - cat >> $cdo_table_file <> $cdo_table_file <> $cdo_table_file <> $cdo_table_file <flux forcing (${PISM_OCEAN_SWITCH:-Unknown}) file with sensible units..." - # PISM0.7 : shelfbtemp [degC], shelfbmassflux [kg m-2 s-1] - # Rename all input variables - cdo_table_file=cdo_partable.txt - iterative_coupling_ocean_pism_fesom2pism_names $cdo_table_file - - # Extend the list: Delete not needed one - cat >> $cdo_table_file <flux forcing (${PISM_OCEAN_SWITCH:-Unknown}) file with sensible units..." - # PISM0.7 : shelfbtemp [degC], shelfbmassflux [kg m-2 s-1] - - # Rename all input variables - cdo_table_file=cdo_partable.txt - iterative_coupling_ocean_pism_fesom2pism_names $cdo_table_file - - # Extend the list: Delete not needed one - cat >> $cdo_table_file < ${_file:-cdo_partable.txt} < remap,$GRIDDES_ICE,$WEIGHTS_OCE2ICE" - $cdo remap,$GRIDDES_ICE,$WEIGHTS_OCE2ICE \ - ocean_file_for_ice.pism_names.nc \ - ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc - - cleanup_list="${cleanup_list}" # $(pwd)/ocean_file_for_ice.nc $(pwd)/ocean_file_for_ice.pism_names.nc" -} - -function iterative_coupling_ocean_pism_regrid_extrapolate { - # - # This has to be called after the interpolation, because after the - # interpolation we have landpoints that does not exist in the - # FESOM ocean grid - regrid_ocean_pism_extrapolate_misstoc=${regrid_ocean_pism_extrapolate_misstoc:-0} - iterative_coupling_ocean_pism_regrid_extra_type=${iterative_coupling_ocean_pism_regrid_extra_type:-fillmiss2} - echo " * Extrapolate GCM forcing with method >>${iterative_coupling_ocean_pism_regrid_extra_type}<< ..." - - _cdo_flag=$( return_allowed_cdo_miss_replace_flags ${iterative_coupling_ocean_pism_regrid_extra_type} ${regrid_ocean_pism_extrapolate_misstoc} ) - - _tmp_file=ocean_file_at_ice.${INTERPOL_TYPE_OCE}_before_extrapolation.nc - mv ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${_tmp_file} - - $cdo $_cdo_flag ${_tmp_file} \ - ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc - - echo " ... done" - cleanup_list="${cleanup_list} $(pwd)/${_tmp_file}" - unset _cdo_flag _tmp_file -} - -function iterative_coupling_ocean_pism_regrid_none { - echo " * Grid-identical GCM forcing (no interpolation)..." - - test_file_or_exit ${COUPLE_DIR}/ocean_file_for_ice.nc 7 - - mv ${COUPLE_DIR}/ocean_file_for_ice.nc \ - ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc - - cleanup_list="${cleanup_list}" # $(pwd)/ocean_file_for_ice.nc" -} - -# -# Compute actual boundary conditions for ice sheet/shelf if wanted -# -function iterative_coupling_ocean_pism_compute_ocean_direct_forcing { - _file=$1 - _action_string=": rename file" - echo " * Building direct ocean forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - mv -f ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/$(basename ${_file}) - echo " ...done." -} - -function iterative_coupling_ocean_pism_compute_ocean_mixed_forcing { - _file=$1 - _action_string=": Rescale basal melt and temperature with temperature and salt to basal melt and temperature" - echo " * Building mixed ocean forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - - echo -e "CCR: \033[41m NOT YET IMPLEMENTED (A) \033[0m" - echo " S T O P "; exit 1999 - cp ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/$(basename ${_file}) - - - echo " ...done." -} - - -function iterative_coupling_ocean_pism_compute_ocean_temp_forcing { - _file=$1 - _action_string=": rename file" - echo " * Building ocean temperature-based forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - mv -f ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/$(basename ${_file}) - # Nothing to do, since ocean forcing is already in the right format - echo " ...done." -} - - -function iterative_coupling_ocean_pism_compute_ocean_tempsalt_forcing { - _file=$1 - if [ 0 -eq 1 ] ; then - _action_string=": vertical mean (150-600m) of temperature and salinity" ; - cdovert_flag="-sellevel,150/600" - else - _action_string=": vertical mean (index 1-20) of temperature and salinity" - cdovert_flag="-sellevidx,1/20" - fi - echo " * Building ocean temperature-based forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - - iterative_coupling_ocean_pism_fesom2pism_collapse_depth ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/$(basename ${_file}) "${cdovert_flag}" - - echo " ...done." -} - - -function iterative_coupling_ocean_pism_compute_ocean_temp2flux_forcing { - _file=$1 - _action_string=": temperature to basal melt and temperature" - echo " * Building ocean temperature->flux forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - - echo -e "CCR: \033[41m NOT YET IMPLEMENTED (B) \033[0m" - echo -e "CCR: \033[41m YOU may switch to NOT YET IMPLEMENTED 'TEMPSALT2FLUX' \033[0m" - echo " S T O P "; exit 2999 - - cp ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/$(basename ${_file}) - - echo " ...done." -} - -function iterative_coupling_ocean_pism_compute_ocean_tempsalt2flux_forcing { - _file=$1 - _action_string=": temperature+salt to basal melt and temperature ($(basename $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT))" - echo " * Building ocean temperature+salt->flux forcing (${PISM_OCEAN_SWITCH:-Unknown}) $_action_string -> $_file ..." - - - test_file_or_exit ${INPUT_FILE_pism} 14 - - case ${VERSION_pism:--0.1} in - "0.7") - _upper_ice_temperature_varname="ice_surface_temp" - ;; - "1.0"|"1.1") - _upper_ice_temperature_varname="ice_surface_temp" - ;; - *) - echo "NOT DEFINED PISM version >${VERSION_pism}<" - echo "Please adjust function >iterative_coupling_ocean_pism_compute_ocean_tempsalt2flux_forcing< in 'coupling_ocean2pism.functions'" - echo " S T O P 15" - exit 15 - ;; - esac - - echo " ---------- starting $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT -------------" - _out_fname=${COUPLE_DIR}/$(basename $_file ) - _py_logging_file="hydrography2ism_ocean_forcing.log" - echo "==> python $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT --OCEAN_INPUT_FILE ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc --ISM_INPUT_FILE ${INPUT_FILE_pism} --OCEAN_TEMP_VARIABLE $_oce_temp3D_varn --OCEAN_SALT_VARIABLE $_oce_salt3D_varn --ISM_ICE_TEMP_VARIABLE $_upper_ice_temperature_varname --ISM_GRID_HEIGHT 0 --ISM_GRID_LENGTH 0 --OUT_CALC_FRONTAL_MELT False --OUT_CALC_LESS_BASAL_LOW_CAVITY False --LOGGING_OUTPUT_FILE ${_py_logging_file} --OUTPUT_FILE ${_out_fname} --LOGGING_OUTPUT_LEVEL INFO" - - echo "Python version:" - python --version - - python $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT \ - --OCEAN_INPUT_FILE ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc \ - --ISM_INPUT_FILE ${INPUT_FILE_pism} \ - --OCEAN_TEMP_VARIABLE $_oce_temp3D_varn \ - --OCEAN_SALT_VARIABLE $_oce_salt3D_varn \ - --ISM_ICE_TEMP_VARIABLE $_upper_ice_temperature_varname \ - --ISM_GRID_HEIGHT 0 \ - --ISM_GRID_LENGTH 0 \ - --OUT_CALC_FRONTAL_MELT False \ - --OUT_CALC_LESS_BASAL_LOW_CAVITY False \ - --LOGGING_OUTPUT_FILE ${_py_logging_file} \ - --OUTPUT_FILE ${_output_filename} -# Standard -# --OUT_CALC_BASAL_MELT True \ -# --OUT_CALC_BASAL_TEMP True \ -# --OUT_CALC_FRONTAL_MELT False \ -# --OUT_CALC_LESS_BASAL_LOW_CAVITY False \ -# -# Plus frontal melting -# --OUT_CALC_FRONTAL_MELT True -# --OUT_CALC_MERGE_BASAL_FRONTAL_MELT True \ - - echo " ---------- returned from $OCEAN_3EQN_ICE_FORCE_PY_SCRIPT --------" - for MessageTag in WARNING ERROR CRITICAL ; do - _nummer=$(grep ${MessageTag} ${_py_logging_file} | wc -l) - if [ ${_nummer} -gt 0 ] ; then - echo "** Found $_nummer ${MessageTag}(s)" - grep ${MessageTag} ${_py_logging_file} - fi - done - - test_file_or_exit ${_out_fname} 15 - - unset _upper_ice_temperature_varname _file _py_logging_file _nummer _out_fname - echo " ...done." -} - -# -# Auxillary functions -# -function iterative_coupling_ocean_pism_set_options { - echo ""; echo " * set PISM setting for ocean forcing" - pism_conf_file_list="${COUPLE_DIR}/pism_coupler_${CHUNK_DATE_TAG_pism}.dat ${COUPLE_DIR}/pism_forcing_${CHUNK_DATE_TAG_pism}.dat ${COUPLE_DIR}/pism_config_value_${CHUNK_DATE_TAG_pism}.dat" - for pism_conf_file in $pism_conf_file_list; do - if [ ! -f $pism_conf_file ]; then - :> $pism_conf_file - fi - done - - echo "$(pism_coupler_to_esm_runsscripts_syntax ${PISM_OCEAN_SWITCH[@]})" \ - >> ${COUPLE_DIR}/pism_coupler_${CHUNK_DATE_TAG_pism}.dat - echo "$(pism_forcing_to_esm_runsscripts_syntax ${PISM_OCEAN_FILE_SWITCH[@]})" \ - >> ${COUPLE_DIR}/pism_forcing_${CHUNK_DATE_TAG_pism}.dat -} - -function iterative_coupling_ocean_pism_regrid_set_time_axis { - _file_name_add_timeaxis=$1 - echo ""; echo " * setting time axis >>${_file_name_add_timeaxis}<<" - _script2build_time_axis=${FUNCTION_PATH}/../utils/CreateTimeAxisNC.bash - - test_file_or_exit ${_file_name_add_timeaxis} 8 - # Number of timesteps in file - _nt=$( ${cdo} -s ntime ${_file_name_add_timeaxis} ) - - if [ $_nt -lt 1 ]; then - echo " - No time step (continue without adjusting the time axis)" - else - __file_taxis=time_axis.steps$(printf '%05i' ${_nt}).nc - - test -f ${__file_taxis} && rm ${__file_taxis} - if [ ! -f ${__file_taxis} ] ; then - if [ ! -f ${_script2build_time_axis} ] ; then - echo " - Missing ${_script2build_time_axis}" - echo " S T O P 9 (coupling_ocean2pism.functions::iterative_coupling_ocean_pism_regrid_set_time_axis)" - exit 9 - else - echo " - Use $_script2build_time_axis to determine continious time axis" - #${_script2build_time_axis} ${_nt} ${__file_taxis} - #${_script2build_time_axis} ${_nt} ${__file_taxis} 0 classic 360 double - ${_script2build_time_axis} ${_nt} ${__file_taxis} 0 classic 365 float - fi - else - echo " - Reuse time axis file ${__file_taxis}" - fi - - ncks -A ${__file_taxis} ${_file_name_add_timeaxis} - fi - - unset _file_name_add_timeaxis __file_taxis -} - -function iterative_coupling_ocean_pism_fesom2pism_collapse_time { - # NOTE: Could be called at any time (also before regridding and - # reshuffling data with pyfesom script), because the time axis is - # well defined regardless of representation of ocean data as a - # array or 3dim field. - _file_time=$1 - echo ""; echo " * collapse time axis/dimension of >>${_file_time}<<" - - - test_file_or_exit ${_file_time:?Missing file name to collapse time dimension} 12 - - if [ 1 -eq 1 ] ; then - _tmp_file=${_file_time}_before_timmean.nc - mv -f ${_file_time} ${_tmp_file} - $cdo timmean ${_tmp_file} ${_file_time} - else - # Does not work. Why? I do not know - _tmp_file=${_file_time}_before_ncwa.nc - mv -f ${_file_time} ${_tmp_file} - ncwa -a time ${_tmp_file} ${_file_time} - fi - - cleanup_list="${cleanup_list} $(pwd)/${_tmp_file}" - - unset _file_time _tmp_file -} - - -function iterative_coupling_ocean_pism_fesom2pism_collapse_depth { - # NOTE: Could be called ONLY AFTER reshuffling data with pyfesom - # script, because the depth axis is not established before. - # - # Example: - # iterative_coupling_ocean_pism_fesom2pism_collapse_depth ocean_file_at_ice.${INTERPOL_TYPE_OCE}.nc ${COUPLE_DIR}/$(basename ${_file}) "-sellevel,150/600" - # - _file_input=$1 - echo ""; echo " * collapse depth axis/dimension of >>${_file_input}<<" - test_file_or_exit ${_file_input:?Missing file name to collapse depth dimension} 13 - - if [ $# -ge 2 ] ; then - _file_output=$2 - else - # Swap input / output, because input and output file name are identical - _file_output=${_file_input} - _file_input=${_file_input}_before_vertmean.nc - mv -f ${_file_output} ${_file_input} - fi - if [ $# -ge 3 ] ; then - _cdovert_sel_flag=$3 - else - #_cdovert_sel_flag="-sellevel,150/600" - _cdovert_sel_flag="-sellevidx,1/20" - fi - - #--> This depth is not recognized since depth(level) - # level is the vertical dimension - ## - ## Ensure depth axis is present by adding the - ## corresponding file array/axis - ## - #_file_depth=${FileName_depth4levels_FESOM:-fesom_depth_axis.nc} - #if [ -f ${_file_depth} ] ; then - # echo " - adding depth array from >>${_file_depth}<<" - # ncks -A ${_file_depth} ${_file_input} - #fi - - echo " - collapse type ${_cdovert_sel_flag} -> $(basename ${_file_output})" - $cdo -vertmean ${_cdovert_sel_flag} ${_file_input} ${_file_output} - echo " ^ Note: Warnings about missing levels are commonly OK" - - cleanup_list="${cleanup_list} $(pwd)/${_file_input}" - - unset _cdovert_sel_flag _file_depth _file_input -} - -# -- last line diff --git a/couplings/pism/coupling_pism2atmosphere.functions b/couplings/pism/coupling_pism2atmosphere.functions deleted file mode 100644 index 80005486d..000000000 --- a/couplings/pism/coupling_pism2atmosphere.functions +++ /dev/null @@ -1,511 +0,0 @@ -#!/usr/bin/ksh - -function pism2atmosphere { - echo " ==================================================================" - echo " *** S T A R T I N G pism2atmosphere *** "; echo - - :> ${COUPLE_DIR}/cdo_stderr_pism2atm - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - - echo "PISM_TO_ATMOSPHERE=${PISM_TO_ATMOSPHERE}" - - echo "LA DEBUG: first_year_in_chunk_input = ${first_year_in_chunk_input}" - echo "LA DEBUG: last_year_in_chunk_restart = ${last_year_in_chunk_restart}" - - if [[ $PISM_TO_ATMOSPHERE -eq 1 ]]; then - iterative_coupling_pism_atmosphere_write_grid - iterative_coupling_pism_atmosphere_write_names - iterative_coupling_pism_atmosphere_make_forcing - else - echo " NOT generating ice forcing for atmosphere" - fi - echo - echo " *** F I N I S H E D pism2atmosphere *** " - echo " ==================================================================" -} -function iterative_coupling_pism_atmosphere_make_forcing { - pism_atmosphere_get_newest_output - pism_atmosphere_update_domain_mask - pism_atmosphere_generate_orography_anomaly - pism_atmosphere_generate_ice_thickness_anomaly - pism_atmosphere_generate_runoff - pism_atmosphere_assemble_final_file -} - -function iterative_coupling_pism_atmosphere_write_names { - : > ${COUPLE_DIR}/ice_names_for_atmosphere.dat - GLACIAL_MASK_VARNAME_pism=mask - OROG_VARNAME_pism=usurf - OROG_ANOM_VARNAME_pism=delta_usurf - TOTAL_MASS_LOSS_VARNAME_pism=total_ice_mass_loss_flux - echo "ice_glacial_mask_name=$GLACIAL_MASK_VARNAME_pism" >> ${COUPLE_DIR}/ice_names_for_atmosphere.dat - echo "ice_orography_name=${OROG_VARNAME_pism}" >> ${COUPLE_DIR}/ice_names_for_atmosphere.dat - echo "ice_orography_difference_name=${OROG_ANOM_VARNAME_pism}" >> ${COUPLE_DIR}/ice_names_for_atmosphere.dat - echo "ice_mass_loss_varname=${TOTAL_MASS_LOSS_VARNAME_pism}" >> ${COUPLE_DIR}/ice_names_for_atmosphere.dat -} - -function iterative_coupling_pism_atmosphere_write_grid { - if [ ! -f ${COUPLE_DIR}/ice.griddes ]; then - #add_to ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - # ice.griddes couple - cp ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - ${COUPLE_DIR}/ice.griddes - fi -} - -function pism_atmosphere_get_newest_output { - echo; echo " * defining the newest PISM file " - # PG: Modification to ensure that we only use SUMMER values (July for Northern Hemisphere): - # LA: Not sure why. Now taking yearly mean. - # LA: Summer value for mask only. Now: Summer value for mask, yearmean for runoff - - # Define list of variables selected from PISM output depending on whether icebergs are used or not - if [ "x${fesom_use_iceberg}" == "x1" ]; then - echo " * use iceberg coupling and exclude iceberg discharge from mass balance" - CDO_SELECT_VAR_LIST="thk,climatic_mass_balance,topg,${OROG_VARNAME_pism},${GLACIAL_MASK_VARNAME_pism},tendency_of_ice_amount,tendency_of_ice_amount_due_to_discharge" - else - echo " * no iceberg coupling" - CDO_SELECT_VAR_LIST="thk,climatic_mass_balance,topg,${OROG_VARNAME_pism},${GLACIAL_MASK_VARNAME_pism},tendency_of_ice_amount" - fi - - LATEST_PISM_FILE_SINGLE=${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${YR0_pism}${M0_pism}${D0_pism}-${END_YEAR_pism}${END_MONTH_pism}${END_DAY_pism}.nc - echo; echo " * OUTPUT_DIR_pism = ${OUTPUT_DIR_pism} " - if [ -f ${LATEST_PISM_FILE_SINGLE} ]; then - echo; echo " * file1 = ${LATEST_PISM_FILE_SINGLE} found ***" - - # Remove old files - if [ -f ${OUTPUT_DIR_pism}/tmp.nc ]; then rm ${OUTPUT_DIR_pism}/tmp.nc; fi - if [ -f ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc ]; then rm ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc; fi - if [ -f ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc ]; then rm ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc; fi - unset PISM_OFILE_LIST - unset PISM_cleanup_list - - # Aggregate PISM output to multi-year monthly mean - echo " *** These fields are selected ${CDO_SELECT_VAR_LIST} *** " - for i in $(seq ${CHUNK_START_YEAR_pism} ${NYEAR} ${CHUNK_END_YEAR_pism}); do - j=$(( $i + ${NYEAR} -1 )) - if [ ${i} -lt 10 ]; then i=0${i}; fi - IFILE="${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${i}0101-${j}1231.nc" - if [[ "x${USE_YMONMEAN}" == "x1" ]]; then - OFILE="${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${i}0101-${j}1231.tendency.timmean.nc" - #PISM_cleanup_list="${PISM_cleanup_list} ${IFILE}" - - if [[ ! -f "${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${i}0101-${j}1231.tendency.timmean.nc" ]]; then - OFILE="${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${i}0101-${j}1231.tendency.timmean.nc" - cdo -ymonmean \ - -select,name="${CDO_SELECT_VAR_LIST}" \ - ${IFILE} \ - ${OFILE} 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - fi - echo; echo " * i = ${i} "; PISM_OFILE_LIST="${PISM_OFILE_LIST} ${OFILE}"; - else - if [[ -f ${IFILE} ]]; then - PISM_OFILE_LIST="${PISM_OFILE_LIST} ${IFILE}" - fi - fi - done - - echo; echo " * Concatenating these files: ${PISM_OFILE_LIST} " - cdo cat ${PISM_OFILE_LIST} ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - cdo timmean ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - - #rm ${PISM_OFILE_LIST} ${PISM_cleanup_list} - else - echo "*** ${LATEST_PISM_FILE_SINGLE} not found ***" - exit 42 - fi - - newest_pism_file=${OUTPUT_DIR_pism}/latest_ex_file_pism.nc - newest_pism_filename=$(basename $newest_pism_file) - newest_pism_file_chunk=${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc - - if [[ ${EX_INT} == "monthly" ]]; then - case $DOMAIN_pism in - "nhem" | "laurentide" | "greenland") - month_to_select=6 - ;; - "shem" | "antarctica" | "Antarctica") - month_to_select=12 - ;; - *) - echo "UNKNOWN PISM domain" - exit 42 - esac - echo " - selecting summer values only! Month=$month_to_select " - echo " - ifile = ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc; ofile = ${COUPLE_DIR}/${EXP_ID}_pism_extra_summer_${YR0_pism}-${END_YEAR_pism}.nc " - - - # Select mask either by minimum ice thickness over year (MIN_MON_SELECT==1) or by summer value (Jun for NH, Dec for SH) - if [[ "x${MIN_MON_SELECT}" == "x1" ]]; then - cdo -s \ - -timmin \ - -selname,thk \ - ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc \ - ${COUPLE_DIR}/${EXP_ID}_pism_extra_summer_${YR0_pism}-${END_YEAR_pism}.nc 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - else - cdo -s \ - -selmon,${month_to_select} \ - -ymonmean \ - ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc \ - ${COUPLE_DIR}/${EXP_ID}_pism_extra_summer_${YR0_pism}-${END_YEAR_pism}.nc 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - fi - # LA: get SMB as another criterion for glacial mask; glacial cell if positive SMB - cdo -s \ - -timmean \ - -selname,climatic_mass_balance \ - ${OUTPUT_DIR_pism}/latest_ex_file_pism.CHUNK.nc \ - ${COUPLE_DIR}/${EXP_ID}_pism_extra_smb_${YR0_pism}-${END_YEAR_pism}.nc 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - newest_pism_mask_file=${COUPLE_DIR}/${EXP_ID}_pism_extra_summer_${YR0_pism}-${END_YEAR_pism}.nc - else - newest_pism_mask_file=${newest_pism_file} - fi - newest_pism_mask_filename=$(basename $newest_pism_mask_file) - -} - -function pism_atmosphere_update_domain_mask { - echo; echo " Updating script-coupler domain mask..." - echo " (This is the area where changes to ECHAM6 files are allowed to be made)" - - update_domain_mask_select_mask - if [[ "x${MIN_MON_SELECT}" != "x1" ]]; then - update_domain_mask_constrain_minimum_ice_thickness - fi - update_domain_mask_merge_masks - update_domain_mask_set_mask_values_to_binary - echo; echo " ...done." -} - -function pism_atmosphere_generate_orography_anomaly { - echo; echo " Generating orography anomaly..." - generate_orography_anomaly_over_pism_run - correct_lonlat_order ${COUPLE_DIR}/ice_orog_difference.nc - echo; echo " ...done." -} - -function pism_atmosphere_generate_ice_thickness_anomaly { - echo; echo " Generating ice_thickness anomaly..." - generate_ice_thickness_anomaly_over_pism_run - correct_lonlat_order ${COUPLE_DIR}/ice_thk_above_flotation_difference.nc - correct_lonlat_order ${COUPLE_DIR}/ice_thk_difference.nc - convert_ice_thk_diff_to_flux_over_pism_run - echo; echo " ...done." -} - -function pism_atmosphere_generate_runoff { - echo; echo " Getting variables relevant for ice mass loss..." - generate_runoff_select_variables - generate_runoff_transform_units - generate_runoff_combine_fields - echo; echo " ...done." -} - -function pism_atmosphere_assemble_final_file { - echo; echo " Assembling final ice_file_for_atmosphere.nc and cleaning up..." - files_needed="${COUPLE_DIR}/ice_mask_current.nc ${COUPLE_DIR}/ice_orog_difference.nc ${COUPLE_DIR}/ice_runoff_flux_total.nc ${COUPLE_DIR}/ice_runoff_kg_m-2_s-1.nc" - cdo -s -O merge $files_needed ${COUPLE_DIR}/ice_file_for_atmosphere.nc - ncwa -a time ${COUPLE_DIR}/ice_file_for_atmosphere.nc tmp; mv tmp ${COUPLE_DIR}/ice_file_for_atmosphere.nc - #rm $files_needed $rmlist - echo; echo " ...done" - unset files_needed -} - -function update_domain_mask_select_mask { - echo ""; echo " * selecting the mask variable" - ifile1=${newest_pism_mask_file} - ifile2=${COUPLE_DIR}/${EXP_ID}_pism_extra_smb_${YR0_pism}-${END_YEAR_pism}.nc - if [[ "x${MIN_MON_SELECT}" == "x1" ]]; then - CRITICAL_THK_FOR_MASK_pism=${CRITICAL_THK_FOR_MASK_pism:-5} - echo ""; echo " * constraining the mask to have at least ${CRITICAL_THK_FOR_MASK_pism} (meters)" - ofile1=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_min_thk.nc - ofile2=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_pos_smb.nc - cdo -s chname,thk,${GLACIAL_MASK_VARNAME_pism} -setmisstoc,0 -ifthenc,1 -gec,${CRITICAL_THK_FOR_MASK_pism} $ifile1 $ofile1 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - cdo -s chname,climatic_mass_balance,${GLACIAL_MASK_VARNAME_pism} -setmisstoc,0 -ifthenc,1 -gtc,0 $ifile2 $ofile2 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - else - ofile1=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}.nc - ofile2=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_pos_smb.nc - cdo -s -selvar,${GLACIAL_MASK_VARNAME_pism} $ifile1 $ofile1 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - cdo -s chname,climatic_mass_balance,${GLACIAL_MASK_VARNAME_pism} -setmisstoc,0 -ifthenc,1 -gtc,0 $ifile2 $ofile2 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - fi - unset ifile1 ifile2 ofile1 ofile2 -} - -function update_domain_mask_constrain_minimum_ice_thickness { - CRITICAL_THK_FOR_MASK_pism=${CRITICAL_THK_FOR_MASK_pism:-5} - echo ""; echo " * constraining the mask to have at least ${CRITICAL_THK_FOR_MASK_pism} (meters)" - ifile=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}.nc - ofile=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_min_thk.nc - cdo -s -setmisstoc,0 \ - -ifthen \ - -gec,${CRITICAL_THK_FOR_MASK_pism} \ - -selvar,thk \ - ${newest_pism_mask_file} \ - ${ifile} \ - ${ofile} 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - rm $ifile - unset ifile ofile -} - -function update_domain_mask_merge_masks { - echo ""; echo " * merging masks from thicknes and surface mass balance criterions" - ifile1=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_min_thk.nc - ifile2=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_pos_smb.nc - ofile=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_merged_mask.nc - #LA: merge both masks: glacial cell if thickness above threshold OR surface mass balance > 0 - cdo -s max $ifile1 $ifile2 $ofile 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - #rm $ifile1 $ifile2 - unset ifile1 ifile2 ofile -} - -function update_domain_mask_set_mask_values_to_binary { - echo ""; echo " * setting binary values for mask: 1=ice, 0=non-ice" - ifile=${COUPLE_DIR}/${newest_pism_filename%.*}_${GLACIAL_MASK_VARNAME_pism}_merged_mask.nc - ofile=${COUPLE_DIR}/ice_mask_min_thk_binary.nc - cdo -s \ - -setvals,2,1 \ - -setvals,3,1 \ - -setvals,4,0 \ - $ifile $ofile 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - mv $ofile ${COUPLE_DIR}/ice_mask_current.nc - #rm $ifile - unset ifile ofile -} - -function generate_ice_thickness_anomaly_over_pism_run { - echo ""; echo " * calculating ice thickness change over the last pism chunk" - ifile1=${last_year_in_chunk_restart} - ifile2=${first_year_in_chunk_input} - ofile1=${COUPLE_DIR}/ice_thk_above_flotation_difference.nc - ofile2=${COUPLE_DIR}/ice_thk_difference.nc - cdo -s -expr,"thk_topg=thk+topg" \ - $ifile1 \ - tmp1 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - - cdo -s -expr,"thk_topg=thk+topg" \ - $ifile2 \ - tmp2 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - - cdo -s -chname,"thk_topg","thk_diff" \ - -sub \ - -ifthen -gtc,0 tmp1 tmp1 \ - -ifthen -gtc,0 tmp2 tmp2 \ - $ofile1 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - - rm tmp1 tmp2 - - cdo -s -chname,"thk","thk_diff" \ - -sub \ - -selvar,"thk" \ - $ifile1 \ - -selvar,"thk" \ - $ifile2 \ - $ofile2 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - - #ncks -O -x -v time,GEOSP $ofile tmp.nc 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - #mv tmp.nc $ofile -} - -function convert_ice_thk_diff_to_flux_over_pism_run { - echo ""; echo " * converting thickness difference to freshwater flux over the last pism chunk" - ifile1=${COUPLE_DIR}/ice_thk_above_flotation_difference.nc - ifile2=${COUPLE_DIR}/ice_thk_difference.nc - ofile1=${COUPLE_DIR}/ice_runoff_from_thk_above_flotation_difference.nc - ofile2=${COUPLE_DIR}/ice_runoff_from_thk_difference.nc - - cdo -s -divc,${CHUNK_SIZE_pism_standalone} \ - -chname,"thk_diff","runoff" \ - -mulc,910 \ - $ifile1 \ - $ofile1 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - - cdo -s -divc,${CHUNK_SIZE_pism_standalone} \ - -chname,"thk_diff","runoff" \ - -mulc,910 \ - $ifile2 \ - $ofile2 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - #-mulc,${RES_pism//km} \ - #-mulc,${RES_pism//km} \ -} - -function generate_orography_anomaly_over_pism_run { - echo ""; echo " * calculating surface height change over the last pism chunk" - ifile1=${last_year_in_chunk_restart} - ifile2=${first_year_in_chunk_input} - ofile=${COUPLE_DIR}/ice_orog_difference.nc - cdo -s -sub \ - -chname,${OROG_VARNAME_pism},${OROG_ANOM_VARNAME_pism} \ - -expr,"${OROG_VARNAME_pism}=thk+topg" \ - $ifile1 \ - -expr,"${OROG_VARNAME_pism}=thk+topg" \ - $ifile2 \ - $ofile 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - - ncks -O -x -v time,GEOSP $ofile tmp.nc 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - mv tmp.nc $ofile -} - -function generate_runoff_select_variables { - echo ""; echo " * selecting vars" - # LA account_all_fw_input needs to be defined - if [[ "x${account_all_fw_input}" == "x1" ]]; then - ifile=${COUPLE_DIR}/ice_runoff_from_thk_difference.nc - else - ifile=${COUPLE_DIR}/ice_runoff_from_thk_above_flotation_difference.nc - fi - ofile=${COUPLE_DIR}/ice_runoff.nc - - case ${VERSION_pism:--0.1} in - "0.7") - PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"discharge_flux_cumulative,floating_basal_flux_cumulative,grounded_basal_flux_cumulative"} - ;; - "1.0"|"1.1"|"1.2") - # basal_mass_flux_floating = basal kg/m2/s of floating ice - # basal_mass_flux_grounded = basal kg/m2/s of grounded ice - # srunoff = surface runoff (kg/m2/s) - # tendency_of_ice_amount_due_to_discharge = calving + frontal melting (kg/m2/s) - #PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"basal_melt_rate_grounded,tendency_of_ice_amount_due_to_discharge"} - # Only use "tendency_of_ice_amount"; Unit: kg m-2 year-1; for both v1.0 and v1.1 - - #*************************************************************************** - #LA include iceberg model - if [[ "x${fesom_use_iceberg}" == "x1" ]]; then - PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"tendency_of_ice_amount_due_to_discharge,runoff"} #,tendency_of_ice_amount_due_to_calving"} - #PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"tendency_of_ice_amount_due_to_discharge,tendency_of_ice_amount"} #,tendency_of_ice_amount_due_to_calving"} - PISM_MASS_LOSS_ARRAY=("tendency_of_ice_amount_due_to_discharge" "runoff") # "tendency_of_ice_amount_due_to_calving") - #*************************************************************************** - else - PISM_MASS_LOSS_VARS=${PISM_MASS_LOSS_VARS:-"runoff"} - fi - ;; - *) - echo "Unknown PISM version=${VERSION_pism} specified, exiting..." - exit 42 - ;; - esac - - cdo -s -selvar,${PISM_MASS_LOSS_VARS} \ - $ifile \ - $ofile 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm -} - -function generate_runoff_transform_units { - ifile=${COUPLE_DIR}/ice_runoff.nc - ofile=${COUPLE_DIR}/ice_runoff_kg_m-2_s-1.nc - years_to_seconds_divc_factor=3.15569e+07 # $(udunits2 -W s -H year | tail -1 | tr -s ' ' | awk -F'=' '{print $2}' | awk -F'*' '{print $1}' | tr -d '[:space:]') - Gt_to_kg_mulc_factor=1e+12 # $(udunits2 -W kg -H Gt | tail -1 | tr -s ' ' | awk -F'=' '{print $2}' | awk -F'*' '{print $1}'| tr -d '[:space:]') - case ${VERSION_pism:--0.1} in - "0.7") - echo ""; echo " * transforming glaciological units to SI standards" - # We need to go from cummulative to delta T - # FIXME: What if a user wants to run more than one run in a pism chunk? - # Then, we need to find the TOTAL delta T over all the files in this chunk. - echo "cdo -mulc,${Gt_to_kg_mult_factor} -mulc,${years_to_seconds_mult_factor} -divc,$CHUNK_SIZE_pism_standalone -sub -seltimestep,-1 $ifile -seltimestep,1 $ifile $ofile" - cdo -s \ - -mulc,${Gt_to_kg_mulc_factor} \ - -divc,${years_to_seconds_divc_factor} \ - -divc,$CHUNK_SIZE_pism_standalone \ - -sub \ - -seltimestep,-1 $ifile \ - -seltimestep,1 $ifile \ - $ofile - - ncatted -a units,floating_basal_flux_cumulative,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - ncatted -a units,grounded_basal_flux_cumulative,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - ncatted -a units,discharge_flux_cumulative,o,c,"kg second-1" $ofile tmp; mv tmp $ofile - cdo -s aexpr,"discharge_flux_cumulative_per_area=discharge_flux_cumulative/${CELL_AREA_pism}" $ofile tmp; mv tmp $ofile - ncatted -a units,discharge_flux_cumulative,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - cdo -s delvar,discharge_flux_cumulative $ofile tmp; mv tmp $ofile - PISM_MASS_LOSS_VARS="discharge_flux_cumulative_per_area,floating_basal_flux_cumulative,grounded_basal_flux_cumulative" - ;; - "1.0" | "1.1" | "1.2") - #echo "unit transform not needed in pism 1.0, skipping step silently" - #cp $ifile $ofile - echo ""; echo " * Transforming mass flux per year to mass flux per second for PISM 1.1 ${years_to_seconds_divc_factor}" - echo "cdo -divc,${years_to_seconds_divc_factor} $ifile $ofile" - cdo -s -divc,${years_to_seconds_divc_factor} $ifile $ofile - #*************************************************************************** - #LA include iceberg model - if [[ "x${fesom_use_iceberg}" == "x1" ]]; then - cdo -s -divc,${years_to_seconds_divc_factor} -selname,tendency_of_ice_amount_due_to_discharge ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc tmp - ncatted -a units,tendency_of_ice_amount_due_to_discharge,o,c,"kg second-1 m-2" tmp tmp2; rm tmp # ; mv tmp $ofile - ncatted -a units,runoff,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - cdo -s merge tmp2 $ofile tmp; mv tmp ${ofile}; rm tmp2 - #*************************************************************************** - else - ncatted -a units,runoff,o,c,"kg second-1 m-2" $ofile tmp; mv tmp $ofile - fi - ;; - *) - echo "Unknown PISM version=${VERSION_pism} specified, exiting..." - exit 42 - ;; - esac - #rmlist="$rmlist $ifile" -} - -function generate_runoff_combine_fields { - echo ""; echo " * combining ${PISM_MASS_LOSS_VARS} to a single field" - echo " - NOTE: Currently we assume all mass loss goes directly to the hydrology scheme" - echo " - NOTE: There is no seperation between calving, grounded basal melt, and" - echo " - NOTE: floating basal melt." - ifile=${COUPLE_DIR}/ice_runoff_kg_m-2_s-1.nc - ofile=${COUPLE_DIR}/ice_runoff_flux_total.nc - - case ${VERSION_pism:--0.1} in - "0.7") - cdo -s -splitname $ifile ${COUPLE_DIR}/ice_runoff_flux_ - set -A PISM_MASS_LOSS_ARRAY $(echo $PISM_MASS_LOSS_VARS | sed s/,/\ /g ) - first_varname=${PISM_MASS_LOSS_ARRAY[0]}; unset PISM_MASS_LOSS_ARRAY[0] - #rmlist="$rmlist ${COUPLE_DIR}/ice_runoff_flux_${first_varname}.nc" - cdo_command_head="cdo -s " - cdo_command_tail=" ${COUPLE_DIR}/ice_runoff_flux_${first_varname}.nc $ofile" - for element in ${PISM_MASS_LOSS_ARRAY[@]}; do - cdo_command_middle="$cdo_command_middle -add ${COUPLE_DIR}/ice_runoff_flux_${element}.nc" - #rmlist="$rmlist ${COUPLE_DIR}/ice_runoff_flux_${element}.nc" - done - cdo_command="$cdo_command_head $cdo_command_middle $cdo_command_tail" - $cdo_command - ;; - "1.0"|"1.1"|"1.2") - #*************************************************************************** - #LA include iceberg model - if [[ "x${fesom_use_iceberg}" == "x1" ]]; then - echo " * substratiing discharge from runoff ${ifile}" - cdo -s -chname,tendency_of_ice_amount_due_to_discharge,runoff -sub -selname,tendency_of_ice_amount_due_to_discharge ${ifile} -selname,runoff ${ifile} ${ofile} 2>> ${COUPLE_DIR}/cdo_stderr_pism2atm - #*************************************************************************** - else - # Only need tendency of ice amount, do not need to combine fields. - cp $ifile $ofile - fi - ;; - *) - echo "Unknown PISM version=${VERSION_pism} specified, exiting..." - exit 42 - ;; - esac - - - case ${VERSION_pism:--0.1} in - "0.7") - ncrename -v floating_basal_flux_cumulative,total_ice_mass_loss_flux $ofile - ;; - "1.0"|"1.1"|"1.2") - #*************************************************************************** - #LA include iceberg model - if [[ "x${fesom_use_iceberg}" == "x1" ]]; then - ncrename -v runoff,total_ice_mass_loss_flux $ofile - else - ncrename -v runoff,total_ice_mass_loss_flux $ofile - fi - ;; - esac -} - -function correct_lonlat_order { - FILENAME=$1 - echo ""; echo " * correcting $FILENAME lonlat order" - ncpdq -a lat,lon $FILENAME tmp; mv tmp $FILENAME -} diff --git a/couplings/pism/coupling_pism2awiesm.functions b/couplings/pism/coupling_pism2awiesm.functions deleted file mode 100644 index c22e080ac..000000000 --- a/couplings/pism/coupling_pism2awiesm.functions +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/ksh -pism2awiesm() { - if [ "$MACHINE" == "mistral" ]; then - module purge - module load defaults - module unload netcdf_c/4.3.2-gcc48 - module load anaconda3 - fi - echo $(module list) - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/general_helpers.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - if [ -f ${COUPLE_DIR}/latest_gfw_atmo.nc ]; then - rm ${COUPLE_DIR}/latest_gfw_atmo.nc - fi - - #if [ -f ${COUPLE_DIR}/latest_jsbach_init_file.nc ]; then - # rm ${COUPLE_DIR}/latest_jsbach_init_file.nc - #fi - # - #if [ -f ${COUPLE_DIR}/latest_jsbach_restart_file.nc ]; then - # rm ${COUPLE_DIR}/latest_jsbach_restart_file.nc - #fi - # - #if [ -f ${COUPLE_DIR}/latest_veg_restart_file.nc ]; then - # rm ${COUPLE_DIR}/latest_veg_restart_file.nc - #fi - - if [ -f ${COUPLE_DIR}/latest_target_orography.nc ]; then - rm ${COUPLE_DIR}/latest_target_orography.nc - fi - - #echo "LA DEBUG: MIN_MON_SELECT=${MIN_MON_SELECT}" - #if [ "x${MIN_MON_SELECT}" == "x1" ]; then - # echo "LA DEBUG: Hier" - . ${FUNCTION_PATH}/coupling_pism2atmosphere.functions - #else - # echo "LA DEBUG: Oder hier" - # . ${FUNCTION_PATH}/coupling_pism2atmosphere.functions.origin - . ${FUNCTION_PATH}/coupling_pism2ocean.functions - - echo "*** Starting pis2atmosphere ***" - pism2atmosphere 2>> ${COUPLE_DIR}/cdo_stderr_pism2awiesm - #pism2ocean -} diff --git a/couplings/pism/coupling_pism2ocean.functions b/couplings/pism/coupling_pism2ocean.functions deleted file mode 100644 index cea2a6dd8..000000000 --- a/couplings/pism/coupling_pism2ocean.functions +++ /dev/null @@ -1,747 +0,0 @@ -#!/bin/ksh - - -function pism2ocean { - echo " *** S T A R T I N G pism2ocean *** (PISM version ${VERSION_pism})" - - . ${FUNCTION_PATH}/../general/general_lists.functions - . ${FUNCTION_PATH}/../general/coupling_general.functions - - echo "PISM_TO_OCEAN=${PISM_TO_OCEAN:-0}" - if [[ $PISM_TO_OCEAN -le 0 ]]; then - echo " NOT generating ice forcing for ocean model" - echo " since PISM_TO_OCEAN=${PISM_TO_OCEAN}" - return - fi - - # - # ==> if [[ $PISM_TO_OCEAN -ge 1 ]]; then - # - # - # PISM OUTPUT 1a) Temporal stream for ice shelf basal melting (ymonmean/timmeam) - # pism2ocean 1b) Temporal stream for ice berg calving/discharging (ymonmean/timmean) - # 1c) Stream of vertical temperature gradient at base (last year-ymonmean/last record) - # 1d) Stream of mask (ice-free ocean, ice shelf, land) (last record) - # 2) Convert them into sensible units (calving: Gt < area, densities) - # 3) Combine the basal melting, calving, temperature gradient files - # ice2fesom (other file) - # 4) Remap/Regrid to FESOM grid - # 5) FESOM Names - # - CHUNK_DATE_TAG_pism="${CURRENT_YEAR_pism}-${END_YEAR_pism}" - #CHUNK_DATE_TAG_awicm="${CHUNK_START_DATE_awicm}-${CHUNK_END_DATE_awicm}" - -#TODO Get the right file names for the forcing/extra and restart/output file names - PISM_FORCING_EXTRA_FILE=../outdata/pism/${EXP_ID}_pismr_extra_${CHUNK_DATE_TAG_pism}.nc - PISM_RESTART_OUTPUT_FILE=../restart/pism/${EXP_ID}_pismr_out_${CHUNK_DATE_TAG_pism}.nc - COMBINED_OUTPUT=ice_file_at_ocean.combined.nc - - # TODO Are these sensible choices? - iter_coup_interact_method_ice2oce=${iter_coup_interact_method_ice2oce:-BASALSHELF_WATER} - - iterative_coupling_pism_ocean_write_names - read_names ice ocean - - cdo_table_file=cdo_partable.txt - iterative_coupling_pism_ocean_fesom2pism_names $cdo_table_file - - NOCOLOR='\033[0m' - GREEN='\033[32m' - - echo "Interaction (ocean) : ${iter_coup_interact_method_ice2oce}" - echo -e " --> Interaction >>> ${GREEN}${iter_coup_interact_method_ice2oce}${NOCOLOR} <<< ocean" - case $iter_coup_interact_method_ice2oce in - "BASALSHELF_WATER_ICEBERG_WATER") - iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_iceberg_water_forcing - ;; - "BASALSHELF_WATER") - iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - ;; - "ICEBERG_WATER") - iterative_coupling_pism_ocean_prepare_ocean_iceberg_water_forcing - ;; - "ICEBERG_HEAT") - iterative_coupling_pism_ocean_prepare_ocean_iceberg_heat_forcing - ;; - "BASALSHELF_WATER_ICEBERG_WATERHEAT") - iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_iceberg_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_iceberg_heat_forcing - ;; - "BASALSHELF_WATER_ICEBERG_PDF") - iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_iceberg_pdf_forcing - ;; - "BASALSHELF_WATER_ICEBERG_MODEL") - #iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing - iterative_coupling_pism_ocean_prepare_ocean_icebergmodel_forcing - ;; - *) - echo " UNKNOWN mass balance selected!" - echo " Known: BASALSHELF_WATER_ICEBERG_WATER, BASALSHELF_WATER, ICEBERG_WATER, ICEBERG_HEAT," - echo " BASALSHELF_WATER_ICEBERG_WATERHEAT, BASALSHELF_WATER_ICEBERG_PDF, BASALSHELF_WATER_ICEBERG_MODEL" - echo " S T O P 1" - exit 1 - esac - - if [ ${iter_coup_interact_method_ice2oce_ice_temp_gradient:-0} -gt 0 ] ; then - iterative_coupling_pism_ocean_prepare_iceshelf_temperature_gradient_forcing - else - echo " * Skip preparation of temperature gradient in lowest iceshelf layer" - fi - if [ ${iter_coup_interact_method_ice2oce_update_mask:-0} -gt 0 ] ; then - iterative_coupling_pism_ocean_prepare_ocean_update_mask_forcing - else - echo " * Skip preparation of actual masks (ocean, ice shelves, land)" - fi - - iterative_coupling_pism_ocean_prepare_combine_forcings - - for file in ${cleanup_list} ; do test -f $file && rm $file ; done - unset cleanup_list file - unset NOCOLOR GREEN - - unset PISM_FORCING_EXTRA_FILE PISM_RESTART_OUTPUT_FILE cdo_table_file - - echo " ...done." -} - - - -function iterative_coupling_pism_ocean_write_names { - echo "Writing fesom1x input names and units for use with generic ocean_file_for_ice.nc" - :> ice_names_for_ocean.dat - - # - # PISM names - # - case ${VERSION_pism:--0.1} in - "0.0") - _pism_basalshelf_freshwater_flux_varn="B_FW_FLX" - _pism_basalshelf_freshwater_flux_unit="Gt/m2/s" - _pism_iceberg_freshwater_flux_varn="IB_FW_FLX" - _pism_iceberg_freshwater_flux_unit="Gt/m2/s" - #_pism_iceberg_heat_flux_varn="IB_H_FLX" - #_pism_iceberg_heat_flux_unit="W/s/m2" - ;; - "0.7") - #SNAPSHOT! _pism_basalshelf_freshwater_flux_varn="floating_basal_flux" - #SNAPSHOT! _pism_iceberg_freshwater_flux_varn="discharge_flux" - _pism_basalshelf_freshwater_flux_varn="floating_basal_flux_cumulative" - _pism_basalshelf_freshwater_flux_unit="Gt/m2/s" - _pism_iceberg_freshwater_flux_varn="discharge_flux_cumulative" - _pism_iceberg_freshwater_flux_unit="Gt" - ;; - "1.0"|"1.1"|"1.2") - _pism_basalshelf_freshwater_flux_varn="basal_mass_flux_floating" #"floating_basal_flux_cumulative" - _pism_basalshelf_freshwater_flux_unit="kg/m2/year" - _pism_iceberg_freshwater_flux_varn="tendency_of_ice_amount_due_to_discharge" #"discharge_flux_cumulative" - _pism_iceberg_freshwater_flux_unit="kg/m2/year" - ;; - *) - echo "NOT DEFINED PISM version >${VERSION_pism}<" - echo "Please adjust function >iterative_coupling_pism_ocean_write_names<" - echo " S T O P 2" - exit 2 - ;; - esac - - echo ""; echo " * basal iceshelf melt flux" - echo "pism_name_basal_shelf_melt_flux=${_pism_basalshelf_freshwater_flux_varn}" >> ice_names_for_ocean.dat - echo "pism_units_basal_shelf_melt_flux=${_pism_basalshelf_freshwater_flux_unit}" >> ice_names_for_ocean.dat - - echo ""; echo " * ice berg calving" - echo "pism_name_iceberg_calving_flux=${_pism_iceberg_freshwater_flux_varn}" >> ice_names_for_ocean.dat - echo "pism_units_iceberg_calving_flux=${_pism_iceberg_freshwater_flux_unit}" >> ice_names_for_ocean.dat - - # - # OCEAN (generic) names - # - echo ""; echo " * freshwater flux" - echo "ocean_name_freshwater_flux=wnet" >> ice_names_for_ocean.dat - echo "ocean_units_freshwater_flux=W/m2" >> ice_names_for_ocean.dat - - echo ""; echo " * heat flux" - echo "ocean_name_heat_flux=qnet" >> ice_names_for_ocean.dat - #echo "ocean_units_heat_flux=kg/m2/s" >> ice_names_for_ocean.dat - echo "ocean_units_heat_flux=m" >> ice_names_for_ocean.dat - - echo ""; echo " * basal ice shelf temperature gradient" - echo "ocean_name_temperature_gradient=dTdz" >> ice_names_for_ocean.dat - echo "ocean_unit_temperature_gradient=K/m" >> ice_names_for_ocean.dat - - echo ""; echo " * landmask" - echo "ocean_name_landmask=mask" >> ice_names_for_ocean.dat - echo "ocean_units_landmask=1" >> ice_names_for_ocean.dat - - echo ""; echo " * oceanmask" - echo "ocean_name_oceanmask=mask" >> ice_names_for_ocean.dat - echo "ocean_units_oceanmask=1" >> ice_names_for_ocean.dat - - echo ""; echo " * iceshelfmask" - echo "ocean_name_iceshelfmask=mask" >> ice_names_for_ocean.dat - echo "ocean_units_iceshelfmask=1" >> ice_names_for_ocean.dat - - add_to $(pwd)/ice_names_for_ocean.dat ice_names_for_ocean.dat couple - echo " ...done." - - unset _pism_basalshelf_freshwater_flux_varn _pism_basalshelf_freshwater_flux_unit - unset _pism_iceberg_freshwater_flux_varn _pism_iceberg_freshwater_flux_unit - unset _pism_iceberg_heat_flux_varn _pism_iceberg_heat_flux_unit -} - - -# -# Compute actual forcing files : Convert variable names to pism names -# - -function iterative_coupling_pism_ocean_prepare_ocean_iceberg_pdf_forcing { - echo " WE DOT NOT have yet an ICEBERG MODULE, where the fresh water is spread along" - echo " static Probability Density Function (pdf) maps" - echo " Please replace iter_coup_interact_method_ice2oce=${iter_coup_interact_method_ice2oce} with something else" - echo " S T O P 3" - exit 3 - - # - # Please add after this comment the commands that are specific for - # running the iceberg PDF module. - # -} - - -######################################################################## -######################################################################## -# Lars Ackermann 07.09.2020 -######################################################################## -function iterative_coupling_pism_ocean_prepare_ocean_icebergmodel_forcing { - # iceberg coupling LA - #latest_pism_output=${OUTPUT_DIR_pism}/${EXP_ID}_${EXE_pism}_extra_${YR0_pism}${M0_pism}${D0_pism}-${END_YEAR_pism}${END_MONTH_pism}${END_DAY_pism}.nc - if [[ -f ${OUTPUT_DIR_pism}/latest_ex_file_pism.nc ]]; then - pism_discharge_file=${OUTPUT_DIR_pism}/latest_ex_file_pism.nc - elif [[ -f ${SPINUP_FILE_pism} ]]; then - pism_discharge_file=${SPINUP_FILE_pism} - fi - - echo " * generating latest_discharge.nc" - echo "PISM_DISCHARGE_FILE: ${pism_discharge_file}" - - cdo mulc,${CHUNK_SIZE_pism_standalone} \ - -timmean -selname,tendency_of_ice_amount_due_to_discharge \ - -setgrid,${COUPLE_DIR}/ice.griddes ${pism_discharge_file} ${COUPLE_DIR}/latest_discharge.nc - -# wc -l ../icb/iceberg.restart.ISM | awk '{ print $1 }' > ../icb/num_non_melted_icb_file -# use_icesheet_coupling=1 - -# get_ib_num_after_ice_sheet_coupling -} - -#function get_ib_num_after_ice_sheet_coupling { -# _a="$( wc -l icb/LON.dat | awk '{ print $1 }' )" -# _b="$( cat ../icb/num_non_melted_icb_file )" -# -# ib_num=$(( $_a + $_b )) -# general_replace_namelist_value namelist.config icebergs ib_num $ib_num -# general_replace_namelist_value namelist.config icebergs use_icesheet_coupling ".true." -#} -############################################################################ -############################################################################ - - - -function iterative_coupling_pism_ocean_prepare_ocean_basalshelf_water_forcing { - echo " * Preparing basal melting iceshelf(PISM) forcing file with sensible units from >${PISM_FORCING_EXTRA_FILE}<" - # Rename all input variables - - test_file_or_exit $PISM_FORCING_EXTRA_FILE 5 - test_file_or_exit $cdo_table_file 6 - - _out_file=ice_file_at_ocean.basalwater.nc -#TODO : -#Warning: Number of OMP threads is greater than number of Cores=1! -#srun: error: prod-0177: task 0: Exited with exit code 1 -#srun: Terminating job step 2518500.0 - $cdo ymonmean \ - -selvar,lon,lat,wnet_basal -setpartabn,${cdo_table_file},convert \ - $PISM_FORCING_EXTRA_FILE ${_out_file} - - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} water_loss - - cleanup_list="${cleanup_list} $(pwd)/${_out_file}" - unset _out_file - echo " ...done." -} - - -function iterative_coupling_pism_ocean_prepare_ocean_iceberg_water_forcing { - echo " * Preparing iceberg melting iceshelf(PISM) forcing file with sensible units from >${PISM_FORCING_EXTRA_FILE}<" - # Rename all input variables - - test_file_or_exit $PISM_FORCING_EXTRA_FILE 7 - test_file_or_exit $cdo_table_file 8 - - _out_file=ice_file_at_ocean.icebergwater.nc - $cdo ymonmean \ - -selvar,lon,lat,wnet_iceberg -setpartabn,${cdo_table_file},convert \ - $PISM_FORCING_EXTRA_FILE ${_out_file} - - case ${VERSION_pism:--0.1} in - "0.7") - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} water_abs - ;; - "1.0"|"1.1"|"1.2") - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} water_loss - ;; - *) - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} water_loss - ;; - esac - - cleanup_list="${cleanup_list} $(pwd)/${_out_file}" - unset _out_file - echo " ...done." -} - - -function iterative_coupling_pism_ocean_prepare_ocean_iceberg_heat_forcing { - echo " * Preparing iceberg heat conversion iceshelf(PISM) forcing file with sensible units from >${PISM_FORCING_EXTRA_FILE}<" - # Rename all input variables - - test_file_or_exit $PISM_FORCING_EXTRA_FILE 9 - test_file_or_exit $cdo_table_file 10 - - # - # Since we shall have a unit "kg ...", we now convert the mass - # into the energy needed to change the phase of the related mass - # from solid to liquid - # TODO : Check if we use a consident set for "heat of fusion of water into ice" - heat_of_fusion_of_water=333550 #Joule kg-1 - - _out_file=ice_file_at_ocean.icebergheat.nc - $cdo ymonmean \ - -setvar,qnet_iceberg \ - -setunit,"Joule" \ - -selvar,wnet_iceberg -setpartabn,${cdo_table_file},convert \ - $PISM_FORCING_EXTRA_FILE ${_out_file} - - case ${VERSION_pism:--0.1} in - "0.7") - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} heat_abs - ;; - "1.0"|"1.1"|"1.2") - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} heat_loss - ;; - *) - iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux ${_out_file} heat_loss - ;; - esac - - cleanup_list="${cleanup_list} $(pwd)/${_out_file}" - unset _out_file - echo " ...done." -} - - -function iterative_coupling_pism_ocean_prepare_iceshelf_temperature_gradient_forcing { - echo " * Preparing temperature gradient in lowest iceshelf(PISM) layer from latest restart file with sensible units from >${PISM_RESTART_OUTPUT_FILE}<" - case ${VERSION_pism:--0.1} in - "0.7") - __varname="shelfbtemp" - ;; - "1.0"|"1.1"|"1.2") - __varname="shelfbtemp" - ;; - *) - __varname="shelfbtemp" - ;; - esac - - test_file_or_exit $PISM_RESTART_OUTPUT_FILE 11 - - #ncks -d time,-1,-1 -d z,0,1 -v ${__varname} \ - ncks -d time,-1,-1 -v ${__varname} \ - ${PISM_RESTART_OUTPUT_FILE} ice_file_at_ocean.laststep.bottom_iceshelf_temp.nc - - cleanup_list="${cleanup_list} $(pwd)/ice_file_at_ocean.laststep.bottom_iceshelf_temp.nc" - unset __varname - echo " ...done." -} - - -function iterative_coupling_pism_ocean_prepare_ocean_update_mask_forcing { - echo " * Preparing actual masks (ocean, ice shelf, land) from restart file with sensible units from >${PISM_RESTART_OUTPUT_FILE}<" - case ${VERSION_pism:--0.1} in - "0.7") - __varname="mask" - ;; - "1.0"|"1.1"|"1.2") - __varname="mask" - ;; - *) - __varname="mask" - ;; - esac - - test_file_or_exit $PISM_RESTART_OUTPUT_FILE 12 - - ncks -d time,-1,-1 -v ${__varname} \ - ${PISM_RESTART_OUTPUT_FILE} ice_file_at_ocean.laststep.pismmask.nc - - $cdo -setvar,${ocean_name_oceanmask} \ - eqc,4 ice_file_at_ocean.laststep.pismmask.nc \ - ice_file_at_ocean.laststep.mask_ocean.nc - $cdo -setvar,${ocean_name_iceshelfmask} \ - -eqc,3 ice_file_at_ocean.laststep.pismmask.nc \ - ice_file_at_ocean.laststep.mask_iceshelf.nc - $cdo -setvar,${ocean_name_landmask} \ - -lec,2 ice_file_at_ocean.laststep.pismmask.nc \ - ice_file_at_ocean.laststep.mask_land.nc - - if [ 1 -eq 0 ] ; then - # - # Drop time axis - # - for _file in \ - ice_file_at_ocean.laststep.mask_land.nc \ - ice_file_at_ocean.laststep.mask_ocean.nc \ - ice_file_at_ocean.laststep.mask_iceshelf.nc - do - if [ -f ${_file} ] ; then - _file_tmp=${_file%.*}_before_collapse_time.nc - mv -f $_file $_file_tmp - ncwa -a time $_file_tmp ${_file} - cleanup_list="${cleanup_list} $(pwd)/${_file} $(pwd)/${_file_tmp}" - fi - done - fi - - cleanup_list="${cleanup_list} $(pwd)/ice_file_at_ocean.laststep.pismmask.nc" - unset _file _file_tmp __varname -} - - -function iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux { - _infile=$1 - _type=$2 - echo " * Convert loss into flux of type >${_type}< (${_infile})..." - if [ ! -f ${_infile} ] ; then - echo " - Missing file ${_infile}" - echo " S T O P 30" - exit 30 - fi - - # - # Physical variables - # - # Determine density of ice - # - if [ -f ${PISM_RESTART_OUTPUT_FILE} ] ; then - density_ice=$(ncdump -h ${PISM_RESTART_OUTPUT_FILE}| grep "pism_config:ice_density =" | tr -d '[:space:],;' | cut -d= -f2) - elif [ -f ${PISM_FORCING_EXTRA_FILE} ] ; then - density_ice=$(ncdump -h ${PISM_FORCING_EXTRA_FILE} | grep "pism_config:ice_density =" | tr -d '[:space:],;' | cut -d= -f2) - fi - density_ice=${density_ice:-910.} - # - # Time step in data file to force the ocean - # - if [ $($cdo -s ntime ${_infile} | tr -d '[:space:]') -gt 1 ] ; then - _time_diff=$(iterative_coupling_get_pism_time_size ${_infile}) - else - if [ $($cdo -s ntime ${PISM_FORCING_EXTRA_FILE} | tr -d '[:space:]') -gt 1 ] ; then - _time_diff=$(iterative_coupling_get_pism_time_size ${PISM_FORCING_EXTRA_FILE}) - else - # Fall back: Delta Time = Years difference - _time_diff=$(echo "86400. * 365.25 * (${END_YEAR_pism}-${CURRENT_YEAR_pism})" | bc -l ) - fi - fi - # - # Area of grid cell - # - _area=$(iterative_coupling_get_pism_area_size ${_infile}) - - # - # CDO commands as multiplier - # - MUL_density="-mulc,${density_ice}" - MUL_recipro_delta_time="-mulc,$( echo 1./${_time_diff} | bc -l)" - MUL_recipro_grid_area="-mulc,$( echo 1./${_area} | bc -l)" - - # - # Combine the CDO flags due to request - # - case ${_type:-"Not provided"} in - heat_loss) - _unit="J m-2 s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time}" - ;; - water_loss) - _unit="m s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time} ${MUL_density_ice}" - ;; - mass_loss) - _unit="kg m-2 s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time}" - ;; - heat_abs) - _unit="J m-2 s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time} ${MUL_recipro_grid_area}" - ;; - water_abs) - _unit="m s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time} ${MUL_recipro_grid_area} ${MUL_density_ice}" - ;; - mass_abs) - _unit="kg m-2 s-1" - _CDO_Factor_flags="${MUL_recipro_delta_time} ${MUL_recipro_grid_area}" - ;; - "Not provided") - echo " - The type was not provided as second argument during the call of the function" - echo " 'iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux'" - echo " Update the call of this function and restart" - echo " S T O P 31" - exit 31 - ;; - *) - echo " - Unkown type=${type}" - echo " => Adjust function 'iterative_coupling_pism_ocean_convert_mass_loss_to_mass_flux'" - echo " S T O P 32" - exit 32 - ;; - esac - - _bak=${_infile%.*}_before_loss2flux.nc - mv -f ${_infile} ${_bak} - - $cdo -setunit,"${_unit}" ${_CDO_Factor_flags} \ - ${_bak} ${_infile} - - cleanup_list="${cleanup_list} $(pwd)/${_bak}" - - unset _bak _infile _type _unit _CDO_Factor_flags - unset MUL_recipro_delta_time MUL_recipro_grid_area - unset _area _time_diff -} - - -function iterative_coupling_pism_ocean_prepare_combine_forcings { - echo " * Combine various ice shelf/sheet forcing (PISM) into one file with sensible units..." - - cdo_task_list="" - # - # Fresh water - # - _file1=ice_file_at_ocean.basalwater.nc - _file2=ice_file_at_ocean.icebergwater.nc - if [ -f $_file1 -a -f $_file2 ] ; then - cdo_task_list="${cdo_task_list} -setvar,${ocean_name_freshwater_flux}" - cdo_task_list="${cdo_task_list} -add -selvar,wnet_basal $_file1 -selvar,wnet_iceberg $_file2" - cleanup_list="${cleanup_list} $(pwd)/${_file1}" - cleanup_list="${cleanup_list} $(pwd)/${_file2}" - else - if [ -f $_file1 ] ; then - cdo_task_list="${cdo_task_list} -setvar,${ocean_name_freshwater_flux} -selvar,wnet_basal $_file1" - cleanup_list="${cleanup_list} $(pwd)/${_file1}" - elif [ -f $_file2 ] ; then - cdo_task_list="${cdo_task_list} -setvar,${ocean_name_freshwater_flux} -selvar,wnet_iceberg $_file2" - cleanup_list="${cleanup_list} $(pwd)/${_file2}" - fi - fi - - # - # Heat flux - # - _file1=ice_file_at_ocean.icebergheat.nc - if [ -f ${_file1} ] ; then - cdo_task_list="${cdo_task_list} -setvar,${ocean_name_heat_flux} -selvar,qnet_iceberg ${_file1}" - cleanup_list="${cleanup_list} $(pwd)/${_file1}" - fi - - # - # Temperature gradient, Masks - # - for _file1 in ice_file_at_ocean.laststep.bottom_iceshelf_temp.nc \ - ice_file_at_ocean.laststep.mask_ocean.nc \ - ice_file_at_ocean.laststep.mask_iceshelf.nc \ - ice_file_at_ocean.laststep.mask_land.nc - do - if [ -f $_file1 ] ; then - # Drop time axis is done above (search for ncwa) - _file2=${_file1%.*}_before_combine.nc - mv -f $_file1 $_file2 - ncwa -a time $_file2 $_file1 - cleanup_list="${cleanup_list} $(pwd)/${_file2}" - - cdo_task_list="${cdo_task_list} ${_file1}" - cleanup_list="${cleanup_list} $(pwd)/${_file1}" - fi - done - - # - # Auxillary fields - # - _file1=aux_field_pism4ocean.nc - if [ -f ${PISM_RESTART_OUTPUT_FILE} ] ; then - ncks -OQv lon,lat ${PISM_RESTART_OUTPUT_FILE} ${_file1} - elif [ -f ${PISM_FORCING_EXTRA_FILE} ] ; then - ncks -OQv lon,lat ${PISM_FORCING_EXTRA_FILE} ${_file1} - fi - if [ -f $_file1 ] ; then - cdo_task_list="${cdo_task_list} ${_file1}" - fi - cleanup_list="${cleanup_list} $(pwd)/${_file1}" - - # - # Merge - # - if [ -f ${COMBINED_OUTPUT} ] ; then - mv -f ${COMBINED_OUTPUT} ${COMBINED_OUTPUT}~ - cleanup_list="${cleanup_list} $(pwd)/${COMBINED_OUTPUT}~" - fi - $cdo -O merge ${cdo_task_list} ${COMBINED_OUTPUT} - - # - # Attributes related to auxillary fields - # - if [ -f $_file1 ] ; then - ncatted -a coordinates,,c,c,'lon lat' \ - -a coordinates,lat,d,, \ - -a coordinates,lon,d,, \ - -a coordinates,time,d,, \ - -a coordinates,x,d,, \ - -a coordinates,y,d,, \ - ${COMBINED_OUTPUT} - fi - - unset cdo_task_list _file1 _file2 -} - - -# -# Auxillary functions -# -function iterative_coupling_get_pism_area_size { - #TODO : generalize the area computation, so that even - # curvlinear grid are recognized - __file=$1 - if [ ! -f ${__file} ] ; then - echo " * Compute PISM grid size..." - echo " - Missing file ${__file} in >iterative_coupling_get_pism_area_size<" - echo " S T O P 38" - exit 38 - fi - - __area_file=tmp_pism_area.nc - # Compute the area - if [ 0 -eq 1 ] ; then - # NCAP2 version (NCAP does not work) - test -f $__area_file && rm -f $__area_file - ncap2 -Ovs "area=abs( (x(0)-x(1)) * (y(0)-y(1)) );" ${__file} $__area_file - __area_size=$(ncks -CHs '%f' -v area $__area_file) - else - # NCAP2 free alternative - __x0=$(ncks -d x,0 -v x -CHs '%14.4f' ${__file} | tr -d '[:space:]') - __x1=$(ncks -d x,1 -v x -CHs '%14.4f' ${__file} | tr -d '[:space:]') - __y0=$(ncks -d y,0 -v y -CHs '%14.4f' ${__file} | tr -d '[:space:]') - __y1=$(ncks -d y,1 -v y -CHs '%14.4f' ${__file} | tr -d '[:space:]') - - #__area_size=$(echo "((${__x1} - ${__x0}) * (${__y1} - ${__y0}))" | bc -l) - # Ensures positive numbers - __area_size=$(echo "sqrt(((${__x1} - ${__x0}) * (${__y1} - ${__y0}))^2)" | bc -l) - unset __x0 __x1 __y0 __y1 - fi - - echo ${__area_size} - cleanup_list="${cleanup_list} $(pwd)/${__area_file}" - unset __area_file __area_size __file -} - - -function iterative_coupling_get_pism_time_size { - #TODO : generalize the time difference computation, so - # that even all time difference between all time - # steps are computed, such as - # time_diff(0)=time(1)-time(0), ..., - # time(i-1)=time(i)-time(i-1), ..., - # time(n-1)=time(n)-time(n-1), - # time(n) = time(n)-time(n-1) <== repeat the last time difference for the last time step?? - # - __file=$1 - if [ ! -f ${__file} ] ; then - echo " * Compute PISM writing time step size..." - echo " - Missing file ${__file} in >iterative_coupling_get_pism_time_size<" - echo " S T O P 39" - exit 39 - fi - - __time_file=tmp_pism_time.nc - - # Compute the time - if [ 0 -eq 1 ] ; then - # NCAP2 version (NCAP does not work) - test -f $__time_file && rm -f $__time_file - ncap2 -Ovs "timediff=abs( time(1)-time(0) );" ${__file} $__time_file - __time_size=$(ncks -CHs '%f' -v timediff $__time_file) - else - # NCAP2 free alternative - __t0=$(ncks -d time,0 -v time -CHs '%14.6f' ${__file} | tr -d '[:space:]') - __t1=$(ncks -d time,1 -v time -CHs '%14.6f' ${__file} | tr -d '[:space:]') - #__time_size=$(echo "(${__t1} - ${__t0})" | bc -l) - # Ensures a positive number - __time_size=$(echo "sqrt((${__t1} - ${__t0})^2)" | bc -l) - - unset __t0 __t1 - fi - - echo ${__time_size} - cleanup_list="${cleanup_list} $(pwd)/${__time_file}" - unset __time_file __time_size __file -} - - -function iterative_coupling_pism_ocean_fesom2pism_names { - _file=$1 - - # - # These names are constant and are also use above internally (!) - # - _fesom_basalshelf_freshwater_flux_varn="wnet_basal" - _fesom_basalshelf_freshwater_flux_unit="kg m-2" - _fesom_iceberg_freshwater_flux_varn="wnet_iceberg" - # Since PISM discharge/ice berg calving may has the unit "Gt" - # and the implicit timing information, we convert it into "kg" - # and repair later the mass loss into a mass flux - # -> iterative_coupling_pism_ocean_compute_calving_loss_to_calving_flux - ##_fesom_iceberg_freshwater_flux_unit="kg m-2" - _fesom_iceberg_freshwater_flux_unit="kg" - -# -# Controlling sequence -# - -cat > ${_file:-cdo_partable.txt} < ${COUPLE_DIR}/ice_names_for_solidearth.dat - ICE_THICKNESS_VARNAME_pism=thk - MASK_VARNAME_pism=mask - TOPOGRAPHY_VARNAME_pism=topg - echo "ice_thickness_name=$ICE_THICKNESS_VARNAME_pism" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "ice_mask_name=${MASK_VARNAME_pism}" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "ice_topography_name=${TOPOGRAPHY_VARNAME_pism}" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "RUN_NUMBER_ice=${RUN_NUMBER_pism}" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "CURRENT_YEAR_ice=${CURRENT_YEAR_pism}" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "END_YEAR_ice=${END_YEAR_pism}" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "VALUE_LAND_ice=0" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "VALUE_GROUNDED_ice=2" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "VALUE_FLOATING_ice=3" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat - echo "VALUE_OCEAN_ice=4" >> ${COUPLE_DIR}/ice_names_for_solidearth.dat -} - -function iterative_coupling_pism_solidearth_write_grid { - if [ ! -f ${COUPLE_DIR}/ice.griddes ]; then - - cp ${POOL_DIR_pism}/grids/${DOMAIN_pism}/${EXE_pism}_${DOMAIN_pism}_${RES_pism}.griddes \ - ${COUPLE_DIR}/ice.griddes - fi -} - -function pism_solidearth_initialize_ice_thickness_file { - if [ "x${RUN_NUMBER_pism}" == "x1" ]; then - solidearth_ice_thickness_file=${COUPLE_DIR}/ice_thickness.nc - - # Three different options, user HAS to make a choice, see runscript - case $pism_solidearth_initialize_method in - "dummy") - echo " " - echo " The initialization method for the pism-solid earth coupling is dummy." - echo " The last timestep of the specfied output file of the dummy run will be taken as initial condition for the ice thickness." - if [ ! -f ${pism_solidearth_initialize_dummyrun_file} ]; then - echo " WARNING: no valid dummy run for the pism-solid earth coupling chosen!" - echo " Ice thickness file will not be initialized." - else - cdo -s \ - selvar,${ICE_THICKNESS_VARNAME_pism},${TOPOGRAPHY_VARNAME_pism} \ - -select,timestep=-1 \ - ${pism_solidearth_initialize_dummyrun_file} \ - ${COUPLE_DIR}/regrid-tmp.nc - - # Create dummy mask with missing values, this mask is not used - ncap2 -s 'mask=byte((thk*0)-127)' ${COUPLE_DIR}/regrid-tmp.nc ${solidearth_ice_thickness_file} - rm ${COUPLE_DIR}/regrid-tmp.nc - fi - ;; - "regrid") - echo " " - echo " The initialization method for the pism-solid earth coupling is regrid." - echo " The PISM input file, regridding to output shape, will be taken as initial condition for the ice thickness." - - INPUT_GRID_pism=${INPUT_GRID_pism:-${COUPLE_DIR}/ice.griddes} - - cdo -s \ - remapcon,${COUPLE_DIR}/ice.griddes \ - -selvar,${ICE_THICKNESS_VARNAME_pism},${TOPOGRAPHY_VARNAME_pism} \ - -setgrid,${INPUT_GRID_pism} \ - ${INPUT_FILE_pism} ${COUPLE_DIR}/regrid-tmp.nc - - # Create dummy mask with missing values, this mask is not used - ncap2 -s 'mask=byte((thk*0)-127)' ${COUPLE_DIR}/regrid-tmp.nc ${solidearth_ice_thickness_file} - rm ${COUPLE_DIR}/regrid-tmp.nc - ;; - "first_timestep") - echo " " - echo " The initialization method for the pism-solid earth coupling is first_timestep." - echo " The first timestep of the first PISM output file will be taken as initial condition for the ice thickness." - - cdo -s \ - selvar,${ICE_THICKNESS_VARNAME_pism},${MASK_VARNAME_pism},${TOPOGRAPHY_VARNAME_pism} \ - -select,timestep=1 \ - ${DATA_DIR_pism}/latest_ex_file_pism.nc \ - ${solidearth_ice_thickness_file} - ;; - *) - echo " WARNING: no valid initialization method for the pism-solid earth coupling chosen!" - echo " Ice thickness file will not be initialized, please set parameter pism_solidearth_initialize_method in your runscript." - esac - - ncap2 -s "time=${YR0_INI_pism}" ${solidearth_ice_thickness_file} -A ${solidearth_ice_thickness_file} - ncatted -a calendar,time,o,c,"365_day" ${solidearth_ice_thickness_file} - - else - continue - fi - - -} - -function pism_solidearth_append_ice_thickness_file { - solidearth_ice_thickness_file=${COUPLE_DIR}/ice_thickness.nc - - cdo -s \ - selvar,${ICE_THICKNESS_VARNAME_pism},${MASK_VARNAME_pism},${TOPOGRAPHY_VARNAME_pism} \ - -select,timestep=-1 \ - ${DATA_DIR_pism}/latest_ex_file_pism.nc \ - ${COUPLE_DIR}/ofile_${RUN_NUMBER_pism}.nc - - ncap2 -s "time=${END_YEAR_pism}" ${COUPLE_DIR}/ofile_${RUN_NUMBER_pism}.nc -A ${COUPLE_DIR}/ofile_${RUN_NUMBER_pism}.nc - - ncrcat -A ${solidearth_ice_thickness_file} ${COUPLE_DIR}/ofile_${RUN_NUMBER_pism}.nc ${solidearth_ice_thickness_file} - - cdo -s -O \ - shifttime,${YR0_INI_pism}year \ - -settaxis,0-1-1,00:00,${NYEAR_pism_standalone}year \ - ${solidearth_ice_thickness_file} ${COUPLE_DIR}/tmp_ice_thickness.nc - - mv ${COUPLE_DIR}/tmp_ice_thickness.nc ${solidearth_ice_thickness_file} - -# clean up - rm ${COUPLE_DIR}/ofile_${RUN_NUMBER_pism}.nc - -} - diff --git a/couplings/pism/coupling_solidearth2pism.functions b/couplings/pism/coupling_solidearth2pism.functions deleted file mode 100644 index 85201f86f..000000000 --- a/couplings/pism/coupling_solidearth2pism.functions +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/ksh - -function solidearth2pism { - echo " ==================================================================" - echo " *** S T A R T I N G solidearth2pism *** "; echo - - echo " SOLID_EARTH_TO_PISM=${SOLID_EARTH_TO_PISM}" - - if [[ "x${SOLID_EARTH_TO_PISM}" == "x1" ]]; then - read_names solidearth ice - iterative_coupling_solid_earth_pism_regrid_rename - iterative_coupling_solid_earth_pism_update_restart_file - else - echo " NOT generating solid earth forcing for ice" - fi - echo - echo " *** F I N I S H E D solidearth2pism *** " - echo " ==================================================================" -} - -function iterative_coupling_solid_earth_pism_regrid_rename { - -# Regrid: use remapbic because is gives smoother results and conservatism is not essential in this case - cdo -s \ - remapbic,${COUPLE_DIR}/ice.griddes \ - -setgrid,${SOLIDEARTH_grid} \ - ${ice_bedrock_change_file} \ - ${COUPLE_DIR}/bedrock_change_regrid.nc - -# Rename - cdo -s \ - chname,${bedrock_change_name},topg \ - ${COUPLE_DIR}/bedrock_change_regrid.nc ${COUPLE_DIR}/add_topg_${RUN_NUMBER_solidearth}.nc -} - -function iterative_coupling_solid_earth_pism_update_restart_file { - -# Import the restart file to be changed - cp $(readlink ${RESTART_DIR_pism}/latest_restart_file_pism.nc) ${COUPLE_DIR}/restart_pre_${RUN_NUMBER_solidearth}.nc - -# Select topg (bedrock height), add the change, and replace this variable in the restart file - cdo -s \ - selvar,topg \ - ${COUPLE_DIR}/restart_pre_${RUN_NUMBER_solidearth}.nc \ - ${COUPLE_DIR}/tmp.nc - - cdo -s \ - add ${COUPLE_DIR}/tmp.nc \ - ${COUPLE_DIR}/add_topg_${RUN_NUMBER_solidearth}.nc \ - ${COUPLE_DIR}/added_topg_${RUN_NUMBER_solidearth}.nc - - cdo -s \ - replace ${COUPLE_DIR}/restart_pre_${RUN_NUMBER_solidearth}.nc \ - ${COUPLE_DIR}/added_topg_${RUN_NUMBER_solidearth}.nc \ - ${COUPLE_DIR}/restart_post_${RUN_NUMBER_solidearth}.nc - -# Export the changed restart file - cp ${COUPLE_DIR}/restart_post_${RUN_NUMBER_solidearth}.nc $(readlink ${RESTART_DIR_pism}/latest_restart_file_pism.nc) - -# Clean up - rm ${COUPLE_DIR}/tmp.nc - rm ${COUPLE_DIR}/add_topg_${RUN_NUMBER_solidearth}.nc ${COUPLE_DIR}/added_topg_${RUN_NUMBER_solidearth}.nc -# You may not want to (but nevertheless you can) delete these files: - rm ${COUPLE_DIR}/restart_pre_${RUN_NUMBER_solidearth}.nc ${COUPLE_DIR}/restart_post_${RUN_NUMBER_solidearth}.nc - -} diff --git a/couplings/pism/debm_compile_stdout_stderr b/couplings/pism/debm_compile_stdout_stderr deleted file mode 100644 index 7eae94c13..000000000 --- a/couplings/pism/debm_compile_stdout_stderr +++ /dev/null @@ -1,3 +0,0 @@ -/home/a/a270124/esm_tools/runscripts/../couplings/pism/coupling_atmosphere2pism.functions: line 1743: ./install_debm.sh: No such file or directory -/home/a/a270124/esm_tools/runscripts/../couplings/pism/coupling_atmosphere2pism.functions: line 1743: ./install_debm.sh: No such file or directory -/home/a/a270124/esm_tools/runscripts/../couplings/pism/coupling_atmosphere2pism.functions: line 1743: ./install_debm.sh: No such file or directory diff --git a/couplings/pism/env_pism.py b/couplings/pism/env_pism.py deleted file mode 100644 index d2e2386db..000000000 --- a/couplings/pism/env_pism.py +++ /dev/null @@ -1,60 +0,0 @@ -def prepare_environment(config): - default_input_grid = config["general"]["experiment_couple_dir"] +"/ice.griddes" - environment_dict = { - "PISM_TO_OCEAN": 0, - "OCEAN_TO_PISM": int(config["general"]["first_run_in_chunk"]), - "COUPLE_DIR": config["general"]["experiment_couple_dir"], - "VERSION_pism": config[config["general"]["setup_name"]]["version"].replace("github", "").replace("index", "").replace("snowflake", "")[:3], - "POOL_DIR_pism": config[config["general"]["setup_name"]]["pool_dir"], - - "YR0_pism": config["general"]["start_date"].syear, - "M0_pism": config["general"]["start_date"].smonth, - "D0_pism": config["general"]["start_date"].sday, - - "END_YEAR_pism": config["general"]["end_date"].syear, - "END_MONTH_pism": config["general"]["end_date"].smonth, - "END_DAY_pism": config["general"]["end_date"].sday, - - "CURRENT_YEAR_pism": config["general"]["current_date"].syear, - "EX_INT": config[config["general"]["setup_name"]]["ex_interval"], - "RUN_NUMBER_pism": config["general"]["run_number"], - "CHUNK_START_DATE_pism": config["general"]["chunk_start_date"], - "CHUNK_END_DATE_pism": config["general"]["chunk_end_date"], - "CHUNK_START_YEAR_pism": config["general"]["chunk_start_date"].syear, - "CHUNK_END_YEAR_pism": config["general"]["chunk_end_date"].syear, - "EXP_ID": config["general"]["command_line_config"]["expid"], - #"ICEBERG_DIR": config["general"]["iceberg_dir"], - "OUTPUT_DIR_pism": config[config["general"]["setup_name"]]["experiment_outdata_dir"], - "SPINUP_FILE_pism": config[config["general"]["setup_name"]]["spinup_file"], - #"MESH_DIR_fesom": config["general"]["mesh_dir"], - "FUNCTION_PATH": config[config["general"]["setup_name"]]["workflow"]["subjobs"]["couple_in"]["script_dir"], - "CHUNK_SIZE_pism_standalone": config["model2"]["chunk_size"], - #"iter_coup_interact_method_ice2oce": "BASALSHELF_WATER_ICEBERG_MODEL", - "MACHINE": config["computer"]["name"], - "DOMAIN_pism": config[config["general"]["setup_name"]]["domain"], - "RES_pism": config[config["general"]["setup_name"]]["resolution"], - "EXE_pism": config[config["general"]["setup_name"]]["executable"], - "iterative_coupling_atmosphere_pism_ablation_method": config[config["general"]["setup_name"]].get("ablation_method", "PDD"), - "DEBM_EXE": config[config["general"]["setup_name"]].get("debm_path", ""), - "MY_OBLIQUITY": config[config["general"]["setup_name"]].get("debm_obl", "23.441"), - "DEBM_BETA": config[config["general"]["setup_name"]].get("debm_beta", 999), - "iterative_coupling_atmosphere_pism_regrid_method": config[config["general"]["setup_name"]].get("regrid_method", "DOWNSCALE"), - "REDUCE_TEMP": int(config[config["general"]["setup_name"]].get("reduce_temp", 0)), - "REDUCE_TEMP_BY": config[config["general"]["setup_name"]].get("reduce_temp_by", 1), - "USE_YMONMEAN": config[config["general"]["setup_name"]].get("use_ymonmean", 0), - "MULTI_YEAR_MEAN_SMB": config[config["general"]["setup_name"]].get("multi_year_mean_smb", 1), - #"PISM_OCEAN_PICO_BASINS_FILE": "/home/ollie/lackerma/pool_pism/basins/antarctica.16km.nc", - - "INPUT_FILE_pism": config[config["general"]["setup_name"]].get("cli_input_file_pism"), - "TEMP2_BIAS_FILE": config[config["general"]["setup_name"]].get("temp2_bias_file"), - "DOWNSCALING_LAPSE_RATE": config[config["general"]["setup_name"]].get("lapse_rate", -0.005), - "DOWNSCALE_PRECIP": config[config["general"]["setup_name"]].get("downscale_precip", 1), - } - print (environment_dict) - return environment_dict - - - - - - diff --git a/couplings/pism/env_pism2awiesm.py b/couplings/pism/env_pism2awiesm.py deleted file mode 100644 index a0647531c..000000000 --- a/couplings/pism/env_pism2awiesm.py +++ /dev/null @@ -1,59 +0,0 @@ -def prepare_environment(config): - default_input_grid = config["general"]["experiment_couple_dir"] +"/ice.griddes" - environment_dict = { - "ATMOSPHERE_TO_PISM": int(config["general"]["first_run_in_chunk"]), - "PISM_TO_ATMOSPHERE": int(config["general"]["last_run_in_chunk"]), - "CHUNK_START_DATE_pism": config["general"]["chunk_start_date"], - "CHUNK_END_DATE_pism": config["general"]["chunk_end_date"], - "CHUNK_START_YEAR_pism": config["general"]["chunk_start_date"].syear, - "CHUNK_END_YEAR_pism": config["general"]["chunk_end_date"].syear, - "NYEAR": config["general"]["nyear"], - "COUPLE_DIR": config["general"]["experiment_couple_dir"], - "DOWNSCALE_TEMP": 1, - "DOWNSCALING_LAPSE_RATE": config[config["general"]["setup_name"]].get("lapse_rate", -0.005), - "DOWNSCALE_PRECIP": config[config["general"]["setup_name"]].get("downscale_precip", 1), - "VERSION_pism": config[config["general"]["setup_name"]]["version"].replace("github", "").replace("index", "").replace("snowflake", "")[:3], - "POOL_DIR_pism": config[config["general"]["setup_name"]]["pool_dir"], - "DOMAIN_pism": config[config["general"]["setup_name"]]["domain"], - "EXE_pism": config[config["general"]["setup_name"]]["executable"], - "RES_pism": config[config["general"]["setup_name"]]["resolution"], - "RUN_NUMBER_pism": config["general"]["run_number"], - "EX_INT": config["pism"]["ex_interval"], - - "YR0_pism": config["general"]["start_date"].syear, - "M0_pism": config["general"]["start_date"].smonth, - "D0_pism": config["general"]["start_date"].sday, - - "END_YEAR_pism": config["general"]["end_date"].syear, - "END_MONTH_pism": config["general"]["end_date"].smonth, - "END_DAY_pism": config["general"]["end_date"].sday, - "MIN_MON_SELECT": int(config["pism"].get("select_min_glacial_depth", 1)), - - "CRITICAL_THK_FOR_MASK_pism": config["pism"].get("thk_threshold", 5.0), - "CURRENT_YEAR_pism": config["general"]["current_date"].syear, - "EXP_ID": config["general"]["command_line_config"]["expid"], - "OUTPUT_DIR_pism": config[config["general"]["setup_name"]]["experiment_outdata_dir"], - "SPINUP_FILE_pism": config[config["general"]["setup_name"]]["spinup_file"], - "CHUNK_SIZE_pism_standalone": config["model2"]["chunk_size"], - "INPUT_FILE_pism": config[config["general"]["setup_name"]].get("cli_input_file_pism"), - "first_year_in_chunk_input": config[config["general"]["setup_name"]]["experiment_input_dir"] + "/" + config["general"]["expid"] + "_pismr_input_" + config["general"]["chunk_start_date"].syear + "0101-" + str(int( config["general"]["chunk_start_date"].syear ) + int( config["general"]["nyear"] - 1 )) + "1231.nc", - "last_year_in_chunk_restart": config[config["general"]["setup_name"]]["restart_out_targets"]["restart"], - "PISM_TO_OCEAN": int(config[config["general"]["setup_name"]].get("iceberg_coupling", False).__bool__()), - "OCEAN_TO_PISM": int(config["general"]["first_run_in_chunk"]), - "fesom_use_iceberg": int(config[config["general"]["setup_name"]].get("iceberg_coupling", False).__bool__()), - "CURRENT_YEAR_pism": config["general"]["current_date"].syear, - "END_YEAR_pism": config["general"]["end_date"].syear, - "EXP_ID": config["general"]["command_line_config"]["expid"], - #"ICEBERG_DIR": config["general"]["iceberg_dir"], - "OUTPUT_DIR_pism": config[config["general"]["setup_name"]]["experiment_outdata_dir"], - "SPINUP_FILE_pism": config[config["general"]["setup_name"]]["spinup_file"], - #"MESH_DIR_fesom": config["general"]["mesh_dir"], - "FUNCTION_PATH": config[config["general"]["setup_name"]]["workflow"]["subjobs"]["couple_in"]["script_dir"], - "CHUNK_SIZE_pism_standalone": config["model2"]["chunk_size"], - "iter_coup_interact_method_ice2oce": "BASALSHELF_WATER_ICEBERG_MODEL", - "MACHINE": config["computer"]["name"], - "account_all_fw_input": config[config["general"]["setup_name"]].get("account_all_fw_input", 0), - "USE_YMONMEAN": config[config["general"]["setup_name"]].get("use_ymonmean", 0), - } - print (environment_dict) - return environment_dict diff --git a/couplings/utils/CreateTimeAxisNC.bash b/couplings/utils/CreateTimeAxisNC.bash deleted file mode 100755 index 2a2c66725..000000000 --- a/couplings/utils/CreateTimeAxisNC.bash +++ /dev/null @@ -1,273 +0,0 @@ -#!/bin/bash -# Builds a netCDF file with a time contentiously increasing time axis -# -# The increasing time axis of $ELEMENTS_NO elements is written to the -# file $OUTPUT_NC. A given offset of $OFFSET is considered. -# -# NOTE: Each month has an identical length and the time are integer-like values -# -# Call: -# CreateTimeAxisNC.bash ELEMENTS_NO (OUTPUT_NC) (OFFSET) (TYPE) (CALENDAR) (NUM_TYPE) -# -# ELEMENTS_NO : Number of time steps -# OUTPUT_NC : Netcdf output file name, optional (default=axis.nc) -# OFFSET : Time offset in years, optional (default=0) -# TYPE : NetCDF file file type, as reported by `ncdump -k` -# (default=classic; -# valid=classic/nc3/3, "64-bit offset"/nc6/6, -# "64-bit data"/nc5/5, netCDF-4/nc4/4, -# "netCDF-4 classic model"/nc7/7) -# CALENDAR : Calendar type 360, 365, ... (default=360) -# NUM_TYPE : Number type of time axis (default=double; -# valid=double, float, int) -# -# Examples: -# ./CreateTimeAxisNC.bash 100 TimeAxis.nc -# ./CreateTimeAxisNC.bash 100 TimeAxis.360.nc 0 classic 360_day double -# -# (c) Christian Rodehacke, AWI, 2017-09-27 (first version) -# Christian Rodehacke, AWI, 2017-09-28 (NetCDF type: optional 4th parameter) -# Christian Rodehacke, AWI, 2018-09-12 (Calendar: optional 5th parameter) -# Christian Rodehacke, AWI, 2018-09-19 (Numeric tyupe:optional 6th parameter) -# -NO_LINES=25 ; NO_NEED_INPUTS=1 -set -e -if [ $# -lt ${NO_NEED_INPUTS} ] ; then - head -n ${NO_LINES} $0 - echo - echo " Need at least ${NO_NEED_INPUTS} input parameter(s)" - echo - exit 1 -fi - -ELEMENTS_NO=$1 -if [ $# -ge 2 ] ; then - OUTPUT_NC=$2 -else - OUTPUT_NC="axis.nc" # default value" -fi -if [ $# -ge 3 ] ; then - OFFSET=$3 -else - OFFSET=0 -fi -if [ $# -ge 4 ] ; then - TYPE=$4 -else - TYPE="classic" -fi -if [ $# -ge 5 ] ; then - CALENDAR=$5 -else - CALENDAR="360" -fi - -if [ $# -ge 6 ] ; then - NUM_TYPE=$6 -else - NUM_TYPE="double" -fi - - -DEBUG_FLAG=0 - - -# ======================================================================== -# -# Subroutines, functions -# -# ======================================================================== - -function CreateTimeAxisNC() { - # Creates a netcdf file with linearily increasing time axis starting at zero - # Call: CreateTimeAxisNC NumberToGo0 TIME_AXIS_FILE (OffsetYear) - NumberToGo0_=$1 - TIME_AXIS_FILE_=$2 - if [ $# -ge 3 ] ; then - OffsetYear_=$3 - else - OffsetYear_=0 - fi - if [ $# -ge 4 ] ; then - calendar_wanted_=$4 - else - calendar_wanted_=360 - fi - if [ $# -ge 5 ] ; then - number_type_=$5 - else - number_type_="double" - fi - # - NoRequire__=2 - if [ $# -lt ${NoRequire__} ] ; then - echo " ***** Missing required ${NoRequire__} input variables in 'CreateTimeAxisNC' in $0 *****" 1>&2 - echo " *** $# :: Received $* *****" 1>&2 - exit 102 - fi - # - # Ensure a dummy value for optional parameter - # - OffsetYear_=${OffsetYear_:=0} - - - # - # Function body - # - SECONDS_PER_DAY_=86400 - MINUTES_PER_DAY_=1440 - - calendar_wanted_=${calendar_wanted_:-360} - - case ${calendar_wanted_} in - "366"|"366_day") - DAYS_PER_YEAR_=366 ; DAYS_PER_MONTH_=30.5 # 366_day; Not used in PISM !! - CALENDAR_="${DAYS_PER_YEAR_}_day" - ;; - "365.242198781"|"standard") - DAYS_PER_YEAR_=365.242198781 ; DAYS_PER_MONTH_=30.436849898 # =(1/12)*365.242198781 : UDUNUITS-2 - CALENDAR_="standard" - ;; - "365"|"365_day"|"noleap") - DAYS_PER_YEAR_=365 ; DAYS_PER_MONTH_=30.416666667 # 365_day=noleap - CALENDAR_="${DAYS_PER_YEAR_}_day" - ;; - "360"|"360_day"|"leap") - DAYS_PER_YEAR_=360 ; DAYS_PER_MONTH_=30 # 360_day - CALENDAR_="${DAYS_PER_YEAR_}_day" - ;; - *) - echo " UNKNOWN calendar <<${calendar_wanted_}>>" - echo " S T O P 4" - exit 4 - ;; - esac - - - # - # *** If you change something here, also change the 'awk' computation below!! - # - ##DAYS_PER_YEAR_=366 ; DAYS_PER_MONTH_=30.5 # 366_day; Not used in PISM !! - ##CALENDAR_="${DAYS_PER_YEAR_}_day" - #DAYS_PER_YEAR_=365.242198781 ; DAYS_PER_MONTH_=30.436849898 # =(1/12)*365.242198781 : UDUNUITS-2 - #CALENDAR_="standard" - #DAYS_PER_YEAR_=365 ; DAYS_PER_MONTH_=30.416666667 # 365_day=noleap - #CALENDAR_="${DAYS_PER_YEAR_}_day" - #DAYS_PER_YEAR_=360 ; DAYS_PER_MONTH_=30 # 360_day - #CALENDAR_="${DAYS_PER_YEAR_}_day" - # - # *** If you change something here, also change the 'awk' computation below!! - # - - CALENDAR_UNIT_="days" ; OffTime_=$(echo "$OffsetYear_ * $DAYS_PER_YEAR_ " | bc -l ) - #CALENDAR_UNIT_="minutes"; OffTime_=$(echo "$OffsetYear_ * $DAYS_PER_YEAR_ * $MINUTES_PER_DAY_ " | bc -l ) - #CALENDAR_UNIT_="seconds"; OffTime_=$(echo "$OffsetYear_ * $DAYS_PER_YEAR_ * $SECONDS_PER_DAY_ " | bc -l ) - - # DOES NOT WORK for calendar "standard" - #CALENDAR_UNIT_="days" ; OffTime_=$(( OffsetYear_ * DAYS_PER_YEAR_ )) - #CALENDAR_UNIT_="minutes"; OffTime_=$(( OffsetYear_ * DAYS_PER_YEAR_ * MINUTES_PER_DAY_ )) - #CALENDAR_UNIT_="seconds"; OffTime_=$(( OffsetYear_ * DAYS_PER_YEAR_ * SECONDS_PER_DAY_ )) - - - time_=$(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*$DAYS_PER_MONTH_+15.0+$OffTime_}else{printf(\",%i\\n\",\$1*$DAYS_PER_MONTH_+15.0+$OffTime_)}}") - time_bnds_=$(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*$DAYS_PER_MONTH_+$OffTime_\",\"(\$1+1)*$DAYS_PER_MONTH_+$OffTime_}else{print \",\"\$1*$DAYS_PER_MONTH_+$OffTime_\",\"(\$1+1)*$DAYS_PER_MONTH_+$OffTime_}}") - - - cat > ${TIME_AXIS_FILE_}.cdl << EOF -netcdf time_axis { -dimensions: - time = UNLIMITED ; - t_nb2 = 2 ; -variables: - //float time(time) ; - //double time(time) ; - ${number_type_} time(time) ; - time:units = "${CALENDAR_UNIT_} since 0000-01-01 00:00:00" ; - time:calendar = "${CALENDAR_}" ; - time:long_name = "time" ; - time:standard_name = "time" ; - time:axis = "T" ; - time:bounds = "time_bnds" ; - time:comment =" Time axis constructed on $(date)" ; - //double time_bnds(time, t_nb2) ; - //double time_bnds(time, t_nb2) ; - ${number_type_} time_bnds(time, t_nb2) ; -// global attributes: - :Comments = "Generic build time axis" ; - :Conventions = "CF-1.3" ; - :Creators = "Christian Rodehacke" ; - :History = "`date`: Created by $USER \n"; - :Title = "Generic time axis" ; - -data: - //For :calendar = "360_day" ; - time = $time_ ; - time_bnds = $time_bnds_ ; - -} -EOF - - -# -## //For :calendar = "360_day" ; -## time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.0+15.0+$OffTime_}else{printf(\",%i\\n\",\$1*30.0+15.0+$OffTime_)}}") ; -## time_bnds = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.0+$OffTime_\",\"(\$1+1)*30.0+$OffTime_}else{print \",\"\$1*30.0+$OffTime_\",\"(\$1+1)*30.0+$OffTime_}}") ; -## //For :calendar = "366_day" ; -## time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.5+15.0}else{printf(\",%i\\n\",\$1*30.5+15.0)}}") ; -## time_bnds = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.5\",\"(\$1+1)*30.5}else{print \",\"\$1*30.5\",\"(\$1+1)*30.5}}") ; -## //For :calendar = "366_day" ; -## time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.5+15.0}else{printf(\",%i\\n\",\$1*30.5+15.0)}}") ; -## time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1*30.5+15.0}else{print \",\"\$1*30.5+15.0}}") ; -# -# //month: time = `seq -s\, 0 ${NumberToGo0_}` ; -# //month: time_bnds = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1\",\"\$1+1}else{print \",\"\$1\",\"\$1+1}}") ; -# -# //time = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1/\$STEPS_PER_YEAR}else{print \",\"\$1/\$STEPS_PER_YEAR}}") ; -# //time_bnds = $(seq 0 ${NumberToGo0_} | awk "{if(NR==1){print \$1/\$STEPS_PER_YEAR\",\"(\$1+1)/\$STEPS_PER_YEAR}else{print \",\"\$1/\$STEPS_PER_YEAR\",\"(\$1+1)/\$STEPS_PER_YEAR}}") ; -# - - ncgen -o ${TIME_AXIS_FILE_} ${TIME_AXIS_FILE_}.cdl -k ${TYPE} && rm ${TIME_AXIS_FILE_}.cdl -} - -# ======================================================================== -# -# Main program -# -# ======================================================================== - -if [ ${DEBUG_FLAG} -gt 0 ] ; then - echo - echo "ELEMENTS_NO : ${ELEMENTS_NO}" - echo "OUTPUT_NC : ${OUTPUT_NC}" - echo "OFFSET : ${OFFSET:=0}" - echo "CALENDAR : ${CALENDAR}" - echo "NUM_TYPE : ${NUM_TYPE}" -fi - -if [ -f ${OUTPUT_NC} ] ;then - echo - echo " OUTPUT_NC=${OUTPUT_NC} exits: $(ls -l ${OUTPUT_NC})" - echo " S T O P 2" - exit 2 -fi - -DIR=$(dirname ${OUTPUT_NC}) -if [ ! -d ${DIR} ] ; then - echo - echo " directory '${DIR}' of '${OUTPUT_NC}' does not exist" - echo " S T O P 3" - exit 3 -fi - -# -# in the function we compute dates from [0 to $ELEMENTS_NO] times TimeStepWith -# Hence we have to reduce $ELEMENTS_NO by one to actually get the requested -# number of elements -# -ELEMENTS_NO=$(( ELEMENTS_NO - 1 )) - -CreateTimeAxisNC ${ELEMENTS_NO} ${OUTPUT_NC} ${OFFSET} ${CALENDAR} ${NUM_TYPE} - - -exit 0 -# -- last line diff --git a/couplings/utils/_build/mo_kinds.mod b/couplings/utils/_build/mo_kinds.mod deleted file mode 100644 index 700174af3..000000000 Binary files a/couplings/utils/_build/mo_kinds.mod and /dev/null differ diff --git a/couplings/utils/_build/mo_vegparams.mod b/couplings/utils/_build/mo_vegparams.mod deleted file mode 100644 index 156c380f1..000000000 Binary files a/couplings/utils/_build/mo_vegparams.mod and /dev/null differ diff --git a/couplings/utils/apply_hosing_correction.py b/couplings/utils/apply_hosing_correction.py deleted file mode 100644 index 00e39d7f1..000000000 --- a/couplings/utils/apply_hosing_correction.py +++ /dev/null @@ -1,53 +0,0 @@ -import pandas as pd -import xarray as xr -import sys -import os.path - -rho_water = 1000 #kg/m3 - -discharge_file = sys.argv[1] -cell_area_echam_file = sys.argv[2] -cell_area_fesom_file = sys.argv[3] -hosing_dir = sys.argv[4] - -if os.path.exists(cell_area_fesom_file): - print(" * Loading total FESOM grid area from ", cell_area_fesom_file) - fl = xr.open_dataset(cell_area_fesom_file, engine="netcdf4") - print(" * Summing up FESOM grid areas") - if "nod_area" in fl.variables: - total_FESOM_cell_area = fl.nod_area[0, :].sum().squeeze().values - elif "cell_area" in fl.variables: - total_FESOM_cell_area = fl.cell_area[:].sum().squeeze().values - print(" * Total cell area = ", total_FESOM_cell_area) -else: - print(" * File does not exist!") - exit - -if os.path.exists(discharge_file): - print(" * Loading ice discharge from ", discharge_file) - fl1 = xr.open_dataset(discharge_file, engine="netcdf4") -else: - print(" * File does not exist!") - exit - -if os.path.exists(discharge_file): - print(" * Loading total ECHAM grid area from ", cell_area_echam_file) - fl2 = xr.open_dataset(cell_area_echam_file, engine="netcdf4") - print(" * Integrate discharge over ECHAM grid") - # Convert kg/s into m3/s - discharge_tot = fl1.total_ice_mass_loss_flux.weighted(fl2.cell_area.squeeze()).sum() / rho_water - print(" * Distribute over FESOM domain evenly") - discharge = -discharge_tot / total_FESOM_cell_area -else: - print(" * File does not exist!") - exit - -if not os.path.isfile(os.path.join(hosing_dir, "landice_nodes_in_region_1.out")): - df = pd.read_csv(os.path.join(os.path.dirname(cell_area_fesom_file), "nod2d.out"), sep="\s+", skiprows=[0], header=None) - n=df.iloc[:, 0] - n.to_csv(os.path.join(hosing_dir, "landice_nodes_in_region_1.out"), header=[str(len(n.values))], index=False) - -mass_loss = discharge.squeeze().values -with open(os.path.join(hosing_dir, "landice_yearly_mass_loss.out"), 'w') as f: - f.write(str(1) + "\n" + str(mass_loss)) - diff --git a/couplings/utils/axis_366.nc b/couplings/utils/axis_366.nc deleted file mode 100644 index 287e932b9..000000000 Binary files a/couplings/utils/axis_366.nc and /dev/null differ diff --git a/couplings/utils/calnoro.f90 b/couplings/utils/calnoro.f90 deleted file mode 100644 index ec649d3fb..000000000 --- a/couplings/utils/calnoro.f90 +++ /dev/null @@ -1,339 +0,0 @@ -PROGRAM calnoro - - WRITE(*,*) 'CALNORO CALLED' - - WRITE(*,*) 'Truncation ?' - READ (*,*) IRES - CALL calres(ires, nlat) - - nlon = 2*nlat - WRITE (*,*) 'RES: ', IRES,' NLAT: ',nlat,' NLON: ',nlon - - CALL sso_par_fil(nlat, nlon) - -END PROGRAM calnoro - -SUBROUTINE calres (ires, nlat) - IF (ires < 21 .OR. ires > 1000) THEN - WRITE(0,*) 'calres: resolution out of range (res=',ires,')' - STOP - END IF - - nlat = NINT((ires*3.+1.)/2.) - IF (MOD(nlat,2) > 0) THEN - nlat = nlat + 1 - nlat2 = NINT(((ires+1)*3.+1.)/2.) - IF (nlat == nlat2) THEN - WRITE(0,*) 'calres: can not calculate number of latitudes for res ', ires - STOP - END IF - END IF -! WRITE (*,*) 'res: ', ires, ' nlat: ', nlat - - RETURN -END SUBROUTINE calres - -SUBROUTINE gauaw (pa, pw, nlat) - - ! Description: - ! - ! Compute abscissas and weights for gaussian integration. - ! - ! Method: - ! - IMPLICIT NONE - - ! Scalar arguments - INTEGER nlat - - ! Array arguments - REAL pa(nlat), pw(nlat) - ! *pa* - array, length at least *k,* to receive abscis abscissas. - ! *pw* - array, length at least *k,* to receive weights. - - - ! Local scalars: - REAL, PARAMETER :: eps = EPSILON(0.0) - REAL :: api - INTEGER, PARAMETER :: itemax = 20 - - INTEGER iter, ins2, isym, jn, jgl - REAL za, zw, z, zan - REAL zk, zkm1, zkm2, zx, zxn, zldn, zmod - - ! Intrinsic functions - INTRINSIC ABS, COS, MOD, TAN, ASIN - - ! Executable statements - - api = 2.*ASIN(1.) - - ins2 = nlat/2+MOD(nlat,2) - - ! Find first approximation of the roots of the - ! Legendre polynomial of degree nlat - - DO jgl = 1, ins2 - z = REAL(4*jgl-1)*api/REAL(4*nlat+2) - pa(jgl) = COS(z+1./(TAN(z)*REAL(8*nlat**2))) - END DO - - ! Computes roots and weights - ! Perform the Newton loop - ! Find 0 of Legendre polynomial with Newton loop - - DO jgl = 1, ins2 - - za = pa(jgl) - - DO iter = 1, itemax+1 - zk = 0.0 - - ! Newton iteration step - - zkm2 = 1.0 - zkm1 = za - zx = za - DO jn = 2, nlat - zk = (REAL(2*jn-1)*zx*zkm1-REAL(jn-1)*zkm2)/REAL(jn) - zkm2 = zkm1 - zkm1 = zk - END DO - zkm1 = zkm2 - zldn = (REAL(nlat)*(zkm1-zx*zk))/(1.-zx*zx) - zmod = -zk/zldn - zxn = zx+zmod - zan = zxn - - ! computes weight - - zkm2 = 1.0 - zkm1 = zxn - zx = zxn - DO jn = 2,nlat - zk = (REAL(2*jn-1)*zx*zkm1-REAL(jn-1)*zkm2)/REAL(jn) - zkm2 = zkm1 - zkm1 = zk - END DO - zkm1 = zkm2 - zw = (1.0-zx*zx)/(REAL(nlat*nlat)*zkm1*zkm1) - za = zan - IF (ABS(zmod) <= eps) EXIT - END DO - - pa(jgl) = zan - pw(jgl) = zw * 2. - - ENDDO - -!DIR$ IVDEP -!OCL NOVREC - DO jgl = 1, nlat/2 - isym = nlat-jgl+1 - pa(isym) = -pa(jgl) - pw(isym) = pw(jgl) - ENDDO - -END SUBROUTINE gauaw - -SUBROUTINE sso_par_fil(nlat, nlon) - -! USE mo_orogwd - IMPLICIT NONE - - INTEGER nlat, nlon - - INTEGER, PARAMETER :: iusn=720, jusn=360 - !INTEGER, PARAMETER :: iusn=1440, jusn=720 - !INTEGER, PARAMETER :: iusn=2160, jusn=1080 - - INTEGER i, j - INTEGER ihead(8) - - REAL zgw(nlat) - REAL xusn(iusn),yusn(jusn),zusn(iusn,jusn) - REAL xlon(nlon),ylat(nlat) - REAL zphi(nlon,nlat),zmea(nlon,nlat), & - zstd(nlon,nlat),zsig(nlon,nlat), & - zgam(nlon,nlat),zthe(nlon,nlat), & - zpic(nlon,nlat),zval(nlon,nlat) - INTEGER mask(nlon,nlat) - REAL xpi, zmin, zmax - - - ! INITIALISATION - - CALL gauaw(ylat, zgw, nlat) - DO j=1,nlat - ylat(j) = ASIN(ylat(j))/(8.*ATAN(1.))*360 -! write (*,*) j, ylat(j) - ENDDO - - xpi=ACOS(-1.) - DO i=1,nlon - xlon(i)=-xpi+2.*(i-1)*xpi/REAL(nlon) - ENDDO - DO j=1,nlat - ylat(j)=ylat(j)*xpi/180. -! write (*,*) j, ylat(j) - ENDDO - - DO i=1,iusn - xusn(i)=-xpi+2.*(REAL(i)-0.5)*xpi/REAL(iusn) - ENDDO - DO j=1,jusn - yusn(j)=xpi/2.-(REAL(j)-0.5)*xpi/REAL(jusn) - ENDDO - -! OPEN(15,file='USN_FMT',form='formatted') - CALL readfield ("OROMEA", zusn, iusn, jusn) - !CALL readfield ("hmean", zusn, iusn, jusn) - - zmin= 10000. - zmax=-10000. - DO j=1,jusn - DO i=1,iusn -! READ(15,*) zusn(i,j) - zmin=MIN(zmin,zusn(i,j)) - zmax=MAX(zmax,zusn(i,j)) - ENDDO - ENDDO - - CLOSE(15) - - PRINT *,' usn min. et max.:',zmin,zmax - - CALL grid_noro(iusn,jusn,xusn,yusn,zusn, & - nlon,nlat,xlon,ylat, & - zphi,zmea,zstd,zsig,zgam,zthe, & - zpic,zval,mask) - - - CALL shift180(zmea, nlat, nlon) - CALL shift180(zstd, nlat, nlon) - CALL shift180(zsig, nlat, nlon) - CALL shift180(zgam, nlat, nlon) - CALL shift180(zthe, nlat, nlon) - CALL shift180(zpic, nlat, nlon) - CALL shift180(zval, nlat, nlon) - - OPEN(22,file='sso_par_fil.srv',form='unformatted') - - - ihead(2) = 0 - ihead(3) = 0 - ihead(4) = 0 - ihead(5) = nlon - ihead(6) = nlat - ihead(7) = 0 - ihead(8) = 0 - - ihead(1) = 51 - WRITE(22) ihead - WRITE(22) zmea - ihead(1) = 52 - WRITE(22) ihead - WRITE(22) zstd - ihead(1) = 53 - WRITE(22) ihead - WRITE(22) zsig - ihead(1) = 54 - WRITE(22) ihead - WRITE(22) zgam - ihead(1) = 55 - WRITE(22) ihead - WRITE(22) zthe - ihead(1) = 56 - WRITE(22) ihead - WRITE(22) zpic - ihead(1) = 57 - WRITE(22) ihead - WRITE(22) zval - - STOP -END SUBROUTINE sso_par_fil - -SUBROUTINE shift180(field, nlat, nlon) - - IMPLICIT NONE - - INTEGER nlat, nlon - - REAL field(nlon, nlat) - REAL tmpfield(nlon, nlat) - - tmpfield(:,:) = field(:,:) - - field(1:nlon/2,:) = tmpfield(nlon/2+1:nlon,:) - field(nlon/2+1:nlon,:) = tmpfield(1:nlon/2,:) - -END SUBROUTINE shift180 - -SUBROUTINE NF_ErrorHandling(func, farg, status) - - CHARACTER (*) func, farg - INTEGER status - - INCLUDE 'netcdf.inc' - - IF (status /= NF_NOERR) THEN - WRITE (0,*) func, '(',farg,') : ', NF_STRERROR(status) - STOP - END IF - -END SUBROUTINE NF_ErrorHandling - -SUBROUTINE readfield (varname, zfield, nlon, nlat) - - USE netcdf - - IMPLICIT NONE - - INTEGER nlat, nlon - REAL zfield(nlon, nlat) - REAL ztmp(nlon) - CHARACTER(*) varname - INTEGER fileid, varid, status - INTEGER jlat, nx, ny - INTEGER start(2), count(2) - CHARACTER(LEN=200) :: dimname - - WRITE (*,*) "READFIELD CALLED:" - WRITE (*,*) " nlat:", nlat, " nlon: ", nlon - WRITE (*,*) " varname: ", varname - - status = nf90_open("topodata.nc", nf90_nowrite, fileid) - CALL NF_ErrorHandling("nf_open", "topodata.nc", status) - - status = nf90_inquire_dimension(fileid, 1, dimname, nx) - status = nf90_inquire_dimension(fileid, 2, dimname, ny) - WRITE (*,*) " ny :", ny, " nx : ", nx - IF(nlon /= nx.OR.nlat /= ny)THEN - WRITE (*,*) ' nlon or nlat bad dimensions' - STOP - ENDIF - - status = nf90_inq_varid(fileid, varname, varid) - CALL NF_ErrorHandling("nf_inq_varid", varname, status) - - DO jlat = 1, nlat - - start(1) = 1 - start(2) = jlat - count(1) = nlon - count(2) = 1 - - status = nf90_get_var(fileid, varid, ztmp, start, count) - CALL NF_ErrorHandling("nf_get_vara_real", varname, status) -! status = nf_get_vara_double(fileid, varid, start, count, ztmp) -! CALL NF_ErrorHandling("nf_get_vara_double", varname, status) - - zfield(1:nlon/2,jlat) = ztmp(nlon/2+1:nlon) - zfield(nlon/2+1:nlon,jlat) = ztmp(1:nlon/2) - - END DO - - status = nf90_close(fileid) - CALL NF_ErrorHandling("nf_close", "topodata.nc", status) - -END SUBROUTINE readfield diff --git a/couplings/utils/fesom_scalar_array_to_LonLat.py b/couplings/utils/fesom_scalar_array_to_LonLat.py deleted file mode 100644 index d9a3a6004..000000000 --- a/couplings/utils/fesom_scalar_array_to_LonLat.py +++ /dev/null @@ -1,287 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Convert FESOM hydrographic output to array at each column point incl lon, lat. - -For the coupling of the FESOM ocean model, the original FESOM output of the -hydrographic fields temp and salt are modified. First values are computed for -all grid point location from the surface layer down to the deepest depth. In -addition for each location the corresponding longitude and latitude information -are provided. - -Dependence: -It depends on the pyfesom code (https://github.com/FESOM/pyfesom) - - -(C) Christian Rodehacke, AWI, 2017-07-12 - -Additional code for command line parsing: - Paul Gierz, AWI, May 7, 2018 -""" - -# -# Command Line Parser -# -import argparse -def parse_arguments(): - parser = argparse.ArgumentParser() - parser.add_argument("--FESOM_PATH", nargs="*", required=True) - parser.add_argument("--FESOM_VARIABLE", nargs="+") - parser.add_argument("--FESOM_MESH", nargs="+") - parser.add_argument("--FESOM_YEARS", nargs="+") - parser.add_argument("--FESOM_OUTPUT", nargs="*", default='fesom_output.nc4') - parser.add_argument("--FESOM_MESH_ROTATED", nargs="*", required=True) - #parser.add_argument("--FESOM_MESH_ALPHA", type=int, default=50) - #parser.add_argument("--FESOM_MESH_BETA", type=int, default=15) - #parser.add_argument("--FESOM_MESH_GAMMA", type=int, default=-90) - return parser.parse_args() - -args = parse_arguments() - -FESOMDATA_OUTPUT = 'fesom_output.nc4' -NAN_REPLACE = 9.96921e36 - -# ---------------------------------------------------------------- -# -# Import external libaries ... -# - -import sys -sys.path.append("./") -sys.path.append("./pyfesom") - -import pyfesom2 as pf -import numpy as np -from netCDF4 import Dataset, MFDataset -import time as time -import xarray as xr -import os - -# ---------------------------------------------------------------- -# -# Some information -# - -print('* Start at '+time.ctime(time.time())) - -# ---------------------------------------------------------------- -# -# Read input data -# -# mesh -print('* Read the mesh MESHPATH=' + " ".join(args.FESOM_MESH)) - -#euler_angle = [args.FESOM_MESH_ALPHA, args.FESOM_MESH_BETA, args.FESOM_MESH_GAMMA] -if not args.FESOM_MESH_ROTATED: - euler_angle = [50, 15, -90] -else: - euler_angle = [0, 0, 0] -print("* Using Euler angles ", euler_angle) - -mesh = pf.load_mesh(*args.FESOM_MESH, abg=euler_angle, usepickle=False) -print("*** mesh.zlev = ", mesh.zlev) - -# -# Oceanographic data -# -#print('* Read the data file args.FESOM_FILE=' + " ".join(args.FESOM_FILE)) -#FID = MFDataset(args.FESOM_PATH + "".join("/temp.fesom.*.01.nc")) -FID = xr.open_dataset(str(args.FESOM_PATH[0]) + str(args.FESOM_VARIABLE[0]) + ".fesom." + str(args.FESOM_YEARS[0]) + ".nc", decode_times=False) - -# ---------------------------------------------------------------- -# -# Initialize size and Preinitialize fields -# -# mesh.n2d = number of 2d nodes, mesh.e2d = number of 2d elements -no_hori_elemnt = mesh.n2d -#no_zlevels = mesh.nlev - 1 -no_zlevels = np.size(mesh.zlev) -#no_zlevels = np.size(mesh_diag.zbar) - -timedim = 'time' if 'time' in FID.dims else 'T' -no_timesteps = FID.dims[timedim] -print("no_timesteps: ", no_timesteps) -sizeVert = no_zlevels -sizeHori = no_hori_elemnt - -sizeFull = (no_timesteps, no_zlevels, no_hori_elemnt) -print("*** sizeFull = ", sizeFull) - -# Fields to write: allocate memory upfront -time_out = np.zeros(no_timesteps, dtype=np.float64) -depth_out = np.zeros(sizeVert, dtype=np.float64) -latitude_out = np.zeros(sizeHori, dtype=np.float64) -longitude_out = np.zeros(sizeHori, dtype=np.float64) -TempFields_out = np.zeros(sizeFull, dtype=np.float64) - -# ---------------------------------------------------------------- -# -# Loop through all depth levels -# -print('* Loop for each time step through all depth levels') - -# -# Depth axis -# -ilevel = -1 -#for depth in mesh_diag.zbar.squeeze().values: -for depth in mesh.zlev: - # Some information - idepth = int(depth) - # - # Prepare data for final netcdf output - # - ilevel = ilevel + 1 - print('* ilevel='+str(ilevel)+' depth='+str(idepth)+\ - ' ('+str(depth)+')') - depth_out[ilevel] = depth - -# -# Time axis -# -time_out = FID.variables['time'][0:no_timesteps] - -# -# Full hydrographic fields -# - -# -# Check shape of input file to process old (2D array) and new (3D array) FESOM files -# -for itime in np.arange(0, no_timesteps, 1, dtype=np.int32): - ##time_out[itime] = FID.variables['time'][itime] - time_read = time_out[itime] - # Some information - print('* TIME('+str(itime)+') = '+str(time_read)) - - ilevel = -1 - #for depth in mesh_diag.zbar.squeeze().values: - for depth in mesh.zlev[:-1]: - # Some information - idepth = int(depth) - print('* depth='+str(idepth)+' ('+str(depth)+\ - ') ++ time('+str(itime)+') = '+str(time_read)) - - # - # Prepare data for final netcdf output - # - ilevel = ilevel + 1 - - flag_verbose=False - - if args.FESOM_YEARS[0] == args.FESOM_YEARS[1]: - level_data = \ - pf.get_data(args.FESOM_PATH[0], args.FESOM_VARIABLE[0], int(args.FESOM_YEARS[0]), mesh, depth=idepth, how="mean") #, flag_verbose) - else: - level_data = \ - pf.get_data(args.FESOM_PATH[0], args.FESOM_VARIABLE[0], [int(args.FESOM_YEARS[0]), int(args.FESOM_YEARS[1])], mesh, depth=idepth, how="mean", use_cftime=True) #, flag_verbose) - level_data[np.where(np.isnan(level_data))] = NAN_REPLACE - TempFields_out[itime, ilevel, :] = level_data - - -# ---------------------------------------------------------------- -# -# Output file -# -print('* Create file "'+args.FESOM_OUTPUT[0]+'"') -#OK: OCE_OUT = Dataset("".join(args.FESOM_OUTPUT), "w", format="NETCDF3_64BIT_OFFSET") -#OCE_OUT = Dataset(args.FESOM_OUTPUT[0], "w", format="NETCDF4") #format="NETCDF3_64BIT_OFFSET") -OCE_OUT = Dataset(args.FESOM_OUTPUT[0], "w", format="NETCDF3_64BIT_OFFSET") #format="NETCDF3_64BIT_OFFSET") - -print('* Create dimensions and define variables') -# -# Create dimensions -# -OCE_OUT.createDimension("time", None) -OCE_OUT.createDimension("level", sizeVert) -OCE_OUT.createDimension("horizontal", no_hori_elemnt) -# -# Create global attributes -# -OCE_OUT.type = "FESOM_ocean_data" -OCE_OUT.title = "FESOM hydrographic ocean data" -OCE_OUT.model_domain = "Generic" -#OCE_OUT.data_input_file = args.FESOM_FILE -OCE_OUT.insitution = 'Alfred Wegener Institute for Polar and Marine Research (AWI)' -OCE_OUT.address = 'Handelshafen, Bremerhaven, Germany' -OCE_OUT.department = "Climate" -OCE_OUT.contact = 'Christian Rodehacke' -OCE_OUT.web = 'http://www.awi.de' -OCE_OUT.acknowledgment = 'ZUWEISS, BMWF, Germany' -OCE_OUT.history = "Created "+time.ctime(time.time()) - -# -# Create variables -# -# -- axis-variables -time_var = OCE_OUT.createVariable("time", "f4", ("time",)) -level_var = OCE_OUT.createVariable("level", "i4", ("level",)) -hori_var = OCE_OUT.createVariable("horizontal", "i4", ("horizontal",)) - -# -- common variables -depth_var = OCE_OUT.createVariable("depth", "f4", ("level",)) -lon_var = OCE_OUT.createVariable("longitude", "f4", ("horizontal",)) -lat_var = OCE_OUT.createVariable("latitude", "f4", ("horizontal",)) - -temp_var = OCE_OUT.createVariable(args.FESOM_VARIABLE[0], "f4", \ - ("time", "level", "horizontal",), fill_value=NAN_REPLACE) -# -# Attributes -# -time_var.long_name = "time" -time_var.axis = "T" -time_var.units = "" #FID.variables['time'].units #"hours since 0001-0101 0:0:0.0" -if hasattr(FID.variables['time'], 'calendar'): - time_var.calendar = FID.variables['time'].calendar #"standard" - -level_var.long_name = "model_level" -level_var.description = "Level number" -level_var.axis = "Z" - -hori_var.long_name = "horizontal_grid_id" -hori_var.description = "Number of horizontal grid element" -hori_var.axis = "X" - -depth_var.long_name = "depth" -depth_var.units = "m" -depth_var.description = "depth below sea level" -depth_var.positive = 'down' - -lon_var.long_name = "longitude" -lon_var.units = "degrees east" -lat_var.long_name = "latitude" -lat_var.units = "degrees north" - -temp_var.long_name = FID.get(args.FESOM_VARIABLE[0]).long_name -temp_var.units = FID.get(args.FESOM_VARIABLE[0]).units -temp_var.coordinates = "longitude latitude" -temp_var.description = "" #FID.variables[args.FESOM_VARIABLE[0]].description -#temp_var.missing_value = NAN_REPLACE - -# -# Write the data fields -# -print('* Write the small fields') -# -- axis variables -#time_var[:] = time_out -level_var[:] = np.arange(0, sizeVert, dtype=np.int32) -hori_var[:] = np.arange(0, sizeHori, dtype=np.int32) - -# -- common variables -depth_var[:] = mesh.zlev -#depth_var[:] = mesh_diag.zbar -lon_var[:] = mesh.x2 -lat_var[:] = mesh.y2 - -print('* Write the larger fields') -temp_var[:] = TempFields_out - -# -# close the files -# -OCE_OUT.close() - -# -# Bye bye -# -print('End at '+time.ctime(time.time())) -print(" ... Bye") diff --git a/couplings/utils/fesom_to_regular_grid.py b/couplings/utils/fesom_to_regular_grid.py deleted file mode 100755 index 6778a8e9a..000000000 --- a/couplings/utils/fesom_to_regular_grid.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python3 - -import argparse, os, sys -import netCDF4 as nc -import numpy as np - -import pyfesom2 as pf -from pyfesom2 import load_mesh, get_data - -def read_data(finname, var): - with nc.Dataset(finname,'r') as fin: - data = fin.variables[var] - # print(data.dimensions) - # print("nz1" in data.dimensions) - # print(len(data.dimensions) == 3) - # print(data.dimensions != ('time', 'nod2', 'nz1')) - ndim = len(data.dimensions) - # check - if ndim == 3 : - print("Read var >>",var,"<< with the dims:") - if data.dimensions == ('time', 'nod2', 'nz1'): - print(data.dimensions) - levdim = 2 - elif data.dimensions == ('time', 'nz1', 'nod2'): - print(data.dimensions) - levdim = 1 - else: - raise ValueError('dimension is not (time nod2 nz1) or (time nz1 nod2)') - - elif ndim == 2: - print("Read var:",var," with the dims:") - print(data.dimensions) - if data.dimensions != ('time', 'nod2'): - raise ValueError('dimension is not (time nod2)') - - levdim = -1 - - data1 = fin.variables[var][:] - return data1, ndim, levdim - - -def function_FESOM2ice_regular_grid( - version_FESOM=2, - meshpath = 'path', abg=[50, 15, -90], - fin='./', - fout='FESOM_for_ice.nc', - depthmax=500., depthmin=300.,): - - if (version_FESOM >= 2) and (version_FESOM < 3) : - print("version:", version_FESOM) - else: - raise ValueError('!!!!! only support for Fesom 2x now, stop !!!!!') - - ####################################### - # predefined var names and time info - varnames = ['temp', 'salt' ] - varnamesout = ['temp', 'salt' ] # fixed names for output file , do not edit - units = ['degC', 'psu'] - unitsout = ['degC', 'g/kg'] # fixed names for output file , do not edit - missingvalue = [0,33.] - nvar = len(varnames) - # - - finname = fin - foutname = fout - depth_range = [depthmin, depthmax] - nlon = 1440 - nlat = 720 - ####################################### - - mesh = pf.load_mesh(meshpath,abg=abg, usepickle=False) - - # get the depth information - if depth_range is None: - depths = mesh.zlev[:-1] - else: - idx = (np.abs(mesh.zlev) >= depth_range[0]) & (np.abs(mesh.zlev) <= depth_range[1]) - depths = mesh.zlev[idx] - - nlev = len(depths) - - # the new regular grids: - lon = np.linspace(-180, 180, nlon) - lat = np.linspace(-90, 90, nlat) - lons, lats = np.meshgrid(lon,lat) - - - # read the time dim: - fin = nc.Dataset(finname,'r') - timein = fin.variables['time'] - ntime = len(timein) - - - # write data - with nc.Dataset(foutname, 'w') as fout: - fout.createDimension('lat', nlat) - latout = fout.createVariable('lat',np.float32, ('lat',)) - latout.units = 'degree_north' - latout.standard_name = 'latitude' - latout[:] = lat - - fout.createDimension('lon', nlon) - lonout = fout.createVariable('lon',np.float32,('lon',)) - lonout.units = 'degree_east' - lonout.standard_name = 'longitude' - lonout[:] = lon - - fout.createDimension('time', None) - timeout = fout.createVariable('time',np.float32,('time',)) - # timeout.setncatts(timein.__dict__) - timeout.standard_name = "time" - timeout.units = "years since 01-01-01 00:00:00" - timeout.calendar = "365_day" - timeout.axis = "T" - - - fout.createDimension('level', None) - levout = fout.createVariable('level',np.float32,('level',)) - levout.units = 'm' - - - fout.description = 'interpolated fesom2.0 data' - - for i in range(nvar): - thevar = varnames[i] - print(">>>>>>>>>> processing >>> ",thevar) - # read data - data, ndim, levdim = read_data(finname, thevar) - print("data.shape, ndim, levdim:") - print(data.shape, ndim, levdim) - - varout = fout.createVariable(thevar,np.float32,('time','level','lat','lon')) - varout.units = unitsout[i] - - for it in range(0,ntime): - print("> time step ", it) - if ndim == 3: - levout[:] = depths - for iz in range(0,nlev): - ilev = pf.ind_for_depth(depths[iz], mesh) - print("> level:", depths[iz]) - if levdim == 2: - level_data = data[it, :, ilev] - elif levdim == 1: - level_data = data[it, ilev, :] - else: - raise ValueError('Something wrong with data!') - - level_data[level_data==0] = np.nan - #idist_fast = pf.fesom2regular(level_data, mesh, lons, lats, how='idist', k=20) - idist_fast = pf.fesom2regular(level_data, mesh, lons, lats ) - new = np.where(np.isnan(idist_fast), missingvalue[i], idist_fast) - varout[it,iz,:,:] = new - - elif ndim == 2: - levout[:] = 0. # meter - print("> surface") - level_data = data[it, :] - idist_fast = pf.fesom2regular(level_data, mesh, lons, lats ) - new = np.where(np.isnan(idist_fast), missingvalue[i], idist_fast) - varout[it,0,:,:] = new - - # close input data - fin.close() - return - -#### defination: -parser = argparse.ArgumentParser(description='Input options') -parser.add_argument("-meshpath", type=str, help='FESOM mesh path') -parser.add_argument("-datain", type=str, help='FESOM data path') -parser.add_argument("-dataout", type=str, help='FESOM output data path') - - - -arguments = parser.parse_args() -print(arguments) - -meshpath = arguments.meshpath -datain = arguments.datain -dataout = arguments.dataout - - -depthmax = os.getenv('OCEAN_depthmax', 300.) -print('... OCEAN depthmax:', depthmax ) - -depthmin = os.getenv('OCEAN_depthmin', 150.) -print('... OCEAN depthmin:', depthmin ) - -a = os.getenv('OCEAN_meshalpha', 0.) -print('... OCEAN meshalpha:', a ) - -b = os.getenv('OCEAN_meshbeta', 0.) -print('... OCEAN meshbeta:', b) - -g = os.getenv('OCEAN_meshgamma', 0.) -print('... OCEAN meshgamma:', g ) - -version = 2. - - -function_FESOM2ice_regular_grid( - version_FESOM=version, - meshpath = meshpath, abg=[a, b, g], - fin=datain, - fout=dataout, - depthmax=depthmax, depthmin=depthmin,) diff --git a/couplings/utils/gfw_atmo_constant_zero.nc b/couplings/utils/gfw_atmo_constant_zero.nc deleted file mode 100644 index 7fb599dc7..000000000 Binary files a/couplings/utils/gfw_atmo_constant_zero.nc and /dev/null differ diff --git a/couplings/utils/grid_noro.f90 b/couplings/utils/grid_noro.f90 deleted file mode 100644 index 1a487f596..000000000 --- a/couplings/utils/grid_noro.f90 +++ /dev/null @@ -1,639 +0,0 @@ -SUBROUTINE grid_noro(imdep, jmdep, xdata, ydata, zdata, & - imar, jmar, x, y, & - zphi,zmea,zstd,zsig,zgam,zthe, & - zpic,zval,mask) - !======================================================================= - ! (F. Lott) (voir aussi z.x. Li, A. Harzallah et L. Fairhead) - ! - ! Compute the Parameters of the SSO scheme as described in - ! LOTT & MILLER (1997) and LOTT(1999). - ! Target points are on a imarxjmar grid. - ! At the poles (if any) the fields value is repeated - ! jmar time. - ! The parameters a,b,c,d represent the limite of the target - ! gridpoint region. The means over this region are calculated - ! from USN data, ponderated by a weight proportional to the - ! surface occupated by the data inside the model gridpoint area. - ! In most circumstances, this weight is the ratio between the - ! surface of the USN gridpoint area and the surface of the - ! model gridpoint area. - ! - ! (c) - ! ----d----- - ! | . . . .| - ! | | - ! (b)a . * . .b(a) - ! | | - ! | . . . .| - ! ----c----- - ! (d) - !======================================================================= - ! INPUT: - ! imdep, jmdep: dimensions X and Y input field - ! xdata, ydata: coordinates X and Y input field - ! zdata: Input field - ! In this version it is assumed that the entry data come from - ! the USNavy dataset: imdep=iusn=2160, jmdep=jusn=1080. - ! OUTPUT: - ! imar, jmar: dimensions X and Y Output field - ! x, y: ccordinates X and Y Output field. - ! zmea: Mean orographie - ! zstd: Standard deviation - ! zsig: Slope - ! zgam: Anisotropy - ! zthe: Orientation of the small axis - ! zpic: Maximum altitude - ! zval: Minimum altitude - !======================================================================= - - - IMPLICIT INTEGER (i,j) - IMPLICIT REAL(x,z) - - PARAMETER(iext=216) - - !#include "dimensions.h" - - - REAL xusn(imdep+2*iext),yusn(jmdep+2) - REAL zusn(imdep+2*iext,jmdep+2) - - INTEGER imdep, jmdep - REAL xdata(imdep),ydata(jmdep) - REAL zdata(imdep,jmdep) - ! - INTEGER imar, jmar - - ! INTERMEDIATE FIELDS (CORRELATIONS OF OROGRAPHY GRADIENT) - - REAL ztz(imar,jmar),zxtzx(imar,jmar) - REAL zytzy(imar,jmar),zxtzy(imar,jmar) - REAL weight(imar,jmar) - REAL num_tot(imar,jmar),num_lan(imar,jmar) - - ! CORRELATIONS OF USN OROGRAPHY GRADIENTS - - REAL zxtzxusn(imdep+2*iext,jmdep+2),zytzyusn(imdep+2*iext,jmdep+2) - REAL zxtzyusn(imdep+2*iext,jmdep+2) - REAL x(imar),y(jmar),zphi(imar,jmar) - ! INPUT FIELDS - REAL zmea(imar,jmar),zstd(imar,jmar) - REAL zsig(imar,jmar),zgam(imar,jmar),zthe(imar,jmar) - REAL zpic(imar,jmar),zval(imar,jmar) - INTEGER mask(imar,jmar) - ! - REAL a(imar),b(imar),c(jmar),d(jmar) - INTEGER ia(imar),ib(imar),ic(jmar),id(jmar) - ! - PRINT *,' Subgrid Scale Orography Parameters' - xpi=ACOS(-1.) - rad = 6371229. - zdeltay=2.*xpi/REAL(jmdep)*rad - - ! print *,'xdata:',xdata - ! print *,'ydata:',ydata - ! print *,'x:',x - ! print *,'y:',y - ! - ! EXTENSION OF THE USN DATABASE TO POCEED COMPUTATIONS AT - ! BOUNDARIES: - ! - - CALL data_treat(zdata,xdata,ydata,imdep,jmdep) - - - DO j=1,jmdep - yusn(j+1)=ydata(j) - DO i=1,imdep - zusn(i+iext,j+1)=zdata(i,j) - xusn(i+iext)=xdata(i) - ENDDO - DO i=1,iext - zusn(i,j+1)=zdata(imdep-iext+i,j) - xusn(i)=xdata(imdep-iext+i)-2.*xpi - zusn(imdep+iext+i,j+1)=zdata(i,j) - xusn(imdep+iext+i)=xdata(i)+2.*xpi - ENDDO - ENDDO - - yusn(1)=ydata(1)+(ydata(1)-ydata(2)) - yusn(jmdep+2)=ydata(jmdep)+(ydata(jmdep)-ydata(jmdep-1)) - DO i=1,imdep/2+iext - zusn(i,1)=zusn(i+imdep/2,2) - zusn(i+imdep/2+iext,1)=zusn(i,2) - zusn(i,jmdep+2)=zusn(i+imdep/2,jmdep+1) - zusn(i+imdep/2+iext,jmdep+2)=zusn(i,jmdep+1) - ENDDO - ! - ! COMPUTE LIMITS OF MODEL GRIDPOINT AREA - ! ( REGULAR GRID) - ! - a(1) = x(1) - (x(2)-x(1))/2.0 - b(1) = (x(1)+x(2))/2.0 - DO i = 2, imar-1 - a(i) = b(i-1) - b(i) = (x(i)+x(i+1))/2.0 - ENDDO - a(imar) = b(imar-1) - b(imar) = x(imar) + (x(imar)-x(imar-1))/2.0 - - IF(y(2) <= y(1))THEN - c(1) = y(1) - (y(2)-y(1))/2.0 - d(1) = (y(1)+y(2))/2.0 - DO j = 2, jmar-1 - c(j) = d(j-1) - d(j) = (y(j)+y(j+1))/2.0 - ENDDO - c(jmar) = d(jmar-1) - d(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0 - ELSE - c(1) = (y(1)+y(2))/2.0 - d(1) = y(1) - (y(2)-y(1))/2.0 - DO j = 2, jmar-1 - d(j) = c(j-1) - c(j) = (y(j)+y(j+1))/2.0 - ENDDO - d(jmar)=c(jmar-1) - c(jmar) = y(jmar) + (y(jmar)-y(jmar-1))/2.0 - ENDIF - - DO ii=1,imar - DO i=2,imdep+2*iext-1 - IF(a(ii) >= xusn(i-1).AND.a(ii) < xusn(i))ia(ii)=i-1 - IF(b(ii) > xusn(i).AND.b(ii) <= xusn(i+1))ib(ii)=i+1 - ENDDO - ENDDO - DO jj=1,jmar - DO j=2,jmdep+1 - IF(c(jj) >= yusn(j).AND.c(jj) < yusn(j-1))ic(jj)=j-1 - IF(d(jj) > yusn(j+1).AND.d(jj) <= yusn(j))id(jj)=j+1 - ENDDO - ENDDO - - ! - ! initialisations: - ! - DO i = 1, imar - DO j = 1, jmar - weight(i,j) = 0.0 - zxtzx(i,j) = 0.0 - zytzy(i,j) = 0.0 - zxtzy(i,j) = 0.0 - ztz(i,j) = 0.0 - zmea(i,j) = 0.0 - zpic(i,j) =-1.e+10 - zval(i,j) = 1.e+10 - ENDDO - ENDDO - ! - ! COMPUTE SLOPES CORRELATIONS ON USN GRID - ! - DO j = 1,jmdep+2 - DO i = 1, imdep+2*iext - zytzyusn(i,j)=0.0 - zxtzxusn(i,j)=0.0 - zxtzyusn(i,j)=0.0 - ENDDO - ENDDO - - - DO j = 2,jmdep+1 - zdeltax=zdeltay*COS(yusn(j)) - DO i = 2, imdep+2*iext-1 - zytzyusn(i,j)=(zusn(i,j+1)-zusn(i,j-1))**2/zdeltay**2 - zxtzxusn(i,j)=(zusn(i+1,j)-zusn(i-1,j))**2/zdeltax**2 - zxtzyusn(i,j)=(zusn(i,j+1)-zusn(i,j-1))/zdeltay & - *(zusn(i+1,j)-zusn(i-1,j))/zdeltax - ENDDO - ENDDO - ! - ! SUMMATION OVER GRIDPOINT AREA - ! - zleny=xpi/REAL(jmdep)*rad - xincr=xpi/2./REAL(jmdep) - DO ii = 1, imar - DO jj = 1, jmar - num_tot(ii,jj)=0. - num_lan(ii,jj)=0. - ! PRINT *,' iteration ii jj:',ii,jj - DO j = ic(jj),id(jj) - zlenx=zleny*COS(yusn(j)) - zdeltax=zdeltay*COS(yusn(j)) - zbordnor=(c(jj)-yusn(j)+xincr)*rad - zbordsud=(yusn(j)-d(jj)+xincr)*rad - weighy=MAX(0.,MIN(zbordnor,zbordsud,zleny)) - DO i = ia(ii),ib(ii) - zbordest=(xusn(i)-a(ii)+xincr)*rad*COS(yusn(j)) - zbordoue=(b(ii)+xincr-xusn(i))*rad*COS(yusn(j)) - weighx=MAX(0.,MIN(zbordest,zbordoue,zlenx)) - num_tot(ii,jj)=num_tot(ii,jj)+1.0 - IF(zusn(i,j) >= 1.)num_lan(ii,jj)=num_lan(ii,jj)+1.0 - weight(ii,jj)=weight(ii,jj)+weighx*weighy - zxtzx(ii,jj)=zxtzx(ii,jj)+zxtzxusn(i,j)*weighx*weighy - zytzy(ii,jj)=zytzy(ii,jj)+zytzyusn(i,j)*weighx*weighy - zxtzy(ii,jj)=zxtzy(ii,jj)+zxtzyusn(i,j)*weighx*weighy - ztz(ii,jj) =ztz(ii,jj) +zusn(i,j)*zusn(i,j)*weighx*weighy - ! mean - zmea(ii,jj) =zmea(ii,jj)+zusn(i,j)*weighx*weighy - ! peacks - zpic(ii,jj)=MAX(zpic(ii,jj),zusn(i,j)) - ! valleys - zval(ii,jj)=MIN(zval(ii,jj),zusn(i,j)) - ENDDO - ENDDO - ENDDO - ENDDO - ! - ! COMPUTE PARAMETERS NEEDED BY THE LOTT & MILLER (1997) AND - ! LOTT (1999) SSO SCHEME. - ! - zllmmea=0. - zllmstd=0. - zllmsig=0. - zllmgam=0. - zllmpic=0. - zllmval=0. - zllmthe=0. - zminthe=0. - ! print 100,' ' - !100 format(1X,A1,'II JJ',4X,'H',8X,'SD',8X,'SI',3X,'GA',3X,'TH') - DO ii = 1, imar - DO jj = 1, jmar - IF (weight(ii,jj) /= 0.0) THEN - ! Mask - IF(num_lan(ii,jj)/num_tot(ii,jj) >= 0.5)THEN - mask(ii,jj)=1 - ELSE - mask(ii,jj)=0 - ENDIF - ! Mean Orography: - zmea (ii,jj)=zmea (ii,jj)/weight(ii,jj) - zxtzx(ii,jj)=zxtzx(ii,jj)/weight(ii,jj) - zytzy(ii,jj)=zytzy(ii,jj)/weight(ii,jj) - zxtzy(ii,jj)=zxtzy(ii,jj)/weight(ii,jj) - ztz(ii,jj) =ztz(ii,jj)/weight(ii,jj) - ! Standard deviation: - zstd(ii,jj)=SQRT(MAX(0.,ztz(ii,jj)-zmea(ii,jj)**2)) - ELSE - PRINT*, 'probleme,ii,jj=', ii,jj - ENDIF - ENDDO - ENDDO - - ! CORRECT VALUES OF HORIZONTAL SLOPES NEAR THE POLES: - - IF(y(jmar) <= -89.95.OR.y(jmar) >= 89.95)THEN - - DO ii = 1, imar - zxtzx(ii,1)=zxtzx(ii,2) - zxtzx(ii,jmar)=zxtzx(ii,jmar-1) - zxtzy(ii,1)=zxtzy(ii,2) - zxtzy(ii,jmar)=zxtzy(ii,jmar-1) - zytzy(ii,1)=zytzy(ii,2) - zytzy(ii,jmar)=zytzy(ii,jmar-1) - ENDDO - - ENDIF - - ! FILTERS TO SMOOTH OUT FIELDS FOR INPUT INTO SSO SCHEME. - - ! FIRST FILTER, MOVING AVERAGE OVER 9 POINTS. - - CALL mva9(zmea,imar,jmar) - CALL mva9(zstd,imar,jmar) - CALL mva9(zpic,imar,jmar) - CALL mva9(zval,imar,jmar) - CALL mva9(zxtzx,imar,jmar) - CALL mva9(zxtzy,imar,jmar) - CALL mva9(zytzy,imar,jmar) - - ! SECOND FILTER FOR SLOPES, MASK AND UNIFORM HORIS RESOLUTION - - DO ii = 1, imar - DO jj = 1, jmar - zxtzx(ii,jj)=zxtzx(ii,jj)*mask(ii,jj) - zxtzy(ii,jj)=zxtzy(ii,jj)*mask(ii,jj) - zytzy(ii,jj)=zytzy(ii,jj)*mask(ii,jj) - ENDDO - ENDDO - - CALL uni_res(zxtzx,y,imar,jmar) - CALL uni_res(zxtzy,y,imar,jmar) - CALL uni_res(zytzy,y,imar,jmar) - - - DO ii = 1, imar - DO jj = 1, jmar - IF (weight(ii,jj) /= 0.0) THEN - ! Coefficients K, L et M: - xk=(zxtzx(ii,jj)+zytzy(ii,jj))/2. - xl=(zxtzx(ii,jj)-zytzy(ii,jj))/2. - xm=zxtzy(ii,jj) - xp=xk-SQRT(xl**2+xm**2) - xq=xk+SQRT(xl**2+xm**2) - xw=1.e-8 - IF(xp <= xw) xp=0. - IF(xq <= xw) xq=xw - IF(ABS(xm) <= xw) xm=xw*SIGN(1.,xm) - ! slope: - zsig(ii,jj)=SQRT(xq)*mask(ii,jj) - ! isotropy: - zgam(ii,jj)=xp/xq*mask(ii,jj) - ! angle theta: - zthe(ii,jj)=57.29577951*ATAN2(xm,xl)/2.*mask(ii,jj) - zphi(ii,jj)=zmea(ii,jj)*mask(ii,jj) - zmea(ii,jj)=zmea(ii,jj)*mask(ii,jj) - zpic(ii,jj)=zpic(ii,jj)*mask(ii,jj) - zval(ii,jj)=zval(ii,jj)*mask(ii,jj) - zstd(ii,jj)=zstd(ii,jj)*mask(ii,jj) - - ! print 101,ii,jj, - ! * zmea(ii,jj),zstd(ii,jj),zsig(ii,jj),zgam(ii,jj), - ! * zthe(ii,jj) - !101 format(1x,2(1x,i2),2(1x,f7.1),1x,f7.4,2x,f4.2,1x,f5.1) - ELSE - ! PRINT*, 'probleme,ii,jj=', ii,jj - ENDIF - zllmmea=MAX(zmea(ii,jj),zllmmea) - zllmstd=MAX(zstd(ii,jj),zllmstd) - zllmsig=MAX(zsig(ii,jj),zllmsig) - zllmgam=MAX(zgam(ii,jj),zllmgam) - zllmthe=MAX(zthe(ii,jj),zllmthe) - zminthe=MIN(zthe(ii,jj),zminthe) - zllmpic=MAX(zpic(ii,jj),zllmpic) - zllmval=MAX(zval(ii,jj),zllmval) - ENDDO - ENDDO - - PRINT *,' MEAN ORO: ',zllmmea - PRINT *,' ST. DEV.: ',zllmstd - PRINT *,' PENTE: ',zllmsig - PRINT *,' ANISOTROP: ',zllmgam - PRINT *,' ANGLE: ',zminthe,zllmthe - PRINT *,' pic: ',zllmpic - PRINT *,' val: ',zllmval - - ! ENSURE PERIODICITY AT HORIZONTAL GRID END - - IF(xdata(imar) >= xdata(1)+2.*xpi-0.001)THEN - DO jj=1,jmar - zmea(imar,jj)=zmea(1,jj) - zpic(imar,jj)=zpic(1,jj) - zval(imar,jj)=zval(1,jj) - zstd(imar,jj)=zstd(1,jj) - zsig(imar,jj)=zsig(1,jj) - zgam(imar,jj)=zgam(1,jj) - zthe(imar,jj)=zthe(1,jj) - ENDDO - ENDIF - - ! - ! VALUES AT THE POLE (IF THERE ARE POLES - ! ON THE GRID CONSIDERED) - ! gamma and theta a 1. and 0. at poles - ! - IF(ydata(1) <= -xpi/2+0.01.OR.ydata(1) >= xpi/2-0.01)THEN - zmeanor=0.0 - zmeasud=0.0 - zstdnor=0.0 - zstdsud=0.0 - zsignor=0.0 - zsigsud=0.0 - zweinor=0.0 - zweisud=0.0 - zpicnor=0.0 - zpicsud=0.0 - zvalnor=0.0 - zvalsud=0.0 - - DO ii=1,imar - zweinor=zweinor+ weight(ii, 1) - zweisud=zweisud+ weight(ii,jmar) - zmeanor=zmeanor+zmea(ii, 1)*weight(ii, 1) - zmeasud=zmeasud+zmea(ii,jmar)*weight(ii,jmar) - zstdnor=zstdnor+zstd(ii, 1)*weight(ii, 1) - zstdsud=zstdsud+zstd(ii,jmar)*weight(ii,jmar) - zsignor=zsignor+zsig(ii, 1)*weight(ii, 1) - zsigsud=zsigsud+zsig(ii,jmar)*weight(ii,jmar) - zpicnor=zpicnor+zpic(ii, 1)*weight(ii, 1) - zpicsud=zpicsud+zpic(ii,jmar)*weight(ii,jmar) - zvalnor=zvalnor+zval(ii, 1)*weight(ii, 1) - zvalsud=zvalsud+zval(ii,jmar)*weight(ii,jmar) - ENDDO - - DO ii=1,imar - zmea(ii, 1)=zmeanor/zweinor - zmea(ii,jmar)=zmeasud/zweisud - zphi(ii, 1)=zmeanor/zweinor - zphi(ii,jmar)=zmeasud/zweisud - zpic(ii, 1)=zpicnor/zweinor - zpic(ii,jmar)=zpicsud/zweisud - zval(ii, 1)=zvalnor/zweinor - zval(ii,jmar)=zvalsud/zweisud - zstd(ii, 1)=zstdnor/zweinor - zstd(ii,jmar)=zstdsud/zweisud - zsig(ii, 1)=zsignor/zweinor - zsig(ii,jmar)=zsigsud/zweisud - zgam(ii, 1)=1. - zgam(ii,jmar)=1. - zthe(ii, 1)=0. - zthe(ii,jmar)=0. - ENDDO - - ENDIF - - RETURN -END SUBROUTINE grid_noro - -SUBROUTINE mva9(x,imar,jmar) - - ! MAKE A MOVING AVERAGE OVER 9 GRIDPOINTS OF THE X FIELDS - - REAL x(imar,jmar),xf(imar,jmar) - REAL weight(-1:1,-1:1) - - - sum=0. - DO is=-1,1 - DO js=-1,1 - weight(is,js)=1./REAL((1+is**2)*(1+js**2)) - sum=sum+weight(is,js) - ENDDO - ENDDO - - DO is=-1,1 - DO js=-1,1 - weight(is,js)=weight(is,js)/sum - ENDDO - ENDDO - - DO j=2,jmar-1 - DO i=2,imar-1 - xf(i,j)=0. - DO is=-1,1 - DO js=-1,1 - xf(i,j)=xf(i,j)+x(i+is,j+js)*weight(is,js) - ENDDO - ENDDO - ENDDO - ENDDO - - DO j=2,jmar-1 - xf(1,j)=0. - is=imar-1 - DO js=-1,1 - xf(1,j)=xf(1,j)+x(is,j+js)*weight(-1,js) - ENDDO - DO is=0,1 - DO js=-1,1 - xf(1,j)=xf(1,j)+x(1+is,j+js)*weight(is,js) - ENDDO - ENDDO - xf(imar,j)=xf(1,j) - ENDDO - - DO i=1,imar - xf(i,1)=xf(i,2) - xf(i,jmar)=xf(i,jmar-1) - ENDDO - - DO i=1,imar - DO j=1,jmar - x(i,j)=xf(i,j) - ENDDO - ENDDO - - RETURN -END SUBROUTINE mva9 - -SUBROUTINE uni_res(xfield,ylat,imar,jmar) - - ! MAKE A MOVING AVERAGE OVER LONGITUDE POINTS - ! TO UNIFORMIZE THE HORIZONTAL RESOLUTION - - REAL xfield(imar,jmar),xfilt(-imar:2*imar,jmar) - REAL ylat(jmar) - - - DO j=1,jmar - DO i=1,imar - xfilt(i+imar,j) = xfield(i,j) - xfilt(i-imar,j) = xfield(i,j) - xfilt(i ,j) = xfield(i,j) - ENDDO - ENDDO - - DO j=2,jmar-1 - ism=1./COS(ylat(j)) - !f77 ism=MIN(ism,imar-1) - ism=MIN(ism,imar-1) - DO i=1,imar - xfield(i,j)=0. - DO is=-ism,ism - xfield(i,j)=xfield(i,j)+xfilt(i+is,j)/REAL(2*ism+1) - ENDDO - ENDDO - ENDDO - - ! POLES TREATMENT FOR SLOPES - - IF(COS(ylat(1)) == 0)THEN - DO i=1,imar - xfield(i,1) =0. - DO ii=1,imar - xfield(i,1) =xfield(i,1)+xfilt(ii,1)/REAL(imar) - ENDDO - ENDDO - ELSE - ism=1./COS(ylat(1)) - !f77 ism=MIN(ism,imar-1) - ism=MIN(ism,imar-1) - DO i=1,imar - xfield(i,1) =0. - DO is=-ism,ism - xfield(i,1)=xfield(i,1)+xfilt(i+is,1)/REAL(2*ism+1) - ENDDO - ENDDO - ENDIF - - IF(COS(ylat(jmar)) == 0)THEN - DO i=1,imar - xfield(i,jmar)=0. - DO ii=1,imar - xfield(i,jmar)=xfield(i,jmar)+xfilt(ii,jmar)/REAL(imar) - ENDDO - ENDDO - ELSE - ism=1./COS(ylat(jmar)) - !f77 ism=MIN(ism,imar-1) - ism=MIN(ism,imar-1) - DO i=1,imar - xfield(i,jmar) =0. - DO is=-ism,ism - xfield(i,jmar)=xfield(i,jmar)+xfilt(i+is,jmar)/REAL(2*ism+1) - ENDDO - ENDDO - ENDIF - - RETURN -END SUBROUTINE uni_res - -SUBROUTINE data_treat(zdata,xdata,ydata,imdep,jmdep) - PARAMETER(iwork=3000,jwork=1500) - REAL zdata(imdep,jmdep),xdata(imdep),ydata(jmdep) - REAL zwork(-iwork:2*iwork,jwork),xwork(-iwork:2*iwork) - REAL xscale(jwork) - INTEGER iscale(jwork) - - IF(iwork < imdep.OR.jwork < jmdep) THEN - WRITE (*,*) 'data_treat: iwork = ', iwork, ' imdep= ', imdep - WRITE (*,*) ' jwork = ', jwork, ' jmdep= ', jmdep - STOP 'iwork < imdep.OR.jwork < jmdep' - END IF - - pi=ACOS(-1.) - DO i=1,imdep - xwork(i)=xdata(i) - xwork(i-imdep)=xdata(i)-2.*pi - xwork(i+imdep)=xdata(i)+2.*pi - DO j=1,jmdep - zwork(i ,j)=zdata(i,j) - zwork(i-imdep,j)=zdata(i,j) - zwork(i+imdep,j)=zdata(i,j) - ENDDO - ENDDO - - xincr=(xdata(2)-xdata(1))/2. - DO j=1,jmdep - xscale(j)=1./ABS(COS(ydata(j)))*xincr - !f77 iscale(j)=MIN(1./ABS(COS(ydata(j))),imdep) - iscale(j)=1./ABS(COS(ydata(j))) - iscale(j)=MIN(iscale(j),imdep) - ! print *,j,iscale(j) - DO i=1,imdep - zdata(i,j)=0. - weight=0. - zlan=0. - ztot=0. - DO is=-iscale(j),iscale(j) - weig = MIN(2.*xincr, & - MAX(xwork(i+is)+xincr-xwork(i)+xscale(j),0.), & - MAX(xwork(i)+xscale(j)-xwork(i+is)+xincr,0.)) - IF(weig > 0.)THEN - ztot=ztot+1. - IF(zwork(i+is,j) >= 1.)zlan=zlan+1. - weight=weight+weig - zdata(i,j)=zdata(i,j)+zwork(i+is,j)*weig - ENDIF - ENDDO - IF(zlan/ztot >= 0.5)THEN - zdata(i,j)=zdata(i,j)/weight - ELSE - zdata(i,j)=0. - ENDIF - ENDDO - ENDDO - - - RETURN -END SUBROUTINE data_treat diff --git a/couplings/utils/icb_apply_distribution.py b/couplings/utils/icb_apply_distribution.py deleted file mode 100644 index b52f4f584..000000000 --- a/couplings/utils/icb_apply_distribution.py +++ /dev/null @@ -1,359 +0,0 @@ -import random -import numpy as np -import numexpr as ne -import xarray as xr -import pandas as pd -import sys -import os -from tqdm import tqdm -from datetime import datetime - -RES_pism = 5 -rho_ice = 910 -height_icb = 250 - -N_min = 0 -N_max = 10000 - -#Nlength = np.array([5000, 500, 100, 50, 20, 10, 5, 2, 1]) #icb_scaled20 -Nlength = np.array([5000, 500, 100, 50, 20, 10, 1, 1, 1]) #icb_scaled21 -#Nlength = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1]) -#sdepth = np.array([40, 67, 133, 175, 250, 250, 250, 250, 250]) * 7/8 -sdepth = np.array([height_icb]*9) -print("sdepth = ", sdepth) -slength_bins = np.array([0, 100, 200, 350, 500, 700, 900, 1200, 1600, 2200]) -svol_bins = np.multiply(slength_bins, slength_bins) * height_icb -print("svol_bins = ", svol_bins) - -mu_length = 250 -trunc_length=0 - -vol_trunc=10e6 #trunc_length**3*16/21 -pism_trunc_fkt=-vol_trunc/(RES_pism*RES_pism*10e6/rho_ice) - -xs = [] -ys = [] -length = [] - -random.seed() - -ifile = sys.argv[1] -mesh_path = sys.argv[2] -icb_path = sys.argv[3] - -nod2d_file = os.path.join(mesh_path, "nod2d.out") -elem2d_file = os.path.join(mesh_path, "elem2d.out") - -#read PISM file -def read_pism_file(ifile): - fl = xr.open_dataset(ifile).squeeze() - - data = fl.tendency_of_ice_amount_due_to_discharge.where(fl.tendency_of_ice_amount_due_to_discharge < pism_trunc_fkt*N_min) - data.to_netcdf(os.path.join(icb_path, "icb_mask.nc")) - #data = fl.discharge_flux_cumulative.where(fl.discharge_flux_cumulative < 0, drop=True) - data = np.array(data).reshape(1, len(data.x)*len(data.y)) - data = data[~np.isnan(data)] - - lon_bnds = fl.lon_bnds.where(fl.tendency_of_ice_amount_due_to_discharge < pism_trunc_fkt*N_min, drop=True) - #lon_bnds = fl.lon_bnds.where(fl.discharge_flux_cumulative < 0, drop=True) - lon_bnds = np.array(lon_bnds).reshape(len(lon_bnds.x)*len(lon_bnds.y), 4) - lon_bnds = lon_bnds[~np.isnan(lon_bnds)] - lon_bnds = lon_bnds.reshape(int(len(lon_bnds)/4), 4) - - lat_bnds = fl.lat_bnds.where(fl.tendency_of_ice_amount_due_to_discharge < pism_trunc_fkt*N_min, drop=True) - #lat_bnds = fl.lat_bnds.where(fl.discharge_flux_cumulative < 0, drop=True) - lat_bnds = np.array(lat_bnds).reshape(len(lat_bnds.x)*len(lat_bnds.y), 4) - lat_bnds = lat_bnds[~np.isnan(lat_bnds)] - lat_bnds = lat_bnds.reshape(int(len(lat_bnds)/4), 4) - - lons = [] - lats = [] - - for x, y in zip(lon_bnds, lat_bnds): - lons.append(np.mean(x)) - lats.append(np.mean(y)) - - return [data, lons, lats] - - -class point: - def __init__(self, x, y): - self.x = x - self.y = y - def to_dict(self): - return {'x': self.x, 'y': self.y} - - -# https://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle -def sign(p1, p2, p3): - return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y) - -def PointInTriangle(pt, v1, v2, v3): - d1 = sign(pt, v1, v2) - d2 = sign(pt, v2, v3) - d3 = sign(pt, v3, v1) - - has_neg = (d1 < 0) or (d2 < 0) or (d3 < 0) - has_pos = (d1 > 0) or (d2 > 0) or (d3 > 0) - - return not (has_neg and has_pos) - - - - -#generate icebergs -def icb_generator(vals, ps1, ps2, ps3, icb_path, rho_ice=910, res_pism=5): - #mu, sigma = mu_length**3*16/21/10e6, 1.2 - mu, sigma = mu_length**2*height_icb/10e6, 1.2 - - points = [] - #depth=length/1.5 - height = [] #height=depth*8/7=length*8/7*2/3=length*16/21 - scaling_tmp = 1 - - with tqdm(total=len(vals), file=sys.stdout, desc='create icebergs') as pbar: - for val, p1, p2, p3 in zip(vals, ps1, ps2, ps3): - disch_cum = val*res_pism*res_pism*10e6/rho_ice - #N = max(int(np.absolute(disch_cum)/(10e6)/10), 1) - N = int(np.absolute(disch_cum)/(10e6)) - if N < N_min: - N = 0 - elif N > N_max: - scaling_tmp = N/N_max - N = N_max - - s = np.random.lognormal(mu, sigma, N)*10e6 - - f_scale = sum(s)/np.absolute(disch_cum) - s_ = s / f_scale / scaling_tmp - - length_tmp = ne.evaluate('(s_/height_icb)**(1/2)') - - #ll = np.digitize(length_tmp, slength_bins) - ll = np.digitize(s_, svol_bins) - for i, (s, d) in enumerate(zip(Nlength, sdepth)): - sbin = np.where(ll==i+1)[0] - if list(sbin): - if len(sbin) <= s: - chunk = [sbin] - else: - chunk = [sbin[k:k + s] for k in range(0, len(sbin), s)] - l = np.array([np.mean(s_[c]) for c in chunk]) - s = np.array([len(c) for c in chunk]) - if not 'length' in locals(): - length = ne.evaluate('(l/height_icb)**(1/2)') - scaling = np.array([s]) - depth = np.array([d]*len(l)) - else: - length = np.append(length, ne.evaluate('(l/height_icb)**(1/2)')) - scaling = np.append(scaling, np.array([s])) - depth = np.append(depth, np.array([d]*len(l))) - - for i in range(len(l)): - r1 = random.random() - r2 = random.random() - - lower_bound = 0.1 - upper_bound = 0.9 - - r1 = r1 * (upper_bound - lower_bound) + lower_bound - r2 = r2 * (upper_bound - lower_bound) + lower_bound - #https://math.stackexchange.com/questions/18686/uniform-random-point-in-triangle - tmp_x = (1-np.sqrt(r1))*p1.x + (np.sqrt(r1)*(1-r2))*p2.x + (r2*np.sqrt(r1))*p3.x - tmp_y = (1-np.sqrt(r1))*p1.y + (np.sqrt(r1)*(1-r2))*p2.y + (r2*np.sqrt(r1))*p3.y - points.append(point(tmp_x, tmp_y)) - #length_tmp = (np.absolute(s_[i])/height_icb)**(1/2) - #length.append(length_tmp) - ##length**2*length*16/21=s_--> length=(s_*21/16)**(1/3) - #length.append(np.absolute(s_[i]*21/16)**(1/3)) - #height.append(height_icb) - #height.append(length[-1]*16/21) - #scaling.append(scaling_tmp) - pbar.update(1) - - points_ = pd.DataFrame.from_records([p.to_dict() for p in points]) - np.savetxt(os.path.join(icb_path, "LON.dat"), points_.x.values) - np.savetxt(os.path.join(icb_path, "LAT.dat"), points_.y.values) - np.savetxt(os.path.join(icb_path, "LENGTH.dat"), length) - np.savetxt(os.path.join(icb_path, "HEIGHT.dat"), depth) - np.savetxt(os.path.join(icb_path, "SCALING.dat"), scaling) - return [points, length] - -def PointTriangle_distance(lon0, lat0, lon1, lat1, lon2, lat2, lon3, lat3): - d1 = ne.evaluate('(lon1 - lon0)**2 + (lat1 - lat0)**2') - d2 = ne.evaluate('(lon2 - lon0)**2 + (lat2 - lat0)**2') - d3 = ne.evaluate('(lon3 - lon0)**2 + (lat3 - lat0)**2') - - dis = d1+d2+d3 - ind = np.where(dis == np.amin(dis)) - - p1 = point(lon1[ind], lat1[ind]) - p2 = point(lon2[ind], lat2[ind]) - p3 = point(lon3[ind], lat3[ind]) - - return [p1, p2, p3], ind - -def find_FESOM_elem(nod2d_file, elem2d_file, lons, lats): - points = [] - nod2d = pd.read_csv(nod2d_file, header=0, names=["lon", "lat", "coastal"], sep='\s+', index_col=0) - elem2d = pd.read_csv(elem2d_file, header=0, names=["nod1", "nod2", "nod3"], sep='\s+') - - lon1=[] - lat1=[] - lon2=[] - lat2=[] - lon3=[] - lat3=[] - - lon1 = nod2d.lon[elem2d.nod1] - lat1 = nod2d.lat[elem2d.nod1] - lon2 = nod2d.lon[elem2d.nod2] - lat2 = nod2d.lat[elem2d.nod2] - lon3 = nod2d.lon[elem2d.nod3] - lat3 = nod2d.lat[elem2d.nod3] - - with tqdm(total=len(lons), file=sys.stdout, desc='find FESOM elements') as pbar: - for lon, lat in zip(lons, lats): - tmp, ind = PointTriangle_distance(lon, lat, np.array(lon1), np.array(lat1), np.array(lon2), np.array(lat2), - np.array(lon3), np.array(lat3)) - - points.append(tmp[:3]) - #print("point in triangle?: ", PointInTriangle(point(lon, lat), tmp[0], tmp[1], tmp[2])) - #print("point: [" + str(lon) + ", " + str(lat) + "]") - #print("triangle: [", str(tmp[0].x) + ", " + str(tmp[0].y) + "], " + "[", str(tmp[1].x) + ", " + str(tmp[1].y) + "], " + "[", str(tmp[2].x) + ", " + str(tmp[2].y) + "]") - pbar.update(1) - return points - - - - - - - - - - - - -data, lons, lats = read_pism_file(ifile) -points = find_FESOM_elem(nod2d_file, elem2d_file, lons, lats) - -ps1, ps2, ps3 = np.transpose(points) -icb_generator(data, ps1, ps2, ps3, icb_path) - -#pos = find_FESOM_elem(nod2d_file, elem2d_file, xs, ys) -# -#np.savetxt("pos.csv", np.array(pos)) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def _generate_rotation_matrix(self): - alphaEuler=50 - betaEuler=15 - gammaEuler=-90 - - al = np.radians(alphaEuler) - be = np.radians(betaEuler) - ga = np.radians(gammaEuler) - - rotate_matrix = np.zeros((3,3)) - rotate_matrix[0,0]=np.cos(ga)*np.cos(al)-np.sin(ga)*np.cos(be)*np.sin(al) - rotate_matrix[0,1]=np.cos(ga)*np.sin(al)+np.sin(ga)*np.cos(be)*np.cos(al) - rotate_matrix[0,2]=np.sin(ga)*np.sin(be) - rotate_matrix[1,0]=-np.sin(ga)*np.cos(al)-np.cos(ga)*np.cos(be)*np.sin(al) - rotate_matrix[1,1]=-np.sin(ga)*np.sin(al)+np.cos(ga)*np.cos(be)*np.cos(al) - rotate_matrix[1,2]=np.cos(ga)*np.sin(be) - rotate_matrix[2,0]=np.sin(be)*np.sin(al) - rotate_matrix[2,1]=-np.sin(be)*np.cos(al) - rotate_matrix[2,2]=np.cos(be) - - self.rotate_matrix = rotate_matrix - -def _g2r(self): - lon1 = np.radians(self.box[0]) - lon2 = np.radians(self.box[1]) - lat1 = np.radians(self.box[2]) - lat2 = np.radians(self.box[3]) - - v1_ = np.zeros((3,1)) - v1_[0]=np.cos(lat1)*np.cos(lon1) - v1_[1]=np.cos(lat1)*np.sin(lon1) - v1_[2]=np.sin(lat1) - vr1 = np.dot(self.rotate_matrix, v1_) - - v2_ = np.zeros((3,1)) - v2_[0]=np.cos(lat2)*np.cos(lon2) - v2_[1]=np.cos(lat2)*np.sin(lon2) - v2_[2]=np.sin(lat2) - vr2 = np.dot(self.rotate_matrix, v2_) - - self.box[0] = np.degrees(math.atan2(vr1[1], vr1[0])) - self.box[2] = np.degrees(math.asin(vr1[2])) - self.box[1] = np.degrees(math.atan2(vr2[1], vr2[0])) - self.box[3] = np.degrees(math.asin(vr2[2])) - -def _r2g(self, lon_r, lat_r): - - A = inv(self.rotate_matrix) - - lon_ = np.radians(lon_r) - lat_ = np.radians(lat_r) - - v_ = np.zeros((3,1)) - v_[0]=np.cos(lat_)*np.cos(lon_) - v_[1]=np.cos(lat_)*np.sin(lon_) - v_[2]=np.sin(lat_) - vr = np.dot(A, v_) - - lon_g = np.degrees(math.atan2(vr[1], vr[0])) - lat_g = np.degrees(math.asin(vr[2])) - return lon_g, lat_g - -def _back_rotate(self): - r2g_v = np.vectorize(self._r2g) - - with open(self.nod_file, 'r') as csvfile: - nodes = pd.read_csv(csvfile, header=None, sep=r'\s* \s*', skiprows=1, engine='python') - nodes.drop(nodes.index[0], inplace=True) - nodes.columns = ['index', 'lon', 'lat', 'mask'] - [lon_tmp, lat_tmp] = r2g_v(np.array(nodes['lon'].values[:], dtype=float).transpose(), - np.array(nodes['lat'].values[:], dtype=float).transpose()) - nodes['lon'] = lon_tmp - nodes['lat'] = lat_tmp - nodes.to_csv('nodes_back_rotated.csv', sep=' ', header=True, index=False) - self.nod_file = 'nodes_back_rotated.csv' diff --git a/couplings/utils/install_calendar.sh b/couplings/utils/install_calendar.sh deleted file mode 100755 index 9463bdb26..000000000 --- a/couplings/utils/install_calendar.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/ksh - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -rm -rf ${thisdir}/calendar/_build/ -mkdir -p ${thisdir}/calendar/_build/ - -gcc ${thisdir}/calendar/time_difference.c -o ${thisdir}/calendar/_build/time_difference diff --git a/couplings/utils/install_calnoro.sh b/couplings/utils/install_calnoro.sh deleted file mode 100755 index 22b3a3a13..000000000 --- a/couplings/utils/install_calnoro.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -MACHINE=$1 - -fortran_compiler=gfortran - -if [[ ${MACHINE} == "albedo" ]]; then - module load gcc/12.1.0 - nc_config=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/bin/nf-config -elif [[ ${MACHINE} == "levante" ]]; then - module load gcc/11.2.0-gcc-11.2.0 - nc_config=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/bin/nf-config -else - echo " * Unknown machine! No installation possible" - exit -fi - -NETCDF_LIB=$($nc_config --flibs) -NETCDF_INCLUDE=-I$($nc_config --includedir) - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -rm -rf ${thisdir}/_build/calnoro -mkdir -p ${thisdir}/_build/ - - - -echo $fortran_compiler \ - ${thisdir}/calnoro.f90 \ - ${thisdir}/grid_noro.f90 \ - -o ${thisdir}/_build/calnoro \ - $NETCDF_LIB $NETCDF_INCLUDE -$fortran_compiler \ - ${thisdir}/calnoro.f90 \ - ${thisdir}/grid_noro.f90 \ - -o ${thisdir}/_build/calnoro \ - $NETCDF_LIB $NETCDF_INCLUDE - -mv _build/calnoro calnoro diff --git a/couplings/utils/install_jsbach_init_file.sh b/couplings/utils/install_jsbach_init_file.sh deleted file mode 100755 index 0db567fa3..000000000 --- a/couplings/utils/install_jsbach_init_file.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -l - -MACHINE=$1 - -fortran_compiler=gfortran - -if [[ ${MACHINE} == "albedo" ]]; then - module load gcc/12.1.0 - nc_config=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/bin/nf-config -elif [[ ${MACHINE} == "levante" ]]; then - module load gcc/11.2.0-gcc-11.2.0 - nc_config=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/bin/nf-config -else - echo " * Unknown machine! No installation possible" - exit -fi - -NETCDF_LIB=$($nc_config --flibs) -NETCDF_INCLUDE=-I$($nc_config --includedir) - -echo "Done loading environment!" - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -prog=jsbach_init_file -srcdir=${thisdir} -rm -rf ${srcdir}/_build/${prog} -mkdir -p ${thisdir}/_build/ - -F90=$fortran_compiler - -echo "Compile ${srcdir}/${prog}.f90..." -echo ${F90} ${F90FLAGS} -o ${srcdir}/_build/${prog} ${srcdir}/${prog}.f90 ${NETCDF_INCLUDE} ${NETCDF_LIBDIR} ${NETCDF_LIB} -${F90} ${F90FLAGS} -o ${srcdir}/_build/${prog} ${srcdir}/${prog}.f90 ${NETCDF_INCLUDE} ${NETCDF_LIBDIR} ${NETCDF_LIB} -mv mo_vegparams.mod mo_kinds.mod ${srcdir}/_build -mv _build/jsbach_init_file jsbach_init_file diff --git a/couplings/utils/install_jsbach_pack_unpack.sh b/couplings/utils/install_jsbach_pack_unpack.sh deleted file mode 100755 index bf49fa208..000000000 --- a/couplings/utils/install_jsbach_pack_unpack.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -l - -MACHINE=$1 - -fortran_compiler=gfortran - -if [[ ${MACHINE} == "albedo" ]]; then - module load gcc/12.1.0 - nc_config=/albedo/soft/sw/spack-sw/netcdf-fortran/4.5.4-yb7woqz/bin/nf-config -elif [[ ${MACHINE} == "levante" ]]; then - module load gcc/11.2.0-gcc-11.2.0 - nc_config=/sw/spack-levante/netcdf-fortran-4.5.3-pywf2l/bin/nf-config -else - echo " * Unknown machine! No installation possible" - exit -fi - -NETCDF_LIB=$($nc_config --flibs) -NETCDF_INCLUDE=-I$($nc_config --includedir) - -thisdir=$(dirname $0) -thisdir=$(readlink -f $thisdir) -old_dir=$(pwd) - -for prog in unpack pack; do - srcdir=${thisdir} - rm -rf ${srcdir}/_build/${prog} - mkdir -p ${thisdir}/_build/ - - F90=$fortran_compiler - - echo "Compile ${srcdir}/${prog}.f90..." - echo ${F90} ${F90FLAGS} -o ${srcdir}/_build/${prog} ${srcdir}/${prog}.f90 ${NETCDF_INCLUDE} ${NETCDF_LIBDIR} ${NETCDF_LIB} - ${F90} ${F90FLAGS} -o ${srcdir}/_build/${prog} ${srcdir}/${prog}.f90 ${NETCDF_INCLUDE} ${NETCDF_LIBDIR} ${NETCDF_LIB} -done - -mv _build/pack pack -mv _build/unpack unpack diff --git a/couplings/utils/jsbach_init_file.f90 b/couplings/utils/jsbach_init_file.f90 deleted file mode 100644 index 86fc901c6..000000000 --- a/couplings/utils/jsbach_init_file.f90 +++ /dev/null @@ -1,4056 +0,0 @@ -!------------------------------------------------------------------------------ -! Program to generate initial files for JSBACH -!------------------------------------------------------------------------------ -! based on Thomas Raddatz' programs -! jsbach_init_file_13tiles.f90 -! jsbach_init_file_8tiles.f90 and -! jsbach_init_file_3or4tiles.f90 -! and scripts and programs by Stefan Hagemann in -! soil_para.com -! -! This script does not exactly reproduces initial files generated with the -! programs listed above. Here the differences: -! - The variables are defined in a new order -! - Added global attributes -! - Added attributes to several variables; particularly cover_type now has -! attributes defining the different land cover types -! - There is no longer a variable lct - only the dimension -! - Consistent use of selected_real_kind _dp -! => slight differences in veg_ratio_factor, albedo_soil_nir, -! albedo_soil_vis, albedo_veg_nir and albedo_veg_vis -! - Consider albedo_compensate with all numbers of tiles -! - The definition of a minimum cover fraction and the scaling happens only -! once, at the end of the calculations -! => small differences in cover_fract, might also lead to different -! cover_type -! -! -! Arrays in the jsbach initial file -! -! ----------------------------------------------------------------------------- -! *) variable description read from file modified? -! ----------------------------------------------------------------------------- -! i init_moist soil wetness jan_surf.nc WS corrected -! i snow snow depth jan_surf.nc SN unchanged -! c slf fract. sea land mask jan_surf.nc SLM unchanged -! c slm sea land mask calculated -! - roughness_length roughness length jan_surf.nc AZ0 unchanged -! - albedo background albedo jan_surf.nc ALB unchanged -! c elevation mean orography jan_surf.nc OROMEA unchanged -! c orography_std_dev orogr. standard dev. jan_surf.nc OROSTD unchanged -! c glac glacier mask jan_surf.nc GLAC unchanged -! c fao FAO soil data flags jan_surf.nc FAO filled -! c maxmoist soil field capacity jan_surf.nc WSMX filled,modifs -! c or soil_parameters.nc -! - forest_fract forest fraction jan_surf.nc FOREST unchanged -! i lai_clim leaf area index VLTCLIM.nc unchanged -! - veg_fract vegetation fraction VGRATCLIM.nc unchanged -! i surf_temp surface temperature TSLCLIM2.nc unchanged -! c/i cover_fract vegetation ratio vegtype_pa14.nc calculated -! c cover_type vegetation cover type vegtype_pa14.nc calculated -! c/i veg_ratio_max max. vegetation ratio vegmax_6.lola reorder -! c/- albedo_veg_vis vegetation albedo (vis) albedo.lola modifs -! c/- albedo_veg_nir vegetation albedo (NIR) albedo.lola modifs -! c albedo_soil_vis soil albedo (visible) albedo.lola modifs -! c albedo_soil_nir soil albedo (NIR) albedo.lola modifs -! c roughness_length_oro roughness without veg topo_75.lola modifs -! c/- natural_veg potential vegetation natural_veg.nc calculated -! c root_depth effective root depth calculated -! c soil_depth soil_depth soil_parameters.nc filled,modifs -! c matrix_potential Saturated matrix pot. soil_parameters.nc filled -! c heat_capacity Volume heat cap. of soil soil_parameters.nc filled -! c heat_conductivity Heat conductivity of s. soil_parameters.nc filled -! c bclapp Clapp&Horneberger exp. soil_paramsters.nc filled -! c hyd_cond_sat Saturated hydraulic soil_parameters.nc filled -! conductivity -! c pore_size_index Soil pore s. dist. index soil_parameters.nc filled -! c soil_porosity Volumetric soil porosity soil_parameters.nc filled -! c wilting_point Volumetric soil soil_parameters.nc filled -! permanent wilting point -! -!*) usage within jsbach -! --------------------- -! i: used for initialization -! c: used throughout the whole simulation -! -: not used in jsbach standard setup -! -!------------------------------------------------------------------------------ -! To compile and run use -! -------------------- -! jsbach_init_file.ksh -! -------------------- -! -! Veronika Gayler , MPI, March 2008: Original code -! Stiig Wilkenskjeld, MPI, January 2012: Added 5-layer soil variables -!------------------------------------------------------------------------------ - -MODULE mo_kinds - ! kind parameters - INTEGER, PARAMETER :: sp = SELECTED_REAL_KIND(6,37) - INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307) - INTEGER, PARAMETER :: i4 = SELECTED_INT_KIND(9) - INTEGER, PARAMETER :: i8 = SELECTED_INT_KIND(14) - REAL(dp),PARAMETER :: pi = 3.14159265358979323846_dp - REAL(dp),PARAMETER :: radius_of_earth = 6371000._dp -END MODULE mo_kinds - -MODULE mo_vegparams - USE mo_kinds - ! vegetation parameters - REAL(dp), PARAMETER :: small_fract = 1.E-10_dp - REAL(dp), PARAMETER :: substantial_woody = 0.05_dp - REAL(dp), PARAMETER :: substantial_tundra = 0.05_dp - - ! - ! land cover types as defined in lctlib file - ! - - ! Parameters for nlct=21 - INTEGER, PARAMETER :: lct_glacier = 1 - INTEGER, PARAMETER :: lct_tropical_evergreen = 2 - INTEGER, PARAMETER :: lct_tropical_deciduous = 3 - INTEGER, PARAMETER :: lct_extratrop_evergreen = 4 - INTEGER, PARAMETER :: lct_extratrop_deciduous = 5 - INTEGER, PARAMETER :: lct_temperate_broadl_evergreen = 6 - INTEGER, PARAMETER :: lct_temperate_broadl_deciduous = 7 - INTEGER, PARAMETER :: lct_evergreen_conifer = 8 - INTEGER, PARAMETER :: lct_deciduous_conifer = 9 - INTEGER, PARAMETER :: lct_raingreen_shrub = 10 - INTEGER, PARAMETER :: lct_deciduous_shrub = 11 - INTEGER, PARAMETER :: lct_c3grass = 12 - INTEGER, PARAMETER :: lct_c4grass = 13 - INTEGER, PARAMETER :: lct_pasture = 14 - INTEGER, PARAMETER :: lct_c3pasture = 15 - INTEGER, PARAMETER :: lct_c4pasture = 16 - INTEGER, PARAMETER :: lct_tundra = 17 - INTEGER, PARAMETER :: lct_swamp = 18 - INTEGER, PARAMETER :: lct_crop = 19 - INTEGER, PARAMETER :: lct_c3crop = 20 - INTEGER, PARAMETER :: lct_c4crop = 21 - INTEGER, PARAMETER :: lctmax=21 ! highest lct number - - ! - ! land cover types of the input vegetation maps (1-14) - ! - INTEGER, PARAMETER :: nvegtyp = 14 ! number of vegetation types - INTEGER, PARAMETER :: nwoody = 9 ! number of woody types - INTEGER, PARAMETER :: woody_types(nwoody) = (/1,2,3,4,5,6,7,8,11/) - INTEGER, PARAMETER :: veg_tropical_evergreen = 1 - INTEGER, PARAMETER :: veg_tropical_deciduous = 2 - INTEGER, PARAMETER :: veg_temperate_broadl_evergreen = 3 - INTEGER, PARAMETER :: veg_temperate_broadl_deciduous = 4 - INTEGER, PARAMETER :: veg_evergreen_conifer = 5 - INTEGER, PARAMETER :: veg_deciduous_conifer = 6 - INTEGER, PARAMETER :: veg_raingreen_shrub = 7 - INTEGER, PARAMETER :: veg_deciduous_shrub = 8 - INTEGER, PARAMETER :: veg_c3grass = 9 - INTEGER, PARAMETER :: veg_c4grass = 10 - INTEGER, PARAMETER :: veg_tundra = 11 - INTEGER, PARAMETER :: veg_crop = 12 - INTEGER, PARAMETER :: veg_c3pasture = 13 - INTEGER, PARAMETER :: veg_c4pasture = 14 - - INTEGER, PARAMETER :: lct(nvegtyp) = & - (/lct_tropical_evergreen, lct_tropical_deciduous, & - lct_temperate_broadl_evergreen, lct_temperate_broadl_deciduous, & - lct_evergreen_conifer, lct_deciduous_conifer, & - lct_raingreen_shrub, lct_deciduous_shrub, & - lct_c3grass, lct_c4grass, & - lct_tundra, lct_crop ,lct_c3pasture, lct_c4pasture /) - - INTEGER :: glacier_tile = -1 ! tile that is reserved for glaciers; set in - ! calc_cover_types. - -END MODULE mo_vegparams - -!------------------------------------------------------------------------------ -PROGRAM jsbach_init_file - - USE mo_kinds - USE mo_vegparams - IMPLICIT NONE - INCLUDE 'netcdf.inc' - - INTERFACE - SUBROUTINE open_file(info,infile,ncin,ret_stat) - CHARACTER*100, INTENT(IN) :: infile - LOGICAL, INTENT(IN) :: info - INTEGER, INTENT(OUT) :: ncin - INTEGER, INTENT(OUT), OPTIONAL :: ret_stat - END SUBROUTINE - - SUBROUTINE define_var(ncin, ncout, varname_in, varname_out, outdimids, missval) - USE mo_kinds - INTEGER, INTENT(IN) :: ncin, ncout - CHARACTER*30, INTENT(IN) :: varname_in, varname_out - INTEGER, INTENT(IN) :: outdimids(6) - REAL(dp), INTENT(OUT), OPTIONAL :: missval - END SUBROUTINE - END INTERFACE - - CHARACTER*20 :: svn_rev = "$Revision: 9230 $" - CHARACTER*128 :: svn_url = & - "$HeadURL: https://svn.zmaw.de/svn/cosmos/branches/mpiesm-landveg/contrib/initial_tarfiles/jsbach_init_file.f90 $" - - ! Dimensions - INTEGER :: nlon, nlat, ntiles, nlct, nsoil, ntime - - ! Variables - REAL(dp), ALLOCATABLE, DIMENSION(:) :: lat - REAL(dp), ALLOCATABLE, DIMENSION(:) :: lon - INTEGER, ALLOCATABLE, DIMENSION(:) :: tiles - INTEGER, ALLOCATABLE, DIMENSION(:) :: time_days - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: veg_fract - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: cover_fract - INTEGER, ALLOCATABLE, DIMENSION(:,:,:) :: cover_type - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: cover_type_dp - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: lai - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: elevation - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: elevationrms - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: az0 - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: roughness_oro - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: snow - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: slf - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: slm - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: non_glacier_land - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: lake - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: glac_dp - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: fao - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: forest_fract - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: surf_temp - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: vegfract - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: vegfract_cf - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: veg_ratio_max - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo_veg_vis, albedo_veg_vis_in - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo_veg_nir, albedo_veg_nir_in - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo_soil_vis, albedo_soil_vis_in - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: albedo_soil_nir, albedo_soil_nir_in - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: C3C4_flag - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: C3_crop - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: C4_crop - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: crop - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: pasture - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: potveg - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: natural_veg - REAL(dp), ALLOCATABLE, DIMENSION(:) :: vegfract_for_types - LOGICAL, ALLOCATABLE, DIMENSION(:) :: is_naturalveg - -! soil parameters and soil moisture - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: max_moisture - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: max_soilwater - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: moisture - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: soilwater - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: soilwater_layer - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: soil_depth - REAL(dp), ALLOCATABLE, DIMENSION(:,:,:) :: soil_depth_layer - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: matrix_potential - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: soil_field_capacity - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: heat_capacity - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: heat_conductivity - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: bclapp - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: hyd_cond_sat - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: pore_size_index - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: soil_porosity - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: wilting_point - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: root_depth - REAL(dp), ALLOCATABLE, DIMENSION(:) :: soillev - REAL(dp), ALLOCATABLE, DIMENSION(:) :: layer_depth - - - ! Indices - INTEGER :: i,j,k - - ! dummies and temporary arrays - REAL(dp), ALLOCATABLE, DIMENSION(:) :: dummy - REAL(dp), ALLOCATABLE, DIMENSION(:,:) :: grid_area - REAL(dp), ALLOCATABLE, DIMENSION(:) :: gauss_weights - REAL(dp) :: area_tropical_forest, area_temperate_forest - REAL(dp) :: area_woody, area_shrubs, area_crops, area_pasture - REAL(dp) :: area_grass, area_all, area_land, area_lake - REAL(dp) :: area_land_tropics, area_land_extratropics, area_glac - - ! names of the in- and output files - CHARACTER(100):: fnam, fnam0, fnam1, fnam2, fnam3, fnam4, fnam5, fnam6, fnam7 - CHARACTER(100):: fnam8, fnam9, fnam10, fnam11, fnam12, fnam13, fnam14, fnam15 - CHARACTER(100):: fnamout - CHARACTER(8) :: cyear_ct, cyear_cf, ctiles, clayer, cvegtyp - CHARACTER(10) :: dynveg_tag - - ! netcdf - INTEGER :: stat, ncin, ncout, ncid, ncin15, varid, dimid - INTEGER :: outdimids(6) ! netcdf dimension ids in the output file - INTEGER :: dimids(6) ! netcdf dimension ids - CHARACTER(30) :: varname, varname_out - - ! parameters - REAL(dp) :: albedo_compensate - - INTEGER :: second_grass - INTEGER :: second_woody - INTEGER :: dominant_crop - CHARACTER(30) :: resol - LOGICAL :: slm_in_input - REAL(dp) :: missval, missmpo, missbcl, misshca, misshco, misspor - REAL(dp) :: missdep, missfca, misspsi, misshyc, misswpo, missmxm - - ! Namelist Parameters - INTEGER, PARAMETER :: nnml = 30 ! Fortran unit to read namelist - LOGICAL :: lcouple, ldynveg, lc3c4crop, lpasture, lread_pasture, lpasture_rule - LOGICAL :: grid_from_rerun, info, cover_fract_only, echam_fractional - LOGICAL :: desert_only, woods_only, grass_only - LOGICAL :: ignore_measurements - CHARACTER(10) :: res_atm, res_oce, maxmoist_version, pasture_tag - CHARACTER(100) :: masks_file - INTEGER :: year_cf, year_ct - REAL(dp) :: slm_fraction ! only used with T31 in coupled setup, if SLM - ! not available in the echam initial file - - NAMELIST /initctl/ & - res_atm, & ! model resolution (T31, T42, ...) - ntiles, & ! number of tiles - nsoil, & ! number of soil layers - nlct, & ! number of land cover types - year_cf, & ! reference year for cover fractions - year_ct, & ! reference year for cover types - lcouple, & ! initial file for coupled run - res_oce, & ! if coupled: ocean model resolution - ldynveg, & ! initial file for a run with dynamic vegetation - lc3c4crop, & ! initial file for a run with C3 and C4 crops - lpasture, & ! distinguish pastures from grasses - lread_pasture, & ! read pasture and crop fractions from a separate file - pasture_tag, & ! tag to define crops and pasture input file (with lread_pasture) - lpasture_rule, & ! apply the pasture rule: pasture is allocated primarily on grass land - slm_fraction, & ! minimum land fraction of a land grid cell - echam_fractional, & ! echam uses fractional land see mask - masks_file, & ! read land sea, glacier and lake masks from this file - maxmoist_version, & ! maximum soil moisture array as in echam (LSP2) or new (LSP3) - grid_from_rerun, & ! read grid from rerun file instead of jan_surf file - fnam0, & ! filename of restart file (if grid_from_rerun = .TRUE.) - desert_only, & ! Initialize all land as desert - grass_only, & ! Initialize all land with grass - woods_only, & ! Initialize all land with woods - cover_fract_only,& ! Generate file containing just cover fractions and types - ignore_measurements, & ! Ignore measured data, only use background values - info ! TRUE: print some extra information - -!------------------------------------------------------------------------------ -! read namelist -!------------------------------------- - !-- defaults: - res_atm = 'T31' - ntiles = 4 - nsoil = 5 - nlct = 14 - year_ct = 800 - year_cf = 800 - lcouple = .FALSE. - res_oce = 'GR30' - ldynveg = .FALSE. - lc3c4crop = .FALSE. - lpasture = .FALSE. - lread_pasture = .FALSE. - pasture_tag = 'LUH' - lpasture_rule = .FALSE. - slm_fraction = 0.5_dp - echam_fractional = .FALSE. - maxmoist_version = 'LSP3' - grid_from_rerun = .FALSE. - masks_file = 'default' - fnam0 = 'restart_file_name' - desert_only = .FALSE. - grass_only = .FALSE. - woods_only = .FALSE. - cover_fract_only = .FALSE. - ignore_measurements = .FALSE. - info = .TRUE. - - OPEN (nnml, file='namelist') - READ (nnml, initctl) - WRITE(ctiles,'(I0)') ntiles - WRITE(clayer,'(I0)') nsoil - WRITE(cyear_ct,'(I0.4)') year_ct - WRITE(cyear_cf,'(I0.4)') year_cf - WRITE(cvegtyp,'(I0)') nvegtyp - - IF (info) THEN - WRITE(*,*) 'Namelist Parameters ' - WRITE(*,*) ' Atmosphere resolution: ', res_atm - WRITE(*,*) ' Configuration with ocean: ', lcouple - IF (lcouple) & - WRITE(*,*) ' Ocean resolution: ', res_oce - WRITE(*,*) ' Number of tiles: ', ntiles - WRITE(*,*) ' Number of land cover types: ', nlct - WRITE(*,*) ' Reference year for cover types: ', year_ct - WRITE(*,*) ' Reference year for cover fractions: ', year_cf - WRITE(*,*) ' Configuration with dynamic vegetation: ', ldynveg - WRITE(*,*) ' Configuration with C3 and C4 crops: ',lc3c4crop - WRITE(*,*) ' Threshold for land in slm: ', slm_fraction - WRITE(*,*) ' Pasture: ',lpasture - WRITE(*,*) ' read pasture: ',lread_pasture - WRITE(*,*) ' pasture rule: ',lpasture_rule - WRITE(*,*) ' Desert only: ',desert_only - WRITE(*,*) ' Grass only: ',grass_only - WRITE(*,*) ' Woods only: ',woods_only - WRITE(*,*) ' Cover fract only: ',cover_fract_only - WRITE(*,*) ' Ignore measurements: ', ignore_measurements - WRITE(*,*) ' Print extra information: ', info ! Pretty dummy output :-) - WRITE(*,*) ' Read grid from another file: ', grid_from_rerun - IF (grid_from_rerun) & - WRITE (*,*) ' Grid file name: ',fnam0 - WRITE(*,*) '' - ENDIF - -!------------------------------------- -! define filenames -!------------------------------------- - !-- input files: - IF (lcouple) THEN - resol=TRIM(res_atm)//TRIM(res_oce) - ELSE - resol=TRIM(res_atm) - END IF - fnam1=TRIM(resol)//'_jan_surf.nc' - fnam2=TRIM(resol)//'_VLTCLIM.nc' - fnam3=TRIM(resol)//'_VGRATCLIM.nc' - fnam4=TRIM(res_atm)//'_TSLCLIM2.nc' - fnam5='vegtype_'//TRIM(cyear_ct)//'_'//TRIM(res_atm)//'gauss_pa'//TRIM(cvegtyp)//'.nc' - fnam6='vegmax_6_'//TRIM(res_atm)//'.nc' - fnam7='albedo_'//TRIM(res_atm)//'.nc' - fnam8=TRIM(res_atm)//'_topo_75.nc' - fnam9='vegtype_'//TRIM(cyear_cf)//'_'//TRIM(res_atm)//'gauss_pa'//TRIM(cvegtyp)//'.nc' - fnam10='C3C4_mask_'//TRIM(res_atm)//'gauss.nc' - fnam11='C3C4_crop_'//TRIM(res_atm)//'.nc' - fnam12='LUH_states_'//TRIM(cyear_cf)//'_'//TRIM(res_atm)//'.nc' - fnam13='potveg_'//TRIM(res_atm)//'.nc' - fnam14='soil_parameters_'//TRIM(res_atm)//'.nc' - fnam15=TRIM(masks_file) - - !-- output file: - IF (echam_fractional) resol=TRIM(resol)//'_fractional' - IF (cover_fract_only) THEN - fnamout='cover_fract_'//TRIM(res_atm)//'_'//TRIM(ctiles)//'tiles_'//TRIM(cyear_cf)//'.nc' - ELSE - IF (ldynveg) THEN - dynveg_tag='_dynveg' - ELSE - dynveg_tag='_no-dynveg' - END IF - IF (nsoil > 1) THEN - fnamout='jsbach_'//TRIM(resol)//'_'//TRIM(ctiles)//'tiles_'//TRIM(clayer)//'layers_'// & - TRIM(cyear_cf)//TRIM(dynveg_tag)//'.nc' - ELSE - fnamout='jsbach_'//TRIM(resol)//'_'//TRIM(ctiles)//'tiles_'//TRIM(cyear_cf)// & - TRIM(dynveg_tag)//'.nc' - END IF - IF (TRIM(cyear_cf) == '0000') THEN - fnamout='jsbach_'//TRIM(resol)//'_'//TRIM(ctiles)//'tiles_'//TRIM(clayer)//'layers_natural-veg.nc' - END IF - - END IF - - !-- print info - IF (info) THEN - IF (grid_from_rerun) WRITE (*,*) 'input0: ',fnam0 - WRITE (*,*) 'input 1: ',fnam1 - WRITE (*,*) 'input 2: ',fnam2 - WRITE (*,*) 'input 3: ',fnam3 - WRITE (*,*) 'input 4: ',fnam4 - WRITE (*,*) 'input 5: ',fnam5 - WRITE (*,*) 'input 6: ',fnam6 - WRITE (*,*) 'input 7: ',fnam7 - WRITE (*,*) 'input 8: ',fnam8 - WRITE (*,*) 'input 9: ',fnam9 - WRITE (*,*) 'input10: ',fnam10 - WRITE (*,*) 'input11: ',fnam11 - WRITE (*,*) 'input12: ',fnam12 - WRITE (*,*) 'input13: ',fnam13 - WRITE (*,*) 'input14: ',fnam14 - IF (TRIM(fnam15) /= 'default') WRITE (*,*) 'input15: ',fnam15 - - WRITE (*,*) 'output: ',fnamout - WRITE (*,*) ' ' - ENDIF - -!------------------------------------------------------------------------------ -! Check consitency of namelist parameters -!------------------------------------------------------------------------------ - IF (lc3c4crop .AND. (ntiles == 1 .OR. ntiles == 8 .OR. ntiles == 9)) THEN - CALL hdlerr & - (1,'C3 and C4 crops indistinguishable in current setups for 1 or 8 tiles') - END IF - IF (.NOT. lc3c4crop .AND. (ntiles == 5 .OR. ntiles == 10)) THEN - CALL hdlerr & - (1,'lc3c4crop needs to be true in current setups for 5 or 10 tiles') - END IF - IF (ldynveg .AND. (ntiles < 8 .OR. ntiles == 13)) THEN - CALL hdlerr & - (1,'running dynveg not possible with less then 8 tiles or 13 tiles') - END IF - IF (ldynveg .AND. cover_fract_only) THEN - CALL hdlerr & - (1,'generation of land cover maps does not make sense for runs with dynveg') - END IF - IF ((grass_only .OR. woods_only) .AND. (ntiles < 8 .OR. ntiles == 13)) THEN - CALL hdlerr & - (1,'grass/woods-only not implemented for less then 8 or 13 tiles') - END IF - IF ((lpasture .OR. lread_pasture .OR. lpasture_rule) & - .AND. (ntiles /= 11 .AND. ntiles /= 12)) THEN - CALL hdlerr & - (1,'lpasture, lread_pasture and lpasture_rule need a setup with pasture tile') - END IF - IF (lread_pasture .AND. .NOT. lpasture) THEN - CALL hdlerr (1,'lread_pasture can only be used with lpasture') - END IF - IF (lpasture_rule .AND. .NOT. lread_pasture) THEN - CALL hdlerr (1,'pasture rule only possible in a setup with lread_pasture') - END IF - IF (lpasture .AND. ntiles /= 11 .AND. .NOT. ldynveg) THEN - CALL hdlerr (1,'for lpasture you need a pasture tile. Use 11 tiles.') - END IF - -!------------------------------------------------------------------------------ -! Read from input files and define output file -!------------------------------------------------------------------------------ -! input-file0: rerun (or jan_surf) -!------------------------------------- - IF (grid_from_rerun) THEN - CALL open_file(info,fnam0,ncin) - ELSE - CALL open_file(info,fnam1,ncin) - END IF - - stat = nf_inq_dimid(ncin,'lon',dimid) - CALL hdlerr(stat,'cannot find dimension lon') - stat = nf_inq_dimlen(ncin,dimid,nlon) - CALL hdlerr(stat,'problems with nlon') - stat = nf_inq_dimid(ncin,'lat',dimid) - CALL hdlerr(stat,'cannot find dimension lat') - stat = nf_inq_dimlen(ncin,dimid,nlat) - CALL hdlerr(stat,'problems with nlat') - ntime=12 - -!------------------------------------- -! define the output-file dimensions -!------------------------------------- - stat = nf_create(fnamout,NF_CLOBBER,ncout) - CALL hdlerr(stat,'creating '//fnamout) - stat = nf_def_dim(ncout,'lon',nlon,outdimids(1)) - CALL hdlerr(stat,'define lon dimension') - stat = nf_def_dim(ncout,'lat',nlat,outdimids(2)) - CALL hdlerr(stat,'define lat dimension') - stat = nf_def_dim(ncout,'ntiles',ntiles,outdimids(3)) - CALL hdlerr(stat,'define tile dimension') - stat = nf_def_dim(ncout,'lct',nlct,outdimids(4)) - CALL hdlerr(stat,'define lct dimension') - stat = nf_def_dim(ncout,'soillev',nsoil,outdimids(5)) - CALL hdlerr(stat,'define soillev dimension') - stat = nf_def_dim(ncout,'time',ntime,outdimids(6)) - CALL hdlerr(stat,'define time dimension') - - !-- get longitudes - varname='lon' - varname_out='lon' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (lon(nlon)) - stat = nf_get_var_double(ncin,varid,lon) - CALL hdlerr(stat,'get latitudes from '//fnam0) - CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get latitudes - varname='lat' - varname_out='lat' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (lat(nlat)) - stat = nf_get_var_double(ncin,varid,lat) - CALL hdlerr(stat,'get latitudes from '//fnam0) - CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam0) - - !-- define tiles - stat = nf_def_var(ncout, 'ntiles', NF_INT, 1, outdimids(3), varid) - CALL hdlerr(stat,'define var ntiles') - stat = nf_put_att_text(ncout, varid,'long_name', 5, 'tiles') - CALL hdlerr(stat,'define var ntiles') - - !-- define soil layers - stat = nf_def_var(ncout, 'soillev', NF_DOUBLE, 1, outdimids(5), varid) - CALL hdlerr(stat,'define var soillev') - stat = nf_put_att_text(ncout, varid, 'long_name', 27, 'soil layer (lower boundary)') - CALL hdlerr(stat,'define long_name soillev') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define unit soillev') - stat = nf_put_att_text(ncout, varid, 'axis', 1, 'Z') - CALL hdlerr(stat,'define axis type soillev') - - !-- define soil layer thickness - stat = nf_def_var(ncout, 'soil_layer_depth', NF_DOUBLE, 1, outdimids(5), varid) - CALL hdlerr(stat,'define var soil_layer_depth') - stat = nf_put_att_text(ncout, varid, 'long_name', 20, 'soil layer thickness') - CALL hdlerr(stat,'define var soil_layer_depth') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define unit soil_layer_depth') - - !-- define time - stat = nf_def_var(ncout, 'time', NF_INT, 1, outdimids(6), varid) - CALL hdlerr(stat,'define var time') - stat = nf_put_att_text(ncout,varid,'units',16,'days since 1-1-1') - CALL hdlerr(stat,'define time units') - -!------------------------------------- -! input-file1: jan_surf -!------------------------------------- - CALL open_file(info,fnam1,ncin) - IF (TRIM(masks_file) /= 'default') CALL open_file(info, fnam15, ncin15) - - !-- get soil wetness - varname='WS' - varname_out='init_moist' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (moisture(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,moisture) - CALL hdlerr(stat,'get soil wetness from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get snow depth - varname='SN' - varname_out='snow' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (snow(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,snow) - CALL hdlerr(stat,'get snow depth from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get fractional and integer land sea mask (if available) - - ! check whether integer mask is available - IF (TRIM(masks_file) /= 'default') THEN - ncid=ncin15 - ELSE - ncid=ncin - END IF - varname='SLF' - stat=nf_inq_varid(ncid,varname,varid) - IF (stat == NF_NOERR) THEN - slm_in_input=.TRUE. - ELSE - slm_in_input=.FALSE. - varname='SLM' ! contains fractional land sea mask - END IF - - !-- get fractional land sea mask - varname_out='slf' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (slf(nlon,nlat)) ! fractional land sea mask - stat = nf_get_var_double(ncid,varid,slf) - CALL hdlerr(stat,'get fractional land sea mask from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - !-- get fractional lake mask - varname='ALAKE' - varname_out='lake' - stat=nf_inq_varid(ncid,varname,varid) - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (lake(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,lake) - CALL hdlerr(stat,'get lake mask from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - ! -- get integer land sea mask and glacier mask - IF (slm_in_input) THEN - varname='SLM' - varname_out='slm' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (slm(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,slm) - CALL hdlerr(stat,'get integer land sea mask from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - ELSE - ! calculate SLM from SLF and ALAKE - ALLOCATE (slm(nlon,nlat)) ! integer land sea mask - slm=0._dp - IF (TRIM(res_atm) == 'T31' .AND. TRIM(res_oce) == 'GR30') THEN - IF (slm_fraction /= 0.435_dp) THEN - CALL hdlerr(stat,'slm_fraction for T31GR30 should be 0.435') - END IF - DO i=1,nlon - DO j=1,nlat - IF (j <= nlat/3 .OR. j > 2*nlat/3) THEN ! extratropics - IF (slf(i,j) > 0.5_dp) slm(i,j) = 1._dp - ELSE ! tropics - IF (slf(i,j) > slm_fraction) slm(i,j) = 1._dp - IF (slf(i,j) > slm_fraction .AND. slf(i,j) <= 0.5_dp) & - WRITE (*,*) 'Land point while slf is < 0.5: ',i,j,slf(i,j) - END IF - END DO - END DO - ELSE - WHERE (slf(:,:) > slm_fraction .AND. .NOT. lake > 0.5_dp) -! .OR. lake >= 1._dp - slm_fraction .AND. .NOT. lake > 0.5_dp) - slm(:,:) = 1._dp - END WHERE - END IF - varname_out='slm' - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - END IF - - ! LU-maps should be independant from the land-sea-mask (i.e. work with different ocean resolutions) - IF (cover_fract_only) THEN - slm(:,:) = 1._dp - END IF - - varname='GLAC' - varname_out='glac' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (glac_dp(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,glac_dp) - CALL hdlerr(stat,'get glacier mask from'//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - IF (echam_fractional) THEN - missval=-9999._dp - WHERE (slm(:,:) == 0._dp .AND. SPREAD(ABS(lat(:)), DIM=1, NCOPIES=nlon) > 50) - glac_dp(:,:) = missval - END WHERE - WHERE (slf(:,:) > 0._dp .AND. lake(:,:) < 1._dp) - slm(:,:) = 1._dp - END WHERE - CALL extrap(nlon, nlat, lon, lat, slm, missval, 'modal', glac_dp) - END IF - - ! define non-glacier land mask (internally used) - ALLOCATE (non_glacier_land(nlon,nlat)) - WHERE (slm(:,:) > 0._dp .AND. glac_dp(:,:) < 1._dp) - non_glacier_land = 1._dp - ELSEWHERE - non_glacier_land = 0._dp - END WHERE - - !-- get surface roughness length - varname='AZ0' - varname_out='roughness_length' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (az0(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,az0) - CALL hdlerr(stat,'get surface roughness length from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get surface background albedo - varname='ALB' - varname_out='albedo' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo) - CALL hdlerr(stat,'get surface background albedo from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get mean orography - varname='OROMEA' - varname_out='elevation' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (elevation(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,elevation) - CALL hdlerr(stat,'get mean orography from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - !-- get orographic standard deviation - varname='OROSTD' - varname_out='orography_std_dev' - CALL check_dimensions(varname, ncid, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (elevationrms(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,elevationrms) - CALL hdlerr(stat,'get orographic standard deviation from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncid, ncout, varname, varname_out, outdimids) - - !-- get FAO data set (soil data flags) - varname='FAO' - varname_out='fao' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (fao(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,fao) - CALL hdlerr(stat,'get FAO from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - !-- get forest fraction - varname='FOREST' - varname_out='forest_fract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (forest_fract(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,forest_fract) - CALL hdlerr(stat,'get forest fraction from '//fnam1) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam1) - -!------------------------------------------ -! input-file1 or 14: field capacity of soil -!------------------------------------------ - - IF (maxmoist_version == 'LSP2') THEN - varname='WSMX' - fnam=fnam1 - ELSE IF (maxmoist_version == 'LSP3') THEN - - ! With dynveg, the soilwater in the root zone needs to be above a certain minimum value, - ! not to suppress plant growth with climate change. - IF (ldynveg) THEN - varname='wcap_dynveg' - ELSE - varname='wcap' - END IF - fnam=fnam14 - ELSE - CALL hdlerr(stat,'value for namelist parameter maxmoist_version not supported') - END IF - CALL open_file(info,fnam,ncin) - - varname_out='maxmoist' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (max_moisture(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,max_moisture) - CALL hdlerr(stat,'get field capacity of soil from '//fnam) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missmxm) - IF (maxmoist_version == 'LSP2') missmxm = 0._dp - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam) - -!------------------------------------- -! input-file2: VLTCLIM -!------------------------------------- - CALL open_file(info,fnam2,ncin) - - !-- get climatolgy of the leaf area index - varname='VLTCLIM' - varname_out='lai_clim' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (lai(nlon,nlat,ntime)) - stat = nf_get_var_double(ncin,varid,lai) - CALL hdlerr(stat,'get leaf area index from'//fnam2) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam2) - -!------------------------------------- -! input-file3: VGRATCLIM -!------------------------------------- - CALL open_file(info,fnam3,ncin) - - !-- get climatology of vegetation ratio - varname='VGRATCLIM' - varname_out='veg_fract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (veg_fract(nlon,nlat,ntime)) - stat = nf_get_var_double(ncin,varid,veg_fract) - CALL hdlerr(stat,'get vegetation ratio from'//fnam3) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam3) - -!------------------------------------- -! input-file4: TSLCLIM2 -!------------------------------------- - CALL open_file(info,fnam4,ncin) - - !-- get climatology of land surface temperature - varname='TSLCLIM' - varname_out='surf_temp' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (surf_temp(nlon,nlat,ntime)) - stat = nf_get_var_double(ncin,varid,surf_temp) - CALL hdlerr(stat,'get surface temperature from'//fnam4) - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam4) - -!------------------------------------- -! input-file5: cover fractions from Julia Pongratz (30.8.2006) -! based on natural vegetation distribution of Ramankutty -!------------------------------------- - ! With lread_pasture we use natural vegetation and separate maps for crops and pastures. - IF ( .NOT. lread_pasture) THEN - CALL open_file(info,fnam5,ncin) - - !-- get fractional cover - varname='vegfract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (vegfract(nlon,nlat,nvegtyp)) - stat = nf_get_var_double(ncin,varid,vegfract) - CALL hdlerr(stat,'get fractional cover from'//fnam5) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam5) - ELSE - ALLOCATE (vegfract(nlon,nlat,nvegtyp)) - END IF - - varname_out='cover_fract' - CALL define_var_new(ncout, varname_out, 3, outdimids(1:3)) - varname_out='cover_type' - CALL define_var_new(ncout, varname_out, 3, outdimids(1:3)) - -!------------------------------------- -! input-file6: vegmax_6 (max. vegetation cover) -!------------------------------------- - CALL open_file(info,fnam6,ncin) - - !-- get veg_ratio_max - varname='veg_ratio_max' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (veg_ratio_max(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,veg_ratio_max) - CALL hdlerr(stat,'get veg_ratio_max from'//fnam6) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam6) - - IF (desert_only) veg_ratio_max(:,:) = 0._dp - IF (grass_only .OR. woods_only) THEN - WHERE (slm(:,:) > 0.5_dp .AND. glac_dp(:,:) < 0.5_dp) - veg_ratio_max(:,:) = 1._dp - END WHERE - END IF - IF (ignore_measurements) THEN - veg_ratio_max(:,:) = 1._dp - END IF - - !-- veg_ratio_max should be non-zero - missval=0._dp - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missval, 'mean', veg_ratio_max) - WHERE (non_glacier_land(:,:) > 0.5_dp) - veg_ratio_max(:,:) = MAX(small_fract,veg_ratio_max(:,:)) - END WHERE - varname_out='veg_ratio_max' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - -!------------------------------------- -! input-file7: albedo (nir/vis vegetation/soil albedo) -!------------------------------------- - CALL open_file(info,fnam7,ncin) - - !-- get albedo - varname='albedo_veg_vis' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo_veg_vis_in(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo_veg_vis_in) - CALL hdlerr(stat,'get vegetation albedo in vis. range from'//fnam7) - - varname='albedo_veg_nir' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo_veg_nir_in(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo_veg_nir_in) - CALL hdlerr(stat,'get vegetation albedo in NIR from'//fnam7) - - varname='albedo_soil_vis' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo_soil_vis_in(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo_soil_vis_in) - CALL hdlerr(stat,'get soil albedo in vis. range from'//fnam7) - - varname='albedo_soil_nir' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (albedo_soil_nir_in(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,albedo_soil_nir_in) - CALL hdlerr(stat,'get soil albedo in NIR from'//fnam7) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam7) - - ALLOCATE (albedo_veg_vis(nlon,nlat)) - ALLOCATE (albedo_veg_nir(nlon,nlat)) - ALLOCATE (albedo_soil_vis(nlon,nlat)) - ALLOCATE (albedo_soil_nir(nlon,nlat)) - DO j = 1,nlat - albedo_compensate = 0.0_dp - IF (ABS(lat(j)) > 40._dp) THEN - albedo_compensate = 0.01_dp - END IF - IF (ABS(lat(j)) > 50._dp) THEN - albedo_compensate = 0.02_dp - END IF - IF (ABS(lat(j)) > 60._dp) THEN - albedo_compensate = 0.03_dp - END IF - IF (ABS(lat(j)) > 70._dp) THEN - albedo_compensate = 0.04_dp - END IF - IF (.NOT. ignore_measurements) THEN - DO i = 1,nlon/2 - albedo_veg_vis(i,j) = albedo_veg_vis_in(i + nlon/2,j) + albedo_compensate - albedo_veg_nir(i,j) = albedo_veg_nir_in(i + nlon/2,j) + albedo_compensate - albedo_soil_vis(i,j) = albedo_soil_vis_in(i + nlon/2,j) + albedo_compensate - albedo_soil_nir(i,j) = albedo_soil_nir_in(i + nlon/2,j) + albedo_compensate - END DO - DO i = nlon/2 + 1,nlon - albedo_veg_vis(i,j) = albedo_veg_vis_in(i - nlon/2,j) + albedo_compensate - albedo_veg_nir(i,j) = albedo_veg_nir_in(i - nlon/2,j) + albedo_compensate - albedo_soil_vis(i,j) = albedo_soil_vis_in(i - nlon/2,j) + albedo_compensate - albedo_soil_nir(i,j) = albedo_soil_nir_in(i - nlon/2,j) + albedo_compensate - END DO - ELSE ! ignore measured data from the continents, only use background values - albedo_veg_vis(:,j) = albedo_veg_vis_in(1,1) + albedo_compensate - albedo_veg_nir(:,j) = albedo_veg_nir_in(1,1) + albedo_compensate - albedo_soil_vis(:,j) = albedo_soil_vis_in(1,1) + albedo_compensate - albedo_soil_nir(:,j) = albedo_soil_nir_in(1,1) + albedo_compensate - END IF - END DO - DEALLOCATE (albedo_veg_vis_in, albedo_veg_nir_in, albedo_soil_vis_in, albedo_soil_nir_in) - - varname_out='albedo_veg_vis' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - varname_out='albedo_veg_nir' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - varname_out='albedo_soil_vis' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - varname_out='albedo_soil_nir' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - -!------------------------------------- -! input-file8: topo_75 (roughness of the orography) -!------------------------------------- - ALLOCATE (roughness_oro(nlon,nlat)) - IF (.NOT. ignore_measurements) THEN - CALL open_file(info,fnam8,ncin) - - !-- get roughness length - varname='roughness_length_oro' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,roughness_oro) - CALL hdlerr(stat,'get roughness length of the orography from'//fnam8) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam8) - - roughness_oro(:,:) = MIN(20._dp,roughness_oro(:,:)) - ELSE - ! simply taking the same arrays for roughness_length and roughness_length_oro - roughness_oro(:,:) = MIN(20._dp,az0(:,:)) - END IF - varname_out='roughness_length_oro' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - -!------------------------------------- -! input-file9: cover fractions from Julia Pongratz (30.8.2006) -! based on natural vegetation distribution of Ramankutty -!------------------------------------- - - IF (year_ct /= year_cf .AND. .NOT. lread_pasture) THEN - CALL open_file(info,fnam9,ncin) - - !-- get cover fractions of year year_cf - varname='vegfract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (vegfract_cf(nlon,nlat,nvegtyp)) - stat = nf_get_var_double(ncin,varid,vegfract_cf) - CALL hdlerr(stat,'get fractional cover from'//fnam9) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam9) - END IF - -!------------------------------------- -! input-file10: C3/C4 mask -!------------------------------------- - CALL open_file(info,fnam10,ncin) - - !-- get C3/C4 fmask - varname='1C3_0C4' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (C3C4_flag(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,C3C4_flag) - CALL hdlerr(stat,'get C3/C4 flag from'//fnam10) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam10) - - C3C4_flag(:,:) = MIN(1.1_dp,MAX(-0.1_dp,C3C4_flag(:,:))) - -!------------------------------------- -! input-file11: C3 and C4 crops -!------------------------------------- - - ALLOCATE (C3_crop(nlon,nlat)) - C3_crop(:,:) = 0._dp - ALLOCATE (C4_crop(nlon,nlat)) - C4_crop(:,:) = 0._dp - - IF (lc3c4crop) THEN - CALL open_file(info,fnam11,ncin) - - !-- get C3 and C4 maps - varname='C3_crop' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,C3_crop) - CALL hdlerr(stat,'get map of C3 crop from'//fnam11) - varname='C4_crop' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,C4_crop) - CALL hdlerr(stat,'get map of C4 crop from'//fnam11) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam11) - END IF - -!------------------------------------- -! input-file12: pasture and crop fractions -! based on harmonized landuse scenarios needed for CMIP -!------------------------------------- - - ALLOCATE (pasture(nlon,nlat)) - pasture(:,:) = 0._dp - ALLOCATE (crop(nlon,nlat)) - crop(:,:) = 0._dp - - IF (lread_pasture) THEN - CALL open_file(info,fnam12,ncin) - - !-- get pasture fractions - varname='gpast' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,pasture) - CALL hdlerr(stat,'get map of pasture fractions from'//fnam12) - CALL get_missval(ncin, varid, missval) - WHERE (pasture(:,:) == missval) pasture(:,:) = 0._dp - - !-- get crop fractions - varname='gcrop' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - stat = nf_get_var_double(ncin,varid,crop) - CALL hdlerr(stat,'get map of crop fractions from'//fnam12) - CALL get_missval(ncin, varid, missval) - WHERE (crop(:,:) == missval) crop(:,:) = 0._dp - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam12) - END IF - -!------------------------------------- -! input-file13: potential vegetation (Julia Pongratz) -! based on natural vegetation distribution of Ramankutty -!------------------------------------- - IF (ldynveg .OR. lread_pasture) THEN - CALL open_file(info,fnam13,ncin) - - !-- get fractional cover - varname='cover_fract' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (potveg(nlon,nlat,nvegtyp)) - stat = nf_get_var_double(ncin,varid,potveg) - CALL hdlerr(stat,'get potential vegetation from'//fnam13) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam13) - - varname_out='natural_veg' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 3, outdimids(1:3)) - END IF - -!------------------------------------- -! input-file14: 5 soil layer parameters (Stefan Hagemann) -!------------------------------------- - CALL open_file(info,fnam14,ncin) - - !-- get soil depth - varname='soildepth' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (soil_depth(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,soil_depth) - CALL hdlerr(stat,'get soil depth from'//fnam14) - varname_out='soil_depth' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missdep) - - !-- get soil porosity - varname='volporosity' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (soil_porosity(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,soil_porosity) - CALL hdlerr(stat,'get soil porosity from'//fnam14) - varname_out='soil_porosity' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misspor) - - !-- get soil pore size index - varname='psi_lambda' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (pore_size_index(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,pore_size_index) - CALL hdlerr(stat,'get soil pore size index from'//fnam14) - varname_out='pore_size_index' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misspsi) - - !-- get soil field capacity - varname='volfc' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (soil_field_capacity(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,soil_field_capacity) - CALL hdlerr(stat,'get soil field cap from'//fnam14) - varname_out='soil_field_cap' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missfca) - - !-- get soil heat capacity - varname='heatcapacity' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (heat_capacity(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,heat_capacity) - CALL hdlerr(stat,'get soil heat capacity from'//fnam14) - varname_out='heat_capacity' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misshca) - - !-- get soil heat conductivity - varname='heatcond' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (heat_conductivity(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,heat_conductivity) - CALL hdlerr(stat,'get soil heat conductivity from'//fnam14) - varname_out='heat_conductivity' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misshco) - - !-- get soil moisture potential - varname='matrixpot' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (matrix_potential(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,matrix_potential) - CALL hdlerr(stat,'get soil moisture potential from'//fnam14) - varname_out='moisture_pot' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missmpo) - - !-- get saturated hydraulic conductivity - varname='hydcond' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (hyd_cond_sat(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,hyd_cond_sat) - CALL hdlerr(stat,'get saturated hydraulic conductivity from'//fnam14) - varname_out='hyd_cond_sat' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misshyc) - - !-- get wilting point - varname='volpwp' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (wilting_point(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,wilting_point) - CALL hdlerr(stat,'get wilting point from'//fnam14) - varname_out='wilting_point' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, misswpo) - - !-- get Clapp & Hornberger exponent b - varname='bclapp' - CALL check_dimensions(varname, ncin, varid, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime) - ALLOCATE (bclapp(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,bclapp) - CALL hdlerr(stat,'get Clapp & Hornberger exponent b from'//fnam14) - varname_out='bclapp' - IF (.NOT. cover_fract_only) CALL define_var(ncin, ncout, varname, varname_out, outdimids, missbcl) - - stat = nf_close(ncin) - CALL hdlerr(stat,'closing '//fnam14) - - !-- Define output variables to be calculated - varname_out='root_depth' - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 2, outdimids(1:2)) - - varname_out='layer_moist' - dimids(1:3)=(/outdimids(1),outdimids(2),outdimids(5)/) - IF (.NOT. cover_fract_only) CALL define_var_new(ncout, varname_out, 3, dimids(1:3)) - -!------------------------------------------------------------------------------ -! CREATE OUTPUT FIELDS -!------------------------------------------------------------------------------ -! TILES -!-------------------- - ALLOCATE (tiles(ntiles)) - DO i=1,ntiles - tiles(i) = i - END DO - -! SOIL LAYER -!-------------------- - ALLOCATE (layer_depth(nsoil)) - IF (nsoil == 5) THEN - layer_depth=(/0.065_dp,0.254_dp,0.913_dp,2.902_dp,5.700_dp/) - ELSE IF (nsoil /= 1) THEN - CALL hdlerr(1,"currently only 5 soil layers supported") - END IF - - ALLOCATE (soillev(nsoil)) - soillev(1) = layer_depth(1) - DO i=2,nsoil - soillev(i) = soillev(i-1) + layer_depth(i) - END DO - -!-------------------- -! TIME -!-------------------- - ALLOCATE (time_days(12)) - time_days=(/30,58,89,119,150,180,211,242,272,303,333,364/) - - -!--------------------------------- -! cover types and cover fractions -!--------------------------------- - - ALLOCATE (cover_type(nlon,nlat,ntiles)) - ALLOCATE (cover_fract(nlon,nlat,ntiles)) - ALLOCATE (vegfract_for_types(nvegtyp)) - ALLOCATE (is_naturalveg(ntiles)) - IF (ldynveg .OR. lread_pasture) ALLOCATE (natural_veg(nlon,nlat,ntiles)) - - DO j=1,nlat - DO i=1,nlon - ! - !-- calculate cover fractions depending on the number of tiles - ! - - IF (slm(i,j) < 0.5_dp) THEN - - !-- ocean - cover_type(i,j,:) = 0 - cover_fract(i,j,:) = 0._dp - IF (ldynveg .OR. lread_pasture) natural_veg(i,j,:) = 0._dp - ELSE - - !-- land - - ! if crops and pastures are read from a separate file, use the - ! potential vegetation to get the fractions of the natural types - IF (lread_pasture) vegfract(i,j,:) = potveg(i,j,:) - - - !-- adapt vegetation fractions to derive reasonable types - - vegfract_for_types(:) = vegfract(i,j,:) - CALL adapt_vegfract (lat(j), NINT(C3C4_flag(i,j)), info, .TRUE., & - lpasture, ignore_measurements, vegfract_for_types(:)) - - - !-- calculate the cover types - - CALL calc_cover_types (ntiles, lat(j), NINT(glac_dp(i,j)), & - vegfract_for_types(:), lc3c4crop, C3_crop(i,j), C4_crop(i,j), & - cover_type(i,j,:), second_woody, second_grass, dominant_crop, & - is_naturalveg(:)) - - - !-- make sure all land points have reasonable vegetation fractions - ! (actual vegetation: vegfract; potential vegetation: potveg) - - IF (year_ct == year_cf .OR. lread_pasture) THEN - CALL adapt_vegfract (lat(j), NINT(C3C4_flag(i,j)), info, .FALSE., & - lpasture, ignore_measurements, vegfract(i,j,:)) - ELSE - CALL adapt_vegfract (lat(j), NINT(C3C4_flag(i,j)), info, .FALSE., & - lpasture, ignore_measurements, vegfract_cf(i,j,:)) - vegfract(i,j,:) = vegfract_cf(i,j,:) - END IF - IF (ldynveg .OR. lread_pasture) THEN - CALL adapt_vegfract (lat(j), NINT(C3C4_flag(i,j)), info, .FALSE., & - .FALSE., ignore_measurements, potveg(i,j,:)) - END IF - - - !-- calculate the actual cover fractions - - CALL calc_cover_fractions (ntiles, lat(j), cover_type(i,j,:), & - second_woody, second_grass, NINT(glac_dp(i,j)), vegfract(i,j,:), & - grass_only, woods_only, lc3c4crop, C3_crop(i,j), C4_crop(i,j), & - crop(i,j), lread_pasture, lpasture_rule, pasture(i,j), & - NINT(C3C4_flag(i,j)), cover_fract(i,j,:)) - - !-- make sure, that all vegetation types have a minimum fraction of - ! small_fract and the sum of all vegetation is 1. in all grid cells. - - CALL scale_cover_fract (ntiles, is_naturalveg(:), NINT(glac_dp(i,j)), & - cover_fract(i,j,:)) - - IF (ldynveg .OR. lread_pasture) THEN - - !-- calculate the potential vegetation - - CALL calc_cover_fractions (ntiles, lat(j), cover_type(i,j,:), & - second_woody, second_grass, NINT(glac_dp(i,j)), potveg(i,j,:), & - grass_only, woods_only, lc3c4crop, 0._dp, 0._dp, & - 0._dp, .FALSE., lpasture_rule, 0._dp, & - NINT(C3C4_flag(i,j)), natural_veg(i,j,:)) - - CALL scale_cover_fract (ntiles, is_naturalveg(:), NINT(glac_dp(i,j)), & - natural_veg(i,j,:)) - - !-- make sure, that potential cover fractions of natural vegetation are - ! greater than the actual cover fractions. - - CALL harmonize_fractions (ntiles, is_naturalveg(:), NINT(glac_dp(i,j)), & - natural_veg(i,j,:), cover_fract(i,j,:)) - END IF - - END IF - END DO - END DO - - DEALLOCATE (crop, pasture, vegfract_for_types, C3C4_flag, is_naturalveg) - IF (year_ct /= year_cf .AND. .NOT. lread_pasture) DEALLOCATE(vegfract_cf) - IF (ldynveg .OR. lread_pasture) DEALLOCATE (potveg) - - - IF (.NOT. cover_fract_only) THEN - !-------------------------------------------------- - ! get fao map consistent with land-sea mask - !-------------------------------------------------- - missval=0._dp - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missval, 'modal', fao) - WHERE (glac_dp(:,:) == 1._dp) - fao(:,:) = 3._dp - END WHERE - - !--------------------------------------------------------------------- - ! get soil parameter arrays consistent with land sea and glacier mask - !--------------------------------------------------------------------- - IF (ignore_measurements) THEN - moisture(:,:) = 0.3_dp ! [m] - max_moisture(:,:) = 0.5_dp ! [m] - fao(:,:) = 3._dp ! [] - matrix_potential(:,:) = 0.3_dp ! [m] - bclapp(:,:) = 6._dp ! [] - heat_capacity(:,:) = 2.26E06_dp ! [J m-3 K-1] - heat_conductivity(:,:) = 6._dp ! [J m-1 s-1 K-1] - soil_porosity(:,:) = 0.45_dp ! [m/m] - soil_depth(:,:) = 5._dp ! [m] - soil_field_capacity(:,:) = 0.3_dp ! [m/m] - pore_size_index(:,:) = 0.3_dp ! [] - hyd_cond_sat(:,:) = 6.E-06_dp ! [m/s] - wilting_point(:,:) = 0.15_dp ! [m/m] - END IF - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missmpo, 'mean', matrix_potential) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missbcl, 'mean', bclapp) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misshca, 'mean', heat_capacity) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misshco, 'mean', heat_conductivity) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misspor, 'mean', soil_porosity) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missdep, 'mean', soil_depth) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missfca, 'mean', soil_field_capacity) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misspsi, 'mean', pore_size_index) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misshyc, 'mean', hyd_cond_sat) - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, misswpo, 'mean', wilting_point) - - - !---------------------------------------------------------------------- - ! get consistant values for water holding capacity and soil parameters - !---------------------------------------------------------------------- - ALLOCATE (max_soilwater(nlon,nlat)) - ALLOCATE (root_depth(nlon,nlat)) - - ! - ! max_soilwater: maximum amount of water possibly held in soil - ! soilwater: initial amount of soil water - ! max_moisture: maximum amount of water reachable for plants - ! moisture: initial amount of water reachable for plants - ! root_depth: length of the roots - ! soil_depth: depth of the soil above bedrock - - ! soil_depth - !------------ - ! Since Lithosols are defined by FAO/Unesco as "soils which are limited in - ! depth by continuous coherent hard rock within 10 cm of the surface," I - ! don't see the need to differentiate between them to such a degree (for - ! my purposes). I consider all Lithosols to be 10 cm thick, and use only - ! the surface texture to distinguish them. (K. Dunne, pers. comm to St. Hagemann, 1995) - ! => soil_depth needs to be at least 10 cm if area is not impermeable. - WHERE (non_glacier_land == 1) - soil_depth(:,:) = MAX(soil_depth(:,:), 0.1_dp) - END WHERE - - ! maximum amount of water fitting into the soil - max_soilwater(:,:) = soil_field_capacity(:,:) * soil_depth(:,:) - - ! max_moisture - !-------------- - ! get max_moisture values for all land grid cells - CALL extrap(nlon, nlat, lon, lat, non_glacier_land, missmxm, 'mean', max_moisture) - - ! maximum amount of water in the root zone cannot be more than what is fitting into the soil - max_moisture(:,:) = MIN(max_moisture(:,:), max_soilwater(:,:)) - - ! define small value on glaciers for technical reasons - WHERE (glac_dp == 1) - max_moisture(:,:) = small_fract - END WHERE - - ! root_depth - !------------ - ! root depth is calculated backwards from the maximum amout of water in the root zone - WHERE (soil_field_capacity(:,:) > 0._dp) - root_depth(:,:) = MIN(soil_depth(:,:), max_moisture(:,:)/soil_field_capacity(:,:)) - ELSEWHERE - root_depth(:,:) = 0._dp - ENDWHERE - - DEALLOCATE (max_soilwater) - - - !----------------------------------------------------------- - ! adapt initial soil moisture - !----------------------------------------------------------- - - ALLOCATE (soilwater(nlon,nlat)) - ALLOCATE (soil_depth_layer(nlon,nlat,nsoil)) - ALLOCATE (soilwater_layer(nlon,nlat,nsoil)) - - ! initial soil moisture must be below maximum soil moisture - moisture(:,:) = MIN(moisture(:,:), max_moisture(:,:)) - ! ... and should not be too small to prevent vegetation die back due to initialization - moisture(:,:) = MAX(moisture(:,:), 0.5_dp*max_moisture(:,:)) - - ! initialize soil moisture below the wilting point in desert areas - WHERE (veg_ratio_max(:,:) < 0.2_dp) - moisture(:,:) = MIN(moisture(:,:), 0.3_dp*max_moisture(:,:)) - END WHERE - - ! initial moisture value for each soil level - ! ------------------------------------------ - - ! initial value of total amount of soil water (not in initial file) - WHERE (root_depth(:,:) > 0._dp) - soilwater(:,:) = moisture(:,:) * soil_depth(:,:) / root_depth(:,:) - ELSEWHERE - soilwater(:,:) = 0._dp - ENDWHERE - - ! calculate soil layer depth for each soil level - soil_depth_layer(:,:,1) = MIN(soil_depth(:,:), layer_depth(1)) - DO i=2,nsoil - WHERE (soil_depth(:,:) > SUM(layer_depth(1:i-1))) - soil_depth_layer(:,:,i) = MIN(soil_depth(:,:)-SUM(layer_depth(1:i-1)), layer_depth(i)) - ELSEWHERE - soil_depth_layer(:,:,i) = 0._dp - ENDWHERE - END DO - - ! initial moisture value for each soil level - ! Conservation of soil water (all soil water, even below root zone) - DO i=1,nsoil - WHERE (soilwater(:,:) >= 0._dp .AND. soil_depth(:,:) > 0._dp ) - soilwater_layer(:,:,i) = soilwater(:,:)/soil_depth(:,:) * soil_depth_layer(:,:,i) - ELSEWHERE - soilwater_layer(:,:,i) = 0._dp - ENDWHERE - END DO - - DEALLOCATE(soilwater) - DEALLOCATE(soil_depth_layer) - - END IF ! .NOT. cover_fract_only - -!----------------------------------------------------------- -! calculate areas covered by grass, woods, deserts -!----------------------------------------------------------- - ALLOCATE (dummy(nlat)) - ALLOCATE (gauss_weights(nlat)) - CALL gauaw(dummy,gauss_weights,nlat,pi) - ALLOCATE (grid_area(nlon,nlat)) - IF (echam_fractional) THEN - grid_area(:,:) = slf(:,:) * SPREAD(gauss_weights(:), DIM=1, NCOPIES=nlon) & - * 2._dp * pi * radius_of_earth**2 / REAL(nlon) - ELSE - grid_area(:,:) = SPREAD(gauss_weights(:), DIM=1, NCOPIES=nlon) & - * 2._dp * pi * radius_of_earth**2 / REAL(nlon) - END IF - DEALLOCATE (dummy) - area_tropical_forest = 0._dp - area_temperate_forest = 0._dp - area_woody = 0._dp - area_shrubs = 0._dp - area_crops = 0._dp - area_pasture = 0._dp - area_grass = 0._dp - area_all = 0._dp - area_lake = 0._dp - area_land = 0._dp - area_land_tropics = 0._dp - area_land_extratropics = 0._dp - area_glac = 0._dp - DO j = 1,nlat - DO i = 1,nlon - IF (echam_fractional) THEN - area_all = area_all + gauss_weights(j) * 2._dp * pi * radius_of_earth**2 / REAL(nlon) - ELSE - area_all = area_all + grid_area(i,j) - END IF - IF (lake(i,j) > 0.5_dp) area_lake = area_lake + grid_area(i,j) - IF (slm(i,j) > 0.5_dp) THEN ! land - area_land = area_land + grid_area(i,j) - DO k = 1,ntiles - - ! tropical forest - IF (cover_type(i,j,k) == lct_tropical_evergreen & - .OR. cover_type(i,j,k) == lct_tropical_deciduous) THEN - area_tropical_forest = area_tropical_forest + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - area_woody = area_woody + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! temperate forest - ELSE IF (cover_type(i,j,k) == lct_extratrop_evergreen & - .OR. cover_type(i,j,k) == lct_extratrop_deciduous & - .OR. cover_type(i,j,k) == lct_temperate_broadl_evergreen & - .OR. cover_type(i,j,k) == lct_temperate_broadl_deciduous & - .OR. cover_type(i,j,k) == lct_evergreen_conifer & - .OR. cover_type(i,j,k) == lct_deciduous_conifer) THEN - area_temperate_forest = area_temperate_forest + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - area_woody = area_woody + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! shrubs - ELSE IF (cover_type(i,j,k) == lct_raingreen_shrub & - .OR. cover_type(i,j,k) == lct_deciduous_shrub) THEN - area_shrubs = area_shrubs + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - area_woody = area_woody + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! grass (and pasture) - ELSE IF (cover_type(i,j,k) == lct_c3grass & - .OR. cover_type(i,j,k) == lct_c4grass) THEN - area_grass = area_grass + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! crops - ELSE IF (cover_type(i,j,k) == lct_crop & - .OR. cover_type(i,j,k) == lct_c3crop & - .OR. cover_type(i,j,k) == lct_c4crop) THEN - area_crops = area_crops + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - - ! pasture - ELSE IF (cover_type(i,j,k) == lct_pasture & - .OR. cover_type(i,j,k) == lct_c3pasture & - .OR. cover_type(i,j,k) == lct_c4pasture) THEN - area_pasture = area_pasture + & - grid_area(i,j) * cover_fract(i,j,k) * veg_ratio_max(i,j) - END IF - - ! glaciers - IF (glac_dp(i,j) >= 0.5_dp) THEN - area_glac = area_glac + grid_area(i,j) * cover_fract(i,j,k) - - ! tropical land - ELSE IF (j <= nlat/3 .OR. j > 2*nlat/3) THEN - area_land_extratropics = area_land_extratropics & - + grid_area(i,j) * cover_fract(i,j,k) - - ! extratropical land - ELSE - area_land_tropics = area_land_tropics & - + grid_area(i,j) * cover_fract(i,j,k) - END IF - END DO - END IF - END DO - END DO - DEALLOCATE (gauss_weights, grid_area) - DEALLOCATE (non_glacier_land) - - IF (info) THEN - WRITE (*,*) '' - WRITE (*,*) 'The surface of the globe [km2]: ',area_all * 1.e-06 - WRITE (*,*) 'Global land surface [km2]: ',area_land * 1.e-06 - WRITE (*,*) 'Global land surface including lakes [km2]: ',(area_land+area_lake) * 1.e-06 - WRITE (*,*) 'Global glacier [km2]: ',area_glac * 1.e-06_dp - WRITE (*,*) 'Land tropics [km2]: ',area_land_tropics * 1.e-06 - WRITE (*,*) 'Land extratropics [km2]: ',area_land_extratropics * 1.e-06 - WRITE (*,*) 'nlat,nlat/3,2*nlat/3: ',nlat,nlat/3,2*nlat/3 - WRITE (*,*) 'Area of tropical forest [km2]: ',area_tropical_forest * 1.e-06 - WRITE (*,*) 'Area of temperate + boreal forest [km2]: ',area_temperate_forest * 1.e-06 - WRITE (*,*) 'Area of crops[km2]: ',area_crops * 1.e-06 - WRITE (*,*) 'Area of pasture [km2]: ',area_pasture * 1.e-06 - WRITE (*,*) 'Area of all woody types [km2]: ',area_woody * 1.e-06 - WRITE (*,*) 'Area of grass lands (incl. pastures)[km2]: ',area_grass * 1.e-06 - ENDIF - -!------------------------------------------------------------------------------ -! Write the output file -!------------------------------------------------------------------------------ - - CALL set_global_attributes(ncout, year_ct, year_cf, res_oce, res_atm, & - nlct, ntiles, nsoil, lcouple, ldynveg, lc3c4crop, lpasture, lread_pasture, & - lpasture_rule, desert_only, grass_only, woods_only, ignore_measurements, & - echam_fractional, maxmoist_version, pasture_tag, masks_file, svn_url, svn_rev) - stat = nf_enddef(ncout) - CALL hdlerr(stat,'problem with enddef') - - !-- dimension variables - - stat = nf_inq_varid(ncout,'lat',varid) - CALL hdlerr(stat,'cannot find lat') - stat = nf_put_var_double(ncout,varid,lat(:)) - CALL hdlerr(stat,'put variable lat') - DEALLOCATE(lat) - - stat = nf_inq_varid(ncout,'lon',varid) - CALL hdlerr(stat,'cannot find lon') - stat = nf_put_var_double(ncout,varid,lon(:)) - CALL hdlerr(stat,'put variable lon') - DEALLOCATE(lon) - - stat = nf_inq_varid(ncout,'ntiles',varid) - CALL hdlerr(stat,'cannot find ntiles') - stat = nf_put_var_int(ncout,varid,tiles(:)) - CALL hdlerr(stat,'put variable tiles') - DEALLOCATE(tiles) - - stat = nf_inq_varid(ncout,'soillev',varid) - CALL hdlerr(stat,'cannot find soillev') - stat = nf_put_var_double(ncout,varid,soillev(:)) - CALL hdlerr(stat,'put variable soillev') - DEALLOCATE(soillev) - - stat = nf_inq_varid(ncout,'soil_layer_depth',varid) - CALL hdlerr(stat,'cannot find soil_layer_depth') - stat = nf_put_var_double(ncout,varid,layer_depth(:)) - CALL hdlerr(stat,'put variable soil_layer_depth') - DEALLOCATE(layer_depth) - - stat = nf_inq_varid(ncout,'time',varid) - CALL hdlerr(stat,'cannot find time') - stat = nf_put_var_int(ncout,varid,time_days(:)) - CALL hdlerr(stat,'put variable time') - DEALLOCATE(time_days) - - !-- other variables - - stat = nf_inq_varid(ncout,'cover_fract',varid) - CALL hdlerr(stat,'cannot find cover_fract') - stat = nf_put_var_double(ncout,varid,cover_fract(:,:,:)) - CALL hdlerr(stat,'put variable cover_fract') - DEALLOCATE(cover_fract) - - ALLOCATE(cover_type_dp(nlon,nlat,ntiles)) - cover_type_dp(:,:,:)=REAL(cover_type(:,:,:)) - DEALLOCATE(cover_type) - stat = nf_inq_varid(ncout,'cover_type',varid) - CALL hdlerr(stat,'cannot find cover_type') - stat = nf_put_var_double(ncout,varid,cover_type_dp(:,:,:)) - CALL hdlerr(stat,'put variable cover_type') - DEALLOCATE(cover_type_dp) - - IF (.NOT. cover_fract_only) THEN - stat = nf_inq_varid(ncout,'veg_fract',varid) - CALL hdlerr(stat,'cannot find veg_fract') - stat = nf_put_var_double(ncout,varid,veg_fract(:,:,:)) - CALL hdlerr(stat,'put variable veg_fract') - DEALLOCATE(veg_fract) - - stat = nf_inq_varid(ncout,'lai_clim',varid) - CALL hdlerr(stat,'cannot find lai_clim') - stat = nf_put_var_double(ncout,varid,lai(:,:,:)) - CALL hdlerr(stat,'put variable lai_clim') - DEALLOCATE(lai) - - stat = nf_inq_varid(ncout,'elevation',varid) - CALL hdlerr(stat,'cannot find elevation') - stat = nf_put_var_double(ncout,varid,elevation(:,:)) - CALL hdlerr(stat,'put variable elevation') - DEALLOCATE(elevation) - - stat = nf_inq_varid(ncout,'orography_std_dev',varid) - CALL hdlerr(stat,'cannot find orography_std_dev') - stat = nf_put_var_double(ncout,varid,elevationrms(:,:)) - CALL hdlerr(stat,'put variable orography_std_dev') - DEALLOCATE(elevationrms) - - stat = nf_inq_varid(ncout,'roughness_length',varid) - CALL hdlerr(stat,'cannot find roughness_length') - stat = nf_put_var_double(ncout,varid,az0(:,:)) - CALL hdlerr(stat,'put variable roughness_length') - DEALLOCATE(az0) - - stat = nf_inq_varid(ncout,'roughness_length_oro',varid) - CALL hdlerr(stat,'cannot find roughness_length_oro') - stat = nf_put_var_double(ncout,varid,roughness_oro(:,:)) - CALL hdlerr(stat,'put variable roughness_length_oro') - DEALLOCATE(roughness_oro) - - stat = nf_inq_varid(ncout,'albedo',varid) - CALL hdlerr(stat,'cannot find albedo') - stat = nf_put_var_double(ncout,varid,albedo(:,:)) - CALL hdlerr(stat,'put variable albedo') - DEALLOCATE(albedo) - - stat = nf_inq_varid(ncout,'fao',varid) - CALL hdlerr(stat,'cannot find fao') - stat = nf_put_var_double(ncout,varid,fao(:,:)) - CALL hdlerr(stat,'put variable fao') - DEALLOCATE(fao) - - stat = nf_inq_varid(ncout,'maxmoist',varid) - CALL hdlerr(stat,'cannot find maxmoist') - stat = nf_put_var_double(ncout,varid,max_moisture(:,:)) - CALL hdlerr(stat,'put variable maxmoist') - DEALLOCATE(max_moisture) - - stat = nf_inq_varid(ncout,'forest_fract',varid) - CALL hdlerr(stat,'cannot find forest_fract') - stat = nf_put_var_double(ncout,varid,forest_fract(:,:)) - CALL hdlerr(stat,'put variable forest_fract') - DEALLOCATE(forest_fract) - - stat = nf_inq_varid(ncout,'init_moist',varid) - CALL hdlerr(stat,'cannot find init_moist') - stat = nf_put_var_double(ncout,varid,moisture(:,:)) - CALL hdlerr(stat,'put variable init_moist') - DEALLOCATE(moisture) - - stat = nf_inq_varid(ncout,'veg_ratio_max',varid) - CALL hdlerr(stat,'cannot find veg_ratio_max') - stat = nf_put_var_double(ncout,varid,veg_ratio_max(:,:)) - CALL hdlerr(stat,'put variable veg_ratio_max') - DEALLOCATE(veg_ratio_max) - - stat = nf_inq_varid(ncout,'albedo_veg_vis',varid) - CALL hdlerr(stat,'cannot find albedo_veg_vis') - stat = nf_put_var_double(ncout,varid,albedo_veg_vis(:,:)) - CALL hdlerr(stat,'put variable albedo_veg_vis') - DEALLOCATE(albedo_veg_vis) - - stat = nf_inq_varid(ncout,'albedo_veg_nir',varid) - CALL hdlerr(stat,'cannot find albedo_veg_nir') - stat = nf_put_var_double(ncout,varid,albedo_veg_nir(:,:)) - CALL hdlerr(stat,'put variable albedo_veg_nir') - DEALLOCATE(albedo_veg_nir) - - stat = nf_inq_varid(ncout,'albedo_soil_vis',varid) - CALL hdlerr(stat,'cannot find albedo_soil_vis') - stat = nf_put_var_double(ncout,varid,albedo_soil_vis(:,:)) - CALL hdlerr(stat,'put variable albedo_soil_vis') - DEALLOCATE(albedo_soil_vis) - - stat = nf_inq_varid(ncout,'albedo_soil_nir',varid) - CALL hdlerr(stat,'cannot find albedo_soil_nir') - stat = nf_put_var_double(ncout,varid,albedo_soil_nir(:,:)) - CALL hdlerr(stat,'put variable albedo_soil_nir') - DEALLOCATE(albedo_soil_nir) - - stat = nf_inq_varid(ncout,'snow',varid) - CALL hdlerr(stat,'cannot find snow') - stat = nf_put_var_double(ncout,varid,snow(:,:)) - CALL hdlerr(stat,'put variable snow') - DEALLOCATE(snow) - - stat = nf_inq_varid(ncout,'slf',varid) - CALL hdlerr(stat,'cannot find slf') - stat = nf_put_var_double(ncout,varid,slf(:,:)) - CALL hdlerr(stat,'put variable slf') - DEALLOCATE(slf) - - stat = nf_inq_varid(ncout,'lake',varid) - CALL hdlerr(stat,'cannot find lake') - stat = nf_put_var_double(ncout,varid,lake(:,:)) - CALL hdlerr(stat,'put variable lake') - DEALLOCATE(lake) - - stat = nf_inq_varid(ncout,'slm',varid) - CALL hdlerr(stat,'cannot find slm') - stat = nf_put_var_double(ncout,varid,slm(:,:)) - CALL hdlerr(stat,'put variable slm') - DEALLOCATE(slm) - - stat = nf_inq_varid(ncout,'glac',varid) - CALL hdlerr(stat,'cannot find glac') - stat = nf_put_var_double(ncout,varid,glac_dp(:,:)) - CALL hdlerr(stat,'put variable glac') - DEALLOCATE(glac_dp) - - stat = nf_inq_varid(ncout,'surf_temp',varid) - CALL hdlerr(stat,'cannot find surf_temp') - stat = nf_put_var_double(ncout,varid,surf_temp(:,:,:)) - CALL hdlerr(stat,'put variable surf_temp') - DEALLOCATE(surf_temp) - - IF (ldynveg .OR. lread_pasture) THEN - stat = nf_inq_varid(ncout,'natural_veg',varid) - CALL hdlerr(stat,'cannot find natural_veg') - stat = nf_put_var_double(ncout,varid,natural_veg(:,:,:)) - CALL hdlerr(stat,'put variable natural_veg') - DEALLOCATE(natural_veg) - END IF - - stat = nf_inq_varid(ncout,'soil_depth',varid) - CALL hdlerr(stat,'cannot find soil_depth') - stat = nf_put_var_double(ncout,varid,soil_depth(:,:)) - CALL hdlerr(stat,'put variable soil_depth') - DEALLOCATE(soil_depth) - - stat = nf_inq_varid(ncout,'heat_conductivity',varid) - CALL hdlerr(stat,'cannot find heat_conductivity') - stat = nf_put_var_double(ncout,varid,heat_conductivity(:,:)) - CALL hdlerr(stat,'put variable heat_conductivity') - DEALLOCATE(heat_conductivity) - - stat = nf_inq_varid(ncout,'heat_capacity',varid) - CALL hdlerr(stat,'cannot find heat_capacity') - stat = nf_put_var_double(ncout,varid,heat_capacity(:,:)) - CALL hdlerr(stat,'put variable heat_capacity') - DEALLOCATE(heat_capacity) - - stat = nf_inq_varid(ncout,'bclapp',varid) - CALL hdlerr(stat,'cannot find bclapp') - stat = nf_put_var_double(ncout,varid,bclapp(:,:)) - CALL hdlerr(stat,'put variable bclapp') - DEALLOCATE(bclapp) - - stat = nf_inq_varid(ncout,'soil_porosity',varid) - CALL hdlerr(stat,'cannot find soil_porosity') - stat = nf_put_var_double(ncout,varid,soil_porosity(:,:)) - CALL hdlerr(stat,'put variable soil_porosity') - DEALLOCATE(soil_porosity) - - stat = nf_inq_varid(ncout,'moisture_pot',varid) - CALL hdlerr(stat,'cannot find moisture_pot') - stat = nf_put_var_double(ncout,varid,matrix_potential(:,:)) - CALL hdlerr(stat,'put variable moisture_pot') - DEALLOCATE(matrix_potential) - - stat = nf_inq_varid(ncout,'soil_field_cap',varid) - CALL hdlerr(stat,'cannot find soil_field_cap') - stat = nf_put_var_double(ncout,varid,soil_field_capacity(:,:)) - CALL hdlerr(stat,'put variable soil_field_cap') - DEALLOCATE(soil_field_capacity) - - stat = nf_inq_varid(ncout,'hyd_cond_sat',varid) - CALL hdlerr(stat,'cannot find hyd_cond_sat') - stat = nf_put_var_double(ncout,varid,hyd_cond_sat(:,:)) - CALL hdlerr(stat,'put variable hyd_cond_sat') - DEALLOCATE(hyd_cond_sat) - - stat = nf_inq_varid(ncout,'pore_size_index',varid) - CALL hdlerr(stat,'cannot find pore_size_index') - stat = nf_put_var_double(ncout,varid,pore_size_index(:,:)) - CALL hdlerr(stat,'put variable pore_size_index') - DEALLOCATE(pore_size_index) - - stat = nf_inq_varid(ncout,'wilting_point',varid) - CALL hdlerr(stat,'cannot find wilting_point') - stat = nf_put_var_double(ncout,varid,wilting_point(:,:)) - CALL hdlerr(stat,'put variable wilting_point') - DEALLOCATE(wilting_point) - - stat = nf_inq_varid(ncout,'layer_moist',varid) - CALL hdlerr(stat,'cannot find layer_moist') - stat = nf_put_var_double(ncout,varid,soilwater_layer(:,:,:)) - CALL hdlerr(stat,'put variable layer_moist') - DEALLOCATE(soilwater_layer) - - stat = nf_inq_varid(ncout,'root_depth',varid) - CALL hdlerr(stat,'cannot find root_depth') - stat = nf_put_var_double(ncout,varid,root_depth(:,:)) - CALL hdlerr(stat,'put variable root_depth') - DEALLOCATE(root_depth) - - END IF - - stat = nf_close(ncout) - CALL hdlerr(stat,'closing file') - - END PROGRAM jsbach_init_file - -!------------------------------------------------------------------------------ -SUBROUTINE adapt_vegfract (lat, C3C4_flag, info, for_types, lpasture, & - ignore_measurements, vegfract) -!------------------------------------------------------------------------------ -! -! Routine to modify vegetation fractions -! -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - - IMPLICIT NONE - - !-- INTENT(in) - INTEGER, INTENT(in) :: C3C4_flag ! 1 for C3, 0 for C4 grasses - REAL(dp), INTENT(in) :: lat ! latitude - LOGICAL, INTENT(in) :: info ! print some additional information - LOGICAL, INTENT(in) :: for_types ! calculation of cover types will be - ! based on vegfract calculated here - LOGICAL, INTENT(in) :: lpasture ! distinguish pasture from grass lands - LOGICAL, INTENT(in) :: ignore_measurements ! covertypes only depend on latitude - - !-- INTENT(inout) - REAL(dp), INTENT(inout) :: vegfract(nvegtyp) - - !-- LOCAL - INTEGER, SAVE :: icount=0 - INTEGER :: k - INTEGER :: idominant, isecond - -!------------------------------------------------------------------------------ - - IF (nvegtyp /= 14) THEN - CALL hdlerr(1,'adapt_vegfract: Routine for 14 vegetation types') - END IF - - IF (ignore_measurements) THEN - vegfract(:) = 0._dp - END IF - - !-- There should not be negative vegetation coverage (missing value) - - vegfract(:) = MAX(vegfract(:),0._dp) - - !-- Define reasonable cover fractions for land points without any vegetation - - If (SUM(vegfract(:)) <= small_fract+EPSILON(1._dp)) THEN - IF (ABS(lat) < 30._dp) THEN - vegfract(veg_tropical_evergreen) = 2._dp * small_fract - ELSE IF (ABS(lat) < 40._dp) THEN - vegfract(veg_temperate_broadl_evergreen) = 2._dp * small_fract - ELSE - vegfract(veg_evergreen_conifer) = 2._dp * small_fract - END IF - IF (ABS(lat) < 40._dp) THEN - vegfract(veg_raingreen_shrub) = 2._dp * small_fract - vegfract(veg_c4grass) = 2._dp * small_fract - ELSE - vegfract(veg_deciduous_shrub) = 2._dp * small_fract - vegfract(veg_c3grass) = 2._dp * small_fract - END IF - END IF - - !-- change tropical forest to temperate/boreal forest outside 40S-40N - - IF (ABS(lat) > 40._dp) THEN - vegfract(veg_temperate_broadl_evergreen) = vegfract(veg_temperate_broadl_evergreen) & - + vegfract(veg_tropical_evergreen) - vegfract(veg_temperate_broadl_deciduous) = vegfract(veg_temperate_broadl_deciduous) & - + vegfract(veg_tropical_deciduous) - vegfract(veg_tropical_evergreen) = 0._dp - vegfract(veg_tropical_deciduous) = 0._dp - END IF - - IF (.NOT. lpasture) THEN - !-- add C3 pasture to C3 grass and C4 pasture to C4 grass - - vegfract(veg_c3grass) = vegfract(veg_c3grass) + vegfract(veg_c3pasture) - vegfract(veg_c4grass) = vegfract(veg_c4grass) + vegfract(veg_c4pasture) - vegfract(veg_c3pasture) = 0._dp - vegfract(veg_c4pasture) = 0._dp - END IF - - - !-- In case C3 and C4 grasses have the same cover fraction, the C3/C4 flag - ! determines which grass dominates - - IF (ABS(vegfract(veg_c3grass) - vegfract(veg_c4grass)) < small_fract) THEN - !! IF (info) WRITE (*,*) 'C3 and C4 grasses have the same cover fractions: ', & - !! vegfract(veg_c3grass), vegfract(veg_c4grass) - IF (C3C4_flag == 0) THEN - vegfract(veg_c4grass) = MIN(1._dp,vegfract(veg_c4grass) + small_fract*10._dp) - vegfract(veg_c3grass) = MAX(0._dp,vegfract(veg_c3grass) - small_fract*10._dp) - ELSE - vegfract(veg_c4grass) = MAX(0._dp,vegfract(veg_c4grass) - small_fract*10._dp) - vegfract(veg_c3grass) = MIN(1._dp,vegfract(veg_c3grass) + small_fract*10._dp) - END IF - END IF - - IF (for_types) THEN - !-- In case the cover fractions of the two dominant PFTs are the same, they - ! are slightly modified. - - idominant = 1 - DO k = 2,nvegtyp - IF (vegfract(k) > vegfract(idominant)) idominant = k - END DO - IF (idominant /= 1) isecond = 1 - IF (idominant == 1) isecond = 2 - DO k = 2,nvegtyp - IF (vegfract(k) > vegfract(isecond) .AND. k /= idominant) isecond = k - END DO - IF (ABS(vegfract(idominant) - vegfract(isecond)) < small_fract) THEN - IF (info) WRITE (*,*) 'The two dominant PFTs have the same cover fractions: ', & - idominant, isecond, vegfract(idominant), vegfract(isecond) - IF (MOD(icount,2) == 1) THEN - vegfract(idominant) = vegfract(idominant) + small_fract * 10._dp - vegfract(isecond) = vegfract(isecond) - small_fract * 10._dp - ELSE - vegfract(idominant) = vegfract(idominant) - small_fract * 10._dp - vegfract(isecond) = vegfract(isecond) + small_fract * 10._dp - END IF - icount = icount + 1 - END IF - END IF - -END SUBROUTINE adapt_vegfract - -!------------------------------------------------------------------------------ -SUBROUTINE calc_cover_fractions (ntiles, lat, cover_type, second_woody, & - second_grass, glac, vegfract, grass_only, woods_only, lc3c4crop, & - C3_crop, C4_crop, crop, lread_pasture, lpasture_rule, pasture, & - C3C4_flag, cover_fract) -!------------------------------------------------------------------------------ -! -! Routine to calculate land cover types and fractions depending on the number -! of tiles -! -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - - IMPLICIT NONE - - !-- INTENT(in) - INTEGER, INTENT(in) :: ntiles ! number of tiles - REAL(dp), INTENT(in) :: lat ! latitude - INTEGER, INTENT(in) :: glac ! glacier flag (1: glacier) - INTEGER, INTENT(in) :: cover_type(ntiles) - INTEGER, INTENT(in) :: second_woody, second_grass - REAL(dp), INTENT(in) :: vegfract(nvegtyp) - LOGICAL, INTENT(in) :: woods_only, grass_only - LOGICAL, INTENT(in) :: lc3c4crop ! distinguish C3 crops from C4 crops - LOGICAL, INTENT(in) :: lread_pasture ! use pastures of array 'pasture' and - ! crops from array 'crop' - LOGICAL, INTENT(in) :: lpasture_rule ! allocate pasture primarily on grass lands - REAL(dp), INTENT(in) :: C3_crop ! fraction of C3 crops - REAL(dp), INTENT(in) :: C4_crop ! fraction of C4 crops - REAL(dp), INTENT(in) :: crop ! crop fraction (if lread_pasture) - REAL(dp), INTENT(in) :: pasture ! pasture fraction (if lread_pasture) - INTEGER, INTENT(in) :: C3C4_flag ! flag used to decide whether C3 or C4 - ! grass/pasture is dominant - - !-- INTENT(out) - REAL(dp), INTENT(out) :: cover_fract(ntiles) - - !-- LOCAL - INTEGER :: k - REAL(dp) :: vegfract_woody, vegfract_grass - REAL(dp) :: vegfract_c3grass, vegfract_c4grass - REAL(dp) :: vegfract_crop, vegfract_c3crop, vegfract_c4crop - REAL(dp) :: vegfract_c3pasture, vegfract_c4pasture - REAL(dp) :: c3ratio - -!------------------------------------------------------------------------------ - - IF (nvegtyp /= 14) THEN - CALL hdlerr(1,'calc_cover_fractions: Routine for 14 vegetation types') - END IF - - !-- calculate woody fraction and grass fraction - vegfract_woody = 0._dp - DO k=1,nwoody - vegfract_woody = vegfract_woody + vegfract(woody_types(k)) - END DO - vegfract_grass = vegfract(veg_c3grass) + vegfract(veg_c4grass) - - !-- find out C3 ratio of grass land - IF (vegfract_grass > 0._dp) THEN - c3ratio = vegfract(veg_c3grass) / vegfract_grass - ELSE - c3ratio = REAL(C3C4_flag, dp) ! 1 for C3, 0 for C4 - END IF - - !-- apply the pasture rule: pasture is primarily allocated on grass lands - IF (lpasture_rule .AND. lread_pasture) THEN - vegfract_grass = MAX(0._dp, vegfract_grass - pasture) - vegfract_c3grass = vegfract_grass * c3ratio - vegfract_c4grass = vegfract_grass * (1._dp - c3ratio) - ELSE - vegfract_c3grass = vegfract(veg_c3grass) - vegfract_c4grass = vegfract(veg_c4grass) - END IF - - !-- Calculate the fractions of C3 and C4 pasture from the total pasture - IF (lread_pasture) THEN - vegfract_c3pasture = pasture * c3ratio - vegfract_c4pasture = pasture * (1._dp - c3ratio) - ELSE - vegfract_c3pasture = vegfract(veg_c3pasture) - vegfract_c4pasture = vegfract(veg_c4pasture) - END IF - - !-- Calculate crop fractions - IF (lread_pasture) THEN - vegfract_crop = crop - ELSE - vegfract_crop = vegfract(veg_crop) - END IF - IF (lc3c4crop) THEN - !-- Calculate C3 and C4 crop fractions by scaling with C3/C4_crop maps - ! needed only if there is more than one tile reserved for crops - IF ((C3_crop + C4_crop) > EPSILON(1._dp)) THEN - vegfract_c3crop = vegfract(veg_crop) * (C3_crop / (C3_crop + C4_crop)) - vegfract_c4crop = vegfract(veg_crop) * (C4_crop / (C3_crop + C4_crop)) - ELSE - vegfract_c3crop = 0._dp - vegfract_c4crop = 0._dp - END IF - ELSE - vegfract_c3crop = 0._dp - vegfract_c4crop = 0._dp - END IF - - !-- glaciers - IF (glac == 1) THEN - cover_fract(1) = 1._dp - cover_fract(2:ntiles) = 0._dp - ELSE - SELECT CASE (ntiles) - CASE (1) - cover_fract(1) = 1._dp - CASE (3) - cover_fract(1) = vegfract_woody - cover_fract(2) = vegfract_grass - cover_fract(3) = vegfract_crop - CASE (4) - IF (cover_type(3) == lct(second_woody)) THEN - cover_fract(1) = vegfract_woody - vegfract(second_woody) - cover_fract(2) = vegfract_grass - cover_fract(3) = vegfract(second_woody) - ELSE - cover_fract(1) = vegfract_woody - cover_fract(2) = vegfract_grass - vegfract(second_grass) - cover_fract(3) = vegfract(second_grass) - END IF - cover_fract(4) = vegfract_crop - CASE (5) - IF (cover_type(3) == lct(second_woody)) THEN - cover_fract(1) = vegfract_woody - vegfract(second_woody) - cover_fract(2) = vegfract_grass - cover_fract(3) = vegfract(second_woody) - ELSE - cover_fract(1) = vegfract_woody - cover_fract(2) = vegfract_grass - vegfract(second_grass) - cover_fract(3) = vegfract(second_grass) - END IF - cover_fract(4) = vegfract_c3crop - cover_fract(5) = vegfract_c4crop - CASE (6) - cover_fract(1) = vegfract(veg_tropical_deciduous) & - + vegfract(veg_temperate_broadl_deciduous) & - + vegfract(veg_deciduous_conifer) - cover_fract(2) = vegfract(veg_tropical_evergreen) & - + vegfract(veg_temperate_broadl_evergreen) & - + vegfract(veg_evergreen_conifer) - cover_fract(3) = vegfract(veg_raingreen_shrub) & - + vegfract(veg_deciduous_shrub) & - + vegfract(veg_tundra) - cover_fract(4) = vegfract_c3grass - cover_fract(5) = vegfract_c4grass - cover_fract(6) = vegfract_crop - CASE (8) - cover_fract(1) = vegfract(veg_tropical_evergreen) - cover_fract(2) = vegfract(veg_tropical_deciduous) - cover_fract(3) = vegfract(veg_temperate_broadl_evergreen) & - + vegfract(veg_evergreen_conifer) - cover_fract(4) = vegfract(veg_temperate_broadl_deciduous) & - + vegfract(veg_deciduous_conifer) - cover_fract(5) = vegfract(veg_raingreen_shrub) - cover_fract(6) = vegfract(veg_deciduous_shrub) - cover_fract(7) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(8) = vegfract_c4grass - CASE (9) - cover_fract(1) = 0._dp - cover_fract(2) = vegfract(veg_tropical_evergreen) - cover_fract(3) = vegfract(veg_tropical_deciduous) - cover_fract(4) = vegfract(veg_temperate_broadl_evergreen) & - + vegfract(veg_evergreen_conifer) - cover_fract(5) = vegfract(veg_temperate_broadl_deciduous) & - + vegfract(veg_deciduous_conifer) - cover_fract(6) = vegfract(veg_raingreen_shrub) - cover_fract(7) = vegfract(veg_deciduous_shrub) - cover_fract(8) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(9) = vegfract_c4grass - CASE (10) - cover_fract(1) = vegfract(veg_tropical_evergreen) - cover_fract(2) = vegfract(veg_tropical_deciduous) - cover_fract(3) = vegfract(veg_temperate_broadl_evergreen) + vegfract(veg_evergreen_conifer) - cover_fract(4) = vegfract(veg_temperate_broadl_deciduous) + vegfract(veg_deciduous_conifer) - cover_fract(5) = vegfract(veg_raingreen_shrub) - cover_fract(6) = vegfract(veg_deciduous_shrub) - cover_fract(7) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(8) = vegfract_c4grass - cover_fract(9) = vegfract_c3crop - cover_fract(10)= vegfract_c4crop - CASE (11) - cover_fract(1) = vegfract(veg_tropical_evergreen) - cover_fract(2) = vegfract(veg_tropical_deciduous) - cover_fract(3) = vegfract(veg_temperate_broadl_evergreen) + vegfract(veg_evergreen_conifer) - cover_fract(4) = vegfract(veg_temperate_broadl_deciduous) + vegfract(veg_deciduous_conifer) - cover_fract(5) = vegfract(veg_raingreen_shrub) - cover_fract(6) = vegfract(veg_deciduous_shrub) - cover_fract(7) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(8) = vegfract_c4grass - cover_fract(9) = vegfract_c3pasture - cover_fract(10)= vegfract_c4pasture - cover_fract(11) = vegfract_crop - CASE (12) - cover_fract(1) = 0._dp - cover_fract(2) = vegfract(veg_tropical_evergreen) - cover_fract(3) = vegfract(veg_tropical_deciduous) - cover_fract(4) = vegfract(veg_temperate_broadl_evergreen) + vegfract(veg_evergreen_conifer) - cover_fract(5) = vegfract(veg_temperate_broadl_deciduous) + vegfract(veg_deciduous_conifer) - cover_fract(6) = vegfract(veg_raingreen_shrub) - cover_fract(7) = vegfract(veg_deciduous_shrub) - cover_fract(8) = vegfract_c3grass + vegfract(veg_tundra) - cover_fract(9) = vegfract_c4grass - cover_fract(10)= vegfract_c3pasture - cover_fract(11)= vegfract_c4pasture - cover_fract(12) = vegfract_crop - CASE (13) - cover_fract(1) = vegfract(veg_tropical_evergreen) - cover_fract(2) = vegfract(veg_tropical_deciduous) - cover_fract(3) = vegfract(veg_temperate_broadl_evergreen) - cover_fract(4) = vegfract(veg_temperate_broadl_deciduous) - cover_fract(5) = vegfract(veg_evergreen_conifer) - cover_fract(6) = vegfract(veg_deciduous_conifer) - cover_fract(7) = vegfract(veg_raingreen_shrub) - cover_fract(8) = 0._dp - cover_fract(9) = vegfract_c3grass - cover_fract(10) = vegfract_c4grass - cover_fract(11) = vegfract(veg_tundra) - cover_fract(12) = 0._dp - cover_fract(13) = vegfract_crop - CASE (14) - cover_fract(1) = 0._dp - cover_fract(2) = vegfract(veg_tropical_evergreen) - cover_fract(3) = vegfract(veg_tropical_deciduous) - cover_fract(4) = vegfract(veg_temperate_broadl_evergreen) - cover_fract(5) = vegfract(veg_temperate_broadl_deciduous) - cover_fract(6) = vegfract(veg_evergreen_conifer) - cover_fract(7) = vegfract(veg_deciduous_conifer) - cover_fract(8) = vegfract(veg_raingreen_shrub) - cover_fract(9) = 0._dp - cover_fract(10)= vegfract_c3grass - cover_fract(11) = vegfract_c4grass - cover_fract(12) = vegfract(veg_tundra) - cover_fract(13) = 0._dp - cover_fract(14) = vegfract_crop - CASE DEFAULT - CALL hdlerr(1,'land cover: number of tiles not supported') - END SELECT - - ! cover fractions for grass-only or woods-only simulations - IF (grass_only) THEN - cover_fract(1:6) = 0._dp - IF (C3C4_flag == 1) THEN - cover_fract(7) = 1._dp - ELSE - cover_fract(8) = 1._dp - END IF - ELSE IF (woods_only) THEN - cover_fract(5:8) = 0._dp - IF (SUM(cover_fract(1:4)) <= small_fract) THEN - IF (ABS(lat) < 30._dp) THEN - cover_fract(1) = 1._dp - ELSE - cover_fract(3) = 1._dp - END IF - END IF - END IF - - END IF - -END SUBROUTINE calc_cover_fractions - -!------------------------------------------------------------------------------ -SUBROUTINE calc_cover_types (ntiles, lat, glac, vegfract, lc3c4crop, C3_crop, & - C4_crop, cover_type, second_woody, second_grass, dominant_crop, & - is_naturalveg) -!------------------------------------------------------------------------------ -! -! Routine to calculate land cover types depending on the number of tiles -! -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - IMPLICIT NONE - - !-- INTENT(IN) - INTEGER, INTENT(in) :: ntiles ! number of tiles - REAL(dp), INTENT(in) :: lat ! latitude - INTEGER, INTENT(in) :: glac ! glacier flag (1: glacier) - REAL(dp), INTENT(in) :: vegfract(nvegtyp) ! vegetated area fraction - LOGICAL, INTENT(in) :: lc3c4crop ! distinguish C3 and C4 crops - REAL(dp), INTENT(in) :: C3_crop - REAL(dp), INTENT(in) :: C4_crop - - !-- INTENT(OUT) - INTEGER, INTENT(out) :: cover_type(ntiles) - INTEGER, INTENT(out) :: second_woody, second_grass, dominant_crop - LOGICAL, INTENT(out) :: is_naturalveg(ntiles) - - !-- LOCAL - INTEGER :: k - INTEGER :: dominant_woody, dominant_grass - INTEGER :: dominant_pft(1) - REAL(dp) :: vegfract_woody - -!------------------------------------------------------------------------------ - - IF (nvegtyp /= 14) THEN - CALL hdlerr(1,'calc_cover_types: Routine for 14 vegetation types') - END IF - - !-- calculate woody fraction and grass fraction - - vegfract_woody = 0._dp - DO k=1,nwoody - vegfract_woody = vegfract_woody + vegfract(woody_types(k)) - END DO - - !-- find out most spread woody type - - dominant_woody = woody_types(1) - DO k = 2,nwoody - IF (vegfract(woody_types(k)) > vegfract(dominant_woody)) & - dominant_woody = woody_types(k) - END DO - - !-- find out second most spread woody type - - IF (woody_types(1) /= dominant_woody) THEN - second_woody = woody_types(1) - ELSE - second_woody = woody_types(2) - END IF - DO k = 1,nwoody - IF (vegfract(woody_types(k)) > vegfract(second_woody) .AND. & - woody_types(k) /= dominant_woody) second_woody = woody_types(k) - END DO - !substantial tundra is always represented - IF (dominant_woody /= veg_tundra .AND. vegfract(veg_tundra) > substantial_tundra) & - second_woody = veg_tundra - - !-- find out most and second most spread grass type - - IF (vegfract(veg_c3grass) > vegfract(veg_c4grass)) THEN - dominant_grass = veg_c3grass - second_grass = veg_c4grass - ELSE - dominant_grass = veg_c4grass - second_grass = veg_c3grass - END IF - - !-- find out most spread crop type - - IF (C3_crop > C4_crop .AND. C3_crop > small_fract) THEN - dominant_crop = lct_c3crop - ELSE IF (C4_crop > C3_crop .AND. C4_crop > small_fract) THEN - dominant_crop = lct_c4crop - ELSE IF (dominant_grass == veg_c3grass) THEN - dominant_crop = lct_c3crop - ELSE - dominant_crop = lct_c4crop - END IF - - !-- find out dominant type - - dominant_pft(:) = MAXLOC(vegfract(:)) - - !-- initialize natural vegetation flag - - IF (glac == 1) THEN - is_naturalveg(:) = .FALSE. - ELSE - is_naturalveg(:) = .TRUE. - END IF - - IF (ntiles == 1) THEN -!------------------------------------------------------------------------------ -! 1 tile: dominant PFT -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - ELSE - cover_type(1) = lct_evergreen_conifer - END IF - ELSE - !-- substantial vegetation - - cover_type(1) = lct(dominant_pft(1)) - - ENDIF - - ELSE IF (ntiles == 3) THEN -!------------------------------------------------------------------------------ -! 3 tiles: 1: woody -! 2: grasses -! 3: crops -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - cover_type(2) = lct_c3grass - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - cover_type(2) = lct_c4grass - ELSE - cover_type(1) = lct_evergreen_conifer - cover_type(2) = lct_c3grass - END IF - ELSE - - !-- substantial vegetation - - cover_type(1) = lct(dominant_woody) - cover_type(2) = lct(dominant_grass) - ENDIF - cover_type(3) = lct_crop - is_naturalveg(3) = .FALSE. - - ELSE IF (ntiles == 4) THEN -!------------------------------------------------------------------------------ -! 4 tiles: 1: woody -! 2: grasses -! 3: second tree or grass (depending on fraction) -! 4: crops -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - cover_type(2) = lct_c3grass - cover_type(3) = lct_evergreen_conifer - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - cover_type(2) = lct_c4grass - cover_type(3) = lct_tropical_evergreen - ELSE - cover_type(1) = lct_evergreen_conifer - cover_type(2) = lct_c3grass - cover_type(3) = lct_temperate_broadl_deciduous - END IF - ELSE - - !-- substantial vegetation - - cover_type(1) = lct(dominant_woody) - cover_type(2) = lct(dominant_grass) - IF (vegfract(second_woody) > vegfract(second_grass) & - .OR. vegfract(second_woody) > substantial_woody) THEN - cover_type(3) = lct(second_woody) - ELSE - cover_type(3) = lct(second_grass) - END IF - END IF - IF (lc3c4crop) THEN - cover_type(4) = dominant_crop - ELSE - cover_type(4) = lct_crop - END IF - is_naturalveg(4) = .FALSE. - - ELSE IF (ntiles == 5) THEN -!------------------------------------------------------------------------------ -! 5 tiles: 1: woody -! 2: grasses -! 3: second tree or grass (depending on fraction) -! 4: C3 crops -! 5: C4 crops -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - cover_type(2) = lct_c3grass - cover_type(3) = lct_evergreen_conifer - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - cover_type(2) = lct_c4grass - cover_type(3) = lct_tropical_evergreen - ELSE - cover_type(1) = lct_evergreen_conifer - cover_type(2) = lct_c3grass - cover_type(3) = lct_temperate_broadl_deciduous - END IF - ELSE - - !-- substantial vegetation - - cover_type(1) = lct(dominant_woody) - cover_type(2) = lct(dominant_grass) - IF (vegfract(second_woody) > vegfract(second_grass) & - .OR. vegfract(second_woody) > substantial_woody) THEN - cover_type(3) = lct(second_woody) - ELSE - cover_type(3) = lct(second_grass) - END IF - END IF - cover_type(4) = lct_c3crop - cover_type(5) = lct_c4crop - - is_naturalveg(4) = .FALSE. - is_naturalveg(5) = .FALSE. - - ELSE IF (ntiles == 6) THEN -!------------------------------------------------------------------------------ -! 6 tiles: 1: deciduous trees -! 2: eveergreen trees -! 3: shrub and tundra -! 4: C3 grasses and pasture -! 5: C4 grasses -! 6: crops -!------------------------------------------------------------------------------ - IF (glac == 1) THEN ! glacier - cover_type(1) = lct_glacier - cover_type(2) = lct_evergreen_conifer - cover_type(3) = lct_deciduous_shrub - - ELSE IF (MAXVAL(vegfract) <= small_fract * 10._dp) THEN - - !-- no substantial vegetation coverage - - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - cover_type(2) = lct_tropical_evergreen - cover_type(3) = lct_raingreen_shrub - ELSE IF (ABS(lat) < 60._dp) THEN - cover_type(1) = lct_temperate_broadl_deciduous - cover_type(2) = lct_temperate_broadl_evergreen - cover_type(3) = lct_deciduous_shrub - ELSE - cover_type(1) = lct_deciduous_conifer - cover_type(2) = lct_evergreen_conifer - cover_type(3) = lct_tundra - END IF - ELSE - - !-- substantial vegetation - - IF (vegfract(veg_tropical_deciduous) > vegfract(veg_temperate_broadl_deciduous) .AND. & - vegfract(veg_tropical_deciduous) > vegfract(veg_deciduous_conifer)) THEN - cover_type(1) = lct_tropical_deciduous - ELSE IF(vegfract(veg_temperate_broadl_deciduous) > vegfract(veg_tropical_deciduous) .AND. & - vegfract(veg_temperate_broadl_deciduous) >= vegfract(veg_deciduous_conifer)) THEN - cover_type(1) = lct_temperate_broadl_deciduous - ELSE IF(vegfract(veg_deciduous_conifer) > vegfract(veg_tropical_deciduous) .AND. & - vegfract(veg_deciduous_conifer) > vegfract(veg_temperate_broadl_deciduous)) THEN - cover_type(1) = lct_deciduous_conifer - ELSE - IF (ABS(lat) < 30._dp) THEN - cover_type(1) = lct_tropical_deciduous - ELSE - cover_type(1) = lct_temperate_broadl_deciduous - END IF - END IF - - IF (vegfract(veg_tropical_evergreen) > vegfract(veg_temperate_broadl_evergreen) .AND. & - vegfract(veg_tropical_evergreen) > vegfract(veg_evergreen_conifer)) THEN - cover_type(2) = lct_tropical_evergreen - ELSE IF(vegfract(veg_temperate_broadl_evergreen) >= vegfract(veg_tropical_evergreen) .AND. & - vegfract(veg_temperate_broadl_evergreen) > vegfract(veg_evergreen_conifer)) THEN - cover_type(2) = lct_temperate_broadl_evergreen - ELSE IF(vegfract(veg_evergreen_conifer) >= vegfract(veg_tropical_evergreen) .AND. & - vegfract(veg_evergreen_conifer) >= vegfract(veg_temperate_broadl_evergreen)) THEN - cover_type(2) = lct_evergreen_conifer - END IF - - IF (vegfract(veg_raingreen_shrub) > vegfract(veg_deciduous_shrub) .AND. & - vegfract(veg_raingreen_shrub) > vegfract(veg_tundra)) THEN - cover_type(3) = lct_raingreen_shrub - ELSE IF(vegfract(veg_deciduous_shrub) >= vegfract(veg_raingreen_shrub) .AND. & - vegfract(veg_deciduous_shrub) >= vegfract(veg_tundra)) THEN - cover_type(3) = lct_deciduous_shrub - ELSE IF(vegfract(veg_tundra) >= vegfract(veg_raingreen_shrub) .AND. & - vegfract(veg_tundra) > vegfract(veg_deciduous_shrub)) THEN - cover_type(3) = lct_tundra - END IF - END IF - cover_type(4) = lct_c3grass - cover_type(5) = lct_c4grass - IF (lc3c4crop) THEN - cover_type(6) = dominant_crop - ELSE - cover_type(6) = lct_crop - ENDIF - is_naturalveg(6) = .FALSE. - - ELSE IF (ntiles == 8) THEN -!------------------------------------------------------------------------------ -! 8 tiles: 1: tropical broadleaf evergreen 7: C3 grass -! 2: tropical broadleaf deciduous 8: C4 grass -! 3: extra-tropical evergreen -! 4: extra-tropical deciduous -! 5: raingreen shrubs -! 6: deciduous shrubs -!------------------------------------------------------------------------------ - IF (glac == 1) THEN - cover_type(1) = lct_glacier - ELSE - cover_type(1) = lct_tropical_evergreen - ENDIF - cover_type(2) = lct_tropical_deciduous - cover_type(3) = lct_extratrop_evergreen - cover_type(4) = lct_extratrop_deciduous - cover_type(5) = lct_raingreen_shrub - cover_type(6) = lct_deciduous_shrub - cover_type(7) = lct_c3grass - cover_type(8) = lct_c4grass - - ELSE IF (ntiles == 9) THEN -!------------------------------------------------------------------------------ -! 9 tiles: 1: glacier 8: C3 grass -! 2: tropical broadleaf evergreen 9: C4 grass -! 3: tropical broadleaf deciduous -! 4: extra-tropical evergreen -! 5: extra-tropical deciduous -! 6: raingreen shrubs -! 7: deciduous shrubs -!------------------------------------------------------------------------------ - cover_type(1) = lct_glacier - cover_type(2) = lct_tropical_evergreen - cover_type(3) = lct_tropical_deciduous - cover_type(4) = lct_extratrop_evergreen - cover_type(5) = lct_extratrop_deciduous - cover_type(6) = lct_raingreen_shrub - cover_type(7) = lct_deciduous_shrub - cover_type(8) = lct_c3grass - cover_type(9) = lct_c4grass - - glacier_tile = 1 - is_naturalveg(1) = .FALSE. - - ELSE IF (ntiles == 10) THEN -!------------------------------------------------------------------------------ -! 10 tiles: 1: tropical broadleaf evergreen 7: C3 grass -! 2: tropical broadleaf deciduous 8: C4 grass -! 3: extra-tropical evergreen 9: C3 crops -! 4: extra-tropical deciduous 10: C4 crops -! 5: raingreen shrubs -! 6: deciduous shrubs -!------------------------------------------------------------------------------ - IF (glac == 1) THEN - cover_type(1) = lct_glacier - ELSE - cover_type(1) = lct_tropical_evergreen - ENDIF - cover_type(2) = lct_tropical_deciduous - cover_type(3) = lct_extratrop_evergreen - cover_type(4) = lct_extratrop_deciduous - cover_type(5) = lct_raingreen_shrub - cover_type(6) = lct_deciduous_shrub - cover_type(7) = lct_c3grass - cover_type(8) = lct_c4grass - cover_type(9) = lct_c3crop - cover_type(10)= lct_c4crop - - is_naturalveg(9) = .FALSE. - is_naturalveg(10) = .FALSE. - - ELSE IF (ntiles == 11) THEN -!------------------------------------------------------------------------------ -! 11 tiles: 1: tropical broadleaf evergreen 7: C3 grass -! 2: tropical broadleaf deciduous 8: C4 grass -! 3: extra-tropical evergreen 9: C3 pasture -! 4: extra-tropical deciduous 10: C4 pasture -! 5: raingreen shrubs 11: C3/C4 crop -! 6: deciduous shrubs -!------------------------------------------------------------------------------ - IF (glac == 1) THEN - cover_type(1) = lct_glacier - ELSE - cover_type(1) = lct_tropical_evergreen - END IF - cover_type(2) = lct_tropical_deciduous - cover_type(3) = lct_extratrop_evergreen - cover_type(4) = lct_extratrop_deciduous - cover_type(5) = lct_raingreen_shrub - cover_type(6) = lct_deciduous_shrub - cover_type(7) = lct_c3grass - cover_type(8) = lct_c4grass - cover_type(9) = lct_c3pasture - cover_type(10)= lct_c4pasture - cover_type(11)= dominant_crop - - is_naturalveg(9) = .FALSE. - is_naturalveg(10) = .FALSE. - is_naturalveg(11) = .FALSE. - - ELSE IF (ntiles == 12) THEN -!------------------------------------------------------------------------------ -! 12 tiles: 1: glacier 7: deciduous shrubs -! 2: tropical broadleaf evergreen 8: C3 grass -! 3: tropical broadleaf deciduous 9: C4 grass -! 4: extra-tropical evergreen 10: C3 pasture -! 5: extra-tropical deciduous 11: C4 pasture -! 6: raingreen shrubs 12: C3/C4 crop -! -!------------------------------------------------------------------------------ - cover_type(1) = lct_glacier - cover_type(2) = lct_tropical_evergreen - cover_type(3) = lct_tropical_deciduous - cover_type(4) = lct_extratrop_evergreen - cover_type(5) = lct_extratrop_deciduous - cover_type(6) = lct_raingreen_shrub - cover_type(7) = lct_deciduous_shrub - cover_type(8) = lct_c3grass - cover_type(9) = lct_c4grass - cover_type(10)= lct_c3pasture - cover_type(11)= lct_c4pasture - cover_type(12)= dominant_crop - - glacier_tile = 1 - is_naturalveg(1) = .FALSE. - is_naturalveg(10) = .FALSE. - is_naturalveg(11) = .FALSE. - is_naturalveg(12) = .FALSE. - - ELSE IF (ntiles == 13) THEN -!------------------------------------------------------------------------------ -! 13 tiles: 1: tropical broadleaf evergreen 8: deciduous shrubs -! 2: tropical broadleaf deciduous 9: C3 grass -! 3: temperate broadleaf evergreen 10: C4 grass -! 4: temperate broadleaf deciduous 11: tundra -! 5: evergreen coniferous 12: swamps -! 6: deciduous coniferous 13: crops -! 7: raingreen shrubs -!------------------------------------------------------------------------------ - IF (glac == 1) THEN - cover_type(1) = lct_glacier - ELSE - cover_type(1) = lct_tropical_evergreen - END IF - cover_type(2) = lct_tropical_deciduous - cover_type(3) = lct_temperate_broadl_evergreen - cover_type(4) = lct_temperate_broadl_deciduous - cover_type(5) = lct_evergreen_conifer - cover_type(6) = lct_deciduous_conifer - cover_type(7) = lct_raingreen_shrub - cover_type(8) = lct_deciduous_shrub - cover_type(9) = lct_c3grass - cover_type(10)= lct_c4grass - cover_type(11)= lct_tundra - cover_type(12)= lct_swamp - cover_type(13)= lct_crop - - is_naturalveg(13) = .FALSE. - - ELSE IF (ntiles == 14) THEN -!------------------------------------------------------------------------------ -! 14 tiles: 1: glacier 8: raingreen shrubs -! 2: tropical broadleaf evergreen 9: deciduous shrubs -! 3: tropical broadleaf deciduous 10: C3 grass -! 4: temperate broadleaf evergreen 11: C4 grass -! 5: temperate broadleaf deciduous 12: tundra -! 6: evergreen coniferous 13: swamps -! 7: deciduous coniferous 14: crops -! -!------------------------------------------------------------------------------ - cover_type(1) = lct_glacier - cover_type(2) = lct_tropical_evergreen - cover_type(3) = lct_tropical_deciduous - cover_type(4) = lct_temperate_broadl_evergreen - cover_type(5) = lct_temperate_broadl_deciduous - cover_type(6) = lct_evergreen_conifer - cover_type(7) = lct_deciduous_conifer - cover_type(8) = lct_raingreen_shrub - cover_type(9) = lct_deciduous_shrub - cover_type(10)= lct_c3grass - cover_type(11)= lct_c4grass - cover_type(12)= lct_tundra - cover_type(13)= lct_swamp - cover_type(14)= lct_crop - - glacier_tile = 1 - is_naturalveg(1) = .FALSE. - is_naturalveg(14) = .FALSE. - - ELSE - CALL hdlerr(1,'calc_cover_types: number of tiles not supported') - END IF - - IF (ANY(cover_type(:) == 0)) THEN - CALL hdlerr(1,'a cover type is 0. Possible reason: ' & - //'lct definitions do not match this routine') - END IF - -END SUBROUTINE calc_cover_types - -!------------------------------------------------------------------------------ -SUBROUTINE harmonize_fractions(ntiles, is_naturalveg, glac, natural_veg, cover_fract) -!------------------------------------------------------------------------------ -! -! !DESCRIPTION: -! -! Rescaling of cover fractions to assure that potential natural vegetation -! is greater or equal than the actual natural vegetation on all tiles. -! -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - IMPLICIT NONE -! -! !INPUT PARAMETERS: -! - INTEGER, INTENT(in) :: ntiles ! number of tiles - INTEGER, INTENT(in) :: glac ! glacier flag (1:glacier) - LOGICAL, INTENT(in) :: is_naturalveg(ntiles) ! flag for natural vegetation - REAL(dp), INTENT(inout) :: natural_veg(ntiles) ! potentially vegetated fraction - ! of natural vegetation types -! -! !IN- and OUTPUT PARAMETERS: -! - REAL(dp), INTENT(inout) :: cover_fract(ntiles) ! vegetated fraction - -! !LOCAL PARAMETERS - INTEGER :: i - REAL(dp) :: delta(ntiles) ! missmach of actual and potential natural types -!------------------------------------------------------------------------------ - - ! glacier points need not be regarded - - IF (glac == 1) RETURN - - delta(:) = 0._dp - WHERE (is_naturalveg) - delta(:) = cover_fract(:) - natural_veg(:) - cover_fract(:) = MIN(cover_fract(:),natural_veg(:)) - END WHERE - - ! Due to the pasture rule, in cells with pastures actual grass fractions are - ! disproportionately smaller than potential grass fractions. The relative - ! scaling in scale_cover_fract can lead to slightly greater fractions of the - ! remaining natural vegetation types if called for cover_fract (in comparison - ! to scale_cover_fract calls for natural_veg). - ! Thus calls to scale_cover_fract can distroy the harmonization just achieved. - ! We thus have to assure here, that no further calls of scale_cover_fract are - ! needed. - ! We add the missmatch (actual natural vegetation fraction is slightly - ! greater than the potential fraction) to the dominant natural grass types. - - DO i = 1, ntiles - IF (delta(i) > 0._dp) THEN - IF (cover_fract(veg_c3grass) > cover_fract(veg_c4grass)) THEN - cover_fract(veg_c3grass) = cover_fract(veg_c3grass) + delta(i) - ELSE - cover_fract(veg_c4grass) = cover_fract(veg_c4grass) + delta(i) - END IF - END IF - END DO - -END SUBROUTINE harmonize_fractions - -!------------------------------------------------------------------------------ -SUBROUTINE scale_cover_fract (ntiles, is_naturalveg, glac, cover_fract) -!------------------------------------------------------------------------------ -! -! !DESCRIPTION: -! -! Rescaling of cover fractions to assure that -! - the sum of cover fractions is one -! - all non-glacier grid cells have at least a minimum vegetated fraction -! -! This is not a copy of the current jsbach routine in mo_land_surface. -!------------------------------------------------------------------------------ - USE mo_kinds - USE mo_vegparams - IMPLICIT NONE -! -! !INPUT PARAMETERS: -! - INTEGER, INTENT(in) :: ntiles ! number of tiles - INTEGER, INTENT(in) :: glac ! glacier flag (1:glacier) - LOGICAL, INTENT(in) :: is_naturalveg(ntiles) ! flag for natural vegetation -! -! !IN- and OUTPUT PARAMETERS: -! - REAL(dp), INTENT(inout) :: cover_fract(ntiles) ! vegetated fraction - -! !LOCAL VARIABLES: -! - INTEGER :: i, iter - INTEGER :: niter ! number of iterations needed - INTEGER :: nsparce ! number of PFTs with a vegetated fraction of less then small_fract - INTEGER :: nsparce_anthro ! number of non natural PFTs with a vegetated fraction < small_fract - INTEGER :: nnatural ! number natural PFTs - REAL(dp) :: sum_fract ! sum of all cover fractions - REAL(dp) :: excluded_fract ! sum of all cover fractions - -!------------------------------------------------------------------------------ - - ! cover fractions of glacier points have already been set in calc_cover_fract - - IF (glac == 1) RETURN - - ! Make sure, crop and pasture have a cover fraction of at least small_fract - - WHERE (.NOT. is_naturalveg) - cover_fract(:) = MAX(small_fract,cover_fract(:)) - END WHERE - - ! If there is a tile reserved for glaciers, it's fractions need to be 0 on non glacier points - - IF (glacier_tile /= -1) THEN - cover_fract(glacier_tile) = 0._dp - END IF - - ! Crops and pastures only need to be scaled if their total fraction is greater than - ! 1-nnatural*small_fract. - - excluded_fract = SUM(cover_fract(:), MASK = .NOT. is_naturalveg) - nnatural = 0 - nsparce_anthro = 0 - DO i = 1, ntiles - IF (is_naturalveg(i) .AND. glacier_tile /= i) THEN - nnatural = nnatural + 1 - END IF - IF (.NOT. is_naturalveg(i) .AND. cover_fract(i) <= small_fract .AND. glacier_tile /= i) THEN - nsparce_anthro = nsparce_anthro + 1 - END IF - END DO - IF (excluded_fract > 1._dp - REAL(nnatural+nsparce_anthro,dp)*small_fract) THEN - WHERE (.NOT. is_naturalveg .AND. cover_fract(:) > small_fract) - cover_fract(:) = cover_fract(:) * (1._dp - REAL(nnatural+nsparce_anthro,dp)*small_fract) & - / (excluded_fract-REAL(nsparce_anthro,dp)*small_fract) - - END WHERE - END IF - - ! Scale the natural vegetation that there is a minimum cover fraction of small_fract on all - ! tiles and the total cover fraction is 1. - - niter = ntiles ! to assure binary identical fractions whether or not - IF (glacier_tile /= -1) niter = niter - 1 ! a glacier tile is used, the niter has to be fix. - DO iter = 1, niter - - sum_fract = 0._dp - excluded_fract = 0._dp - nsparce = 0 - - DO i = 1,ntiles - IF (cover_fract(i) > small_fract .AND. is_naturalveg(i)) THEN - sum_fract = sum_fract + cover_fract(i) - ELSE IF (is_naturalveg(i)) THEN - nsparce = nsparce + 1 - ELSE - excluded_fract = excluded_fract + cover_fract(i) - END IF - END DO - DO i = 1,ntiles - IF (cover_fract(i) > small_fract .AND. is_naturalveg(i)) THEN - cover_fract(i) = cover_fract(i) * (1._dp - excluded_fract - REAL(nsparce,dp)*small_fract) / sum_fract - ELSE IF (glacier_tile == i) THEN - cover_fract(i) = 0._dp - ELSE IF (is_naturalveg(i)) THEN - cover_fract(i) = small_fract - ELSE - cover_fract(i) = MAX(small_fract,cover_fract(i)) - END IF - END DO - - END DO - - IF (ANY(cover_fract(:) < small_fract) .AND. glacier_tile == -1) THEN - WRITE(*,*) 'cover_fract still smaller ', small_fract, ' after ', niter, ' iterations:', & - MINVAL(cover_fract(:)), ' (tile: ', MINLOC(cover_fract(:)), ')' - STOP 1 - END IF - - IF (SUM(cover_fract(:)) > 1._dp + REAL(ntiles,dp)*EPSILON(1._dp) .OR. & - SUM(cover_fract(:)) < 1._dp - REAL(ntiles,dp)*EPSILON(1._dp)) THEN - WRITE(*,*) 'SUM(cover_fract) differs from 1: ', SUM(cover_fract(:)) - STOP 1 - END IF - -END SUBROUTINE scale_cover_fract - -!------------------------------------------------------------------------------ -SUBROUTINE put_lct_attributes(ncout, varid) -!------------------------------------------------------------------------------ -! -! Write attributes for land cover types -! -!------------------------------------------------------------------------------ - USE mo_vegparams - IMPLICIT NONE - include 'netcdf.inc' - - !-- INTENT(in) - INTEGER, INTENT(IN) :: ncout, varid - - !-- INTENT(out) - - !-- LOCAL - INTEGER :: stat - CHARACTER(5) :: attnam -!------------------------------------------------------------------------------ - - stat = nf_put_att_text(ncout,varid,'long_name',15,'land cover type') - CALL hdlerr(stat,'put_lct_attributes: long_name') - stat = nf_put_att_text(ncout,varid,'units',1,'1') - CALL hdlerr(stat,'put_lct_attributes: units') - - IF (lct_glacier /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_glacier - stat = nf_put_att_text(ncout,varid,attnam, 7,'glacier') - CALL hdlerr(stat,'put_lct_attributes: lct_glacier') - END IF - IF (lct_tropical_evergreen /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_tropical_evergreen - stat = nf_put_att_text(ncout,varid,attnam,28,'tropical broadleaf evergreen') - CALL hdlerr(stat,'put_lct_attributes: lct_tropical_evergreen') - END IF - IF (lct_tropical_deciduous /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_tropical_deciduous - stat = nf_put_att_text(ncout,varid,attnam,28,'tropical broadleaf deciduous') - CALL hdlerr(stat,'put_lct_attributes: lct_tropical_deciduous') - END IF - IF (lct_extratrop_evergreen /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_extratrop_evergreen - stat = nf_put_att_text(ncout,varid,attnam,24,'extra-tropical evergreen') - CALL hdlerr(stat,'put_lct_attributes: lct_extratrop_evergreen') - END IF - IF (lct_extratrop_deciduous /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_extratrop_deciduous - stat = nf_put_att_text(ncout,varid,attnam,24,'extra-tropical deciduous') - CALL hdlerr(stat,'put_lct_attributes: lct_extratrop_deciduous') - END IF - IF (lct_temperate_broadl_evergreen /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_temperate_broadl_evergreen - stat = nf_put_att_text(ncout,varid,attnam,29,'temperate broadleaf evergreen') - CALL hdlerr(stat,'put_lct_attributes: lct_temperate_broadl_evergreen') - END IF - IF (lct_temperate_broadl_deciduous /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_temperate_broadl_deciduous - stat = nf_put_att_text(ncout,varid,attnam,29,'temperate broadleaf deciduous') - CALL hdlerr(stat,'put_lct_attributes: lct_temperate_broadl_deciduous') - END IF - IF (lct_evergreen_conifer /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_evergreen_conifer - stat = nf_put_att_text(ncout,varid,attnam,20,'evergreen coniferous') - CALL hdlerr(stat,'put_lct_attributes: lct_evergreen_conifer') - END IF - IF (lct_deciduous_conifer /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_deciduous_conifer - stat = nf_put_att_text(ncout,varid,attnam,20,'deciduous coniferous') - CALL hdlerr(stat,'put_lct_attributes: lct_deciduous_conifer') - END IF - IF (lct_raingreen_shrub /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_raingreen_shrub - stat = nf_put_att_text(ncout,varid,attnam,16,'raingreen shrubs') - CALL hdlerr(stat,'put_lct_attributes: lct_raingreen_shrub') - END IF - IF (lct_deciduous_shrub /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_deciduous_shrub - stat = nf_put_att_text(ncout,varid,attnam,16,'deciduous shrubs') - CALL hdlerr(stat,'put_lct_attributes: lct_deciduous_shrub') - END IF - IF (lct_c3grass /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c3grass - stat = nf_put_att_text(ncout,varid,attnam, 8,'C3 grass') - CALL hdlerr(stat,'put_lct_attributes: lct_c3grass') - END IF - IF (lct_c4grass /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c4grass - stat = nf_put_att_text(ncout,varid,attnam, 8,'C4 grass') - CALL hdlerr(stat,'put_lct_attributes: lct_c4gras') - END IF - IF (lct_c3pasture /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c3pasture - stat = nf_put_att_text(ncout,varid,attnam,10,'C3 pasture') - CALL hdlerr(stat,'put_lct_attributes: lct_c3pasture') - END IF - IF (lct_c4pasture /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c4pasture - stat = nf_put_att_text(ncout,varid,attnam,10,'C4 pasture') - CALL hdlerr(stat,'put_lct_attributes: lct_c4pasture') - END IF - IF (lct_tundra /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_tundra - stat = nf_put_att_text(ncout,varid,attnam, 6,'tundra') - CALL hdlerr(stat,'put_lct_attributes: lct_tundra') - END IF - IF (lct_swamp /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_swamp - stat = nf_put_att_text(ncout,varid,attnam, 5,'swamp') - CALL hdlerr(stat,'put_lct_attributes: lct_swamp') - END IF - IF (lct_crop /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_crop - stat = nf_put_att_text(ncout,varid,attnam, 5,'crops') - CALL hdlerr(stat,'put_lct_attributes: lct_crop') - END IF - IF (lct_c3crop /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c3crop - stat = nf_put_att_text(ncout,varid,attnam, 8,'C3 crops') - CALL hdlerr(stat,'put_lct_attributes: lct_c3crop') - END IF - IF (lct_c4crop /= 0) THEN - WRITE(attnam,'(a3,i2.2)') 'lct', lct_c4crop - stat = nf_put_att_text(ncout,varid,attnam, 8,'C4 crops') - CALL hdlerr(stat,'put_lct_attributes: lct_c4crop') - END IF - -END SUBROUTINE put_lct_attributes - -!------------------------------------------------------------------------------ -SUBROUTINE gauaw (pa, pw, nlat, api) -!------------------------------------------------------------------------------ - !-- copied from echam - - ! Description: - ! - ! Compute abscissas and weights for Gaussian integration. - ! - USE mo_kinds - IMPLICIT NONE - - INTEGER :: nlat - REAL(dp) :: pa(nlat), pw(nlat) - REAL(dp) :: api - - REAL(dp), PARAMETER :: epsil = EPSILON(0.0_dp) - INTEGER, PARAMETER :: itemax = 20 - - INTEGER :: iter, ins2, isym, jn, jgl - REAL(dp) :: za, zw, z, zan - REAL(dp) :: zk, zkm1, zkm2, zx, zxn, zldn, zmod - - ! Intrinsic functions - INTRINSIC ABS, COS, MOD, TAN - - ins2 = nlat/2+MOD(nlat,2) - - DO jgl = 1, ins2 - z = REAL(4 * jgl - 1) * api / REAL(4 * nlat + 2) - pa(jgl) = COS(z + 1._dp / (TAN(z) * REAL(8 * nlat**2))) - END DO - - DO jgl = 1, ins2 - - za = pa(jgl) - - DO iter = 1, itemax+1 - zk = 0._dp - - zkm2 = 1._dp - zkm1 = za - zx = za - DO jn = 2, nlat - zk = (REAL(2 * jn - 1) * zx * zkm1 - REAL(jn - 1) * zkm2) / REAL(jn) - zkm2 = zkm1 - zkm1 = zk - END DO - zkm1 = zkm2 - zldn = (REAL(nlat) * (zkm1 - zx * zk)) / (1._dp - zx * zx) - zmod = -zk / zldn - zxn = zx + zmod - zan = zxn - - zkm2 = 1._dp - zkm1 = zxn - zx = zxn - DO jn = 2,nlat - zk = (REAL(2 * jn - 1) * zx * zkm1 - REAL(jn - 1) * zkm2) / REAL(jn) - zkm2 = zkm1 - zkm1 = zk - END DO - zkm1 = zkm2 - zw = (1._dp - zx * zx) / (REAL(nlat * nlat) * zkm1 * zkm1) - za = zan - IF (ABS(zmod) <= epsil) EXIT - END DO - - pa(jgl) = zan - pw(jgl) = 2._dp * zw - - ENDDO - - DO jgl = 1, nlat/2 - isym = nlat - jgl + 1 - pa(isym) = -pa(jgl) - pw(isym) = pw(jgl) - ENDDO - -END SUBROUTINE gauaw - -!------------------------------------------------------------------------------ -SUBROUTINE extrap(nlon, nlat, lon, lat, mask, missval, method, val) -!------------------------------------------------------------------------------ -! Extrapolation to grid cells with missing values -! -! extrapolation methods (argument method): -! -! nneigh: use value of the nearest neighbor only -! mean: distance weighted mean of neighboring cells -! modal: modal value of neighboring cells, ignoring the distance. This -! only works for integers (technically defined as real). -! -! search for neighbors takes place in a square around the grid cell, with the -! radius being increased until valid neighbors are found. -! This is not optimal for large radii and/or high latitudes, as diagonal -! neighbors in a greater distance might be taken into account while closer -! cells to the east and west might not. -! -!------------------------------------------------------------------------------ - USE mo_kinds - IMPLICIT NONE - - INTEGER, INTENT(in) :: nlon, nlat ! dimensions - REAL(dp), INTENT(in) :: lon(nlon), lat(nlat) ! longitudes, latitudes - REAL(dp), INTENT(in) :: mask(nlon,nlat) ! land sea /glacier mask - REAL(dp), INTENT(in) :: missval ! value for missing data - CHARACTER(*), INTENT(in) :: method ! extrapolation method: nneigh, mean, modal - REAL(dp), INTENT(inout) :: val(nlon,nlat) ! array to be extrapolated - - REAL(dp), PARAMETER :: deg2rad = 1.74532925199432957692e-2 ! Degree to rad: 2pi/360 - - INTEGER :: i, j ! looping index of global grid - INTEGER :: ip, im, jp, jm, ii, jj - INTEGER :: ni, nj ! looping index on neighbors array - INTEGER :: m ! iteration counter - INTEGER :: mmax ! maximum number of iterations - INTEGER :: mini, maxi ! minimum, maximum value - INTEGER :: nval ! number of different values - INTEGER :: loc(2) ! location of nearest neighbor - LOGICAL :: filled ! flag to indicate if gap is filled - REAL(dp) :: x1, y1, z1, x2, y2, z2 ! x,y,z-coordinates - REAL(dp) :: dx ! distance - REAL(dp) :: lon_ctl, lat_ctl ! coordinates of missing cell - REAL(dp) :: lon_nbr, lat_nbr ! coordinates of neighboring cell - REAL(dp) :: sum_dist ! sum of distances of the neighbors - REAL(dp) :: val_new(nlon,nlat) ! filled array (no missing values on land) - REAL(dp), ALLOCATABLE :: neighbours_val(:,:) ! value on neighbors array - REAL(dp), ALLOCATABLE :: neighbours_lon(:,:) ! corresponding longitude - REAL(dp), ALLOCATABLE :: neighbours_lat(:,:) ! corresponding latitude - REAL(dp), ALLOCATABLE :: neighbours_dist(:,:) ! distance of the neighbor - REAL(dp), ALLOCATABLE :: count_values(:) ! array to count different values - - DO i = 1, nlon - DO j = 1, nlat - - ! gap on non-glacier land grid cell - IF (mask(i,j) > 0._dp .AND. val(i,j) == missval) THEN - - ! check neighboring grid cells - - ! initializations - ip = i - im = i - jp = j - jm = j - - m=1 - mmax = nlat ! maximum number of iterations - filled = .FALSE. - - sum_dist = 0._dp - - DO WHILE (.NOT. filled) - - ip = ip+1 - im = im-1 - jp = MIN(jp+1, nlat) - jm = MAX(jm-1, 1) - - ALLOCATE(neighbours_val(ip-im+1,jp-jm+1)) - ALLOCATE(neighbours_lon(ip-im+1,jp-jm+1)) - ALLOCATE(neighbours_lat(ip-im+1,jp-jm+1)) - ALLOCATE(neighbours_dist(ip-im+1,jp-jm+1)) - - DO ni = 1, ip-im+1 ! index on neighbors array - DO nj = 1, jp-jm+1 - ii = im + ni - 1 ! index on global grid - jj = jm + nj - 1 - - IF (ii <= 0) ii = ii + nlon - IF (ii > nlon) ii = ii - nlon - - neighbours_lon(ni,nj) = lon(ii) - neighbours_lat(ni,nj) = lat(jj) - neighbours_val(ni,nj) = val(ii,jj) - END DO - END DO - - IF ( ANY(neighbours_val(:,:) /= missval) ) THEN - SELECT CASE (method) - CASE ('modal') - mini = NINT(MINVAL(neighbours_val(:,:), MASK=neighbours_val(:,:)/=missval)) - maxi = NINT(MAXVAL(neighbours_val(:,:), MASK=neighbours_val(:,:)/=missval)) - ALLOCATE (count_values(maxi-mini+1)) - count_values(:) = 0 - DO nval = mini, maxi - DO ni = 1, ip-im+1 - DO nj = 1, jp-jm+1 ! index on neighbors array - IF (NINT(neighbours_val(ni,nj)) == nval) & - count_values(nval-mini+1) = count_values(nval-mini+1) + 1 - END DO - END DO - END DO - val_new(i,j) = MAXLOC(count_values(:), DIM=1) + mini - 1 - DEALLOCATE (count_values) - - CASE ('nneigh', 'mean') - lon_ctl = lon(i) * deg2rad ! central longitude [rad] - lat_ctl = lat(j) * deg2rad ! central latitude [rad] - - DO nj = 1, jp-jm+1 ! index on neighbors array - DO ni = 1, ip-im+1 - - IF (neighbours_val(ni,nj) /= missval) THEN - - lon_nbr = neighbours_lon(ni,nj) * deg2rad ! lon of neighbor [rad] - lat_nbr = neighbours_lat(ni,nj) * deg2rad ! lat of neighbor [rad] - - ! Transformation to x,y,z-coordinates - - x1 = cos(lat_ctl)*cos(lon_ctl) - y1 = cos(lat_ctl)*sin(lon_ctl) - z1 = sin(lat_ctl) - - x2 = cos(lat_nbr)*cos(lon_nbr) - y2 = cos(lat_nbr)*sin(lon_nbr) - z2 = sin(lat_nbr) - - ! direct distance - dx = SQRT((x2-x1)**2 + (y2-y1)**2 + (z2-z1)**2) - - ! distance along the surface - dx = 2*ASIN(dx/2) - - neighbours_dist(ni,nj) = dx - sum_dist = sum_dist + neighbours_dist(ni,nj) - ELSE - neighbours_dist(ni,nj) = 0._dp - END IF - END DO - END DO - IF (method == 'nneigh') THEN - loc(:) = MINLOC(neighbours_dist(:,:), MASK=neighbours_dist(:,:) /= 0._dp) - val_new(i,j) = neighbours_val(loc(1),loc(2)) - ELSE IF (method == 'mean') THEN - val_new(i,j) = SUM(neighbours_val(:,:) * neighbours_dist(:,:)/sum_dist) - END IF - - CASE default - CALL hdlerr(1, "extrapolation method not supported") - END SELECT - filled = .TRUE. - - ELSE - IF (m >= mmax) CALL hdlerr(1, "Not enough iterations for extrapolation") - m = m + 1 - END IF - - DEALLOCATE(neighbours_val) - DEALLOCATE(neighbours_lon) - DEALLOCATE(neighbours_lat) - DEALLOCATE(neighbours_dist) - - END DO - ELSE - IF (mask(i,j) == 0._dp) THEN - val_new(i,j) = 0._dp - ELSE - val_new(i,j) = val(i,j) - END IF - END IF - END DO - END DO - val(:,:)=val_new(:,:) - -END SUBROUTINE extrap - -!------------------------------------------------------------------------------ -SUBROUTINE open_file(info, infile, ncin, ret_stat) -!------------------------------------------------------------------------------ -! -! Routine to open a netcdf file as read only input file -! -!------------------------------------------------------------------------------ - IMPLICIT NONE - - include 'netcdf.inc' - - !-- INTENT(in) - CHARACTER*100, INTENT(IN) :: infile - LOGICAL, INTENT(IN) :: info - - !-- INTENT(out) - INTEGER, INTENT(OUT) :: ncin - INTEGER, INTENT(OUT), OPTIONAL :: ret_stat - - !-- LOCAL - INTEGER :: stat -!------------------------------------------------------------------------------ - - stat=nf_open(infile, NF_NOWRITE, ncin) - IF (PRESENT(ret_stat) .AND. stat /= NF_NOERR) THEN - ret_stat = stat - RETURN - ENDIF - CALL hdlerr(stat,'opening file '//infile) - IF (info) WRITE(*,*) ' File ', TRIM(infile),' opened' - -END SUBROUTINE open_file - -!------------------------------------------------------------------------------ -SUBROUTINE check_dimensions (varname, ncin, varid, nlon, nlat, ntiles, nlct, & - nvegtyp, nsoil, ntime) -!------------------------------------------------------------------------------ -! -! Routine to find dimensions of an input variable and to compare them with the -! dimensions defined in the output file -! -!------------------------------------------------------------------------------ - IMPLICIT NONE - - include 'netcdf.inc' - - !-- INTENT(in) - CHARACTER*30, INTENT(in) :: varname - INTEGER, INTENT(in) :: ncin, nlon, nlat, ntiles, nlct, nvegtyp, nsoil, ntime - - - !-- INTENT(out) - INTEGER, INTENT(out) :: varid - -!-- LOCAL - INTEGER :: stat, len, dim, ndims - INTEGER, ALLOCATABLE :: dimids(:) - CHARACTER*30 :: dimname -!------------------------------------------------------------------------------ - - stat=nf_inq_varid(ncin, varname, varid) - CALL hdlerr(stat,'check_dimensions: inq. varid of '//varname) - - stat=nf_inq_varndims(ncin, varid, ndims) - CALL hdlerr(stat,'check_dimensions: inq. ndims of '//varname) - - ALLOCATE(dimids(ndims)) - stat=nf_inq_vardimid(ncin, varid, dimids(:)) - CALL hdlerr(stat,'check_dimensions: inq. dimids of '//varname) - - DO dim=1,ndims - stat=nf_inq_dim(ncin, dimids(dim), dimname, len) - CALL hdlerr(stat,'check_dimensions: inq. dim of '//varname) - IF (dimname == 'lon') THEN - IF (nlon /= len) WRITE (*,*) 'Dimension error: nlon=',nlon,' len=', len - ELSE IF (dimname == 'lat') THEN - IF (nlat /= len) WRITE (*,*) 'Dimension error: nlat=',nlat,' len=', len - ELSE IF (dimname == 'level') THEN - IF (1 /= len) WRITE (*,*) 'Dimension error: nlevel=', 1,' len=', len - ELSE IF (dimname == 'lct') THEN - IF (nlct /= len) WRITE (*,*) 'Dimension error: nlct=',nlct,' len=', len - ELSE IF (dimname == 'ntiles') THEN - IF (ntiles /= len) WRITE (*,*) 'Dimension error: ntiles=',ntiles,' len=', len - ELSE IF (dimname == 'soillev') THEN - IF (nsoil /= len) WRITE (*,*) 'Dimension error: soillev=',nsoil,' len=', len - ELSE IF (dimname == 'time') THEN - IF (ntime /= len .AND. len /= 1) & - WRITE (*,*) 'Dimension error: ntime=',ntime,' len=', len - ELSE IF (dimname == 'vegtype') THEN - IF (len /= nvegtyp) WRITE (*,*) & - 'Dimension error: nvegtyp=', nvegtyp, ' len=', len - ELSE - WRITE (*,*) 'Unexpected dimension: ', dimname,' of ',varname - END IF - END DO - DEALLOCATE(dimids) - -END SUBROUTINE check_dimensions - -!------------------------------------------------------------------------------ -SUBROUTINE get_missval (ncid, varid, missval) -!------------------------------------------------------------------------------ -! -! Routine to find out the missing value of an input file variable -! -!------------------------------------------------------------------------------ - USE mo_kinds - IMPLICIT NONE - include 'netcdf.inc' - - !-- INTENT(in) - INTEGER, INTENT(in) :: ncid, varid - - !-- INTENT(out) - REAL(dp), INTENT(out) :: missval - - !-- LOCAL - INTEGER :: stat -!------------------------------------------------------------------------------ - - stat = nf_get_att_double(ncid, varid, "_FillValue", missval) - CALL hdlerr(stat,'get_missval: no missing value available') - -END SUBROUTINE get_missval - -!------------------------------------------------------------------------------ -SUBROUTINE define_var(ncin, ncout, varname_in, varname_out, outdimids, missval) -!------------------------------------------------------------------------------ -! -! Routine to define an output variable that had been read from another -! netcdf file. Attributes and dimensions are copied. -! -!------------------------------------------------------------------------------ - USE mo_kinds - - IMPLICIT NONE - - include 'netcdf.inc' - - !-- INTENT(in) - CHARACTER*30, INTENT(in) :: varname_in, varname_out - INTEGER, INTENT(in) :: ncin, ncout - INTEGER, INTENT(in) :: outdimids(6) - REAL(dp), INTENT(out), OPTIONAL :: missval - - !-- LOCAL - LOGICAL :: dimlon, dimlat, dimtil, dimlct, dimnsoil, dimtim - INTEGER :: stat, dim, att - INTEGER :: varid_in, varid_out, type, natts - INTEGER :: ndims_in, ndims_out - INTEGER, ALLOCATABLE :: dimids_in(:), dimids_out(:) - CHARACTER*30 :: dimname, attname - REAL(dp) :: miss -!------------------------------------------------------------------------------ - stat=nf_inq_varid(ncin, varname_in, varid_in) - CALL hdlerr(stat,'define_var: inq. varid of '//varname_in) - - stat=nf_inq_varndims(ncin, varid_in, ndims_in) - CALL hdlerr(stat,'define_var: inq. ndims of '//varname_in) - ALLOCATE(dimids_in(ndims_in)) - stat=nf_inq_vardimid(ncin, varid_in, dimids_in(:)) - CALL hdlerr(stat,'define_var: inq. dimids of '//varname_in) - - ndims_out=0 - dimlon = .FALSE. - dimlat = .FALSE. - dimtil = .FALSE. - dimlct = .FALSE. - dimtim = .FALSE. - dimnsoil = .FALSE. - - DO dim=1,ndims_in - stat=nf_inq_dimname(ncin, dimids_in(dim), dimname) - CALL hdlerr(stat,'define_var: dimname of '//varname_in) - IF (dimname == 'lon') THEN - dimlon = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'lat') THEN - dimlat = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'ntiles') THEN - dimtil = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'time') THEN - dimtim = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'lct') THEN - dimlct = .TRUE. - ndims_out = ndims_out + 1 - ELSE IF (dimname == 'nsoil') THEN - dimnsoil = .TRUE. - ndims_out = ndims_out + 1 - ELSE - WRITE(*,*) "New dimension: "//dimname - END IF - END DO - - ALLOCATE(dimids_out(ndims_out)) - IF (ndims_out == 1) THEN - IF (dimlon) dimids_out(1:1) = (/outdimids(1)/) - IF (dimlat) dimids_out(1:1) = (/outdimids(2)/) - IF (dimtil) dimids_out(1:1) = (/outdimids(3)/) - IF (dimlct) dimids_out(1:1) = (/outdimids(4)/) - IF (dimtim) dimids_out(1:1) = (/outdimids(5)/) - IF (dimnsoil) dimids_out(1:1) = (/outdimids(6)/) - ELSE IF (ndims_out == 2) THEN - dimids_out(1:2) = (/outdimids(1),outdimids(2)/) - ELSE IF (ndims_out == 3) THEN - IF (dimtil) dimids_out(1:3) = outdimids((/1,2,3/)) - IF (dimlct) dimids_out(1:3) = outdimids((/1,2,4/)) - IF (dimnsoil) dimids_out(1:3) = outdimids((/1,2,5/)) - IF (dimtim) dimids_out(1:3) = outdimids((/1,2,6/)) - ELSE IF (ndims_out == 4) THEN - IF (dimtil) dimids_out(1:4) = (/outdimids(1),outdimids(2),outdimids(3),outdimids(5)/) - IF (dimlct) dimids_out(1:4) = (/outdimids(1),outdimids(2),outdimids(4),outdimids(5)/) - ELSE - WRITE(*,*) "WARNING: No more than four dimensions expected" - END IF - - stat=nf_inq_vartype(ncin, varid_in, type) - CALL hdlerr(stat,'define_var: inq. type of '//varname_in) - stat=nf_inq_varnatts(ncin, varid_in, natts) - CALL hdlerr(stat,'define_var: inq. natts of '//varname_in) - - stat=nf_def_var(ncout, varname_out, type, ndims_out, dimids_out, varid_out) - CALL hdlerr(stat,'define_var: defining var '//varname_out) - DO att=1,natts - stat = nf_inq_attname(ncin, varid_in, att, attname) - CALL hdlerr(stat,'define_var: attname of '//varname_in) - stat = nf_copy_att(ncin, varid_in, attname, ncout,varid_out) - CALL hdlerr(stat,'define_var: copy attribute '//attname) - IF (attname == "_FillValue") THEN - stat = nf_get_att_double(ncin, varid_in, attname, miss) - CALL hdlerr(stat,'get missing value of: '//varname_in) - ENDIF - END DO - IF (PRESENT(missval)) missval = miss - - DEALLOCATE(dimids_in) - DEALLOCATE(dimids_out) - -END SUBROUTINE define_var - -!------------------------------------------------------------------------------ -SUBROUTINE define_var_new(ncout, varname, ndims, outdimids) -!------------------------------------------------------------------------------ -! -! Routine to define an output variable that had not been read from an other -! netcdf file. -! -!------------------------------------------------------------------------------ - IMPLICIT NONE - include 'netcdf.inc' - - !-- INTENT(in) - CHARACTER*30, INTENT(in) :: varname - INTEGER, INTENT(in) :: ncout, ndims - INTEGER, INTENT(in) :: outdimids(ndims) - - !-- LOCAL - INTEGER :: stat, varid - INTEGER, ALLOCATABLE :: dimids(:) -!------------------------------------------------------------------------------ - - ALLOCATE(dimids(ndims)) - IF (ndims == 2) THEN - dimids(1:2) = (/outdimids(1),outdimids(2)/) - ELSE IF (ndims == 3) THEN - dimids(1:3) = (/outdimids(1),outdimids(2),outdimids(3)/) - ELSE - WRITE(*,*) 'Only 2 or 3 dimensions supported so far' - END IF - - stat=nf_def_var(ncout, varname, NF_DOUBLE, ndims, dimids, varid) - CALL hdlerr(stat,'define_var_new: defining var '//varname) - DEALLOCATE(dimids) - - ! define attributes - - IF (varname == 'slm') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 19, 'land sea mask') - CALL hdlerr(stat,'define_var_new: put slm long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put slm units') - - ELSE IF (varname == 'cover_fract') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 19, 'land cover fraction') - CALL hdlerr(stat,'define_var_new: put cover_fract long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put cover_fract units') - - ELSE IF (varname == 'cover_type') THEN - CALL put_lct_attributes(ncout, varid) - - ELSE IF (varname == 'veg_ratio_max') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 27, 'maximum vegetation fraction') - CALL hdlerr(stat,'define_var_new: put veg_ratio_max long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put veg_ratio_max units') - - ELSE IF (varname == 'albedo_veg_vis') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 38, & - 'vegetation albedo in the visible range') - CALL hdlerr(stat,'define_var_new: put albedo_veg_vis long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put albedo_veg_vis units') - - ELSE IF (varname == 'albedo_veg_nir') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 28, 'vegetation albedo in the NIR') - CALL hdlerr(stat,'define_var_new: put albedo_veg_nir long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put albedo_veg_nir units') - - ELSE IF (varname == 'albedo_soil_vis') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 32, 'soil albedo in the visible range') - CALL hdlerr(stat,'define_var_new: put albedo_soil_vis long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put albedo_soil_vis units') - - ELSE IF (varname == 'albedo_soil_nir') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 22, 'soil albedo in the NIR') - CALL hdlerr(stat,'define_var_new: put albedo_soil_nir long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put albedo_soil_nir units') - - ELSE IF (varname == 'roughness_length_oro') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 33, 'roughness_length due to orography') - CALL hdlerr(stat,'define_var_new: put roughness_length_oro long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put roughness_length_oro units') - - ELSE IF (varname == 'natural_veg') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 30, 'natural (potential) vegetation') - CALL hdlerr(stat,'define_var_new: put natural_veg long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put natural_veg units') - - ELSE IF (varname == 'soil_depth') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 10, 'soil depth') - CALL hdlerr(stat,'define_var_new: put soil_depth long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put soil_depth units') - - ELSE IF (varname == 'soil_porosity') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 14, 'soil porosity') - CALL hdlerr(stat,'define_var_new: put soil_porosity long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put soil_porosity units') - - ELSE IF (varname == 'pore_size_index') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 20, 'soil pore size index') - CALL hdlerr(stat,'define_var_new: put pore_size_index long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put pore_size_index units') - - ELSE IF (varname == 'soil_field_cap') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 19, 'soil field capacity') - CALL hdlerr(stat,'define_var_new: put soil_field_cap long_name') - stat = nf_put_att_text(ncout, varid, 'units', 4, 'mm-1') - CALL hdlerr(stat,'define_var_new: put soil_field_cap units') - - ELSE IF (varname == 'heat_capacity') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 25, 'heat capacity of dry soil') - CALL hdlerr(stat,'define_var_new: put heat_capacity long_name') - stat = nf_put_att_text(ncout, varid, 'units', 7, 'Jm-3K-1') - CALL hdlerr(stat,'define_var_new: put heat_capacity units') - - ELSE IF (varname == 'heat_conductivity') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 29, 'heat conductivity of dry soil') - CALL hdlerr(stat,'define_var_new: put heat_conductivity long_name') - stat = nf_put_att_text(ncout, varid, 'units', 10, 'Jm-1s-1K-1') - CALL hdlerr(stat,'define_var_new: put heat_conductivity units') - - ELSE IF (varname == 'moisture_pot') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 34, 'saturated matrix potential of soil') - CALL hdlerr(stat,'define_var_new: put moisture_pot long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put moisture_pot units') - - ELSE IF (varname == 'hyd_cond_sat') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 19, 'saturated hydraulic conductivity') - CALL hdlerr(stat,'define_var_new: put hyd_cond_sat long_name') - stat = nf_put_att_text(ncout, varid, 'units', 4, 'ms-1') - CALL hdlerr(stat,'define_var_new: put hyd_cond_sat units') - - ELSE IF (varname == 'wilting_point') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 39, 'Volumetric soil permanent wilting point') - CALL hdlerr(stat,'define_var_new: put wilting_point long_name') - stat = nf_put_att_text(ncout, varid, 'units', 4, 'mm-1') - CALL hdlerr(stat,'define_var_new: put wilting_point units') - - ELSE IF (varname == 'bclapp') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 31, 'Clapp and Hornberger b exponent') - CALL hdlerr(stat,'define_var_new: put bclapp long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, '1') - CALL hdlerr(stat,'define_var_new: put bclapp units') - - ELSE IF (varname == 'root_depth') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 13, 'rooting depth') - CALL hdlerr(stat,'define_var_new: put root_depth long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put root_depth units') - - ELSE IF (varname == 'layer_moist') THEN - stat = nf_put_att_text(ncout, varid, 'long_name', 37, 'initial moisture for multilayer soils') - CALL hdlerr(stat,'define_var_new: put layer_moist long_name') - stat = nf_put_att_text(ncout, varid, 'units', 1, 'm') - CALL hdlerr(stat,'define_var_new: put layer_moist units') - - ENDIF - -END SUBROUTINE define_var_new - -!------------------------------------------------------------------------------ -SUBROUTINE set_global_attributes(ncout, year_ct, year_cf, res_oce, res_atm, & - nlct, ntiles, nsoil, lcouple, ldynveg, lc3c4crop, lpasture, lread_pasture, & - lpasture_rule, desert_only, grass_only, woods_only, ignore_measurements, & - echam_fractional, maxmoist_version, pasture_tag, masks_file, svn_url, svn_rev) -!------------------------------------------------------------------------------ -! -! Routine to set global attributes -! -!------------------------------------------------------------------------------ - IMPLICIT NONE - include 'netcdf.inc' - - !-- INTENT(in) - INTEGER, INTENT(in) :: ncout - INTEGER, INTENT(in) :: nlct, ntiles, nsoil - INTEGER, INTENT(in) :: year_ct, year_cf - CHARACTER(8), INTENT(in) :: res_oce, res_atm, maxmoist_version, pasture_tag - LOGICAL, INTENT(in) :: lcouple, desert_only, grass_only, woods_only - LOGICAL, INTENT(in) :: ldynveg, lc3c4crop, lpasture, lread_pasture, lpasture_rule - LOGICAL, INTENT(in) :: echam_fractional, ignore_measurements - CHARACTER(100), INTENT(in) :: masks_file - CHARACTER(*), INTENT(in) :: svn_url, svn_rev - - !-- LOCAL - INTEGER :: stat - CHARACTER(8) :: date - CHARACTER(10) :: time - CHARACTER(400) :: comment, history, references, configuration - CHARACTER(120) :: url, rev - -!------------------------------------------------------------------------------ - - stat = nf_put_att_text(ncout, NF_GLOBAL, 'title', 31, & - 'initial surface data for JSBACH') - CALL hdlerr(stat,'set_global_attributes: title') - - stat = nf_put_att_text(ncout, NF_GLOBAL, 'institution', 54, & - 'Max Planck Institute for Meteorology, Hamburg, Germany') - CALL hdlerr(stat,'set_global_attributes: institution') - - stat = nf_put_att_text(ncout, NF_GLOBAL, 'Conventions', 6, 'CF-1.0') - CALL hdlerr(stat,'set_global_attributes: Conventions') - - stat = nf_put_att_int(ncout, NF_GLOBAL, 'refyear_for_cover_types', NF_INT, 1, year_ct ) - CALL hdlerr(stat,'set_global_attributes: year_ct') - - stat = nf_put_att_int(ncout, NF_GLOBAL, 'refyear_for_cover_fractions', NF_INT, 1, year_cf ) - CALL hdlerr(stat,'set_global_attributes: year_cf') - - stat = nf_put_att_text(ncout, NF_GLOBAL, 'spherical_truncation', LEN_TRIM(res_atm), TRIM(res_atm)) - CALL hdlerr(stat,'set_global_attributes: spherical_truncation') - - stat = nf_put_att_int(ncout, NF_GLOBAL, 'nlct', NF_INT, 1, nlct) - CALL hdlerr(stat,'set_global_attributes: nlct') - - WRITE (configuration,'(a,i2,a,i2.1,a)') TRIM(res_atm)//TRIM(res_oce)//' ', ntiles, 'tiles ', nsoil, 'layers' - stat = nf_put_att_text(ncout, NF_GLOBAL, 'configuration', LEN_TRIM(configuration), TRIM(configuration)) - CALL hdlerr(stat,'set_global_attributes: configuration') - - IF (lcouple) THEN - comment = 'setup for an experiment with ocean model: grid '//TRIM(res_oce) - ELSE - comment = 'setup for an experiment without ocean model' - END IF - IF (desert_only) THEN - comment = TRIM(comment)//CHAR(10)//'desert_only: all land has desert conditions' - ELSE IF (grass_only) THEN - comment = TRIM(comment)//CHAR(10)//'grass_only: all land covered by grass' - ELSE IF (woods_only) THEN - comment = TRIM(comment)//CHAR(10)//'woods_only: all land covered by woods' - END IF - IF (ignore_measurements) THEN - comment = TRIM(comment)//CHAR(10)//'ignore_measurements: cover fractions only depend on latitude' - END IF - IF (ldynveg) THEN - comment = TRIM(comment)//CHAR(10)//'setup for runs with dynamic vegetation' - ELSE - comment = TRIM(comment)//CHAR(10)//'setup for runs without dynamic vegetation' - END IF - IF (lc3c4crop) THEN - comment = TRIM(comment)//CHAR(10)//'C3 and C4 crops distinguished' - ELSE - comment = TRIM(comment)//CHAR(10)//'C3 and C4 crops not distinguished' - END IF - IF (lpasture) THEN - comment = TRIM(comment)//CHAR(10)//'pastures distinguished from crops' - ELSE - comment = TRIM(comment)//CHAR(10)//'pastures not distinguished form crops' - END IF - IF (lread_pasture) THEN - SELECT CASE (TRIM(pasture_tag)) - CASE ('LUH') - comment = TRIM(comment)//CHAR(10)// & - 'crop and pasture fractions calculated from LUH harmonized land use data '// & - 'generated for CMIP5' - CASE ('LUH2v2h') - comment = TRIM(comment)//CHAR(10)// & - 'crop and pasture fractions calculated from LUH2 v2h Release (10/14/16)' & - //CHAR(10)//'crop cover types calculated from 1961 to 2005 average of FAO data' - CASE DEFAULT - comment = TRIM(comment)//CHAR(10)// & - 'crop and pasture fractions from '//(TRIM(pasture_tag)) - END SELECT - END IF - IF (lpasture_rule) THEN - comment = TRIM(comment)//CHAR(10)//'pasture rule applied' - END IF - IF (echam_fractional) THEN - comment = TRIM(comment)//CHAR(10)//'setup for ECHAM with fractional land sea mask' - END IF - IF (maxmoist_version == 'LSP3') THEN - comment = TRIM(comment)//CHAR(10)//'maximum soil moisture from LSP3 (Stacke 2013) ' - ELSE IF (maxmoist_version == 'LSP2') THEN - comment = TRIM(comment)//CHAR(10)//'maximum soil moisture from LSP2 (as in echam5) ' - END IF - IF (TRIM(masks_file) /= 'default') THEN - comment = TRIM(comment)//CHAR(10)//'land sea, glacier and lake masks read from file: ' & - //TRIM(masks_file) - END IF - stat = nf_put_att_text(ncout, NF_GLOBAL, 'comment', LEN_TRIM(comment), TRIM(comment)) - CALL hdlerr(stat,'set_global_attributes: comment') - - CALL DATE_AND_TIME(date,time) - url=svn_url(11:LEN_TRIM(svn_url)-2) - rev=svn_rev(2:LEN_TRIM(svn_rev)-2) - history = date(1:4)//'-'//date(5:6)//'-'//date(7:8)//' ' & - //time(1:2)//':'//time(3:4)//' : created with ' & - //CHAR(10)//TRIM(url)//CHAR(10)//TRIM(rev) - stat = nf_put_att_text(ncout, NF_GLOBAL, 'history', LEN_TRIM(history), TRIM(history)) - CALL hdlerr(stat,'set_global_attributes: history') - - - references = 'Hagemann, S. (2002): An improved land surface parameter ' & - //CHAR(10)//' dataset for global and regional climate models, ' & - //CHAR(10)//' Max Planck Institute for Meteorology, Report 336' & - //CHAR(10)//'Pongratz, J. et al. (2008), A reconstruction of global ' & - //CHAR(10)//' agricultural areas and land cover for the last millennium, '& - //CHAR(10)//' Global Biogeochem. Cycles, 22, GB3018, doi:10.1029/2007GB003153.' - stat = nf_put_att_text(ncout, NF_GLOBAL, 'references', LEN_TRIM(references), TRIM(references)) - CALL hdlerr(stat,'set_global_attributes: references') - - -END SUBROUTINE set_global_attributes - -!------------------------------------------------------------------------------ -SUBROUTINE hdlerr(stat,string) -!------------------------------------------------------------------------------ -! -! Routine to handle netcdf errors -! -!------------------------------------------------------------------------------ - - IMPLICIT NONE - - include 'netcdf.inc' - -! INTENT(in) - INTEGER, INTENT(in) :: stat - CHARACTER*(*), INTENT(in) :: string - -!------------------------------------------------------------------------------ - - IF (stat /= NF_NOERR) THEN - WRITE (6,*) '--------' - WRITE (6,*) ' ERROR: ', string - WRITE (6,*) '--------' - STOP 1 - END IF - -END SUBROUTINE hdlerr -!------------------------------------------------------------------------------ diff --git a/couplings/utils/jsbach_init_file.ksh b/couplings/utils/jsbach_init_file.ksh deleted file mode 100755 index c8b37d167..000000000 --- a/couplings/utils/jsbach_init_file.ksh +++ /dev/null @@ -1,209 +0,0 @@ -#!/bin/ksh -#------------------------------------------------------------------------------ -# Script to compile and run jsbach_init_file.f90 -# For more information read the header of jsbach_init_file.f90. -# -# The script is usually called by create_input_cosmos.ksh, were several -# variables are exported (interactive=false). -# Alternatively, it can be run interactively (interactive=true), to just create -# a specific initial file for jsbach. -# -# To generate a series of vegetation cover maps for runs with landcover change, -# the script needs to be called interactivly with landcover_series=true -# -# Veronika Gayler -# Stiig Wilkenskjeld, 2012-01: Added variables for 5 layer soil scheme -#------------------------------------------------------------------------------ -# -# !NOTE FOR USAGE ON MISTRAL: MAKE SURE TO LOAD THE MODULE 'NAG' PRIOR TO -# EXECUTION OF THIS SCRIPT, OR THE PREDEFINED COMPILER (nagfor) WILL NOT BE -# FOUND! -# Christian Stepanek, 20.04.2016 -# -#------------------------------------------------------------------------------ -# Updates to this script so it is suitable for iterative coupling. -# * Throws away unneeded library definition variables. -# * Turns echam input files into passable arguments. -# -# Paul Gierz, 15.08.2018 -#------------------------------------------------------------------------------ - -set -e - -# Variables that need to be defined if the sript is used interctively. -# If called from create_input_cosmos.ksh these variables are exported. -# -res_atm=T63 # horizontal grid resopution -res_oce=GR15 # ocean model grid (for a coupled setup) - -ntiles=11 # number of jsbach tiles - -dynveg=true # setup for dynamic vegetation -c3c4crop=true # differentiate between C3 and C4 crops -cmip5_pasture=true # use landuse maps for pastures and crops - -year_ct=1850 # year the cover_types are derived from -year_cf=1850 # year cover fractions are derived from - -landcover_series=false # generate a series of files with cover_types of - # year_ct and fractions from year_cf to year_cf2 -year_cf2=1859 # only used with landcover_series - -echam_fractional=false # initial file for echam runs with fractional - # land sea mask -# TODO: Replace this with a ${POOL_DIR}, which should be defined by esm-runscripts... -pool=/work/ollie/pool/ECHAM6/T63 # directories with echam input data -pool_land=/work/ollie/pool/JSBACH/prepare/T63 -srcdir=./ - -# TODO: Something that copies prog from utils here - -if [[ -f ${prog} ]]; then - #------------------------------------------------------------------------------ - # prepare the namelist - #------------------------------------------------------------------------------ - - [[ ${res_oce} = "" ]] && lcouple=.false. || lcouple=.true. - [[ ${dynveg} = true ]] && ldynveg=.true. || ldynveg=.false. - [[ ${c3c4crop} = true ]] && lc3c4crop=.true. || lc3c4crop=.false. - [[ ${cmip5_pasture} = true ]] && lcmip5_pasture=.true. || lcmip5_pasture=.false. - - if [[ ${ntiles} -eq 11 || ${dynveg} = true ]]; then - lpasture=.true. - else - lpasture=.false. - fi - - desert_only=.false. # setup for a desert-only experiment - grass_only=.false. # setup for a grass-only experiment - woods_only=.false. # setup for a woods-only experiment - - cat > namelist < LUH_states_${res_atm}.nc - fi - cdo selyear,${year_cf} LUH_states_${res_atm}.nc \ - LUH_states_${year_cf}_${res_atm}.nc - fi - - ln -sf ${pool_land}/soil_parameters_${res_atm}.nc . - - #------------------------------------------------------------------------------ - # run the program - #------------------------------------------------------------------------------ - echo "Run ${prog}..." - chmod 755 ${prog} - - yr=${year_cf} - [[ ${landcover_series} = true ]] || year_cf2=${year_cf} - while [[ ${yr} -le ${year_cf2} ]]; do - sed "s/year_cf=.*/year_cf=${yr}/" namelist > namelist.tmp - mv namelist.tmp namelist - ./${prog} - (( yr = yr + 1 )) - done - - #------------------------------------------------------------------------------ - # clean up - #------------------------------------------------------------------------------ - if [[ $? -eq 0 ]]; then - rm namelist - rm ${res_atm}${res_oce}_jan_surf.nc - rm ${res_atm}${res_oce}_VGRATCLIM.nc - rm ${res_atm}${res_oce}_VLTCLIM.nc - rm ${res_atm}_TSLCLIM2.nc - rm vegtype_${year_cf}_${res_atm}gauss_pa14.nc - if [[ ${year_cf} != ${year_ct} ]]; then - rm vegtype_${year_ct}_${res_atm}gauss_pa14.nc - fi - rm vegmax_6_${res_atm}.lola - rm ${res_atm}_topo_75.lola - rm albedo_${res_atm}.lola - rm C3C4_mask_${res_atm}gauss.nc - rm potveg_${res_atm}.nc - if [[ ${c3c4crop} = true ]]; then - rm C3C4_crop_${res_atm}.nc - fi - if [[ ${cmip5_pasture} = true ]]; then - rm LUH_states_${res_atm}.nc - rm LUH_states_${year_cf}_${res_atm}.nc - fi - [[ -f mo_kinds.mod ]] && rm mo_kinds.mod - [[ -f mo_vegparams.mod ]] && rm mo_vegparams.mod - rm -f 5soillayers_${res_atm}.nc soil_parameters_${res_atm}.nc - else - echo "error in ${prog}" - exit 1 - fi -else - echo "${prog} could not be created" - exit 1 -fi - -ofile=jsbach_T63GR15_11tiles_5layers_Lev_21ka_noTOPO_xzhang.nc -mv jsbach_T63GR15_11tiles_5layers_1850.nc ${ofile} diff --git a/couplings/utils/pack.f90 b/couplings/utils/pack.f90 deleted file mode 100644 index c61637a72..000000000 --- a/couplings/utils/pack.f90 +++ /dev/null @@ -1,253 +0,0 @@ -!------------------------------------------------------------------------------ -! -! program reading an unpacked array and a corresponding 2d-mask and writes the -! packed array -! -! Compilation: -! -!linux-x64: -! module load nag -! nagfor -colour -nan -gline -O0 -C=all -w=uep pack.f90 -o pack -I/sw/jessie-x64/netcdf_fortran-4.4.2-static-nag60/include -L/sw/jessie-x64/netcdf_fortran-4.4.2-static-nag60/lib -lnetcdff -L/sw/jessie-x64/netcdf-4.3.3.1-static-gccsys/lib/ -lnetcdf -L/sw/jessie-x64/hdf5-1.8.16-static-gccsys/lib -lhdf5_hl -lhdf5 -ldl -L/sw/jessie-x64/szip-2.1-static-gccsys/lib -lsz -lz - -!mistral: -! module load nag -! export LD_LIBRARY_PATH="/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib:/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib:/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib" -! -! nagfor -colour '-maxcontin=100' '-wmismatch=define_var_new,nf_get_var_double,nf_copy_att,nf_get_var_real,nf_put_var_double,nf_def_var,nf_put_vara_double,dgemm,nfmpi_def_dim,nfmpi_put_vara_double,nfmpi_def_var' '-C=all' -g -gline -nan '-w=uep' -o pack ./pack.f90 -I/sw/rhel6-x64/netcdf/netcdf_fortran-4.4.2-static-nag60/include -L/sw/rhel6-x64/netcdf/netcdf_fortran-4.4.2-static-nag60/lib -lnetcdff -L/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib -lnetcdf -L/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib -lhdf5_hl -lhdf5 -ldl -L/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib -lsz -L/usr/lib64/lib -lz -ldl -lm -lnuma -Wl,--export-dynamic -lrt -lnsl -lutil -lm -ldl -!------------------------------------------------------------------------------ -PROGRAM pack_array - - IMPLICIT NONE - INCLUDE 'netcdf.inc' - - INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307) - INTEGER :: i, j, nlon, nlat, ntiles, nland, nsoil, nnlon, nnlat - INTEGER :: stat, ncid, ncin, varid, landid, tileid, soilid, varndims, idtile, idland, idsoil - INTEGER, ALLOCATABLE :: vardimids(:) - - REAL(dp), ALLOCATABLE :: packed1d(:) - REAL(dp), ALLOCATABLE :: packed2d(:,:) - REAL(dp), ALLOCATABLE :: packed3d(:,:,:) - REAL(dp), ALLOCATABLE :: unpacked2d(:,:) - REAL(dp), ALLOCATABLE :: unpacked3d(:,:,:) - REAL(dp), ALLOCATABLE :: unpacked4d(:,:,:,:) - REAL(dp), ALLOCATABLE :: landpoints(:) - REAL(dp), ALLOCATABLE :: tiles(:) - REAL(dp), ALLOCATABLE :: rmask(:,:) - LOGICAL, ALLOCATABLE :: lmask(:,:) - - CHARACTER*100 :: array_name, mask_name, tile_name, soil_name - - PRINT*, 'enter array file name (without .nc)' - READ*, array_name - PRINT*, 'enter mask file name (without .nc)' - READ*, mask_name - - !-- read land sea mask from mask file (array and file have the same names) - - stat = nf_open(TRIM(mask_name)//'.nc',NF_NOWRITE, ncin) - CALL hdlerr(stat) - stat = nf_inq_varid(ncin,mask_name,varid) - CALL hdlerr(stat) - - stat = nf_inq_varndims(ncin,varid,varndims) - CALL hdlerr(stat) - ALLOCATE(vardimids(varndims)) - stat = nf_inq_vardimid(ncin,varid,vardimids) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncin,vardimids(1),nlon) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncin,vardimids(2),nlat) - CALL hdlerr(stat) - DEALLOCATE(vardimids) - ALLOCATE(rmask(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,rmask) - CALL hdlerr(stat) - - !-- read unpacked array from file (array and file have the same names) - - stat = nf_open(TRIM(array_name)//'.nc',NF_NOWRITE,ncid) - CALL hdlerr(stat) - stat = nf_inq_varid(ncid,array_name,varid) - CALL hdlerr(stat) - - stat = nf_inq_varndims(ncid,varid,varndims) - CALL hdlerr(stat) - ALLOCATE(vardimids(varndims)) - stat = nf_inq_vardimid(ncid,varid,vardimids) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncid,vardimids(1),nnlon) - CALL hdlerr(stat) - IF (nnlon /= nlon) PRINT*, 'Dimensions of mask and data files do not match: ', nlon, nnlon - stat = nf_inq_dimlen(ncid,vardimids(2),nnlat) - CALL hdlerr(stat) - IF (nnlat /= nlat) PRINT*, 'Dimensions of mask and data files do not match: ', nlat, nnlat - IF (varndims > 2) THEN - stat = nf_inq_dimlen(ncid,vardimids(3),ntiles) - CALL hdlerr(stat) - stat = nf_inq_dimname(ncid,vardimids(3),tile_name) - CALL hdlerr(stat) - END IF - IF (varndims > 3) THEN - stat = nf_inq_dimlen(ncid,vardimids(4),nsoil) - CALL hdlerr(stat) - stat = nf_inq_dimname(ncid,vardimids(4),soil_name) - CALL hdlerr(stat) - END IF - DEALLOCATE(vardimids) - - nland=SUM(rmask(:,:)) - IF (varndims == 2) THEN - ALLOCATE(unpacked2d(nlon,nlat)) - stat = nf_get_var_double(ncid,varid,unpacked2d) - CALL hdlerr(stat) - ELSE IF (varndims == 3) THEN - ALLOCATE(unpacked3d(nlon,nlat,ntiles)) - stat = nf_get_var_double(ncid,varid,unpacked3d) - CALL hdlerr(stat) - ELSE IF (varndims == 4) THEN - ALLOCATE(unpacked4d(nlon,nlat,ntiles,nsoil)) - stat = nf_get_var_double(ncid,varid,unpacked4d) - CALL hdlerr(stat) - ELSE - STOP ('maximum number of dimensions is 4!') - END IF - stat = nf_close(ncid) - CALL hdlerr(stat) - - !-- pack the array - - ALLOCATE(lmask(nlon,nlat)) - WHERE (rmask == 1._dp) - lmask = .TRUE. - ELSEWHERE - lmask = .FALSE. - ENDWHERE - - IF (varndims == 2) THEN - ALLOCATE(packed1d(nland)) - packed1d(:) = PACK(unpacked2d(:,:), MASK=lmask(:,:)) - ELSE IF (varndims == 3) THEN - ALLOCATE(packed2d(nland,ntiles)) - DO i = 1, ntiles - packed2d(:,i) = PACK(unpacked3d(:,:,i), MASK=lmask(:,:)) - END DO - ELSE IF (varndims == 4) THEN - ALLOCATE(packed3d(nland,ntiles,nsoil)) - DO j = 1, nsoil - DO i = 1, ntiles - packed3d(:,i,j) = PACK(unpacked4d(:,:,i,j), MASK=lmask(:,:)) - END DO - END DO - END IF - - !-- write the output file - - !-- dimensions - stat = nf_create('1d_'//TRIM(array_name)//'.nc',NF_CLOBBER,ncid) - CALL hdlerr(stat) - stat = nf_def_dim(ncid, 'landpoint', nland, idland) - CALL hdlerr(stat) - IF (varndims > 2) THEN - stat = nf_def_dim(ncid, tile_name, ntiles, idtile) - CALL hdlerr(stat) - END IF - IF (varndims > 3) THEN - stat = nf_def_dim(ncid, soil_name, nsoil, idsoil) - CALL hdlerr(stat) - END IF - - stat = nf_def_var(ncid, 'landpoint', NF_DOUBLE, 1, (/idland/), landid) - CALL hdlerr(stat) - IF (varndims > 2) THEN - stat = nf_def_var(ncid, tile_name, NF_DOUBLE, 1, (/idtile/), tileid) - CALL hdlerr(stat) - END IF - IF (varndims > 3) THEN - stat = nf_def_var(ncid, soil_name, NF_DOUBLE, 1, (/idsoil/), soilid) - CALL hdlerr(stat) - END IF - - IF (varndims == 2) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 1, (/idland/), varid) - CALL hdlerr(stat) - ELSE IF (varndims == 3) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 2, (/idland,idtile/), varid) - CALL hdlerr(stat) - ELSE IF (varndims == 4) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 3, (/idland,idtile,idsoil/), varid) - CALL hdlerr(stat) - END IF - stat = nf_enddef(ncid) - CALL hdlerr(stat) - - !-- dimension variables - ALLOCATE(landpoints(nland)) - DO i = 1, nland - landpoints(i)=i - END DO - stat = nf_put_var_double(ncid,landid,landpoints) - DEALLOCATE(landpoints) - CALL hdlerr(stat) - IF (varndims > 2) THEN - ALLOCATE(tiles(ntiles)) - DO i = 1, ntiles - tiles(i)=i - END DO - stat = nf_put_var_double(ncid,tileid,tiles) - CALL hdlerr(stat) - DEALLOCATE(tiles) - END IF - - !-- packed data array - IF (varndims == 2) THEN - stat = nf_put_var_double(ncid,varid,packed1d) - CALL hdlerr(stat) - ELSE IF (varndims == 3) THEN - stat = nf_put_var_double(ncid,varid,packed2d) - CALL hdlerr(stat) - ELSE IF (varndims == 4) THEN - stat = nf_put_var_double(ncid,varid,packed3d) - CALL hdlerr(stat) - END IF - stat = nf_close(ncid) - CALL hdlerr(stat) - stat = nf_close(ncin) - CALL hdlerr(stat) - - DEALLOCATE(rmask, lmask) - IF (varndims == 2) THEN - DEALLOCATE(packed1d, unpacked2d) - ELSE IF (varndims == 3) THEN - DEALLOCATE(packed2d, unpacked3d) - ELSE IF (varndims == 4) THEN - DEALLOCATE(packed3d, unpacked4d) - END IF - -END PROGRAM pack_array - -!------------------------------------------------------------------------------ -! -! Routine to handle netcdf errors -! -!------------------------------------------------------------------------------ -SUBROUTINE hdlerr(stat) - - IMPLICIT NONE - - include 'netcdf.inc' - -! INTENT(in) - INTEGER, INTENT(in) :: stat - -!------------------------------------------------------------------------------ - - IF (stat /= NF_NOERR) THEN - WRITE (6,*) '--------' - WRITE (6,*) ' ERROR: ', nf_strerror(stat) - WRITE (6,*) '--------' - STOP - END IF - -END SUBROUTINE hdlerr -!------------------------------------------------------------------------------ diff --git a/couplings/utils/pack_file.ksh b/couplings/utils/pack_file.ksh deleted file mode 100755 index 62d33bdb6..000000000 --- a/couplings/utils/pack_file.ksh +++ /dev/null @@ -1,120 +0,0 @@ -#!/bin/ksh -#------------------------------------------------------------------------------ -# Script to re-pack all variables of an unpacked jsbach restart file. -# to be used in combination with unpack_file.ksh to e.g. modify the some -# arrays of the restart file -# -# Veronika Gayler, August 2014 -#------------------------------------------------------------------------------ -set -e - -restart=$1 # file with unpacked (lon/lat) data -maskfile=$2 # file with corresponding land sea mask -#maskfile=/pool/data/JSBACH/T63/jsbach_T63GR15_11tiles_1850.nc -maskname=slm # variable name of the land sea mask in maskfile - -#------------------------------------------------------------------------------ -. ${MODULESHOME}/init/ksh -module load nco || true -module unload cdo -if [[ $(uname -n | cut -c1-6) == mlogin || $(uname -n | cut -c1-9) == mistralpp || $(uname -n) == m????? ]]; then - module load cdo/1.7.2-magicsxx-gcc48 - export LD_LIBRARY_PATH="/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib:/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib:/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib" -else - #module load cdo/1.7.2-gccsys - module load cdo #/1.7.2 -fi -cdo="cdo -b 64 -s" -#------------------------------------------------------------------------------ - -if [[ ${restart} = "" ]]; then - echo " ERROR: " - echo " you need to define the name of the file with unpacked data" - echo " and a file containing the corresponding land sea mask" - exit 1 -fi - -restartfile=${restart##*/} -[[ ${restartfile} = ${restart} ]] && restart=./${restart} -restartdir=${restart%/*}; cd ${restartdir}; restartdir=$(pwd) -scriptdir=${0%/*} #; cd ${scriptdir}/..; scriptdir=$(pwd) -script=$(basename $0) - -if [[ ! -f ./pack ]]; then - echo " ERROR: " - echo " The program 'pack' is missing." - echo " Compile /contrib/pack.f90 and place the executable in this " - echo " directory. Instructions are given in the program header." - exit 1 -fi - -# data processing -#----------------- - -cd ${restartdir} -[[ -f 1d_${restartfile} ]] && rm 1d_${restartfile} -${cdo} -selvar,${maskname} ${maskfile} ${maskname}.nc - -# start restart file with (2d) land sea mask; -h: suppress history - -ncks -A -h --no_abc -v ${maskname} ${maskname}.nc 1d_${restartfile} -ncrename -h -v ${maskname},'landseamask' 1d_${restartfile} 1> /dev/null - -# 'cdo showvar' does not work for variables with more than three dimensiones -variables=$(ncdump -h ${restartfile} | grep 'double ' | cut -f 2 -d ' ' | cut -f1 -d '(') - -for var in ${variables}; do - { - # extract specific variable; -a: suppress alphabetical order of variables and dimensions - ncks -O --no_abc -v ${var} ${restartfile} ${var}.nc - case ${var} in - lon | lat ) - echo "${script}: ignoring ${var}: not needed in restart file" - ;; - landseamask | disch | awfre ) - echo "${script}: ${var} should not be packed" - cp ${var}.nc 1d_${var}.nc - ;; - vct_a | vct_b ) - echo "${script}: ${var} cannot be packed" - cp ${var}.nc 1d_${var}.nc - ;; - * ) - echo "${script}: ${var}" - ${scriptdir}/pack < global_atts.$$ -#nlines=$(cat global_atts.$$ | wc -l) -#for (( l = 1; l <= $nlines; l++ )); do -# glatt=$(cat global_atts.$$ | head -$l | tail -1) -# name=$(echo ${glatt} | cut -f4 -d' ' | cut -f 1 -d,) -# type=$(echo ${glatt} | cut -f8 -d' ' | cut -c 4 | tr "A-Z" "a-z") -# value=$(echo ${glatt} | cut -f3 -d= ) -# [[ ${value} = "" ]] && value=' ' -# ncatted -h -a ${name},global,a,${type},"${value}" 1d_${restartfile} -#done -#rm global_atts.$$ -#ncatted -h -a history,global,a,c," $(date): pack_file.ksh ${restartfile}; " 1d_${restartfile} - diff --git a/couplings/utils/rotate_mesh.py b/couplings/utils/rotate_mesh.py deleted file mode 100644 index 6258812c1..000000000 --- a/couplings/utils/rotate_mesh.py +++ /dev/null @@ -1,68 +0,0 @@ -import random -import numpy as np -import xarray as xr -import pandas as pd -import sys -import math -import os -from tqdm import tqdm -from datetime import datetime -from numpy.linalg import inv - -mesh_path = sys.argv[1] -opath = sys.argv[2] -nod2d_file = os.path.join(mesh_path, "nod2d.out") - -def _generate_rotation_matrix(): - alphaEuler=50 - betaEuler=15 - gammaEuler=-90 - - al = np.radians(alphaEuler) - be = np.radians(betaEuler) - ga = np.radians(gammaEuler) - - rotate_matrix = np.zeros((3,3)) - rotate_matrix[0,0]=np.cos(ga)*np.cos(al)-np.sin(ga)*np.cos(be)*np.sin(al) - rotate_matrix[0,1]=np.cos(ga)*np.sin(al)+np.sin(ga)*np.cos(be)*np.cos(al) - rotate_matrix[0,2]=np.sin(ga)*np.sin(be) - rotate_matrix[1,0]=-np.sin(ga)*np.cos(al)-np.cos(ga)*np.cos(be)*np.sin(al) - rotate_matrix[1,1]=-np.sin(ga)*np.sin(al)+np.cos(ga)*np.cos(be)*np.cos(al) - rotate_matrix[1,2]=np.cos(ga)*np.sin(be) - rotate_matrix[2,0]=np.sin(be)*np.sin(al) - rotate_matrix[2,1]=-np.sin(be)*np.cos(al) - rotate_matrix[2,2]=np.cos(be) - - return rotate_matrix - -def _r2g(lon_r, lat_r): - A = _generate_rotation_matrix() - A_ = inv(A) - - lon_ = np.radians(lon_r) - lat_ = np.radians(lat_r) - - v_ = np.zeros((3,1)) - v_[0]=np.cos(lat_)*np.cos(lon_) - v_[1]=np.cos(lat_)*np.sin(lon_) - v_[2]=np.sin(lat_) - vr = np.dot(A_, v_) - - lon_g = np.degrees(math.atan2(vr[1], vr[0])) - lat_g = np.degrees(math.asin(vr[2])) - return lon_g, lat_g - -def _back_rotate(): - r2g_v = np.vectorize(_r2g, excluded="A") - - with open(nod2d_file, 'r') as csvfile: - nodes = pd.read_csv(csvfile, header=None, sep=r'\s* \s*', skiprows=1, engine='python') - #nodes.drop(nodes.index[0], inplace=True) - nodes.columns = ['index', 'lon', 'lat', 'mask'] - [lon_tmp, lat_tmp] = r2g_v(np.array(nodes['lon'].values[:], dtype=float).transpose(), - np.array(nodes['lat'].values[:], dtype=float).transpose()) - nodes['lon'] = lon_tmp - nodes['lat'] = lat_tmp - nodes.to_csv(os.path.join(opath, "nod2d.out"), sep=' ', header=[str(len(nodes)), "", "", ""], index=False) - -_back_rotate() diff --git a/couplings/utils/unpack.f90 b/couplings/utils/unpack.f90 deleted file mode 100644 index 85dd2d470..000000000 --- a/couplings/utils/unpack.f90 +++ /dev/null @@ -1,238 +0,0 @@ -!------------------------------------------------------------------------------ -! -! program reading a packed array and a corresponding 2d-mask and writes the unpacked array -! -! Compilation -! -! linux-x64: -! module load nag -! nagfor -colour -nan -gline -O0 -C=all -w=uep unpack.f90 -o unpack -I/sw/jessie-x64/netcdf_fortran-4.4.2-static-nag60/include -L/sw/jessie-x64/netcdf_fortran-4.4.2-static-nag60/lib -lnetcdff -L/sw/jessie-x64/netcdf-4.3.3.1-static-gccsys/lib/ -lnetcdf -L/sw/jessie-x64/hdf5-1.8.16-static-gccsys/lib -lhdf5_hl -lhdf5 -ldl -L/sw/jessie-x64/szip-2.1-static-gccsys/lib -lsz -lz -! -! mistral: -! module load nag -! export LD_LIBRARY_PATH="/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib:/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib:/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib" -! -! nagfor -colour '-maxcontin=100' '-wmismatch=define_var_new,nf_get_var_double,nf_copy_att,nf_get_var_real,nf_put_var_double,nf_def_var,nf_put_vara_double,dgemm,nfmpi_def_dim,nfmpi_put_vara_double,nfmpi_def_var' '-C=all' -g -gline -nan '-w=uep' -o unpack ./unpack.f90 -I/sw/rhel6-x64/netcdf/netcdf_fortran-4.4.2-static-nag60/include -L/sw/rhel6-x64/netcdf/netcdf_fortran-4.4.2-static-nag60/lib -lnetcdff -L/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib -lnetcdf -L/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib -lhdf5_hl -lhdf5 -ldl -L/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib -lsz -L/usr/lib64/lib -lz -ldl -lm -lnuma -Wl,--export-dynamic -lrt -lnsl -lutil -lm -ldl -!------------------------------------------------------------------------------ -PROGRAM unpack_array - - IMPLICIT NONE - INCLUDE 'netcdf.inc' - - INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(12,307) - REAL(dp), PARAMETER :: missval=NF_FILL_DOUBLE - INTEGER :: i, j, nlon, nlat, ntiles, nland, nsoil - INTEGER :: stat, ncid, ncin, varid, lonid, latid, varndims, idlon, idlat, idtile, idsoil - INTEGER, ALLOCATABLE :: vardimids(:) - - REAL(dp), ALLOCATABLE :: packed1d(:) - REAL(dp), ALLOCATABLE :: packed2d(:,:) - REAL(dp), ALLOCATABLE :: packed3d(:,:,:) - REAL(dp), ALLOCATABLE :: unpacked2d(:,:) - REAL(dp), ALLOCATABLE :: unpacked3d(:,:,:) - REAL(dp), ALLOCATABLE :: unpacked4d(:,:,:,:) - REAL(dp), ALLOCATABLE :: rmask(:,:) - REAL(dp), ALLOCATABLE :: lon(:) - REAL(dp), ALLOCATABLE :: lat(:) - LOGICAL, ALLOCATABLE :: lmask(:,:) - - CHARACTER*100 :: array_name, mask_name, tile_name, soil_name - - !PRINT*, 'enter array file name (without .nc)' - READ*, array_name - !PRINT*, 'enter mask file name (without .nc)' - READ*, mask_name - !PRINT*, 'Got:', array_name, 'and', 'mask_name' - !-- read land sea mask from mask file (array and file have the same names) - - stat = nf_open(TRIM(mask_name)//'.nc',NF_NOWRITE, ncin) - CALL hdlerr(stat) - stat = nf_inq_varid(ncin,mask_name,varid) - CALL hdlerr(stat) - - stat = nf_inq_varndims(ncin,varid,varndims) - CALL hdlerr(stat) - ALLOCATE(vardimids(varndims)) - stat = nf_inq_vardimid(ncin,varid,vardimids) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncin,vardimids(1),nlon) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncin,vardimids(2),nlat) - CALL hdlerr(stat) - DEALLOCATE(vardimids) - ALLOCATE(rmask(nlon,nlat)) - stat = nf_get_var_double(ncin,varid,rmask) - CALL hdlerr(stat) - - !-- read packed array from file (array and file have the same names) - - stat = nf_open(TRIM(array_name)//'.nc',NF_NOWRITE,ncid) - CALL hdlerr(stat) - stat = nf_inq_varid(ncid,array_name,varid) - CALL hdlerr(stat) - - stat = nf_inq_varndims(ncid,varid,varndims) - CALL hdlerr(stat) - ALLOCATE(vardimids(varndims)) - stat = nf_inq_vardimid(ncid,varid,vardimids) - CALL hdlerr(stat) - stat = nf_inq_dimlen(ncid,vardimids(1),nland) - CALL hdlerr(stat) - IF (varndims > 1) THEN - stat = nf_inq_dimlen(ncid,vardimids(2),ntiles) - CALL hdlerr(stat) - stat = nf_inq_dimname(ncid,vardimids(2),tile_name) - CALL hdlerr(stat) - END IF - IF (varndims > 2) THEN - stat = nf_inq_dimlen(ncid,vardimids(3),nsoil) - CALL hdlerr(stat) - stat = nf_inq_dimname(ncid,vardimids(3),soil_name) - CALL hdlerr(stat) - END IF - DEALLOCATE(vardimids) - - IF (varndims == 1) THEN - ALLOCATE(packed1d(nland)) - stat = nf_get_var_double(ncid,varid,packed1d) - CALL hdlerr(stat) - ELSE IF (varndims == 2) THEN - ALLOCATE(packed2d(nland,ntiles)) - stat = nf_get_var_double(ncid,varid,packed2d) - CALL hdlerr(stat) - ELSE - ALLOCATE(packed3d(nland,ntiles,nsoil)) - stat = nf_get_var_double(ncid,varid,packed3d) - CALL hdlerr(stat) - END IF - stat = nf_close(ncid) - CALL hdlerr(stat) - - !-- unpack the array - - ALLOCATE(lmask(nlon,nlat)) - WHERE (rmask == 1._dp) - lmask = .TRUE. - ELSEWHERE - lmask = .FALSE. - ENDWHERE - - IF (varndims == 1) THEN - ALLOCATE(unpacked2d(nlon,nlat)) - unpacked2d(:,:) = UNPACK(packed1d(:), MASK=lmask(:,:), FIELD=missval) - ELSE IF (varndims == 2) THEN - ALLOCATE(unpacked3d(nlon,nlat,ntiles)) - DO i = 1, ntiles - unpacked3d(:,:,i) = UNPACK(packed2d(:,i), MASK=lmask(:,:), FIELD=missval) - END DO - ELSE - ALLOCATE(unpacked4d(nlon,nlat,ntiles,nsoil)) - DO j = 1, nsoil - DO i = 1, ntiles - unpacked4d(:,:,i,j) = UNPACK(packed3d(:,i,j), MASK=lmask(:,:), FIELD=missval) - END DO - END DO - END IF - - !-- write the output file - - stat = nf_inq_varid(ncin,'lon',lonid) - CALL hdlerr(stat) - ALLOCATE(lon(nlon)) - stat = nf_get_var_double(ncin,lonid,lon) - CALL hdlerr(stat) - stat = nf_inq_varid(ncin,'lat',latid) - CALL hdlerr(stat) - ALLOCATE(lat(nlat)) - stat = nf_get_var_double(ncin,latid,lat) - CALL hdlerr(stat) - - stat = nf_create('2d_'//TRIM(array_name)//'.nc',NF_CLOBBER,ncid) - CALL hdlerr(stat) - stat = nf_def_dim(ncid, 'lon', nlon, idlon) - CALL hdlerr(stat) - stat = nf_def_dim(ncid, 'lat', nlat, idlat) - CALL hdlerr(stat) - IF (varndims > 1) THEN - stat = nf_def_dim(ncid, tile_name, ntiles, idtile) - CALL hdlerr(stat) - END IF - IF (varndims > 2) THEN - stat = nf_def_dim(ncid, soil_name, nsoil, idsoil) - CALL hdlerr(stat) - END IF - stat = nf_def_var(ncid, 'lon', NF_DOUBLE, 1, (/idlon/), lonid) - CALL hdlerr(stat) - stat = nf_def_var(ncid, 'lat', NF_DOUBLE, 1, (/idlat/), latid) - CALL hdlerr(stat) - IF (varndims == 1) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 2, (/idlon,idlat/), varid) - CALL hdlerr(stat) - ELSE IF (varndims == 2) THEN - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 3, (/idlon,idlat,idtile/), varid) - CALL hdlerr(stat) - ELSE - stat = nf_def_var(ncid, array_name, NF_DOUBLE, 4, (/idlon,idlat,idtile,idsoil/), varid) - CALL hdlerr(stat) - END IF - stat = nf_put_att_double(ncid, varid, '_FillValue', NF_DOUBLE, 1, missval) - CALL hdlerr(stat) - - stat = nf_enddef(ncid) - CALL hdlerr(stat) - - stat = nf_put_var_double(ncid,lonid,lon) - CALL hdlerr(stat) - stat = nf_put_var_double(ncid,latid,lat) - CALL hdlerr(stat) - IF (varndims == 1) THEN - stat = nf_put_var_double(ncid,varid,unpacked2d) - CALL hdlerr(stat) - ELSE IF (varndims == 2) THEN - stat = nf_put_var_double(ncid,varid,unpacked3d) - CALL hdlerr(stat) - ELSE - stat = nf_put_var_double(ncid,varid,unpacked4d) - CALL hdlerr(stat) - END IF - stat = nf_close(ncid) - CALL hdlerr(stat) - stat = nf_close(ncin) - CALL hdlerr(stat) - - DEALLOCATE(rmask, lmask, lon, lat) - IF (varndims == 1) THEN - DEALLOCATE(packed1d, unpacked2d) - ELSE IF (varndims == 2) THEN - DEALLOCATE(packed2d, unpacked3d) - ELSE - DEALLOCATE(packed3d, unpacked4d) - END IF - -END PROGRAM unpack_array - -!------------------------------------------------------------------------------ -! -! Routine to handle netcdf errors -! -!------------------------------------------------------------------------------ -SUBROUTINE hdlerr(stat) - - IMPLICIT NONE - - include 'netcdf.inc' - -! INTENT(in) - INTEGER, INTENT(in) :: stat - -!------------------------------------------------------------------------------ - - IF (stat /= NF_NOERR) THEN - WRITE (6,*) '--------' - WRITE (6,*) ' ERROR: ', nf_strerror(stat) - WRITE (6,*) '--------' - STOP - END IF - -END SUBROUTINE hdlerr -!------------------------------------------------------------------------------ diff --git a/couplings/utils/unpack_file.ksh b/couplings/utils/unpack_file.ksh deleted file mode 100755 index e8dc5a7c8..000000000 --- a/couplings/utils/unpack_file.ksh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/ksh -#------------------------------------------------------------------------------ -# Script to unpack all variables of a jsbach restart file. -# -# Veronika Gayler, June 2013 -#------------------------------------------------------------------------------ -set -e - -restart=$1 # file with packed data -maskfile=$2 # file with corresponding land sea mask -# maskfile=/pool/data/JSBACH/T63/jsbach_T63GR15_11tiles_1850.nc -maskname=slm # variable name of the land sea mask in maskfile - -#------------------------------------------------------------------------------ -. ${MODULESHOME}/init/ksh -module load nco || true -module unload cdo || true -if [[ $(uname -n | cut -c1-6) == mlogin || $(uname -n | cut -c1-9) == mistralpp || $(uname -n) == m????? ]]; then - module load cdo/1.7.2-magicsxx-gcc48 - export LD_LIBRARY_PATH="/sw/rhel6-x64/hdf5/hdf5-1.8.14-threadsafe-gcc48/lib:/sw/rhel6-x64/netcdf/netcdf_c-4.4.0-gcc48/lib:/sw/rhel6-x64/sys/libaec-0.3.2-gcc48/lib" -else - #module load cdo/1.7.2-gccsys - module load cdo #/1.7.2 -fi -#------------------------------------------------------------------------------ - -if [[ ${restart} = "" ]]; then - echo " ERROR: " - echo " you need to define the name of the file with packed data" - echo " and a file containing the corresponding land sea mask" - exit 1 -fi - -restartfile=${restart##*/} -[[ ${restartfile} = ${restart} ]] && restart=./${restart} -mydir=$(pwd) -restartdir=${restart%/*}; cd ${restartdir}; restartdir=$(pwd) -cd ${mydir} -scriptdir=${0%/*} #; cd ${scriptdir}/..; scriptdir=$(pwd) -script=$(basename $0) - -if [[ ! -f ./unpack ]]; then - echo " ERROR: " - echo " The program 'unpack' is missing." - echo " Compile /contrib/unpack.f90 and place the executable in this " - echo " directory. Instructions are given in the program header." - exit 1 -fi - -# data processing -#----------------- - -cd ${restartdir} -[[ -f 2d_${restartfile} ]] && rm 2d_${restartfile} -cdo -s -selvar,${maskname} ${maskfile} ${maskname}.nc - -variables=$(cdo -s showvar ${restartfile}) -for var in ${variables}; do - { - echo "${script}: ${var}" - ncks -O -v ${var} ${restartfile} ${var}.nc - case ${var} in - landseamask | disch | awfre ) - echo "${script}: copying ${var}: already on lat lon grid" - ln -fs ${var}.nc 2d_${var}.nc - ;; - vct_a | vct_b ) - echo "${script}: copying ${var}: no landpoint dimension" - ln -fs ${var}.nc 2d_${var}.nc - ;; - *) - ${scriptdir}/unpack < global_atts.$$ -#nlines=$(cat global_atts.$$ | wc -l) -#for (( l = 1; l <= $nlines; l++ )); do -# glatt=$(cat global_atts.$$ | head -$l | tail -1) -# name=$(echo ${glatt} | cut -f4 -d' ' | cut -f 1 -d,) -# type=$(echo ${glatt} | cut -f8 -d' ' | cut -c 4 | tr "A-Z" "a-z") -# value=$(echo ${glatt} | cut -f3 -d= ) -# [[ ${value} = "" ]] && value=' ' -# ncatted -h -a ${name},global,a,${type},"${value}" 2d_${restartfile} -#done -#rm global_atts.$$ -ncatted -h -a history,global,a,c," $(date): unpack_file.ksh ${restartfile}; " 2d_${restartfile} -echo "All done with ${script}: Output is $(pwd)/2d_${restartfile}" diff --git a/couplings/vilma/coupling_ice2vilma.functions b/couplings/vilma/coupling_ice2vilma.functions deleted file mode 100644 index 987f1bdcf..000000000 --- a/couplings/vilma/coupling_ice2vilma.functions +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/ksh - -function ice2vilma { - echo " ==================================================================" - echo " *** S T A R T I N G ice2vilma *** "; echo - - echo " ICE_TO_VILMA=${ICE_TO_VILMA}" - - if [[ "x${ICE_TO_VILMA}" == "x1" ]]; then - read_names ice solidearth - iterative_coupling_ice_vilma_regrid - iterative_coupling_ice_vilma_make_eislastfile - iterative_coupling_ice_vilma_make_dflag - iterative_coupling_ice_vilma_make_loadh - else - echo " NOT generating ice forcing for solid earth" - fi - echo - echo " *** F I N I S H E D ice2vilma *** " - echo " ==================================================================" -} - -function iterative_coupling_ice_vilma_regrid { - -# Regrid to vilma input grid - cdo -s \ - -remapcon,${VILMA_GRID_input} \ - -setgrid,${COUPLE_DIR}/ice.griddes \ - ${solidearth_ice_thickness_file} \ - ${COUPLE_DIR}/tmp.nc - -# Split for ice thickness and mask - ncks -v ${ice_thickness_name} ${COUPLE_DIR}/tmp.nc ${COUPLE_DIR}/tmp_${ice_thickness_name}.nc - ncks -v ${ice_mask_name},${ice_topography_name} ${COUPLE_DIR}/tmp.nc ${COUPLE_DIR}/tmp_${ice_mask_name}.nc - -# Clean up - rm ${COUPLE_DIR}/tmp.nc -} - -function iterative_coupling_ice_vilma_make_eislastfile { - - ADD_UNCHANGED_ICE=${ADD_UNCHANGED_ICE:-0} # Options to add ice that is left unchanged by the ice sheet model results - if [ "x${ADD_UNCHANGED_ICE}" == "x1" ]; then - - cdo -s \ - setmisstoc,0 \ - ${COUPLE_DIR}/tmp_${ice_thickness_name}.nc ${COUPLE_DIR}/tmp2_${ice_thickness_name}.nc - - cdo -s \ - add ${COUPLE_DIR}/tmp2_${ice_thickness_name}.nc ${ADD_UNCHANGED_ICE_file} \ - ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - - rm tmp2_${ice_thickness_name}.nc - else - cdo -s \ - setmisstoc,0 \ - ${COUPLE_DIR}/tmp_${ice_thickness_name}.nc \ - ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - fi - -# Make the file compatible with the format of the eislastfile - ncap2 -s "time=time * 0.001" ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc -A ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncrename -d time,epoch -v time,epoch ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncatted -a units,epoch,o,c,'ka BP' ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncatted -a long_name,epoch,o,c,'ka BP' ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncrename -v ${ice_thickness_name},Ice ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - - cp ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc ${EISLASTFILE_vilma} - -# Clean up - # In principle one can delete: rm ${COUPLE_DIR}/eislastfile_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - rm tmp_${ice_thickness_name}.nc -} - -function iterative_coupling_ice_vilma_make_dflag { - - if [[ ${RUN_NUMBER_vilma} > 1 ]]; then - -# Select the relevant timesteps - cdo -s \ - delete,timestep=1 \ - -delete,timestep=-1 \ - ${COUPLE_DIR}/tmp_${ice_mask_name}.nc ${COUPLE_DIR}/tmp5.nc - mv ${COUPLE_DIR}/tmp5.nc ${COUPLE_DIR}/tmp_${ice_mask_name}.nc - -# Change from the ice sheet model mask to VILMA mask - ncap2 -s "flg2=mask*0; where(mask==${VALUE_LAND_ice}){flg2=0;} where(mask==${VALUE_GROUNDED_ice}){flg2=2;} where((mask==${VALUE_GROUNDED_ice}) && (${ice_topography_name} < 0)){flg2=3;} where(mask==${VALUE_FLOATING_ice}){flg2=4;} where(mask==${VALUE_OCEAN_ice}){flg2=1;}" ${COUPLE_DIR}/tmp_${ice_mask_name}.nc ${COUPLE_DIR}/dflag-tmp_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - -# Import the existing dflag file that is to be changed - cp ${DATA_DIR_vilma}/dflag.nc ${COUPLE_DIR}/to_merge.nc - ncrename -d epoch,time -v epoch,time ${COUPLE_DIR}/to_merge.nc - ncap2 -s "time=time * 1000." ${COUPLE_DIR}/to_merge.nc -A ${COUPLE_DIR}/to_merge.nc - -# Merge to prepare for the replacement on the ice sheet model grid - cdo -s \ - merge ${COUPLE_DIR}/dflag-tmp_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc ${COUPLE_DIR}/to_merge.nc \ - ${COUPLE_DIR}/dflag-tmp2_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - -# Replace those areas affected by the ice sheet model - ncap2 -s 'where (flg2 > -1) {flg=flg2;}' ${COUPLE_DIR}/dflag-tmp2_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - -# Make the file compatible with the format of the dflag file - ncap2 -s "time=double(time * 0.001)" ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc -A ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncrename -d time,epoch -v time,epoch ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncatted -a units,epoch,o,c,'ka BP' ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncatted -a long_name,epoch,o,c,'Time Epoch' ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncatted -a standard_name,epoch,o,c,'epoch' ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncatted -a axis,epoch,o,c,'Epoch' ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncatted -O -a calendar,epoch,d,, ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncatted -O -a reference,flg,d,, ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - ncks -v flg ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc ${COUPLE_DIR}/dflag_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - - cp ${COUPLE_DIR}/dflag_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc ${DATA_DIR_vilma}/dflag.nc - -# Clean up - # In principle one can delete: rm ${COUPLE_DIR}/dflag_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - rm ${COUPLE_DIR}/dflag-tmp_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - rm ${COUPLE_DIR}/dflag-tmp2_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - rm ${COUPLE_DIR}/dflag-tmp3_vilma_${CURRENT_YEAR_ice}-${END_YEAR_ice}.nc - else - continue - fi - - rm tmp_${ice_mask_name}.nc -} - -function iterative_coupling_ice_vilma_make_loadh { - - if [ $RUN_NUMBER_ice -eq 1 ]; then - - : > ${COUPLE_DIR}/eislastconf_vilma.inp - - INITIAL_YEAR_vilma=$(echo "${INITIAL_DATE_vilma_standalone}" | awk '{print substr($0, 0, length($0)-6)}' ) - FINAL_YEAR_vilma=$(echo "${FINAL_DATE_vilma_standalone}" | awk '{print substr($0, 0, length($0)-6)}' ) - LOADH_NO_OF_RUNS=$(echo "((${FINAL_YEAR_vilma} - ${INITIAL_YEAR_vilma}) / ${NYEAR_vilma_standalone}) + 1" | bc ) - - case ${VILMA_GRID_input} in - "n128") - echo "256 512 910 1020" >> ${COUPLE_DIR}/eislastconf_vilma.inp - ;; - "n256") - echo "512 1024 910 1020" >> ${COUPLE_DIR}/eislastconf_vilma.inp - ;; - *) - echo "Undefined VILMA_GRID_input! Should be n128 or n256." >> ${COUPLE_DIR}/eislastconf_vilma.inp - esac - echo "${LOADH_NO_OF_RUNS}" >> ${COUPLE_DIR}/eislastconf_vilma.inp - for i in $(seq ${INITIAL_YEAR_vilma} ${NYEAR_vilma_standalone} ${FINAL_YEAR_vilma}) - do - LOADH_NEXT_VALUE=$(echo "${i} * 0.001" | bc -l ) - echo "${LOADH_NEXT_VALUE}" >> ${COUPLE_DIR}/eislastconf_vilma.inp - done - - cp ${COUPLE_DIR}/eislastconf_vilma.inp ${EISLASTCONF_vilma} - - else - continue - fi - -} - - - diff --git a/couplings/vilma/coupling_vilma2ice.functions b/couplings/vilma/coupling_vilma2ice.functions deleted file mode 100644 index 996e0003e..000000000 --- a/couplings/vilma/coupling_vilma2ice.functions +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/ksh - -function vilma2ice { - echo " ==================================================================" - echo " *** S T A R T I N G vilma2ice *** "; echo - - echo " VILMA_TO_ICE=${VILMA_TO_ICE}" - - if [[ "x$VILMA_TO_ICE" == "x1" ]]; then - - iterative_coupling_vilma_ice_write_names - iterative_coupling_vilma_ice_make_forcing - - else - echo " NOT generating solid earth forcing for ice" - fi - echo - echo " *** F I N I S H E D vilma2ice *** " - echo " ==================================================================" -} - -function iterative_coupling_vilma_ice_write_names { - : > ${COUPLE_DIR}/solidearth_names_for_ice.dat - SOLIDEARTH_grid=${VILMA_GRID_input} - BEDROCK_CHANGE_VARNAME_vilma=rsl - echo "bedrock_change_name=${BEDROCK_CHANGE_VARNAME_vilma}" >> ${COUPLE_DIR}/solidearth_names_for_ice.dat - echo "RUN_NUMBER_solidearth=${RUN_NUMBER_vilma}" >> ${COUPLE_DIR}/solidearth_names_for_ice.dat -} - -function iterative_coupling_vilma_ice_make_forcing { - - ice_bedrock_change_file=${COUPLE_DIR}/bedrock_change.nc - - cp ${DATA_DIR_vilma}/rsl.nc ${COUPLE_DIR}/new_bedrock.nc - - # Subtract the previous bedrock conditions to obtain the change - # At first time step there are no previous conditions to subtract - if [ "x${RUN_NUMBER_vilma}" == "x1" ]; then - cp ${COUPLE_DIR}/new_bedrock.nc ${ice_bedrock_change_file} - else - cdo -s \ - sub ${COUPLE_DIR}/new_bedrock.nc ${COUPLE_DIR}/old_bedrock.nc \ - ${ice_bedrock_change_file} - fi - - # rsl is minus the change in bedrock - ncap2 -s 'rsl=-rsl' ${ice_bedrock_change_file} -A ${ice_bedrock_change_file} - - # The new conditions become the old for the next timestep - mv ${COUPLE_DIR}/new_bedrock.nc ${COUPLE_DIR}/old_bedrock.nc - -}