#!/bin/sh


inputFilesLocation="../src"
NPROC=40 #default number of processors, in case this isn't specified in the json file


# this might need to be an input (to the bash script, I mean...)
HydrojsonFile="input.json"

# pretty sure you can change this, but why would you?
nameOfCoupledPatchOrSurfaceFile="interface"


# these are easy to change without messing things up 
numOpenSeesSubSteps=1 # int - the coupling data is interpolated over time
numOpenFOAMSubSteps=500 # int - same ^

OpenFOAMSolver="olaFlow"
OpenFOAMFileHandler="collated" # 'collated' or 'uncollated'





# # load OpenFOAM, add preCICE library to path in the right places, install all the python things you need... 
# pip3 install os
# pip3 install concurrent.futures
# pip3 install logging
# pip3 install queue
# pip3 install random
# pip3 install subprocess
# pip3 install time
# pip3 install argparse
# pip3 install copy
# pip3 install sys

# ## math and matrices
# pip3 install numpy 
# pip3 install pandas
# pip3 install re, csv
# pip3 install math

# ### meshes and visualization
# pip3 install meshio
# pip3 install matplotlib
# pip3 install scipy
# pip3 install vtk
# pip3 install pyvista 

# ## openseespy
# pip3 install openseespy.opensees 

# ## precice
# pip3 install precice



# HYAK
module load cesg/openfoam/2012
module load cesg/eigen/3.3.9
module load cesg/libxml2/2.9.10
module load gcc/10.2.0
module load cesg/python/3.8.10
module load cesg/boost/1.76.0
module load cesg/openmpi/4.0.5
module load cmake/3.20.0


# TACC
# module load intel/19.1.1 
# module load impi/19.0.9    
# module load git/2.24.1    
# module load autotools/1.2   
# module load cmake/3.24.2   
# module load pmix/3.1.4     
# module load hwloc/1.11.12 
# module load xalt/2.10.34   
# module load TACC         
# module load python3/3.9.2 
# module load petsc/3.17   
# module load eigen/3.4.0  
# module load fftw3/3.3.10  
# module load boost/1.72

# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/work2/07720/nsaoirse/frontera/lib/lib64:/work2/07720/nsaoirse/frontera/lib:/work2/07720/nsaoirse/frontera/source/OpenFOAM-v2106/nsaoirse-v2106/platforms/linux64GccDPInt32Opt/lib"
# export PATH=$PATH:"/work2/07720/nsaoirse/frontera/source/OpenFOAM-v2106/nsaoirse-v2106/platforms/linux64GccDPInt32Opt/bin:/work2/07720/nsaoirse/frontera/source/precice/src/precice"
# source /work2/07720/nsaoirse/frontera/source/OpenFOAM-v2106/etc/bashrc
# export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:"/work2/07720/nsaoirse/frontera/lib/lib64/pkgconfig"
. $WM_PROJECT_DIR/bin/tools/RunFunctions    # Tutorial run functions




# don't change any of this unless you feel like debugging
parallel=1	
# this is a flag, which I don't use
solverroot="./"	
# where all the magic happens
Participant1="OpenFOAMCase"	
# the name of the openfoam case folder with which the structural analysis solution is coupled
Participant2="FOAMySeesCouplingDriver"	
# the name of the python script holding the coupling driver for the structural analysis solver
configfile="precice-config.xml"	
# name of the preCICE case configuration file (this is automatically generated for you, depending on your settings)
CouplingDataProjectionMesh="CouplingDataProjectionMesh.obj" 
# this is the name of the file which will be loaded into the coupling driver as the coupling data projection mesh -
makeCouplingDataProjectionMesh=1	
# the file can be generated automatically, using the name of the coupled patch specified above under nameOfCoupledPatchOrSurfaceFile
OpenSeesPyModelFile=OpenSeesModel.py 
# this is the name of the OpenSees model python file which will construct the coupled OpenSees model. 
# This file can contain preliminary analyses, but the time series and pattern objects should be removed before a FSI analysis
OpenFOAMCaseFolder="OpenFOAMCase" 
# this is the name of the folder within which the OpenFOAM case will be held
isPartOfHydro="Yes" 
# is this analysis run through HydroUQ?

useExistingOpenFOAMCaseFolder=0 
# flag (unused at the moment)


ExistingOpenFOAMCase="../existingCase" 
# similarly, unused at the moment




# preparing the case folder
rm -rf RunCase
mkdir RunCase

# entering the case folder
cd RunCase

cp -r ../ProgramFiles/FOAMySees/FOAMySeesFiles/* . 

cp -r ${ExistingOpenFOAMCase}/* ./OpenFOAMCase
mv fromUserDefaults/* ./
cp -r ${inputFilesLocation}/* ./

# echo determining parallel processing parameters...
. $WM_PROJECT_DIR/bin/tools/RunFunctions    # Tutorial run functions


# configuring the case
python3 configureCoupledCase.py ${isPartOfHydro} ${HydrojsonFile} ${nameOfCoupledPatchOrSurfaceFile} ${CouplingDataProjectionMesh} ${makeCouplingDataProjectionMesh} ${OpenSeesPyModelFile} ${OpenFOAMCaseFolder} ${OpenFOAMSolver} ${NPROC} ${OpenFOAMFileHandler} ${useExistingOpenFOAMCaseFolder} ${ExistingOpenFOAMCase} ${numOpenSeesSubSteps} ${numOpenFOAMSubSteps}


# starting the OpenSees model preliminary analysis and waiting for coupling to initialize
echo "Starting ${Participant2} participant..."
mpirun -np 1 python3 ${solverroot}${Participant2}.py ${solverroot}${configfile} ${CouplingDataProjectionMesh} > ${Participant2}.log 2>&1 &
PIDParticipant2=$!        

# starting the OpenFOAM model
echo "Preparing the ${Participant1} participant..."
cd ${OpenFOAMCaseFolder}
        nproc=$(getNumberOfProcessors)
        Solver1=$(getApplication)    # solver
cd ..

surfaceMeshExtract -case ${OpenFOAMCaseFolder} -patches ${nameOfCoupledPatchOrSurfaceFile} -latestTime ${CouplingDataProjectionMesh}
cp ${OpenFOAMCaseFolder}/${CouplingDataProjectionMesh} .
decomposePar -force -fileHandler ${OpenFOAMFileHandler} -case ${OpenFOAMCaseFolder} > decomposePar.log 2>&1



mpirun -np ${nproc} ${Solver1} -parallel -case ${OpenFOAMCaseFolder} > ${Participant1}.log 2>&1 &
PIDParticipant1=$!

# tailing the OpenSees output (OpenFOAM is verbose)
tail -f ${Participant2}.log &
tail -f ${Participant1}.log &

# waiting for input to cancel
while [ -e /proc/${PIDParticipant1} ]; do
    read -r  input
    if [ "$input" = "c" ]; then
        kill ${PIDParticipant1}
        kill ${PIDParticipant2}
        false
    fi
done

# if anything went wrong, do this
if [ $? -ne 0 ] || [ "$(grep -c -E "error:" ${Participant1}.log)" -ne 0 ] || [ "$(grep -c -E "error:" ${Participant2}.log)" -ne 0 ]; then
    echo ""
    echo "Something went wrong... See the log files for more."
    # Precaution
    kill ${PIDParticipant1}
    kill ${PIDParticipant2}
else # nothing went wrong, but double check to make sure
    echo ""
    echo "The simulation seems to be complete, but make sure by looking at the log files and output!"
    if [ $parallel -eq 1 ]; then
        echo "Reconstructing fields..."
        reconstructPar -case ${Participant1} > ${Participant1}_reconstructPar.log 2>&1 & 
    fi
        wait 
        foamToVTK -case ${PIDParticipant1}
        wait
        
        python3 FSIPVD.py
        python3 FOAMySeesPlotter.py
        wait
        mkdir results
        cp -r SeesOutput results
        cp -r OpenSeesOutput.pvd results
        cp -r ${PIDParticipant1}/VTK results
        cp -r ${PIDParticipant1}/postProcessing results        
        zip -r ../results.zip results

fi

echo ""

cd ..

echo 'Analysis Complete, results stored in results.zip'

