#!/bin/bash

#########################################################################
# ------   ELK_TEST_GEN  ---- ELK_TEST_GEN  ---- ELK_TEST_GEN  ----     #
#                                                                       #
# Shell script to generate a set of test files using a new version      #
# of the MCTDH program, and compare the files to a standard comparison  #
# set                                                                   #
#                                                                       #
# testcode: name of code to be tested (1st argument)                    #
# potcode : name of potfit code to be used                              #
# inppath : path to directory containing the comparison set of files.   #
#                                                                       #
# 4/98  GW                                                              #
#########################################################################

#################################################################
#############--------  SET DEFAULTS HERE  ---------------########
#################################################################
inppath=$MCTDH_DIR/elk_inputs                                   #
outpath=`pwd`                                                   #
outpath=${outpath%/$MCTDH_PLATFORM}/$MCTDH_PLATFORM             #
potcode=potfit$MCTDH_VERSION                                    #
projcode=projection$MCTDH_VERSION                               #
#################################################################

#-----------------------------------------------------------------------
# FUNCTION  helpf. Print help information.
#-----------------------------------------------------------------------
helpf() {
    if [ -n "${potcode##/*}"   ] ; then  potcode=`which $potcode`  ; fi
    echo ' '
    echo "$minus40$minus40"
    echo 'Purpose: Generates a set of test files for the MCTDH program.'
    echo 'Usage:   elk_test_gen [-h] [-M mpipro] [-P pthreads]'
    echo '              [-i inpname] [-o outname] [-p potcode]'
    echo '                             [-j projcode] [-s skip] program'
    echo '   -h:   Print this help text.'
    echo '   -i:   Get input files from "inpname" directory.'
    echo '   -j:   Use the projection-program "projcode".'
    echo '   -p:   Use the potfit-program "potcode".'
    echo '   -o:   Write output in "outname" directory.'
    echo '         If "outname" ends with a slash, $MCTDH_PLATFORM'\
                   'will be appended.'
    echo '         The default outname is the current directory'\
                  '(with /$MCTDH_PLATFORM).'
    echo '   -s:   Do not generate the first "skip" elk-test'
    echo '   -M:   Number of MPI processes for the elk-test'
    echo '   -P:   Number of POSIX-threads for the elk-test'
    echo ' '
    echo ' The default setting reads:'
    echo " Potfit code    : $potcode"
    echo " Projection code: $projcode"
    echo " Input set      : $inppath"
    echo " Output path    : $outpath"
    echo "$minus40$minus40"
    echo ' '
    exit
}


#-----------------------------------------------------------------------
# FUNCTION  mktest. Checks if a certain run was previously done
#                   successfully, and - if not - runs mctdh or potfit.
#-----------------------------------------------------------------------
mktest() {

name=$1
runcode=$2
mpi=$3
pth=$4
logf=$name/log

if [ -e "$name" ] ; then
    unset tt
    if [ -f "$logf" ] ; then
       tt=`tail -n 15 $logf | fgrep 'Program terminated normally'` 2>/dev/null
    elif [ -z "${runcode##*potf*}" ] && [ -f "$name/plog" ] ; then
       tt=`tail -n 15 $name/plog | \
           fgrep 'Program terminated normally'` 2>/dev/null
    fi
    if [ -z "$tt" ] ; then
        echo "removing the directory of the failed run: $name"
        rm -rf $name
        rm  -f ${name}.inp
    else
        dirname=`echo "directory  $name                          " `
        dirname=`echo "$dirname" | cut -c 1-20 `
        echo "$dirname already exist.  Skipped."
        echo "$dirname already exist.  Skipped." >> log
    fi
fi

if [ ! -e $name ] ; then
    mkdir $name
    if [ $name = test17 ] ; then
       cp nocl1_10/* test17
    fi
    cp $inppath/$name.inp .
    if [ $mpi -ge 1 ] ; then
       mv $name.inp temp.inp
       sed 's/^RUN\-SECTION.*$/&\nusempi/' temp.inp > $name.inp
       rm -rf temp.inp
    fi
    if [ $pth -ge 1 ] ; then
       mv $name.inp temp.inp
       sed "s/^RUN\-SECTION.*$/&\nusepthreads=$pth/" temp.inp > $name.inp
       rm -rf temp.inp
    fi
    vname=`echo  "Generating $name                      " `
    vname=`echo  "$vname" | cut -c 1-20 `
    echo -n "$vname"
    echo -n "$vname" >> log
    if [ $mpi -ge 1 ] ; then
       mpirun -np $mpi $runcode $name || exit 1
    else
       $runcode $name || exit 1
    fi
    unset tt
    tt=`tail -n 15 $logf | fgrep 'Program terminated normally'` 1>/dev/null
    if [ -z "$tt" ] ; then
       echo ' '
       echo ' '
       echo '#########################################################'
       echo ' '
       echo "         Generation of $name failed!  "
       echo ' '
       echo '---------------  Last 20 lines of log file --------------'
       tail -n 20 $logf
       echo ' '
       echo '#########################################################'
       echo "  Generation of $name failed!" >> log
    else
      zeit=`date '+%T' `
       echo " : done.  $zeit"
       echo " : done.  $zeit" >> log
    fi
fi
}


############################################################################
##-------------------- ACTUAL SCRIPT BEGINNS HERE ------------------------##
############################################################################

minus40='----------------------------------------'
ierr=0

if [ -z "$MCTDH_DIR" ] ; then
   echo $MCTDH_DIR
  ierr=1
fi
if [ -z "$MCTDH_VERSION" ] ; then
   echo $MCTDH_VERSION
   ierr=1
fi
if [ "$ierr" = 1 ] ; then
   echo ' '
   echo 'Check environment variables. '
   echo '$MCTDH_DIR is root directory of MCTDH package installation '
   echo '$MCTDH_VERSION is version of MCTDH package '
   echo ' '
   exit
fi

mpipro=0
pthreads=0
skip=0
#-----------------------------------------------------------------------
#  Read the options (if any).
#-----------------------------------------------------------------------
while getopts ":hi:o:p:j:s:M:P:" opt; do
    case $opt in
    h  )  helpf ;;
    i  )  inppath=$OPTARG  ;;
    o  )  outpath=$OPTARG  ;;
    p  )  potcode=$OPTARG  ;;
    j  )  projcode=$OPTARG  ;;
    s  )  skip=$OPTARG  ;;
    M  )  mpipro=$OPTARG  ;;
    P  )  pthreads=$OPTARG  ;;
    \? )  echo ' Unkown option!'
          helpf ;;
  esac
done
shift $(($OPTIND - 1))

parallel=`expr $mpipro + $pthreads`
if [ $parallel -ge 0 ] ; then
   parpath=/"mpi"$mpipro"pth"$pthreads"/"
fi

testcode="$1"
if [ -z "${outpath%%*/}" ] ; then outpath=$outpath$MCTDH_PLATFORM$parpath ; fi

if [ -z "$testcode" ] ; then
  echo ' '
  echo '#####  No program (argument) specified for test generation !  #####'
  echo ' '
  helpf
fi

if ! [ `which "$testcode" 2>/dev/null` ] ; then
   echo ' '
   echo '#####  The program (argument) specified is invalid !  #####'
   echo ' '
   exit
fi

#-----------------------------------------------------------------------
# Make the paths of the programs absolute.
#-----------------------------------------------------------------------
if [ -n "${testcode##/*}"  ] ; then testcode=`which $testcode` ; fi
if [ -n "${potcode##/*}"   ] ; then  potcode=`which $potcode`  ; fi
if [ -n "${projcode##/*}"  ] ; then projcode=`which $projcode` ; fi

#-----------------------------------------------------------------------
# Print the current parameter setting to screen and log-file.
#-----------------------------------------------------------------------
echo " "
echo "$minus40$minus40"
echo " ELK_TEST_GEN     "`date`"          ELK_TEST_GEN"
echo "$minus40$minus40"
echo "*** Generating elk_test comparison set ***"
echo " "
echo "Test code      : $testcode"
echo "Potfit code    : $potcode"
echo "Projection code: $projcode"
echo "Input set      : $inppath"
echo "Output path    : $outpath"
echo " "

if [ -z "$potcode" ] ; then
   echo '#####  There is no Potfit code!  #####'
   exit
fi
if [ -z "$projcode" ] ; then
   echo '#####  There is no Projection code!  #####'
   exit
fi


if [ ! -e $outpath ] ; then
   mkdir -p $outpath
fi
cd $outpath

if [ -e log ] ; then
   mv -f log log.old
fi

echo "$minus40$minus40" >  log
echo " ELK_TEST_GEN     "`date`"          ELK_TEST_GEN" >> log
echo "$minus40$minus40" >> log
echo " "
echo "Test code      : $testcode" >> log
echo "Potfit code    : $potcode"  >> log
echo "Projection code: $projcode" >> log
echo "Input set      : $inppath"  >> log
echo "Output path    : $outpath"  >> log
$testcode -ver  >> log


#---------------------------------------------------------------------------
#  Generate data needed as input for some of the tests.
#---------------------------------------------------------------------------

mktest H4proj $projcode 0 0

for i in pot_hd2 pot_boson H4cmm H4cpp H4ft0 H4ft1 H4ft2 H4ft3; do
    mktest $i   $potcode 0 0
done

for i in nocl0 nocl0fft nocl1_10 ch3i01 ch3i03 ch3i03_1 t36go; do
    mktest  $i  $testcode 0 0
done


#---------------------------------------------------------------------------
#  Generate the test$i directories
#---------------------------------------------------------------------------

notfound=0
i=$(($skip+1))

while [ $notfound -le 30 ] ; do
    mktest  test$i  $testcode $mpipro $pthreads
    i=$(($i+1))
    found=0

    while [ $notfound -le 30 ] && [ $found = 0 ] ; do
      if [ -f $inppath/test$i.inp ] ; then
         found=1
         notfound=0
      else
	 notfound=$(($notfound+1))
	 i=$(($i+1))
      fi
    done
done

echo " ELK_TEST_GEN     "`date`"          Good bye!" >> log
echo " ELK_TEST_GEN     "`date`"          Good bye!"

exit

