#!/bin/csh
#
# $Header$
#
#set verbose echo

########################################################################
# path a changer contenant les sources et les objets du modele
########################################################################

###### VERSION LMDZ.4

set LMDGCM=$WORKDIR/LMDZ4_V3_LAURENT
set NCDFLIB=/usr/local/SX6/soft/netcdf/lib
set NCDFINC=/usr/local/SX6/soft/netcdf/include
set IOIPSLDIR=$WORKDIR/IOIPSL_MPP/src
set ORCH_LIBDIR=$WORKDIR/LSCE/ORCHIDEE_PARA/libbis
#1set IOIPSLDIR=$SCRATCHDIR/MODIPSL_NEW/modipsl/lib

setenv localdir "`pwd`"

  if ( ! $?LMDGCM ) then
    echo You must initialize the variable LMDGCM in your environnement
    echo for instance: "setenv LMDGCM /usr/myself/supergcm" in .cshrc
    exit
  endif

  if ( ! $?LIBOGCM ) then
    set LIBOGCM=$LMDGCM/libo
  endif

  if ( ! $?IOIPSLDIR ) then
    echo You must initialize the variable IOIPSLDIR in your environnement
    echo for instance: "setenv IOIPSLDIR /usr/myself/ioipsl" in .cshrc
    exit
  endif

  if ( ! $?NCDFLIB ) then
    echo You must initialize the variable NCDFLIB in your environnement
    echo for instance: "setenv NCDFLIB /usr/myself/netcdf" in .cshrc
    exit
  endif

  if ( ! $?NCDFINC ) then
    echo You must initialize the variable NCDFINC in your environnement
    echo for instance: "setenv NCDFINC /usr/myself/netcdf" in .cshrc
    exit
  endif
endif

set model=$LMDGCM
set libf=$model/libf
set libo=$LIBOGCM
if ( ! -d $libo )  then
   mkdir $libo
endif

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

set dyn=
set opt_link=""
set adjnt=""
set opt_dep=""

set optim=""
set optimbis=""
set optim90=""
set oplink=""


########################################################################
# options du compilateur
########################################################################

  set machine=SX6
  set f77=sxf90.new
  set f90=sxf90.new
  set optim90='-C vsafe -gv -P stack -Wf,-pvctl res=whole,-A dbl4,-init stack=nan,-init heap=nan,-ptr byte -EP -ts ${GCM}/tmp_src -R5 -float0 -size_t64 -dw -Wf,"-pvctl loopcnt=999999 fullmsg noassume" -I/SX/usr/include'
  set optimtru90="$optim90"
  set optim="$optim90"
  set cppflags='-DNC_DOUBLE -DBLAS -DSGEMV=DGEMV -DSGEMM=DGEMM'
  set opt_link='-float0 -size_t64 -Wf,-A dbl4 -lblas'
  set mod_suffix="mod"
  set mod_loc_dir="./"
  set make="sxmake -i RANLIB=ls"
  set link="$f90 -Wl,-hlib_cyclic"   
  set ar=sxar
  set optim90="$optim90 -f3"
  
########################################################################
# options par defaut pour la commande make
########################################################################

  set dim="96x72x19"
  set physique=lmd
  set phys="PHYS=$physique" 
  set include='-I$(LIBF)/filtrez -I$(LIBF)/grid -I$(LIBF)/bibio -I. '
  set ntrac = 4
  set filtre=filtrez
  set grille=reg
  set couple=false
  set veget=false
  set psmile=false
  set io=ioipsl
  set inca=false
  set vampir=false
  set parallel=false
  
  if ($parallel == true) then
    set cppflags = " $cppflags -DCPP_PARA"
    set include="$include"' -I$(LIBF)/dyn3d_par'
  else
    set include="$include"' -I$(LIBF)/dyn3d'
  endif
   
  if ($inca == true) then
    set cppflags="$cppflags -DINCA -DINCA_CH4"
    set opt_link="$opt_link -linca"
  endif

  if ($couple == true) then
     set opt_link="$opt_link -L/scratchdir/p86yann/MODIPSL_NEW/modipsl/prism/SX/lib -lpsmile.MPI2 -lmpp_io"
     set cppflags="$cppflags -DCPP_COUPLE -DCPP_PSMILE -I/scratchdir/p86yann/MODIPSL_NEW/modipsl/prism/SX/build/lib/psmile.MPI2"
  endif

  if ($veget == true) then
     set opt_link="$opt_link -L $ORCH_LIBDIR -lsxparameters -lsxsechiba -lsxstomate -lsxparallel"
     set cppflags="$cppflags -DCPP_VEGET"
     set include="$include"" -I$ORCH_LIBDIR"
  endif
 
  if ($vampir == true) then 
    set cppflags="$cppflags -vt -DUSE_VT"
    set opt_link="$opt_link -vt"
  else
    set cppflags="$cppflags -DNUSE_VT"
    set opt_link="$opt_link"
  endif
  
  set optim90=" $optim90  -I$libo $cppflags"
  set optimtru90=" $optimtru90 -I$libo $cppflags"
  set optim=" $optim  -I$libo $cppflags"
  set opt_link="$opt_link -L$IOIPSLDIR -lsxioipsl -L$NCDFLIB -lnetcdf"
  
########################################################################
#  Les differentes platformes reconnues
########################################################################
set X6NEC=1


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

top:
if ($#argv > 0) then
    switch ($1:q)

    case -h:

########################################################################
# Manuel en ligne
########################################################################
more <<eod


makegcm [Options] prog




Par default, la commande makegcm:
---------------------------------

1. compile une serie de sous programmes se trouvant dans des sous-repertoires
de $LMDGCM/libf.
Les sous programmes sont ensuite stokes sur dans des librairies FORTRAN
sur $LIBOGCM.

2. Ensuite, makegcm compile le programme prog.f se trouvant par default sur
$LMDGCM/libf/dyn3d et effectue le lien avec l ensemble des librairies.

La variable '$LMDGCM' doit etre initialisee dans votre .cshrc ou en dur
dans la comande makegcm.

La commande makegcm est faite pour permettre de gerer en parallele des
versions differentes du modele, compilees avec des options de compilation
et des dimensions differentes sans avoir a chaque fois a recompiler tout
le modele.

Les librairies FORTRAN sont stoquees sur le directory $LIBOGCM.


OPTIONS:
--------

Les options suivantes peuvent etre definies soit par defaut en editant le
"script" makegcm, soit en interactif:

-d imxjmxlm  ou im, jm, et lm sont resp. le nombre de longitudes, latitudes
             et couches verticales. 

-t ntrac   selectionne le nombre de traceur advectes par la dynamique.
           Dans les versions courantes du modele terrestre on a par exemple
           ntrac=2 pour l'eau vapeur et liquide

             L'effet des options -d et -t est d'ecraser le fichier 
             $LMDGCM/libf/grid/dimensions.h
             qui contient sous forme de 4 PARAMETER FORTRAN les 3 dimensions
             de la grille horizontale im, jm, lm plus le nombre de traceurs
             advectes passivement par la dynamique ntrac, par un nouveu fichier
             $LMDGCM/libf/grid/dimension/dimensions.im.jm.lm.tntrac
             Si ce fichier n'existe pas encore, il est cree par le script
             $LMDGCM/libf/grid/dimension/makdim

-p PHYS    pour selectionner le jeu de parametrisations physiques avec
           lequel on veut compiler le modele.
           Le modele sera alors compile en prenant les sources des
           parametrisations physiques dans le repertoire:
            $LMDGCM/libf/phyPHYS

-c false|true
           pour selectionner le mode force (par defaut) ou couple

-io ioipsl|noioipsl
           pour selectionner le logiciel IO : IOIPSL par defaut

-psmile false|true
           pour selectionner le mode psmile ou non (par defaut)

-v true|false
           pour selectionner la vegetation (par defaut) ou non

-g grille  selectionne le type de grille qu'on veut utiliser.
           L'effet de cette option est d'ecraser le fichier
           $LMDGCM/libf/grid/fxyprim.h
           avec le fichier
           $LMDGCM/libf/grid/fxy_grille.h
           grille peut prendre les valeurs:
           1. reg pour la grille reguliere
           2. sin pour avoir des points equidistants en sinus de la latitude
           3. new pour pouvoir zoomer sur une partie du globe

-O "optimisation fortran" ou les optimisations fortran sont les options de la
            commande f77

-include path
           Dans le cas ou on a dans des sous programmes des fichiers 
           #include (cpp) qui se trouve sur des repertoires non references
           par defaut

-adjnt     Pour compiler la l'adjoint du code dynamique

-filtre  filtre
           Pour choisir le filtre en longitude dans les regions polaires.
           "filtre" correspond au nom d'un repertoire se trouvant sur
           $LMDGCM/libf. Le filtre standard du modele est "filtrez" qui peut
           etre utilise aussi bien pour une grille reguliere que pour une 
           grille zoomee en longitude.

-link "-Ldir1 -lfile1 -Ldir2 -lfile2 ..."
          Pour rajouter un lien avec les librairies FORTRAN
          libfile1.a, libfile2.a ... se trouvant respectivement sur les
          repertoires dir1, dir2 ...
          Si dirn est un repertoire dont le chemin est automatique (comme
          par exemple /usr/lib ...) il n'est pas besoin de specifier -Ldirn.

Auteur: Frederic Hourdin  (hourdin@lmd.jussieu.fr)
eod
exit

########################################################################
# Lecture des differentes options
########################################################################

    case -d:
        set dim=$2 ; shift ; shift ; goto top
                        
    case -O:
        set optim="$2" ; shift ; shift ; goto top

     case -p
        set physique="$2" ; set phys="PHYS=$physique" ; shift ; shift ; goto top

     case -g
        set grille="$2" ; shift ; shift ; goto top

     case -c
        set couple="$2" ; shift ; shift ; goto top

     case -io
        set io="$2" ; shift ; shift ; goto top

     case -v
        set veget="$2" ; shift ; shift ; goto top

     case -psmile
        set psmile="$2" ; shift ; shift ; goto top
  
     case -t
        set ntrac=$2 ; shift ; shift ; goto top

     case -include
        set include="$include -I$2" ; shift ; shift ; goto top

     case -adjnt
        set opt_dep="$opt_dep adjnt" ; set adjnt="-ladjnt -ldyn3d "
        set optim="$optim -Dadj" ; shift ; goto top

     case -filtre
        set filtre=$2 ; shift ; shift ; goto top

     case -link
        set opt_link="$opt_link $2" ; shift ; shift ; goto top

     case -debug
        if $X6NEC then
        else 
           echo pas d option debug predefinie pour cette machine
           exit
        endif
        shift ; goto top

     default
        set code="$1" ; shift ; goto top

   endsw
endif

########################################################################
# Definition des clefs CPP
########################################################################

if ( $io == ioipsl ) then
   set optim="$optim -DCPP_IOIPSL"
   set optim90="$optim90 -DCPP_IOIPSL"
   set optimtru90="$optimtru90 -DCPP_IOIPSL"
endif

if ( "$physique" == 'nophys' ) then
   set phys="L_PHY= LIBPHY="
else
   set optim="$optim -DCPP_PHYS"
   set optim90="$optim90 -DCPP_PHYS"
   set optimtru90="$optimtru90 -DCPP_PHYS"
endif

#set link_veget=" "
#if ( "$veget" == 'true' ) then
#   set optim="$optim -DCPP_VEGET"
#   set optim90="$optim90 -DCPP_VEGET"
#   set optimtru90="$optimtru90 -DCPP_VEGET"
#   set link_veget=" -lsechiba -lparameters -lstomate"
#endif

if ($parallel == 'true') then
  set FLAG_PARA='_par'
else
  set FLAG_PARA=''
endif

########################################################################
# cas special sans physique
########################################################################
if ( "$physique" == 'nophys' ) then
   set phys="L_PHY= LIBPHY="
endif

########################################################################
# choix du nombre de traceur par defaut si il n'a pas ete choisi,
# suivant la physique
########################################################################

if ( $ntrac == 0  ) then
    if ( "$physique" == 'nophys' ) then
        set ntrac=1
    else if ( "$physique" == 'lmd' ) then
        set ntrac=2
    else if ( "$physique" == 'lmd_test_li' ) then
        set ntrac=2
    else if ( "$physique" == 'ec' ) then
        set ntrac=1
    else
        set ntrac = 1
    endif
endif

########################################################################
#subtilites sur le nom de la librairie
########################################################################

\rm -f tmp ; touch tmp
\rm -f tmp90 ; touch tmp90
foreach i ( $optim )
   echo $i | sed -e 's/\"//g' -e "s/\'//g" -e 's/-//g'  >> tmp
end
set suf=
foreach i ( `sort tmp | uniq ` )
   set suf=$suf$i
end

   set dim=`echo $dim | sed -n -e 's/[^0-9]/ /gp'`
   set dim_=`echo $dim | sed -n -e 's/[^0-9]/_/gp'`
   set nomlib=`echo ${machine}_${dim_}_t${ntrac}`

echo calcul de la dimension
set dimc=`echo $dim | wc -w`

if ( "$dimc" == "2" ) then
set include="$include "'-I$(LIBF)/dyn2d '
set dimh=$dim
else
set include="$include "
set dimh=`echo $dim | awk ' { print $1 "." $2 } '`
endif
echo $dimc

########################################################################
# path pour les #include
########################################################################

  set include="$include -I$NCDFINC -I$IOIPSLDIR"
  echo $include

########################################################################
# Gestion des dimensions du modele.
# on cree ou remplace le fichier des dimensions/nombre de traceur
########################################################################

cd $libf/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?"
if ( $< == "oui" ) then
\rm -f $libf/grid/dimensions.h
else
exit
endif
endif

cd dimension
makdim $ntrac $dim
cat $libf/grid/dimensions.h

cd $LMDGCM
set libo=$libo/$nomlib
if ( ! -d $libo )  then
   mkdir $libo
   cd $model
endif

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

set dimension=`echo $dim | wc -w`
echo dimension $dimension
if ( $dimension == 1 ) then
echo pas de dynamique
set dyn="L_DYN= DYN= L_FILTRE= DIRMAIN=phy$physique "
endif
endif
cd $model
if ( $dimension == 3 ) then
cd libf/grid
\rm fxyprim.h
cp -p fxy_${grille}.h fxyprim.h
endif

######################################################################
#   Traitement special pour le nouveau rayonnement de Laurent Li.
######################################################################

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.$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
 endif
endif

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

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

echo $dimc

########################################################################
#  utilisation des vraies routines de couplage si on est en couple
########################################################################
if ( $couple == 'true' ) then
  pwd
#  if ( `diff $libf/phy$physique/oasis.F $libf/phy$physique/oasis.true | wc -w` ) then
#   \cp $libf/phy$physique/oasis.F $libf/phy$physique/oasis.dummy
#   \cp $libf/phy$physique/oasis.true $libf/phy$physique/oasis.F
#  endif
   if ( -f $libf/phy$physique/oasis.F ) then 
     rm -f $libf/phy$physique/oasis.F
   endif	
   \cp $libf/phy$physique/oasis.psmile $libf/phy$physique/oasis.F90
else
  if ( `diff $libf/phy$physique/oasis.F $libf/phy$physique/oasis.dummy | wc -w` ) then
   \cp $libf/phy$physique/oasis.F $libf/phy$physique/oasis.true
   \cp $libf/phy$physique/oasis.dummy $libf/phy$physique/oasis.F
  endif
   rm -f $libf/phy$physique/oasis.F90
endif
########################################################################
#  Avant de lancer le make, on recree le makefile si necessaire
########################################################################
# c'est a dire dans 3 cas:
# 1. si la liste des fichiers .F et .h a ete modifiee depuis la
#    derniere creation du makefile
# 2. si le fichier contenant cette liste "liste_des_sources"
#    n'existe pas.
# 3. Si le makefile n'existe pas.
########################################################################

cd $model
find libf -name '*.[Fh]' -print >! tmp77
find libf -name '*.[Fh]' -exec egrep -i " *use *ioipsl" {} \; -print >! tmp90
find libf -name '*.[Fh]90' -print >> tmp90

if (    `diff tmp77 liste_des_sources_f77 | wc -w` \
     || `diff tmp90 liste_des_sources_f90 | wc -w` \
     || ! -f makefile \
     || ! -f liste_des_sources_f90 \
     || ! -f liste_des_sources_f77 ) then
        echo les fichiers suivants ont ete crees ou detruits
        echo ou les fichiers suivants sont passes ou ne sont plus en Fortran 90
        diff liste_des_sources_f77 tmp77
        diff liste_des_sources_f90 tmp90
        \cp tmp77 liste_des_sources_f77
        \cp tmp90 liste_des_sources_f90
        echo On recree le makefile
        ./create_make_gcm >! tmp
        \mv tmp makefile
        echo Nouveau makefile cree.
endif

########################################################################
#  Execution de la comande make
########################################################################

echo PHYSIQUE $phys
echo dynamique $dyn $dimension
echo OPTIM="$optim" $filtre LIBO=$libo $dyn PHYS=$phys DIM=$dimc PROG=$code
echo PATH pour les fichiers INCLUDE $include
echo OPLINK="$oplink"


set include="$include"' -I$(LIBF)/phy'"$physique"
set include="$include"' -I$(LIBO)'


#################################################################
# Execution de la comande make... ENFIN!
#################################################################



cd $localdir

echo $make -f $LMDGCM/makefile \
OPTION_DEP="$opt_dep" OPTION_LINK="$opt_link" \
OPTIM90="$optim90" \
OPTIMTRU90="$optimtru90" \
OPTIM="$optim$optimbis" \
INCLUDE="$include" \
$filtre \
LIBO=$libo \
$dyn \
$phys \
DIM=$dimc \
FLAG_PARA="$FLAG_PARA"\
L_ADJNT="$adjnt" \
LOCAL_DIR="$localdir"  \
F77="$f77" \
F90="$f90" \
OPLINK="$oplink" \
LINK="$link" \
GCM="$LMDGCM" \
MOD_LOC_DIR=$mod_loc_dir \
MOD_SUFFIX=$mod_suffix \
AR=$ar \
PROG=$code


$make -f $LMDGCM/makefile \
OPTION_DEP="$opt_dep" OPTION_LINK="$opt_link" \
OPTIM90="$optim90" \
OPTIMTRU90="$optimtru90" \
OPTIM="$optim$optimbis" \
INCLUDE="$include" \
$filtre \
LIBO=$libo \
$dyn \
$phys \
DIM=$dimc \
FLAG_PARA="$FLAG_PARA"\
L_ADJNT="$adjnt" \
LOCAL_DIR="$localdir"  \
F77="$f77" \
F90="$f90" \
OPLINK="$oplink" \
LINK="$link" \
GCM="$LMDGCM" \
MOD_LOC_DIR=$mod_loc_dir \
MOD_SUFFIX=$mod_suffix \
AR=$ar \
PROG=$code

\rm -f $libf/grid/dimensions.h
