#!/bin/bash
# $Id: makelmdz_fcm 1696 2012-12-19 09:30:26Z fairhead $
# This is a script in Bash.

# FH : on ne cre plus le fichier arch.mk qui est suppos exister par
# FH : ailleurs.
# FH : ulterieurement, ce fichier sera pr-existant pour une srie
# FH : de configurations en versions optimises et debug qui seront
# FH : lis (ln -s) avec arch.mk en fonction de l'architecture.
# FH : Pour le moment, cette version est en test et on peut crer les
# FH : arch.mk en lanant une premire fois makegcm.
#
##set -x
########################################################################
# options par defaut pour la commande make
########################################################################

dim="96x72x19"
physique=lmd
filtre=filtrez
grille=reg
couple=false
veget=false
chimie=false
parallel=none
paramem="par"
compil_mod=prod
io=ioipsl
LIBPREFIX=""
cosp=false

LMDGCM=`/bin/pwd`
LIBOGCM=$LMDGCM/libo
LIBFGCM=$LMDGCM/libf
COSP_PATH=$LMDGCM/.void_dir
fcm_path=$LMDGCM/tools/fcm/bin

########################################################################
#  Quelques initialisations de variables du shell.
########################################################################

CPP_KEY="" 
INCLUDE=""
LIB=""
adjnt=""
COMPIL_FFLAGS="%PROD_FFLAGS"
PARA_FFLAGS=""
PARA_LD=""
EXT_SRC=""

########################################################################
# lecture des options de mymake
########################################################################

while (($# > 0))
  do
  case $1 in
      "-h") cat <<fin
manuel complet sur http://...
Usage :
makegcm [options] -m arch exec
[-h]                       : manuel abrégé
[-d [[IMx]JMx]LM]          : IM, JM, LM sont les dims en x, y, z (def: $dim)
[-p PHYS]                  : compilation avec la physique libf/phyPHYS, (def: lmd)
[-prod / -dev / -debug]    : compilation en mode production (default) / developpement / debug .
[-c false/MPI1/MPI2]       : couplé océan : MPI1/MPI2/false (def: false)
[-v false/true]            : avec ou sans végétation (def: false)
[-chimie INCA/false]       : avec ou sans model de chimie INCA (def: false)
[-parallel none/mpi/omp/mpi_omp] : parallelisation (default: none) : mpi, openmp ou mixte mpi_openmp
[-g GRI]                   : conf. grille dans dyn3d/GRI_xy.h  (def: reg inclue un zoom)
[-io IO]                   : choix d'une librairie I/O, experts (def: ioipsl)
[-include INCLUDES]        : variables supplementaires pour include
[-cpp CPP_KEY]             : cle cpp supplementaires
[-adjnt]                   : adjoint, a remettre en route ...
[-mem]                     : version memoire reduite (si en mode parallele)
[-filtre NOMFILTRE]        : prend le filtre dans libf/NOMFILTRE (def: filtrez)
[-link LINKS]              : liens optionels avec d'autres librairies
[-fcm_path path]           : chemin pour fcm (def: tools/fcm/bin)
[-ext_src path]            : chemin d'un repertoire source avec des sources externe a compiler avec le modele
 -arch nom_arch            : nom de l'architecture cible
 exec                      : exécutable généré
fin
	  exit;;

      "-d")
	  dim=$2 ; shift ; shift ;;
      
      "-O")
	  echo "option obsolete dans cette version intermediaire de makegcm"
	  exit;;

      "-p")
	  physique="$2" ;  shift ; shift ;;

      "-g")
	  grille="$2" ; shift ; shift ;;

      "-c")
	  couple="$2" ; shift ; shift ;;

      "-prod")
	  compil_mod="prod" ; shift ;;

      "-dev")
	  compil_mod="dev" ; shift ;;

      "-debug")
	  compil_mod="debug" ; shift ;;

      "-io")
	  io="$2" ; shift ; shift ;;

      "-v")
	  veget="$2" ; shift ; shift ;;

      "-chimie")
	  chimie="$2" ; shift ; shift ;;

      "-parallel")
	  parallel="$2" ; shift ; shift ;;
      
      "-include")
	  INCLUDE="$INCLUDE -I$2" ; shift ; shift ;;

      "-cpp")
	  CPP_KEY="$CPP_KEY $2" ; shift ; shift ;;

      "-adjnt")
	  echo "option a reactiver ";exit
	  opt_dep="$opt_dep adjnt" ; adjnt="-ladjnt -ldyn3d "
	  optim="$optim -Dadj" ; shift ;;

      "-cosp")
          cosp="$2" ; shift ; shift ;;
      
      "-mem")
          paramem="mem" ; shift ;;

      "-filtre")
	  filtre=$2 ; shift ; shift ;;

      "-link")
	  LIB="$LIB $2" ; shift ; shift ;;

      "-fcm_path")
	  fcm_path=$2 ; shift ; shift ;;

      "-ext_src")
	  EXT_SRC=$2 ; shift ; shift ;;

      "-arch")
	  arch=$2 ; shift ; shift ;;

      *)
	  code="$1" ; shift ;;
  esac
done

###############################################################
# mettre le chemin du fcm dans le path
###############################################################
export PATH=${fcm_path}:${PATH}

echo "Chemin du fcm utlise :" 
which fcm

###############################################################
# lecture des chemins propres  l'architecture de la machine #
###############################################################
rm -f .void_file
echo > .void_file
rm -rf .void_dir
mkdir .void_dir
rm -f arch.path
ln -s arch/arch-${arch}.path ./arch.path
source arch.path

########################################################################
# Definition des clefs CPP, des chemins des includes et modules
#  et des libraries
########################################################################

if [[ "$compil_mod" == "prod" ]]
then
  COMPIL_FFLAGS="%PROD_FFLAGS"
elif [[ "$compil_mod" == "dev" ]]
then
  COMPIL_FFLAGS="%DEV_FFLAGS"
elif [[ "$compil_mod" == "debug" ]]
then
  COMPIL_FFLAGS="%DEBUG_FFLAGS"
fi

if [[ "$physique" != "nophys" ]]
then
   #We'll use some physics
   CPP_KEY="$CPP_KEY CPP_PHYS"
   if [[ "${physique:0:3}" == "lmd" ]]
   then
   #For lmd physics, default planet type is Earth
   CPP_KEY="$CPP_KEY CPP_EARTH"
   fi
fi

if [[ "$chimie" == "INCA" ]]
then
   CPP_KEY="$CPP_KEY INCA"
   INCLUDE="$INCLUDE -I${INCA_INCDIR}"
   LIB="$LIB -L${INCA_LIBDIR} -lchimie"
fi

if [[ "$couple" != "false" ]]
then
   CPP_KEY="$CPP_KEY CPP_COUPLE"
   INCLUDE="$INCLUDE -I${OASIS_INCDIR}"
   LIB="$LIB -L${OASIS_LIBDIR} -lpsmile.${couple} -lmpp_io"
fi

if [[ "$parallel" == "mpi" ]]
then
   CPP_KEY="$CPP_KEY CPP_PARA CPP_MPI"
   PARA_FFLAGS="%MPI_FFLAGS"
   PARA_LD="%MPI_LD"
elif [[ "$parallel" == "omp" ]]
then
   CPP_KEY="$CPP_KEY CPP_PARA CPP_OMP"
   PARA_FFLAGS="%OMP_FFLAGS"
   PARA_LD="%OMP_LD"
elif [[ "$parallel" == "mpi_omp" ]]
then
   CPP_KEY="$CPP_KEY CPP_PARA CPP_MPI CPP_OMP"
   PARA_FFLAGS="%MPI_FFLAGS %OMP_FFLAGS"
   PARA_LD="%MPI_LD %OMP_LD"
fi

if [[ ( "$parallel" == "omp" || "$parallel" == "mpi_omp" ) \
   && "$compil_mod" == "debug" ]]
then
    echo "Usually, parallelization with OpenMP requires some optimization."
    echo "We suggest switching to \"-dev\"."
fi

if [[ "$veget" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_VEGET"
   INCLUDE="${INCLUDE} -I${ORCH_INCDIR}"
   LIB="${LIB} -L${ORCH_LIBDIR} -l${LIBPREFIX}sechiba -l${LIBPREFIX}parameters -l${LIBPREFIX}stomate -l${LIBPREFIX}parallel -l${LIBPREFIX}orglob"
fi

if [[ $io == ioipsl ]]
then
   CPP_KEY="$CPP_KEY CPP_IOIPSL"
   INCLUDE="$INCLUDE -I${IOIPSL_INCDIR}"
   LIB="$LIB -L${IOIPSL_LIBDIR} -l${LIBPREFIX}ioipsl"
fi
if [[ "$cosp" == "true" ]]
then
   CPP_KEY="$CPP_KEY CPP_COSP"
   COSP_PATH="$LIBFGCM/cosp"
#   LIB="${LIB} -l${LIBPREFIX}cosp"
fi

INCLUDE="$INCLUDE ${NETCDF_INCDIR}"
LIB="$LIB ${NETCDF_LIBDIR}"

########################################################################
# calcul du nombre de dimensions
########################################################################


dim_full=$dim
dim=`echo $dim | sed -e 's/[^0-9]/ /g'` 
set $dim
dimc=$#
echo calcul de la dimension
echo dim $dim
echo dimc $dimc


########################################################################
# Gestion des dimensions du modele.
# on cree ou remplace le fichier des dimensions
########################################################################

cd $LIBFGCM/grid
if [[ -f dimensions.h ]]
then
  echo 'ATTENTION: vous etes sans doute en train de compiler le modele par ailleurs'
  echo "Attendez que la premiere compilation soit terminee pour relancer la suivante."
  echo "Si vous etes sur que vous ne compilez pas le modele par ailleurs,"
  echo  vous pouvez continuer en repondant oui.
  echo "Voulez-vous vraiment continuer?"
  read reponse
  if [[ $reponse == "oui" ]]
  then
    \rm -f $LIBFGCM/grid/dimensions.h
  else
    exit
  fi
fi


cd $LIBFGCM/grid/dimension
./makdim $dim
cat $LIBFGCM/grid/dimensions.h
cd $LMDGCM


########################################################################
# Differentes dynamiques (3d, 2d, 1d)
########################################################################

dimension=`echo $dim | wc -w`
echo dimension $dimension

if (( $dimension == 3 ))
then
  cd $LIBFGCM/grid
  \rm fxyprim.h
  cp -p fxy_${grille}.h fxyprim.h
else
  echo "Probleme dans les dimensions de la dynamique !!"
  echo "Non reactive pour l'instant !!!"
fi

######################################################################
#   Traitement special pour le nouveau rayonnement de Laurent Li.
#   ---> YM desactive pour le traitemement en parallele
######################################################################

#if [[ -f $libf/phy$physique/raddim.h ]]
#then
# if [[ -f $libf/phy$physique/raddim.$dimh.h ]]
#then
#  \rm -f $libf/phy$physique/raddim.h
#  cp -p $libf/phy$physique/raddim.$dimh.h $libf/phy$physique/raddim.h
#  echo $libf/phy$physique/raddim.$dimh.h 
#  cat $libf/phy$physique/raddim.h
# else
#  echo On peut diminuer la taille de l executable en creant
#  echo le fichier $libf/phy$physique/raddim.$dimh.h
#  \cp -p $libf/phy$physique/raddim.defaut.h $libf/phy$physique/raddim.h
# fi
#fi

######################################################################
# Gestion du filtre qui n'existe qu'en 3d.
######################################################################

if (( `expr $dimc \> 2` == 1 ))
then
   filtre="FILTRE=$filtre"
else
   filtre="FILTRE= L_FILTRE= "
fi
echo MACRO FILTRE $filtre

echo $dimc



######################################################################
# Creation du suffixe de la configuration
######################################################################


SUFF_NAME=_${dim_full}
SUFF_NAME=${SUFF_NAME}_phy${physique}

if [[ "$parallel" != "none" ]]
then
  SUFF_NAME=${SUFF_NAME}_para
  DYN=dyn${dimc}d${paramem}
  if [[ "$paramem" == "mem" ]]
  then
   SUFF_NAME=${SUFF_NAME}_${paramem}
  fi
else
  SUFF_NAME=${SUFF_NAME}_seq
  DYN=dyn${dimc}d
fi

if [[ $veget == "true" ]]
then
  SUFF_NAME=${SUFF_NAME}_orch
fi

if [[ $couple != "false" ]]
then
  SUFF_NAME=${SUFF_NAME}_couple
fi

if [[ $chimie == "INCA" ]]
then
  SUFF_NAME=${SUFF_NAME}_inca
fi

cd $LMDGCM
config_fcm="config.fcm"
rm -f $config_fcm
touch $config_fcm
rm -f bin/${code}${SUFF_NAME}.e
rm -f arch.fcm
rm -f arch.opt

echo "%ARCH          $arch"          >> $config_fcm
echo "%INCDIR        $INCLUDE"       >> $config_fcm 
echo "%LIB           $LIB"           >> $config_fcm
echo "%ROOT_PATH     $PWD"           >> $config_fcm
echo "%LIBF          $LIBFGCM"       >> $config_fcm
echo "%LIBO          $LIBOGCM"       >> $config_fcm
echo "%DYN           $DYN"           >> $config_fcm
echo "%PHYS          phy${physique}" >> $config_fcm
echo "%COSP          $COSP_PATH"     >> $config_fcm
echo "%CPP_KEY       $CPP_KEY"       >> $config_fcm
echo "%EXEC          $code"          >> $config_fcm
echo "%SUFF_NAME     $SUFF_NAME"     >> $config_fcm
echo "%COMPIL_FFLAGS $COMPIL_FFLAGS" >> $config_fcm
echo "%PARA_FFLAGS   $PARA_FFLAGS"   >> $config_fcm
echo "%PARA_LD       $PARA_LD"       >> $config_fcm
echo "%EXT_SRC       $EXT_SRC"       >> $config_fcm



ln -s arch/arch-${arch}.fcm arch.fcm
if test -f arch/arch-${arch}.opt &&  [ $compil_mod = "prod" ]
  then
  ln -s arch/arch-${arch}.opt arch.opt
else
  ln -s .void_file arch.opt
fi


rm -f $LIBOGCM/${arch}${SUFF_NAME}/.config/fcm.bld.lock
./build_gcm

rm -rf tmp_src
rm -rf config
ln -s $LIBOGCM/${arch}${SUFF_NAME}/.config config
ln -s $LIBOGCM/${arch}${SUFF_NAME}/.config/tmp tmp_src

if [[ -r $LIBFGCM/grid/dimensions.h ]]
then
  # Cleanup: remove dimension.h file
  \rm -f $LIBFGCM/grid/dimensions.h
fi
