#!/bin/bash

###########################################################################
# Author : Frédéric Hourdin/LMD/hourdin@lmd.jussieu.fr
# Usage  : install.sh
#
# bash installation script of the LMDZ model on a Linux PC.
# the model is downloaded in the following direcory tree
# $MODEL/modipsl/modeles/...
# using the "modipsl" infrastructure created by the "IPSL"
# for coupled (atmosphere/ocean/vegetation/chemistry) climate modeling
# activities.
# Here we only download atmospheric (LMDZ) and vegetation (ORCHIDEE)
# components.
#
# The sources of the models can be found in the "modeles" directory.
# In the present case, LMDZ5, ORCHIDEE and IOIPSL (handling of input-outputs
# using the NetCDF library.
#
# The script downloads various source files (including a version of NetCDF)
# and utilities, compiles the model, and runs a test simulation in a
# munimal configuration.
#
# Prerequisites : g95/pgf90/gfortran, ksh, wget , gunzip, tar, ... 
#
# Modif 18/11/2011
#    changes for option real 8.
#      We comopile with -r8 (or equivalent) and -DNC_DOUBLE for the GCM
#      but with -r4 for netcdf. Variable real must be set to 
#      r4 or r8 at the beginning of the script below.
#
###########################################################################

echo install.sh DEBUT `date`

set -e

echo '################################################################'
echo  Choice of installation options 
echo '################################################################'


#real=r4
real=r8

# WARNING !!!! For versions before october 2009, use
# install.v2.sh instead of install.sh

version=20130716.trunk
version=testing
compilo=gfortran # compilo=pgf90 or g95 or gfortran or ifort sur PC linux

#Chemin pour placer le modele
MODEL=./LMDZ$version


getlmdzor=1
netcdf=1   #  1 for automatic installation
           #  0 for no installation
           #  /.../../netcdf-4.0.1 if wanting to link with an already
           #  compiled netcdf library (implies to check option compatibility)
check_linux=1
ioipsl=1
veget=1
bench=1
pclinux=1

# choose the resolution for the bench runs
# grid_resolution= 32x24x11 or 48x36x19 for tests (test without ORCHIDEE)
#                  96x71x19  standard configuration
grid_resolution=48x36x19

## compile_with_fcm=1 : use makelmdz_fcm, possible a of version 20111103.trunk (LMDZ5/trunk rev 1578)
## compile_with_fcm=0 : use makelmdz
compile_with_fcm=0


#####################################################################
# Test for old gfortran compilers
# If the compiler is too old (older than 4.3.x) we test if the
# temporary gfortran44 patch is available on the computer in which
# case the compiler is changed from gfortran to gfortran44
# Must be aware than parallelism can not be activated in this case
#####################################################################

if [ $compilo = gfortran ] ; then
   gfortran=gfortran
   gfortranv=`gfortran --version | \
   head -1 | awk ' { print $NF } ' | awk -F. ' { print $1 * 10 + $2 } '`
   if [ $gfortranv -le 43 ] ; then
       echo ERROR : Your gfortran compiler is too old
       echo 'Please choose a new one (g95, ifort) and change the line'
       echo compilo=xxx
       echo in the install.sh script and rerun it
       if [ `which gfortran44 | wc -w` -ne 0 ] ; then
          gfortran=gfortran44
       else
          echo gfotran trop vieux ; exit
       fi
   fi
   compilo=$gfortran
fi
#####################################################################



OPTPREC=""
echo '################################################################'
echo  Choix des options de compilation
echo '################################################################'

OPTIMNC=$OPTIM
export FC=$compilo
export F90=$compilo
export F77=$compilo
export CPPFLAGS=
BASE_LD=
if [ $compilo = g95 ] ; then
# Set the appropriate compilation options
   OPTIM='-i4 -O3'
   OPTDEB="-g -O0 -Wall -ftrace=full -fbounds-check -freal=nan"
   OPTDEV="-g -O1 -Wall"
   fmod='fmod='
   BASE_LD=""
   if [ $real = r8 ] ; then OPTPREC="-r8 -DNC_DOUBLE" ; fi
   export F90FLAGS=" -cpp -ffree-form $OPTIMNC"
   export FFLAGS=" -cpp $OPTIMNC"
   export CPPFLAGS=-Df2cFortran
   export CC=gcc
   export CXX=g++
elif [ $compilo = $gfortran ] ; then
   OPTIM='-O3'
   OPTDEB="-g3 -Wall -fbounds-check -ffpe-trap=invalid,zero,overflow -O0 -fstack-protector-all"
   OPTDEV="-Wall -fbounds-check"
   fmod='I '
   if [ $real = r8 ] ; then OPTPREC="-fdefault-real-8 -DNC_DOUBLE" ; fi
   export F90FLAGS=" -ffree-form $OPTIMNC"
   export FFLAGS=" $OPTIMNC"
   export CC=gcc
   export CXX=g++
elif [ $compilo = mpif90 ] ; then
   OPTIM='-O3'
   OPTDEB="-g3 -Wall -fbounds-check -ffpe-trap=invalid,zero,overflow -O0 -fstack-protector-all"
   OPTDEV="-Wall -fbounds-check"
   BASE_LD="-lblas"
   fmod='I '
   if [ $real = r8 ] ; then OPTPREC="-fdefault-real-8 -DNC_DOUBLE -fcray-pointer" ; fi
   export F90FLAGS=" -ffree-form $OPTIMNC"
   export FFLAGS=" $OPTIMNC"
   export CC=gcc
   export CXX=g++
elif [ $compilo = pgf90 ] ; then
   OPTIM='-O2 -Munroll -Mnoframe -Mautoinline -Mcache_align'
   fmod='module '
   if [ $real = r8 ] ; then OPTPREC="-r8 -DNC_DOUBLE" ; fi
   export CPPFLAGS="-DNDEBUG -DpgiFortran"
   export CC=pgcc
   export CFLAGS="-Msignextend"
   export CXX=pgCC
   export CXXFLAGS="-Msignextend"
   export FFLAGS="$OPTIMNC"
   export F90FLAGS="$OPTIMNC"
   compile_with_fcm=1
elif [ $compilo = ifort ] ; then
   OPTIM="-O2 -fp-model strict -ip -align all "
   OPTDEV="-p -g -O2 -traceback -fp-stack-check -ftrapuv -check"
   OPTDEB="-g -no-ftz -traceback -ftrapuv -fp-stack-check -check"
   fmod='module '
   if [ $real = r8 ] ; then OPTPREC="-real-size 64 -DNC_DOUBLE" ; fi
   export CPP="icc -E"
   export FFLAGS="-O2 -ip -fpic -mcmodel=large"
   export FCFLAGS="-O2 -ip -fpic -mcmodel=large"
   export CC=icc
   export CFLAGS="-O2 -ip -fpic -mcmodel=large"
   export CXX=icpc
   export CXXFLAGS="-O2 -ip -fpic -mcmodel=large"
   compile_with_fcm=1
else
   echo unexpected compiler $compilo ; exit
fi

OPTIMGCM="$OPTIM $OPTPREC"

hostname=`hostname`

##########################################################################
# If installing on know machines such as IBM x3750 (Ada)
# at IDRIS, don't check for available software and don"t install netcdf
if [ ${hostname:0:5} = ada33 ] ; then
  netcdf=0 # no need to recompile netcdf, alreday available
  check_linux=0
  pclinux=0
  ioipsl=0 # no need to recompile ioipsl, already available
  #netcdf="/smplocal/pub/NetCDF/4.1.3"
  compilo="ifort"
  fmod='module '
  if [ $real = r8 ] ; then OPTPREC="-real-size 64 -DNC_DOUBLE" ; fi
  OPTIM="-O2 -fp-model strict -ip -axAVX,SSE4.2 -align all "
  OPTIMGCM="$OPTIM $OPTPREC"
fi
##########################################################################


mkdir -p $MODEL
echo $MODEL
MODEL=`( cd $MODEL ; pwd )` # to get absolute path, if necessary



# Option -fendian=big is only to be used with ARPEGE1D.
# The -r8 should probably be avoided if running on 32 bit machines
# Option r8 is not mandatory and generates larger executables.
# It is however mandatory if using ARPEGE1D
# Better optimization options might be a better choice (e.g. -O3)


echo '################################################################'
if [ "$check_linux" = 1 ] ; then
echo   Check if required software is available
echo '################################################################'

#### Ehouarn: test if ksh and/or bash are available
use_shell="ksh" # default: use ksh
if [ "`which ksh`" = "" ] ; then
  echo "no ksh ... we will use bash"
  use_shell="bash"
  if [ "`which bash`" = "" ] ; then
    echo "ksh (or bash) needed!! Install it!"
  fi
fi


for logiciel in csh wget tar gzip make $compilo gcc ; do
if [ "`which $logiciel`" = "" ] ; then
echo You must first install $logiciel on your system
exit
fi
done

if [ $pclinux = 1 ] ; then
cd $MODEL
cat <<eod > tt.f90
print*,'coucou'
end
eod
$compilo tt.f90 -o a.out
./a.out >| tt
if [ "`cat tt | sed -e 's/ //g' `" != "coucou" ] ; then
echo problem installing with compiler $compilo ; exit ; fi
\rm tt a.out tt.f90
fi
fi

###########################################################################
if [ $getlmdzor = 1 ] ; then
echo '##########################################################'
echo  Download a slightly modified version of  LMDZ
echo '##########################################################'
cd $MODEL
wget http://www.lmd.jussieu.fr/~lmdz/DistribG95/modipsl.$version.tar.gz
echo install.sh wget_OK `date`
gunzip modipsl.$version.tar.gz
tar xvf modipsl.$version.tar
\rm modipsl.$version.tar

# We download LMDZ and make some modifications to make it
#compatible with $compilo
# and we use an old stable but robust and well tested version of ORCHIDEE
# That version of ORCHIDEE can be obtained using
# wget http://www.lmd.jussieu.fr/~lmdz/DistribG95/getlmdzor.x
fi

echo OK1

if [ $netcdf = 1 ] ; then
echo '##########################################################'
echo Compiling the Netcdf library
echo '##########################################################'
cd $MODEL
wget http://www.lmd.jussieu.fr/~lmdz/DistribG95/netcdf-4.0.1.tar.gz
gunzip netcdf-4.0.1.tar.gz
tar xvf netcdf-4.0.1.tar
\rm -f netcdf-4.0.1.tar

cd netcdf-4.0.1

sed -e 's/gfortran/'$gfortran'/g' configure >| tmp ; mv -f tmp configure ; chmod +x configure
localdir=`pwd -P`
./configure --prefix=$localdir
sed -e 's/gfortran/'$gfortran'/g' Makefile >| tmp ; mv -f tmp Makefile
make check
make install
echo install.sh netcdf_OK `date`
fi # of if [ $netcdf = 1 ]


#=======================================================================================
echo OK2 ioipsl=$ioipsl
echo '##########################################################'
echo 'Installing MODIPSL, the installation package manager for the '
echo 'IPSL models and tools'
echo '##########################################################'

if [ $netcdf = 0 -o $netcdf = 1 ] ; then
ncdfdir=$MODEL/netcdf-4.0.1
else
ncdfdir=$netcdf
fi

if [ $ioipsl = 1 ] ; then
  cd $MODEL/modipsl
  \rm -rf lib/*

  cd util

  cp AA_make.gdef AA_make.orig
  F_C="$compilo -c " ; if [ "$compilo" = "$gfortran" -o "$compilo" = "mpif90" ] ; then F_C="$compilo -c -cpp " ; fi
  sed -e 's/^\#.*.g95.*.\#.*.$/\#/' AA_make.gdef > tmp
  sed -e "s:F_L = g95:F_L = $compilo:" -e "s:F_C = g95 -c:F_C = $F_C": \
  -e 's/g95.*.w_w.*.(F_D)/g95      w_w = '"$OPTIMGCM"'/' \
  -e 's:g95.*.NCDF_INC.*.$:g95      NCDF_INC= '"$ncdfdir"'/include:' \
  -e 's:g95.*.NCDF_LIB.*.$:g95      NCDF_LIB= -L'"$ncdfdir"'/lib -lnetcdf:' \
  -e "s:-fmod=:-$fmod:" -e 's/-fno-second-underscore//' \
  -e 's:#-Q- g95      M_K = gmake:#-Q- g95      M_K = make:' \
  tmp >| AA_make.gdef


  if [ "$use_shell" = "ksh" ] ; then
    if [ "$pclinux" = 1 ] ; then
       ./ins_make -t g95 # We use lines for g95 even for the other compilers
    fi
  else # bash
    sed -e s:/bin/ksh:/bin/bash:g ins_make > ins_make.bash
    chmod u=rwx ins_make.bash
    if [ "$pclinux" = 1 ] ; then
    ./ins_make.bash -t g95 # We use lines for g95 even for the other compilers
    else
    ./ins_make.bash
    fi
  fi # of if [ "$use_shell" = "ksh" ]

#=======================================================================================
  echo '##########################################################'
  echo 'Compiling IOIPSL, the interface library with Netcdf'
  echo '##########################################################'

  cd $MODEL/modipsl/modeles/IOIPSL/src
  if [ "$use_shell" = "bash" ] ; then
    cp Makefile Makefile.ksh
    sed -e s:/bin/ksh:/bin/bash:g Makefile.ksh > Makefile
  fi
  if [ "$pclinux" = 1 ] ; then
    # Build IOIPSL modules and library
    if [ $compilo = g95 ] ; then
       cp restcom.f90 restcom.f90.orig
       sed -e 's:cmode=or(NF90_NOCLOBBER,NF90_64BIT_OFFSET):cmode=NF90_NOCLOBBER:' restcom.f90.orig > restcom.f90  
    fi
    make clean
    make
    if [ "$compilo" = "$gfortran" -o "$compilo" = "mpif90" ] ; then # copy module files to lib
      cp -f *.mod ../../../lib
    fi
    # Build IOIPSL tools (ie: "rebuild", if present)
    if [ -f $MODEL/modipsl/modeles/IOIPSL/tools/rebuild ] ; then
      cd $MODEL/modipsl/modeles/IOIPSL/tools
      # adapt Makefile & rebuild script if in bash
      if [ "$use_shell" = "bash" ] ; then
        cp Makefile Makefile.ksh
        sed -e s:/bin/ksh:/bin/bash:g Makefile.ksh > Makefile
        cp rebuild rebuild.ksh
        sed -e 's:/bin/ksh:/bin/bash:g' \
            -e 's:print -u2:echo:g' \
            -e 's:print:echo:g' rebuild.ksh > rebuild
      fi
      make clean
      make
    fi
  fi # of if [ "$pclinux" = 1 ] 

else # of if [ $ioipsl = 1 ]
  if [ ${hostname:0:5} = ada33 ] ; then
    cd $MODEL/modipsl
    cd util

    cp AA_make.gdef AA_make.orig
    sed -e 's/^\#.*.g95.*.\#.*.$/\#/' AA_make.gdef > tmp
    sed -e "s:F_L = g95:F_L = $compilo:" -e "s:F_C = g95 -c:F_C = $compilo -c": \
    -e 's/g95.*.w_w.*.(F_D)/g95      w_w = '"$OPTIMGCM"'/' \
    -e 's:g95.*.NCDF_INC.*.$:g95      NCDF_INC= -I/smplocal/pub/HDF5/1.8.9/seq/include -I/smplocal/pub/NetCDF/4.1.3/include:' \
    -e 's:g95.*.NCDF_LIB.*.$:g95      NCDF_LIB= -L/smplocal/pub/NetCDF/4.1.3/lib -lnetcdff -lnetcdf:' \
    -e "s:-fmod=:-$fmod:" -e 's/-fno-second-underscore//' \
    -e 's:#-Q- g95      M_K = gmake:#-Q- g95      M_K = make:' \
    tmp >| AA_make.gdef

    ./ins_make -t g95 # We use lines for g95 even for the other compilers

    # on Ada, IOIPSL is already installed in ~rpsl035/IOIPSL_PLUS
    # so link it to current settings
    cd $MODEL/modipsl/modeles/
    \rm -r -f IOIPSL
    ln -s ~rpsl035/IOIPSL_PLUS IOIPSL
    cd ..
    ln -s ~rpsl035/IOIPSL_PLUS/modipsl/bin/* bin/
    ln -s ~rpsl035/IOIPSL_PLUS/modipsl/lib/* lib/

  fi # of if [ ${hostname:0:5} = ada33 ]
  echo install.sh ioipsl_OK `date`
fi # of if [ $ioipsl = 1 ]


#============================================================================
veget_version=false
if [ "$veget" = 1 ] ; then
  echo '########################################################'
  echo 'Compiling ORCHIDEE, the continental surfaces model '
  echo '########################################################'
  cd $MODEL/modipsl/modeles/ORCHIDEE
  echo OKpwd ; pwd
  if [ -d src_parallel ] ; then
     liste_src="parallel parameters global stomate sechiba driver"
     veget_version=orchidee2.0
  else
     # Obsolete, for ORCHIDEE_beton only
     liste_src="parameters stomate sechiba "
     # A trick to compile ORCHIDEE depending on if we are using real*4 or real*8
     cd src_parameters ; \cp reqdprec.$real reqdprec.f90 ; cd ..
     veget_version=orchidee1.9
  fi
  echo liste_strc $liste_src

  for d in $liste_src ; do src_d=src_$d
      echo src_d $src_d
      echo ls ; ls
      if [ ! -d $src_d ] ; then echo Problem orchidee : no $src_d ; exit ; fi
      cd $src_d ; \rm -f *.mod make ; make clean
      make ; if [ "$compilo" = "$gfortran" -o "$compilo" = "mpif90" ] ; then cp -f *.mod ../../../lib ; fi
      cd ..
  done
  echo install.sh orchidee_OK `date`
fi # of if [ "$veget" = 1 ]


#============================================================================
# Ehouarn: it may be directory LMDZ4 or LMDZ5 depending on tar file...
if [ -d $MODEL/modipsl/modeles/LMDZ[45] ] ; then
  echo '##########################################################'
  echo 'Compiling LMDZ'
  echo '##########################################################'
  cd $MODEL/modipsl/modeles/LMDZ[45]
else
  echo "ERROR: No LMDZ4 (or LMDZ5) directory !!!"
  exit
fi

###########################################################
# For those who want to use fcm to compile via :
#  makelmdz_fcm -arch local .....
############################################################

if [ "$pclinux" = "1" ] ; then

# create local 'arch' files (if on Linux PC):
cd arch
# arch-local.path file
echo "NETCDF_LIBDIR=\"-L${ncdfdir}/lib -lnetcdf\"" > arch-local.path
echo OK3
echo "NETCDF_INCDIR=-I${ncdfdir}/include" >> arch-local.path
echo 'IOIPSL_INCDIR=$LMDGCM/../../lib' >> arch-local.path
echo 'IOIPSL_LIBDIR=$LMDGCM/../../lib' >> arch-local.path
echo 'ORCH_INCDIR=$LMDGCM/../../lib' >> arch-local.path
echo 'ORCH_LIBDIR=$LMDGCM/../../lib' >> arch-local.path
# arch-local.fcm file (adapted from arch-linux-32bit.fcm)

if [ $real = r8 ] ; then FPP_DEF=NC_DOUBLE ; else FPP_DEF="" ; fi
sed -e s:"%COMPILER        .*.$":"%COMPILER            $compilo":1 \
    -e s:"%LINK            .*.$":"%LINK                $compilo":1 \
    -e s:"%PROD_FFLAGS     .*.$":"%PROD_FFLAGS         $OPTIM":1 \
    -e s:"%DEV_FFLAGS      .*.$":"%DEV_FFLAGS          $OPTDEV":1 \
    -e s:"%DEBUG_FFLAGS    .*.$":"%DEBUG_FFLAGS        $OPTDEB":1 \
    -e s:"%BASE_FFLAGS     .*.$":"%BASE_FFLAGS         $OPTPREC":1 \
    arch-linux-32bit.fcm > arch-local.fcm

cd ..
### Adapt "bld.cfg" (add the shell):
whereisthatshell=$(which ${use_shell})
echo "bld::tool::SHELL   $whereisthatshell" >> bld.cfg

fi # of if [ "$pclinux" = 1 ]


cd $MODEL/modipsl/modeles/LMDZ?

##################################################################
# Compile LMDZ
##################################################################
echo install.sh avant_compilation `date`
if [ $compile_with_fcm = 1 ] ; then makelmdz=makelmdz_fcm ; else makelmdz=makelmdz ; fi

./$makelmdz -d ${grid_resolution} -v $veget_version gcm
echo install.sh apres_compilation `date`


if [ -f gcm.e ] || [ -f bin/gcm_${grid_resolution}_phylmd_seq_orch.e ] || [ -f bin/gcm_${grid_resolution}_phylmd_seq.e ] ; then
echo '##########################################################'
echo 'Compilation successfull !! '
echo '##########################################################'
else
echo 'Compilation failed !!'
exit
fi

##################################################################
# Below, we run a benchmark test (if bench=0)
##################################################################
if [ $bench = 0 ] ; then
		exit
fi

echo '##########################################################'
echo ' Running a test run '
echo '##########################################################'

\rm -rf BENCH${grid_resolution}
bench=bench_lmdz_${grid_resolution}
echo install.sh avant_chargement_bench  `date`
wget http://www.lmd.jussieu.fr/~lmdz/DistribG95/$bench.tar.gz
echo install.sh apres_chargement_bench  `date`
gunzip $bench.tar.gz
tar xvf $bench.tar

if [ -f gcm.e ] ; then 
    cp gcm.e BENCH${grid_resolution}/
elif [ -f bin/gcm_${grid_resolution}_phylmd_seq_orch.e ] ; then
    cp bin/gcm_${grid_resolution}_phylmd_seq_orch.e  BENCH${grid_resolution}/gcm.e
elif [ -f bin/gcm_${grid_resolution}_phylmd_seq.e ] ; then
    cp bin/gcm_${grid_resolution}_phylmd_seq.e  BENCH${grid_resolution}/gcm.e
else
    echo "No gcm.e found"
    exit
fi


cd BENCH${grid_resolution}
./bench.sh > bench.out  2>&1


echo '##########################################################'
echo ' Bench results '
echo '##########################################################'

cat ./bench.out
echo install.sh FIN_du_BENCH  `date`

echo '##########################################################'
echo 'Simulation finished in' `pwd`
echo 'You may re-run it with : cd ' `pwd` ' ; gcm.e'
echo 'or ./bench.sh'
echo '##########################################################'

if [ "$gfortran" = "gfortran44" ] ; then
    echo Your gfortran compiler was too old so that the model was automatically
    echo compiled with gfortran44 instead. It can not be used in parallel mode.
    echo You can change the compiler at the begining of the install.sh
    echo script and reinstall.
fi
