#!/bin/ksh 

## Script to test the surface only model in a 2D global configuration 
## Emanuel Dutra, August 2017

## The variable $SLOC should be defined before calling the script or it will 
## fall to the default: ${SCRATCH}/ec-earth/r4381-surface_only/surf/ (at ECMWF machines)

##==================================================
##  00. function to create model input namelist 
function create_input_namelist {

cat > input << EOF
&NAMCT01S
  NSTART=$NSTART           ! first timestep of model 0 
  NSTOP=$NSTOP             ! last timestep of model 17520
  NFRPOS=$NFRPOS           ! frequency of post-processing events (time-steps)
  NFRRES=0                 ! frequency of writing intermediate restart files (time-steps)
  LNF=$LNF                 ! .T. = start, .F. = restart
  NCYCLE=1                 ! number of the experiment
  CNMEXP="TEST"            ! name of the experiment
  /
  &NAMDYN1S
  TSTEP=$OSMTSTEP          !  TSTEP   : length of the timestep in seconds
  NACCTYPE=2               ! =0  Forcing fluxes assument centered on timestamp (linear interp.)
                           ! =1  forward accumulation (starting at timestamp)
                           ! =2  backward accumulation (ending at timestamp)
  LSWINT=.TRUE.            ! SWdown solar angle interpolation if true 
  LPREINT=.FALSE.          ! precipitation interpolation if true
  LFLXINT=.FALSE.          ! SWdown/LWdown linear interpolation if true 
  /
  &NAMDIM
  NLAT=$NLAT               ! number of latitudes
  NLON=$NLON               ! number of longitudes
  NDFORC=$NDFORC           ! namelist forcing dimension
  NSLAB=0                  ! 2D, NSLAB = nr of latitude lines
  NPROMA=${NPROMA:-240}    ! working dimension for grid-point computations
  /
  &NAMRIP
  NINDAT=${NINDAT}         ! run initial date in the form YYYYMMDD 
  NSSSSS=0                 ! initial time in seconds (e.g. for 12h, 43200)
  /
  &NAM1S
  CFFORC='netcdf'          ! CHARACTER: IDENTIFIES THE FORCING DATA SET
  CFOUT='netcdf'           ! CHARACTER: IDENTIFIES THE OUTPUT DATA SET
  CFSURF='netcdf'          ! CHARACTER: IDENTIFIES THE SURFACE CLIMATOLOGY DATA SET 
  CFINIT='netcdf'          ! CHARACTER: IDENTIFIES THE INITIALIZATION DATA SET
  CMODID='EC-EARTH3'       ! CHARACTER: MODEL IDENTIFICATION
  CVERID='test'            ! CHARACTER: VERSION IDENTIFICATION 
  LACCUMW=.TRUE.           ! LOGICAL : WRITE OUT ACCUMULATED FLUXES (DEFAULT=TRUE)
  LRESET=.TRUE.            ! LOGICAL : RESET ACCUMULATION EVERY WRITE OUT TIME STEP
  NACCUR=1                 ! INTEGER : OUTPUT CDF ACCURACY: 1=SINGLE PREC, 2=DOUBLE PREC
  NDIMCDF=${NDIMCDF}       ! INTEGER : NR OF GRID DIMENSIONS
  NDLEVEL=${NDLEVEL:-0}    ! INTEGER : Level of netcdf4 compression 0-9: 0== no compression -faster output
  NCDFTYPE=${NCDFTYPE:-4}  ! type of netcdf output
  LNCSNC=.FALSE.           ! if true sync netcdf output every writting step (slows down run)
  LWRGG=${LWRGG:-.T.}      ! logical, wrtie o_gg  - instantaneus prognostics 
  LWRCLM=.True.             ! logical, write o_fix - fix soil properties 
  LWRGGD=${LWRGGD:-.T.}           ! logical, write o_ggd - mean prognostic since previous post-processing 
  LWREFL=${LWREFL:-.T.}           ! logical, write o_efl - surface energy balance 
  LWRWAT=${LWRWAT:-.T.}           ! logical, write o_wat - water balance
  LWRD2M=${LWRD2M:-.T.}           ! logical, write o_d2m - 2 meters diagnostics 
  LWRSUS=${LWRSUS:-.T.}           ! logical, write o_sus - surface state variables (vegT,albedo, etc..)
  LWREVA=${LWREVA:-.T.}           ! logical, write o_eva - evaporation components 
  LWRCLD=${LWRCLD:-.T.}           ! logical, write o_cld - cold processes variables 
  LWRCO2=${LWRCO2:-.F.}           ! logical, write o_co2 - cO2 fluxes 
  LWRBIO=${LWRBIO:-.F.}           ! logical, write o_bio - biomass 
  LWRVEG=${LWRVEG:-.F.}           ! logical, write o_veg - vegetation 2D high/low veg 
  LWRVTY=${LWRVTY:-.F.}           ! logical, write o_vty - vegetation 2D high/low veg biomass
  LWRTIL=${LWRTIL:-.T.}           ! logical, write o_til - tiles 2D (tile) state
  LSEMISS=.FALSE.          ! LOGICAL : EMISSIVITY SET TO CONSTANT VALUE REMISS
  LDBGS1=.FALSE.           ! LOGICAL : PRINT DEBUG INFO, EG FORCING DATA (DEFAULT=FALSE)
  IDBGS1=2                 ! Debug level : output printing 
  /
  &NAMFORC
  ZPHISTA=${FCHEIGHT:-10}      ! REFERENCE LEVEL (FOR T, Q) last model level ERAI
  ZUV=${FCHEIGHT:-10}          ! REFERENCE LEVEL FOR WIND   last model level ERAI
  ZDTFORC=$ZDTFORC         ! FORCING TIME STEP     3h forcing from ERAI 
  INSTFC=0                 ! NUMBER OF TIME STEPS TO BE READ (0 = ALL)
  NDIMFORC=${NDIMCDF}      ! NUMBER OF GRID DIMENSIONS in FORCING
  LOADIAB=.FALSE.          ! FLAG FOR APPLYING ADIABATIC HEIGHT CORRECTION
  CFORCV="${CFORCV:-'xx'}"         ! netcdf file name with wind U component
  CFORCU="$CFORCU"         ! netcdf file name with wind V component 
  CFORCT="$CFORCT"         ! netcdf file name with air temperature
  CFORCQ="$CFORCQ"         ! netcdf file name with wind air specific humidity
  CFORCP="$CFORCP"         ! netcdf file name with surface pressure
  CFORCRAIN="$CFORCRAIN"   ! netcdf file name with rainfall 
  CFORCSNOW="$CFORCSNOW"   ! netcdf file name with snowfall
  CFORCSW="$CFORCSW"       ! netcdf file name with short-wave down radiation
  CFORCLW="$CFORCLW"       ! netcdf file name with long-wave down radiation
  /
  &NAMPHY
  LEVGEN=.TRUE.            ! LOGICAL : TURN THE VAN GENUCHTEN HYDROLOGY ON
  LESSRO=.TRUE.            ! LOGICAL : TURN THE SUB-GRID SURFACE RUNOFF ON
  LEFLAKE=.FALSE.          ! LOGICAL : TURN THE FLAKE ON
  LESN09=.TRUE.            ! LOGICAL : TURN THE NEW SNOW PARAMETERIZATION ON 
  LELAIV=.TRUE.           ! LOGICAL : TURN THE LAI SEASONAL ON
  LECTESSEL=.FALSE.        ! LOGICAL : TURN CTESSEL ON
  LEAGS=.FALSE             ! LOGICAL : TURN AGS EVAPORATION
  LECLIM10D=.FALSE.        ! LOGICAL : TURN usage of 10-day Climatology for Alb and LAI
  LE4ALB=.TRUE.
  /
  &NAMPHYOFF
  LRDALB=.FALSE. 
  N_COMPUTE_EFF_VEG_FRACTION=1
  /
EOF

}

set -exuv 

SCRATCH=${SCRATCH:-unset}  # check if SCRATCH is defined 
## BASEDIR 
SLOC=${SLOC:-"${SCRATCH}/ec-earth/r1902-merge-new-components_surface_only/surf/"}  # at ecmwf or predefined 



##===============================0
## 0. Some defaults 
FYYYYMM=197901    # forcing YYYYMM 
if [[ "${SCRATCH}" != "unset" ]]; then
  # at ECMWF set the http proxy for wget to work 
  export http_proxy=proxy.ecmwf.int:3333
  MASTERBIN="$SLOC/../osm/cce-opt/build/bin/master1s.exe"  # location of model binary 
  INICLM="/perm/rd/need/public/ini_clm_e2o_dflt_050.nc"  #Initial / climate conditions on ECMWF HPC cca/ccb 
else
  # My local definitions
  INICLM="/home/emanuel/data/work/e2o/ini_clm_e2o_dflt_050_bare.nc" 
  MASTERBIN="$SLOC/../osm/gnu-opt/build/bin/master1s.exe"  # location of model binary 
fi


## Define other paths
DATADIR=$SLOC/../test/data/    # location of data 
RDIR=$SLOC/../test/run2d/      # location to run the model 
mkdir -p $DATADIR
mkdir -p $RDIR 

# model run specifics 
OSMTSTEP=3600  # model time step in seconds 
FREQ_PP_OSM=3  # frequency of model post-processing in hours 
ZDTFORC=10800  # forcing frequency in seconds 
NSTART=0       # model start time-step 
LNF=.TRUE.     # .T. = start, .F. = restart
NDAYS=2        # number of days to run 
NDIMCDF=2      # number of netcdf dimensions 



##===================================
## 1. Get forcing and IniClm 
## Here we use the Earth2Observe forcing data (see doi.org/10.5194/essd-9-389-2017)
cvars="LWdown SWdown Rainf Snowf Tair Qair PSurf Wind "
cd $DATADIR
for ff in $cvars 
do
  if [[ ! -r ${ff}_E2OBS_${FYYYYMM}.nc ]]; then
    wget http://wci.earth2observe.eu/thredds/fileServer/ecmwf/met_forcing_v0/${FYYYYMM:0:4}/${ff}_E2OBS_${FYYYYMM}.nc
  fi
done
cp $INICLM $DATADIR/ini_clm_test2d.nc 

##===================================
## 2. Go to RUn dir and prepare stuff 
cd $RDIR
rm -rfv *

# 2.1 get data here as symlinks 
for ff in $cvars
do 
  ln -sf $DATADIR/${ff}_E2OBS_${FYYYYMM}.nc ${ff}.nc 
done
CFORCU=Wind.nc 
CFORCT=Tair.nc 
CFORCQ=Qair.nc
CFORCP=PSurf.nc 
CFORCRAIN=Rainf.nc
CFORCSNOW=Snowf.nc 
CFORCSW=SWdown.nc
CFORCLW=LWdown.nc 

ln -sf $DATADIR/ini_clm_test2d.nc surfclim
ln -sf $DATADIR/ini_clm_test2d.nc soilinit 
if [[ -r $MASTERBIN ]]; then
  ln -sf $MASTERBIN master1s.exe
else
  echo "Could not find binary "
  exit -1 LELAIV
fi 

#2.2 Some calculations
NFRPOS=$(( $(( 3600*${FREQ_PP_OSM} ))/$OSMTSTEP ))
NSTEPSDAY=$(( 86400/$OSMTSTEP ))
NSTOP=$(( $NSTART + $NDAYS*$NSTEPSDAY ))

#2.3 Info from forcing data 
## Info from forcing data 
NDFORC=$( ncdump -h ${CFORCLW}  | grep UNLIMITED | awk '{print $6 }' | cut -c2- )
NDFORC=$(( $NDFORC + 1 ))
NLAT=$( ncdump -h ${CFORCLW}  | grep "^.y = " |  head -1 | awk '{print $3}' )
NLON=$( ncdump -h ${CFORCLW}  | grep "^.x = " |  head -1 | awk '{print $3}' )
if [[ $NLAT = "" ]]; then 
    NLAT=$( ncdump -h ${CFORCLW}  | grep "^.lat = " |  head -1 | awk '{print $3}' )
    NLON=$( ncdump -h ${CFORCLW} | grep "^.lon = " |  head -1 | awk '{print $3}' )
fi 
STEP1=$( cdo -s -infov -seltimestep,1 $CFORCLW | head -2 | tail -1 | awk '{print $3$4}' )
NINDAT=$( echo $STEP1 | cut -c1-4)$( echo $STEP1 | cut -c6-7)$( echo $STEP1 | cut -c9-10)
NSSSSS=0

# create namelist 
create_input_namelist

## RUN THE MODEL 
export OMP_NUM_THREADS=${OMP_NUM_THREADS:-1}
export OMP_STACKSIZE=128M # can be increased in case you have seg. faults / core dump when running with large OMP_NUM_THREADS 
ulimit -s unlimited 
echo $PWD
# exit -1 
time -o tmp.txt ./master1s.exe 1> run.log 2>&1 
if [ $? -ne 0 ];then 
  echo "Error running osmMaster..."
  tail -n50 run.log
  echo "running at: $RDIR"
  exit 1
else
  echo "OSM run OK "
fi
cat tmp.txt >> run.log 

