#!/bin/bash

# Create ww3_ codes in NCO format for use at NCEP Cray

# Run script from tree level above model directory

# Set version number (Manually, should somewhat resemble trunk version)
WW3VER="6.02"

# Check out latest trunk
if [ -d model ]
then
# Update model
  cd model
  svn update
  cd ..
else
  svn co https://svnemc.ncep.noaa.gov/projects/ww3/branches/ncep_opcode/model ./model
fi

# Set WWATCH package and work directories
SAVE=`pwd`
export WWATCH3_DIR=${SAVE}/model
export WWATCH3_TMP=/gpfs/hps/stmp/emc.wavepa/make_multi/work   # Scratch directory
export WWATCH3_BUILD=${SAVE}/ww3_code.v${WW3VER}

# Create parameter indicating source-term and other code options (eg nc etc)
options=st4nc

# FORTRAN source code extension
fextf='F90'

echo ' '
echo " Creating new code on ${WWATCH3_BUILD}"

mkdir -p $WWATCH3_BUILD
mkdir -p $WWATCH3_TMP

cd $WWATCH3_BUILD

# Load system-specific modules 
chipset=sandybridge

source $MODULESHOME/etc/modules.sh
  module load prod_util prod_envir
  module load PrgEnv-intel
  module unload craype-haswell
  module load craype-${chipset}

  module load HDF5-serial-intel-${chipset}
  module load NetCDF-intel-${chipset}
  module load iobuf

# used for multiwavegrib2
  module load jasper-gnu-${chipset}
  module load png-intel-${chipset}
  module load zlib-intel-${chipset}
  module load g2-intel

# used for multiwavegrib1 and grib2
  module load w3nco-intel
  module load bacio-intel/2.0.2

# Create new env file for this build
cat > wwatch3.env << EOF
WWATCH3_LPR Printer
WWATCH3_F90 ifort
WWATCH3_CC  icc
WWATCH3_DIR ${WWATCH3_DIR}
WWATCH3_TMP ${WWATCH3_TMP}
WWATCH3_SOURCE no
WWATCH3_LIST no
EOF

export WWATCH3_ENV=${WWATCH3_BUILD}/bin/wwatch3.env

comps=ftn
compm=ftn
progs='ww3_grid ww3_bound ww3_prep ww3_prnc ww3_multi ww3_sbs1 ww3_outf ww3_ounf ww3_ounp ww3_outp gx_outf gx_outp ww3_grib ww3_gint ww3_systrk'

# SWITCH file
# Source term and propagation scheme choices for switch file
GEN="F90 NCO LRB4"
GRB="NCEP2"
SCRIP="SCRIP SCRIPNC"
NC="NC4"
PROP="PR3 UQ"
#STERM="ST4 STAB0 FLX0 LN1 NL3 BT1 DB1 IC0 IS0 REF0 MLIM TR0 BS0 XX0"; 
STERM="ST4 STAB0 FLX0 LN1 NL1 BT1 DB1 IC0 IS0 REF0 MLIM TR0 BS0 XX0"; 
WNDCUR="WNX1 WNT1 CRX1 CRT1"
OFLAG="O0 O1 O2 O4 O5 O6 O7 O14 O15"
MOV="MGP MGW MGG"

# Define alternate switch types
# Shared memory/serial
PROC='SHRD'
GRB='NCEP2'
SBS=
SWITCH_SHRD="${GEN} ${GRB} ${PROC} ${SBS} ${SCRIP} ${NC} ${PROP} ${STERM} ${WNDCUR} ${OFLAG} ${MOV}"

# MPI
PROC='DIST MPI'
GRB=NOGRB
SBS=
SWITCH_MPI="${GEN} ${GRB} ${PROC} ${SBS} ${SCRIP} ${NC} ${PROP} ${STERM} ${WNDCUR} ${OFLAG} ${MOV}"

# Side-by-side multi
PROC='DIST MPI'
GRB=NOGRB
SBS='SBS'
SWITCH_SBS="${GEN} ${GRB} ${PROC} ${SBS} ${SCRIP} ${NC} ${PROP} ${STERM} ${WNDCUR} ${OFLAG} ${MOV}"

# NetCDF libraries
NCINC='-I${NETCDF}/include'
LIBFCSTNC='-L${NETCDF}/lib -lnetcdff -lnetcdf -L${HDF5}/lib -lhdf5_hl -lhdf5 -lrt -lm -lz'

# Define compilation options
OPTFL="-O3  -convert big_endian -assume byterecl -prec-div -prec-sqrt -ip -ftz"

# Loop through programs
for prog in $progs
do
    case $prog in
     ww3_grid  ) name=multiwavegrid  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs= ;;
     ww3_bound ) name=multiwavebound  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs= ;;
     ww3_prep  ) name=multiwaveprep  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs= ;;
     ww3_prnc  ) name=multiwaveprnc  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL}' -I${NETCDF}/include' ;
                 ldflags= ;
                 libs='-L${NETCDF}/lib -lnetcdff -lnetcdf -L${HDF5}/lib -lhdf5_hl -lhdf5 -lrt -lm -lz' ;;
     ww3_shel  ) name=multiwaveshel  ; switch="$SWITCH_MPI" ; comp=$compm ;
                 fflags=${OPTFL}' '${NCINC} ;
                 ldflags= ;
                 libs=${LIBFCSTNC} ;;
     ww3_multi ) name=multiwavefcst  ; switch="$SWITCH_MPI" ; comp=$compm ;
                 fflags=${OPTFL}' '${NCINC} ;
                 ldflags= ;
                 libs=${LIBFCSTNC} ;;
     ww3_sbs1 )  name=multiwavefcst_sbs ; switch="$SWITCH_SBS" ; comp=$compm ;
                 fflags=${OPTFL}' '${NCINC} ;
                 ldflags= ;
                 libs=${LIBFCSTNC} ;;
     ww3_gint)   name=multiwavegrid_interp  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs= ;;
     ww3_outp  ) name=multiwavespec  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs= ;;
     ww3_outf  ) name=multiwaveflds  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs= ;;
     ww3_ounf  ) name=multiwavefldn  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL}' -I${NETCDF}/include' ;
                 ldflags= ;
                 libs='-L${NETCDF}/lib -lnetcdff -lnetcdf -L${HDF5}/lib -lhdf5_hl -lhdf5 -lrt -lm -lz' ;;
     ww3_ounp  ) name=multiwavespnc  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL}' -I${NETCDF}/include' ; 
                 ldflags= ; 
                 libs='-L${NETCDF}/lib -lnetcdff -lnetcdf -L${HDF5}/lib -lhdf5_hl -lhdf5 -lrt -lm -lz' ;;
     ww3_grib  ) name=multiwavegrib2 ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 libs='${G2_LIB4} ${W3NCO_LIB4} ${BACIO_LIB4} ${JASPER_LIB} ${PNG_LIB} ${Z_LIB}' ;
                 fflags=${OPTFL} ;
                 ldflags= ;;
     ww3_systrk) name=wavesystrk  ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs='-L${NETCDF}/lib -lnetcdff -lnetcdf -L${HDF5}/lib -lhdf5_hl -lhdf5 -lrt -lm -lz' ;;
     gx_outf   ) name=multiwavegrads_fields   ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs= ;;
     gx_outp   ) name=multiwavegrads_points   ; switch="$SWITCH_SHRD" ; comp=$comps ;
                 fflags=${OPTFL} ;
                 ldflags= ;
                 libs= ;;
        *      ) echo "do not recognize $prog." ; exit ;;
    esac

# Set up flags for w3_source
export FC=${comp}
export FFLAGS=${fflags}
export LDFLAGS=${ldflags}
export LIBS=${libs}

rm -f ${WWATCH3_DIR}/bin/switch

echo $switch > ${WWATCH3_DIR}/bin/switch

# Run w3_source
echo ' '
echo " Running w3_source for $prog "

${WWATCH3_DIR}/bin/w3_setup ${WWATCH3_DIR} -q -c Intel 

${WWATCH3_DIR}/bin/w3_source $prog > source_${prog}.out 2>&1

# Move to build directory
rm -rf ${WWATCH3_BUILD}/${options}/sorc/${prog}.fd
mkdir -p ${WWATCH3_BUILD}/${options}/exec
mkdir -p ${WWATCH3_BUILD}/${options}/sorc/${prog}.fd
mv -f ${WWATCH3_DIR}/work/$prog.tar.gz ${WWATCH3_BUILD}/${options}/sorc/${prog}.fd
tar zxvf ${WWATCH3_BUILD}/${options}/sorc/${prog}.fd/$prog.tar.gz -C ${WWATCH3_BUILD}/${options}/sorc/${prog}.fd > /dev/null 2>&1
rm -f ${WWATCH3_BUILD}/${options}/sorc/${prog}.fd/$prog.tar.gz 


cd ${WWATCH3_BUILD}/${options}/sorc/${prog}.fd/

  echo " Changing ${prog} and input file to NCO main program name "
  echo ' ' 

    case $prog in
      ww3_grid ) sed -e 's/W3GRID/WAVEGRID/g' \
                     -e 's/ww3_grid/${name}/g' $prog.${fextf} > $name.${fextf} 
                 sed -e 's/NOSW   = 5/NOSW   = 2/g' $name.${fextf}  > ${name}.dummy
                 mv ${name}.dummy ${name}.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_bound ) sed -e 's/W3BOUND/WAVEBOUND/g' \
                     -e 's/ww3_bound/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_prep ) sed -e 's/W3PREP/WAVEPREP/g' \
                     -e 's/ww3_prep/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_prnc ) sed -e 's/W3PRNC/WAVEPRNC/g' \
                     -e 's/ww3_prnc/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_shel ) sed -e 's/W3SHEL/WAVEFCST/g' \
                     -e 's/ww3_shel/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_multi ) sed -e 's/W3SHEL/WAVEFCST/g' \
                     -e 's/ww3_multi/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_sbs1 ) sed -e 's/W3SHEL/WAVEFCST/g' \
                     -e 's/ww3_multi/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_gint ) sed -e 's/W3GRID_INT/WAVEGRID_INT/g' \
                        -e 's/ww3_gint/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf} ;;
      ww3_grib ) sed -e 's/W3GRIB/WAVEGRIB2/g' \
                     -e 's/ww3_grib/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_outp ) sed -e 's/W3OUTP/WAVESPEC/g' \
                     -e 's/ww3_outp/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_outf ) sed -e 's/W3OUTF/WAVEFLDS/g' \
                     -e 's/ww3_outf/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_ounp ) sed -e 's/W3OUNF/WAVESPNC/g' \
                     -e 's/ww3_ounp/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_ounf ) sed -e 's/W3OUNF/WAVEFLDS/g' \
                     -e 's/ww3_ounf/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      ww3_systrk ) sed -e 's/W3SYSTRK/WAVESYSTRK/g' -e 's/WW3_SYSTRK/WAVESYSTRK/g'\
                     -e 's/ww3_systrk/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      gx_outf  ) sed -e 's/GXOUTF/WAVEGXFL/g' \
                     -e 's/gx_outf/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
      gx_outp  ) sed -e 's/GXOUTP/WAVEGXSP/g' \
                     -e 's/gx_outp/${name}/g' $prog.${fextf} > $name.${fextf}
                 rm -f $prog.${fextf}      ;;
         *     ) if [ "$prog" != "$name" ]
                 then
                   mv $prog.${fextf} $name.${fextf}
                 fi;;
    esac

# Change makefile to reflect NCO main prog name
    sed  -e "s/$prog/$name/g" makefile > makefile.temp

    mv makefile.temp makefile
    rm -rf ${WWATCH3_BUILD}/${options}/sorc/${name}.fd
    mv ${WWATCH3_BUILD}/${options}/sorc/${prog}.fd ${WWATCH3_BUILD}/${options}/sorc/${name}.fd

cd $WWATCH3_BUILD/${options}/sorc/${name}.fd

make clean
make  > $WWATCH3_BUILD/${options}/sorc/${name}.fd/make.${name}.out 2>&1
mv -f $WWATCH3_BUILD/${options}/sorc/${name}.fd/${name} $WWATCH3_BUILD/${options}/exec
make clean

# Remove obj and mod files to ensure switch options are enforced
rm -f ${WWATCH3_DIR}/obj*/*
rm -f ${WWATCH3_DIR}/mod*/*

done

# Copy make.codes.sh script from aux/scripts 
#cp ${SAVE}/aux/scripts/make.codes.sh ${WWATCH3_BUILD}/${options}/sorc/

echo ' '
echo " All done "
