#!/bin/bash

###########################################################################
# Auteur : Frédéric Hourdin/LMD/hourdin@lmd.jussieu.fr
# Usage  : install.sh
#
# Script bash d'installation du modele LMDZ sur un ordinateur PC/Linux
# en utilisant le compilateur g95.
# Le modele est récupéré dans une arborescence
# $MODEL/modipsl/modeles/...
# en utilisant l'infrastructure "modipsl" mise au point à l'"IPSL" pour
#les besoins de la modélisation couplée du climat
#(atmosphere/ocean/vegetation/chimie)
# On ne récupère ici que les composantes atmosphériques (LMDZ4)
# et végétation (ORCHIDEE).
#
# Sous le répertoire "modeles", on trouve en fait les sources de différents
# modèles. Ici, LMDZ4, ORCHIDEEet IOIPSL, ensemble de programmes
# d'entrée/sortie faisant appel à la librairie netcdf.
#
# Le script récupères les différents jeux de sources (y compris une
# version de netcdf) et utilitaires, compile le modèle, et lance une
# simulation de test dans une configuration très légère sur
# $MODEL/modipsl/modeles/LMDZ4/INI
#
# Pré-requis : g95/pgf90/gfortran, ksh, wget , gunzip, tar, ... (à compléter)
#
# Modif 18/11/2011
#    changement pour l'option real 8.
#      On compile avec -r8 (ou équivalent) et -DNC_DOUBLE pour le GCM
#      mais avec -r4 netcdf. La variable real est initialisée à 
#      r4 ou r8 en début de script.
#
###########################################################################

echo '################################################################'
echo  Choix des options d installation
echo '################################################################'


#real=r4
real=r8

# ATTENTION !!!! Pour des versions anterieures a octobre 2009, utiliser
# install.v2.sh au lieu de install.sh

version=20110921.trunk
#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=0
bench=1
## compilo=pgf90 ou g95 ou gfortran ou ifort sur PC linux
compilo=gfortran
pclinux=1

## compile_with_fcm=1 : utilise makelmdz_fcm, possible a partir de la version 20111103.trunk (LMDZ5/trunk rev 1578)
## compile_with_fcm=0 : utilise makegcm (default)
compile_with_fcm=0

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

if [ $compilo = g95 ] ; then
   if [ $real = r8 ] ; then OPTPREC="-r8 -DNC_DOUBLE" ; fi
   OPTIM='-i4 -O3'
elif [ $compilo = gfortran ] ; then
   if [ $real = r8 ] ; then OPTPREC="-fdefault-real-8 -DNC_DOUBLE" ; fi
   OPTIM='-O3'
elif [ $compilo = pgf90 ] ; then
   if [ $real = r8 ] ; then OPTPREC="-r8 -DNC_DOUBLE" ; fi
   OPTIM='-O2 -Munroll -Mnoframe -Mautoinline -Mcache_align'
   # with pgf90, compile with fcm
   compile_with_fcm=1
else 
   # ifort
   if [ $real = r8 ] ; then OPTPREC="-real-size 64 -DNC_DOUBLE" ; fi
   OPTIM="-O2 -ip -mkl=sequential -align all -static "
   # with ifort, compile with fcm
   compile_with_fcm=1
fi
OPTIMGCM="$OPTIM $OPTPREC"

# choix de la resolution pour le bench
# grid_resolution= 32x24x11 for test (test without ORCHIDEE)
#                  96x71x19  standard configuration
grid_resolution=48x36x19

hostname=`hostname`

##########################################################################
# Dans le cas où on installe sur des machines connues comme la NEC
# brodie
# de l'IDRIS, on ne verifie pas les logiciels existants et on n'installe
# pas netcdf.
if [ $hostname = brodie ] ; then
netcdf=0
check_linux=0
pclinux=0
fi
##########################################################################


mkdir -p $MODEL
echo $MODEL
MODEL=`( cd $MODEL ; pwd )` # transformation en chemin absolu si necessaire



# Le -fendian=big n'est à utiliser vraiment utile que pour ARPEGE1D.
# Le -r8 doit sans doute être éviter si on veut tourner rapidement sur
# des machines 32 bits.
# L'option r8 n'est pas forcement indispensable et elle produit
# des executables plus gros.
# Elles est indispensable cependant pour ARPEGE1D
# On doit pouvoir aussi utiliser des optimisations plus fortes (-O3 par
# exemple).


echo '################################################################'
if [ "$check_linux" = 1 ] ; then
echo   Test sur les logiciels requis
echo '################################################################'

#### Ehouarn: test if ksh and/or bash are available
use_shell="ksh" # default: use ksh
if [ "`which ksh`" = "" ] ; then
  echo "pas de ksh ... on va utiliser bash"
  use_shell="bash"
  if [ "`which bash`" = "" ] ; then
    echo "Il faut d\'abord installer ksh (ou bash)"
  fi
fi


for logiciel in csh wget tar gzip make $compilo gcc ; do
if [ "`which $logiciel`" = "" ] ; then
echo Il faut installer d\'abord $logiciel
exit
fi
done

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

###########################################################################



if [ $getlmdzor = 1 ] ; then
echo '##########################################################'
echo  On recupere une version un peu modifiee de LMDZ
echo '##########################################################'
cd $MODEL
wget http://www.lmd.jussieu.fr/~lmdz/DistribG95/modipsl.$version.tar.gz
gunzip modipsl.$version.tar.gz
tar xvf modipsl.$version.tar
\rm modipsl.$version.tar

# On recupere en fait une version du 01 10 2006 obtenue
# Par un cvs get
# Puis modifiees pour etre compatible avec la compilation $compilo.
# et pour betoner ORCHIDEE
# Cette version est recuperable avec le script
# wget http://www.lmd.jussieu.fr/~lmdz/DistribG95/getlmdzor.x
fi

echo OK1

if [ $netcdf = 1 ] ; then
echo '##########################################################'
echo Compilation de netcdf
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

OPTIMNC=$OPTIM
if [ $compilo = g95 ] ; then
# On modifie les options de compilation
   export FC=g95
   export F90=g95
   export F90FLAGS=" -cpp -ffree-form $OPTIMNC"
   export FFLAGS=" -cpp $OPTIMNC"
   export CPPFLAGS=-Df2cFortran
   export CC=gcc
   export CXX=g++
elif [ $compilo = gfortran ] ; then
   export FC=gfortran
   export F90=gfortran
   export F90FLAGS=" -ffree-form $OPTIMNC"
   export FFLAGS=" $OPTIMNC"
   export CPPFLAGS=
   export CC=gcc
   export CXX=g++
elif [ $compilo = pgf90 ] ; then
   export CPPFLAGS="-DNDEBUG -DpgiFortran"
   export CC=pgcc
   export CFLAGS="-Msignextend"
   export CXX=pgCC
   export CXXFLAGS="-Msignextend"
   export FC=pgf90
   export FFLAGS="$OPTIMNC"
   export F90=pgf90
   export F90FLAGS="$OPTIMNC"
elif [ $compilo = ifort ] ; then
   export CPP="icc -E"
   export F77=ifort
   export FFLAGS="-O2 -ip -fpic -mcmodel=large"
   export F90=ifort
   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"
else
   echo Le compilateur $compilo pas prevu ; exit
fi
## end of if [ $netcdf = 1 ]
cd src

### Correction d'un petit probleme de netcdf
##sed -e '83s/^$/\#define f2cFortran/' cfortran.h >| tmp ; \mv tmp cfortran.h

# Compilation
# Modif du 6 juillet 2009. Plantage quand on essaie de compiler netcdf avec
# gcc plutÃ´t que c++
##sed -e 's/ c++/ gcc/g' configure >| tmp ; mv -f tmp configure ; chmod +x configure
localdir=`pwd -P`
./configure --prefix=$localdir
make check
make install
fi

echo OK2 ioipsl=$ioipsl
echo '##########################################################'
echo Installation de MODIPSL, la procedure d\'installation des
echo modeles de l\'IPSL
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 -r lib/*

cd util

if [ $compilo = pgf90 ] ; then 
  fmod='module '
elif [ $compilo = g95 ] ; then
  fmod='fmod='
elif [ $compilo = ifort ] ; then
  fmod='module '
else # gfortran
  fmod='I '
fi
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='"$ncdfdir"'/include:' \
-e 's:g95.*.NCDF_LIB.*.$:g95      NCDF_LIB='"$ncdfdir"'/lib:' \
-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 # On utilise les lignes g95 meme pour les autres compilo
  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 # On utilise les lignes g95 meme pour les autres compilo
  else
  ./ins_make.bash
  fi
fi

echo '##########################################################'
echo Compilation de IOIPSL, bibliotheque d\'interface avec Netcd
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
  make clean
  make
  if [ $compilo = gfortran ] ; then # copy module files to lib
    cp -f *.mod ../../../lib
  fi
else
  # we're on brodie
  sxgmake clean
  sxgmake
fi

if [ "$veget" = 1 ] ; then
echo '########################################################'
echo Compilation de ORCHIDEE, modele des surface continentales
echo '########################################################'
cd $MODEL/modipsl/modeles/ORCHIDEE
cd src_parameters
# Une petite astuce pour ORCHIDEE suivant qu'on est en real*4 ou real*8


\cp reqdprec.$real reqdprec.f90
make
if [ $compilo = gfortran ] ; then # copy module files to lib
  cp -f *.mod ../../../lib
fi
cd ../src_stomate
make
if [ $compilo = gfortran ] ; then # copy module files to lib
  cp -f *.mod ../../../lib
fi
cd ../src_sechiba
make
if [ $compilo = gfortran ] ; then # copy module files to lib
  cp -f *.mod ../../../lib
fi
fi
fi


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

if [ "$pclinux" = 1 ] ; then
  if [ $compilo = gfortran ] ; then
sed \
-e 's:\#setenv NCDFINC.*.$:setenv NCDFINC '"$ncdfdir"'/include:' \
-e 's:\#setenv NCDFLIB.*.$:setenv NCDFLIB '"$ncdfdir"'/lib:' \
-e 's:setenv NCDFINC.*.$:setenv NCDFINC '"$ncdfdir"'/include:' \
-e 's:setenv NCDFLIB.*.$:setenv NCDFLIB '"$ncdfdir"'/lib:' \
-e 's/set FC_LINUX.*.$/set FC_LINUX='$compilo'/' \
-e 's/g95/gfortran/g' \
-e 's/-fmod=/-I/g' \
-e 's/-fno-second-underscore//' -e 's/-fstatic//' \
-e 's/-lparallel//' \
-e 's/-lorglob//' \
-e 's/-ffixed-form//' -e 's/-ffree-form//' \
-e 's/set OPT_LINUX.*.$/set OPT_LINUX=\"'"$OPTIMGCM"\"'/' makegcm.orig >| makegcm
  elif [ $compilo = ifort ] ; then
sed \
-e 's:\#setenv NCDFINC.*.$:setenv NCDFINC '"$ncdfdir"'/include:' \
-e 's:\#setenv NCDFLIB.*.$:setenv NCDFLIB '"$ncdfdir"'/lib:' \
-e 's:setenv NCDFINC.*.$:setenv NCDFINC '"$ncdfdir"'/include:' \
-e 's:setenv NCDFLIB.*.$:setenv NCDFLIB '"$ncdfdir"'/lib:' \
-e 's/set FC_LINUX.*.$/set FC_LINUX='$compilo'/' \
-e 's/g95/ifort/g' \
-e 's/-fmod=/-module /g' \
-e 's/-fno-second-underscore//' -e 's/-fstatic//' \
-e 's/-lparallel//' \
-e 's/-lorglob//' \
-e 's/-ffixed-form//' -e 's/-ffree-form//' \
-e 's/set OPT_LINUX.*.$/set OPT_LINUX=\"'"$OPTIMGCM"\"'/' makegcm.orig >| makegcm
  else # g95 or pgf90
sed \
-e 's:\#setenv NCDFINC.*.$:setenv NCDFINC '"$ncdfdir"'/include:' \
-e 's:\#setenv NCDFLIB.*.$:setenv NCDFLIB '"$ncdfdir"'/lib:' \
-e 's:setenv NCDFINC.*.$:setenv NCDFINC '"$ncdfdir"'/include:' \
-e 's:setenv NCDFLIB.*.$:setenv NCDFLIB '"$ncdfdir"'/lib:' \
-e 's/set FC_LINUX.*.$/set FC_LINUX='$compilo'/' \
-e 's/-fno-second-underscore//' -e 's/-fstatic//' \
-e 's/-lparallel//' \
-e 's/-lorglob//' \
-e 's/-ffixed-form//' -e 's/-ffree-form//' \
-e 's/set OPT_LINUX.*.$/set OPT_LINUX=\"'"$OPTIMGCM"\"'/' makegcm.orig >| makegcm
  fi
else
sed \
-e 's/-lparallel//' \
-e 's/-lorglob//' \
-e 's/-lsxorglob//' \
-e 's/-lsxparallel//' \
-e 's/-lsxioipsl/-lioipsl/g' \
makegcm.orig >| makegcm
fi

chmod +x makegcm

###########################################################
# Pour ceux qui voudraient utiliser fcm et pouvoir faire :
#  makelmdz_fcm -arch local .....
############################################################

if [ "$pclinux" = 1 ] ; then
# creation de fichiers 'arch' locaux (si sur PC Linx):
cd arch
# fichier arch-local.path
echo "NETCDF_LIBDIR=\"-L${ncdfdir}/lib -lnetcdf\"" > arch-local.path
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
# fichier arch-local.fcm (adaptation de arch-linux-32bit.fcm)
if [ $compilo = g95 ] ; then
sed -e s:"%COMPILER            pgf95":"%COMPILER            g95":1 \
    -e s:"%LINK                pgf95":"%LINK                g95":1 \
    -e s:"%PROD_FFLAGS         -fast":"%PROD_FFLAGS         $OPTIM":1 \
    -e s:"%BASE_FFLAGS         ":"%BASE_FFLAGS         $OPTPREC":1 \
   arch-linux-32bit.fcm > arch-local.fcm
   if [ $real = r8 ] ; then
     sed -e s:"%FPP_DEF             ":"%FPP_DEF             NC_DOUBLE":1 \
     arch-local.fcm > arch-local.fcm.new
     mv -f arch-local.fcm.new arch-local.fcm
   fi
elif [ $compilo = gfortran ] ; then
sed -e s:"%COMPILER            pgf95":"%COMPILER            gfortran":1 \
    -e s:"%LINK                pgf95":"%LINK                gfortran":1 \
    -e s:"%PROD_FFLAGS         -fast":"%PROD_FFLAGS         $OPTIM":1 \
    -e s:"%BASE_FFLAGS         ":"%BASE_FFLAGS         $OPTPREC":1 \
   arch-linux-32bit.fcm > arch-local.fcm
   if [ $real = r8 ] ; then
     sed -e s:"%FPP_DEF             ":"%FPP_DEF             NC_DOUBLE":1 \
     arch-local.fcm > arch-local.fcm.new
     mv -f arch-local.fcm.new arch-local.fcm
   fi
elif [ $compilo = pgf90 ] ; then
sed -e s:"-Wl,-Bstatic -L/usr/lib/gcc-lib/i386-linux/2.95.2":" ":1 \
    -e s:"%PROD_FFLAGS         -fast":"%PROD_FFLAGS         $OPTIM":1 \
    -e s:"%BASE_FFLAGS         ":"%BASE_FFLAGS         $OPTPREC":1 \
   arch-linux-32bit.fcm > arch-local.fcm
   if [ $real = r8 ] ; then
     sed -e s:"%FPP_DEF             ":"%FPP_DEF             NC_DOUBLE":1 \
     arch-local.fcm > arch-local.fcm.new
     mv -f arch-local.fcm.new arch-local.fcm
   fi
elif [ $compilo = ifort ] ; then
sed -e s:"%COMPILER            pgf95":"%COMPILER            ifort":1 \
    -e s:"%LINK                pgf95":"%LINK                ifort":1 \
    -e s:"-Wl,-Bstatic -L/usr/lib/gcc-lib/i386-linux/2.95.2":" ":1 \
    -e s:"%PROD_FFLAGS         -fast":"%PROD_FFLAGS         $OPTIM":1 \
    -e s:"%BASE_FFLAGS         ":"%BASE_FFLAGS         $OPTPREC":1 \
    -e s:"%DEBUG_FFLAGS        -g -O0 -Kieee -Ktrap=fp -Mbounds":"%DEBUG_FFLAGS        -g -no-ftz -traceback -ftrapuv -fp-stack-check -check":1 \
   arch-linux-32bit.fcm > arch-local.fcm
   if [ $real = r8 ] ; then
     sed -e s:"%FPP_DEF             ":"%FPP_DEF             NC_DOUBLE":1 \
     arch-local.fcm > arch-local.fcm.new
     mv -f arch-local.fcm.new arch-local.fcm
   fi
else
   echo Le compilateur $compilo pas prevu ; exit
fi # of if [ $compilo = g95 ] elif [ $compilo = pgf90 ]
cd ..
### Adaptation de "bld.cfg" (ajout du shell):
whereisthatshell=$(which ${use_shell})
echo "bld::tool::SHELL   $whereisthatshell" >> bld.cfg

### Modification de makelmdz_fcm pour utilisation de ORCHIDEE dans cette bench:
### on enleve liborglob.a et libparallel.a
cp makelmdz_fcm makelmdz_fcm.orig
sed -e "s/-l\${LIBPREFIX}parallel//" \
sed -e "s/-l\${LIBPREFIX}orglob//" \
    makelmdz_fcm.orig > makelmdz_fcm

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

##################################################################
# Lance compilation de LMDZ
##################################################################
ok_veget=false
if [ "$veget" = 1 ] ; then ok_veget = true; fi
if [ $compile_with_fcm = 1 ] ; then
# Compilation avec makelmdz_fcm
	./makelmdz_fcm -d ${grid_resolution} -arch local -v $ok_veget gcm
else
# Compilation avec makegcm:
#       3 times! because some dependecies are not well resolved with makegcm
	./makegcm -d ${grid_resolution} -v $ok_veget gcm
	./makegcm -d ${grid_resolution} -v $ok_veget gcm
	./makegcm -d ${grid_resolution} -v $ok_veget gcm
fi

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 reussie
echo '##########################################################'
else
echo Probleme de compilation
exit
fi

##################################################################
# Ci dessous le lancement eventuel d'un cas test (si bench=0)
##################################################################
if [ $bench = 0 ] ; then
		exit
fi

echo '##########################################################'
echo Lancement d\'une simulation de test
echo '##########################################################'

\rm -r BENCH${grid_resolution}
bench=bench_lmdz_${grid_resolution}
wget http://www.lmd.jussieu.fr/~lmdz/DistribG95/$bench.tar.gz
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

if [ $hostname = brodie ] ; then
echo POUR LANCER LE BENCH, IL FAUT SE LOGUER SUR BRODIE01
echo puis aller sur `pwd`/BENCH${grid_resolution}
echo et lancer le gcm
exit
fi

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

echo '##########################################################'
echo ' Resultat du bench '
echo '##########################################################'

cat ./bench.out

echo '##########################################################'
echo 'La simulation test est terminee sur' `pwd`
echo 'vous pouvez la relancer : cd ' `pwd` ' ; gcm.e'
echo 'ou ./bench.sh'
echo '##########################################################'

