#!/bin/bash
printf "###############################################################################\n"
printf "Allrun script started on $(date)\n\n"
allrun_start_seconds=$(date +%s)

. $WM_PROJECT_DIR/bin/tools/RunFunctions

###############################################################################
# Case configuration                                                          #
# User-defined Variables begin with ccfg ("case configuration")               #
###############################################################################
# leave empty: Use config from this file
# file name: overwrite variables with variables in the given file
ccfg_overwrite_config_file="Allrunconf.ValidateFSI"

ccfg_surface_structure_type="membrane"
ccfg_fluid_kinematic_viscosity=0.001
ccfg_is_transient=yes                   # 'yes' or 'no'
ccfg_is_dynamic_mesh=yes                # 'yes' or 'no'

ccfg_transient_write_interval=0.01
ccfg_transient_end_time=0.1
ccfg_transient_deltaT=0.0001
ccfg_transient_image_output_deltaT=0.0009
ccfg_transient_sample_output_deltaT=0.01
ccfg_transient_probe_output_deltaT=0.01
ccfg_transient_coupling_start_time=0.01

ccfg_stationary_write_interval=10
ccfg_stationary_end_time=20
ccfg_stationary_image_output_deltaT=10
ccfg_stationary_sample_output_deltaT=10
ccfg_stationary_probe_output_deltaT=10
ccfg_stationary_coupling_start_time=2

# coupling options
# set load field to fsiCoupling (pressure) or dummyLoadField (with value)
# before coupling start time, only flow equations will be solved
ccfg_load_field_name=dummyLoadField
ccfg_dummy_load_field_value=0.0
ccfg_is_strong_coupling=yes
ccfg_write_unconverged_time_steps=yes    # yes or no (no for weak coupling!)
ccfg_adaptive_aitken_urel="no"           # singleValue, field, no
ccfg_deflection_transfer_urel=1.0        # value for start or if aitken is off

# initial and boundary conditions
ccfg_ic_deflection="0.0"
ccfg_ic_deflection_type="sin1"          # type of initial deflection: sin1, sin3, sin1sin3
ccfg_bc_inlet_velocity=1                # do not set to exactly zero

# set to "blockMesh", otherwise set to the "./fluentMeshes/*.msh" file name 
ccfg_mesh_name="blockMesh"

# blockMesh configuration
# x and y are spanwise, z is nozzle flow direction
# surface structure baffle will be at the bottom (z plus plane)
# a refinement box can be placed around the surface structure for increased resolution (disable by resetting z values)
ccfg_mesh_X_minus=-1.0
ccfg_mesh_X_plus=1.0
ccfg_mesh_Y_minus=-1.0
ccfg_mesh_Y_plus=1.0
ccfg_mesh_Z_minus=-0.1
ccfg_mesh_Z_plus=0.0

ccfg_mesh_nozzle_X_minus=-0.5
ccfg_mesh_nozzle_X_plus=0.5
ccfg_mesh_nozzle_Y_minus=-0.5
ccfg_mesh_nozzle_Y_plus=0.5

ccfg_mesh_surface_structure_X_minus=-0.5
ccfg_mesh_surface_structure_X_plus=0.5
ccfg_mesh_surface_structure_Y_minus=-0.5
ccfg_mesh_surface_structure_Y_plus=0.5

ccfg_mesh_probes_x=0.05
ccfg_mesh_probes_y=0.05

ccfg_mesh_cells_X=40
ccfg_mesh_cells_Y=40
ccfg_mesh_cells_Z=3
ccfg_mesh_cells_Z_expansion_factor=0.1


if [ ! -z $ccfg_overwrite_config_file ]
then
    echo "Overwriting Variables by sourcing $ccfg_overwrite_config_file"
    source $ccfg_overwrite_config_file
fi

###############################################################################
# Case-Config variables that are not directly specified by the user have the  #
# prefix ccfgi ("case configuration indirect")                                #
###############################################################################
printf "###############################################################################\n"
printf "Setting/Computing additional configuration data...\n"

if [ $ccfg_is_transient = "yes" ]
then 
    ccfgi_solver_name="pimpleFaSurfaceStructureSolver"
    
    ccfg_image_output_deltaT=$ccfg_transient_image_output_deltaT
    ccfg_sample_output_deltaT=$ccfg_transient_sample_output_deltaT
    ccfg_probe_output_deltaT=$ccfg_transient_probe_output_deltaT
    ccfg_coupling_start_time=$ccfg_transient_coupling_start_time
else 
    ccfgi_solver_name="simpleFaSurfaceStructureSolver";
    
    ccfg_image_output_deltaT=$ccfg_stationary_image_output_deltaT
    ccfg_sample_output_deltaT=$ccfg_stationary_sample_output_deltaT
    ccfg_probe_output_deltaT=$ccfg_stationary_probe_output_deltaT
    ccfg_coupling_start_time=$ccfg_stationary_coupling_start_time
fi


# create/copy files for (initial) configuration
cp system/configDict.empty system/configDict
cp -r ./0.init ./0.000000
mv ./0.000000/U.${ccfgi_solver_name} ./0.000000/U
cp constant/faSurfaceStructureProperties.${ccfg_surface_structure_type} constant/faSurfaceStructureProperties

# dynamic meshing is enabled, if constant/dynamicMeshDict exists
[ $ccfg_is_dynamic_mesh = "yes" ] && { cp constant/dynamicMeshDict.disabled constant/dynamicMeshDict; }

###############################################################################
# Here the OpenFOAM-Part starts                                               #
# First update the dictionaries according to the given configuration          #
###############################################################################
printf "###############################################################################\n"
printf "Adapting dictionaries according to the chosen configuration...\n"

# write mesh info
foamDictionary -entry meshXMinus                 -add "${ccfg_mesh_X_minus}"                   system/configDict
foamDictionary -entry meshXPlus                  -add "${ccfg_mesh_X_plus}"                    system/configDict
foamDictionary -entry meshYMinus                 -add "${ccfg_mesh_Y_minus}"                   system/configDict
foamDictionary -entry meshYPlus                  -add "${ccfg_mesh_Y_plus}"                    system/configDict
foamDictionary -entry meshZMinus                 -add "${ccfg_mesh_Z_minus}"                   system/configDict
foamDictionary -entry meshZPlus                  -add "${ccfg_mesh_Z_plus}"                    system/configDict
                                                                                               
foamDictionary -entry meshProbesX                -add "${ccfg_mesh_probes_x}"                  system/configDict
foamDictionary -entry meshProbesY                -add "${ccfg_mesh_probes_y}"                  system/configDict

foamDictionary -entry meshSurfaceStructureXMinus -add "${ccfg_mesh_surface_structure_X_minus}" system/configDict
foamDictionary -entry meshSurfaceStructureXPlus  -add "${ccfg_mesh_surface_structure_X_plus}"  system/configDict
foamDictionary -entry meshSurfaceStructureYMinus -add "${ccfg_mesh_surface_structure_Y_minus}" system/configDict
foamDictionary -entry meshSurfaceStructureYPlus  -add "${ccfg_mesh_surface_structure_Y_plus}"  system/configDict

foamDictionary -entry meshNozzleXMinus           -add "${ccfg_mesh_nozzle_X_minus}"            system/configDict
foamDictionary -entry meshNozzleXPlus            -add "${ccfg_mesh_nozzle_X_plus}"             system/configDict
foamDictionary -entry meshNozzleYMinus           -add "${ccfg_mesh_nozzle_Y_minus}"            system/configDict
foamDictionary -entry meshNozzleYPlus            -add "${ccfg_mesh_nozzle_Y_plus}"             system/configDict

foamDictionary -entry meshCellsX                 -add "${ccfg_mesh_cells_X}"                   system/configDict
foamDictionary -entry meshCellsY                 -add "${ccfg_mesh_cells_Y}"                   system/configDict
foamDictionary -entry meshCellsZ                 -add "${ccfg_mesh_cells_Z}"                   system/configDict
                                                                                               
foamDictionary -entry meshCellsZExpansionFactor  -add "${ccfg_mesh_cells_Z_expansion_factor}"  system/configDict

# solver-dependent configuration
if [ $ccfg_is_transient = "yes" ]
then 
    printf "Writing configuration for transient computation\n"
    foamDictionary -entry d2dt2Scheme    -add "Euler"                           system/configDict
    foamDictionary -entry ddtScheme      -add "Euler"                           system/configDict
    foamDictionary -entry deltaT         -add $ccfg_transient_deltaT            system/configDict
    foamDictionary -entry writeControl   -add "runTime"                         system/configDict
    foamDictionary -entry writeInterval  -add ${ccfg_transient_write_interval}  system/configDict
    foamDictionary -entry endTime        -add ${ccfg_transient_end_time}        system/configDict
else 
    printf "Writing configuration for stationary computation\n"
    foamDictionary -entry d2dt2Scheme    -add steadyState                       system/configDict
    foamDictionary -entry ddtScheme      -add steadyState                       system/configDict
    foamDictionary -entry deltaT         -add "1"                               system/configDict
    foamDictionary -entry writeControl   -add timeStep                          system/configDict
    foamDictionary -entry writeInterval  -add ${ccfg_stationary_write_interval} system/configDict 
    foamDictionary -entry endTime        -add ${ccfg_stationary_end_time}       system/configDict
fi

foamDictionary -entry adjustTimeStep            -add "no"                                   system/configDict

foamDictionary -entry imageOutputDeltaT         -add $ccfg_image_output_deltaT              system/configDict
foamDictionary -entry sampleOutputDeltaT        -add $ccfg_sample_output_deltaT             system/configDict
foamDictionary -entry probeOutputDeltaT         -add $ccfg_probe_output_deltaT              system/configDict

# write ic/bc configuration
foamDictionary -entry icDeflection              -add $ccfg_ic_deflection                    system/configDict
foamDictionary -entry icDeflectionType          -add $ccfg_ic_deflection_type               system/configDict
foamDictionary -entry bcInletVelocity           -add $ccfg_bc_inlet_velocity                system/configDict
foamDictionary -entry bcNegInletVelocity        -add $(bc <<< "-1*$ccfg_bc_inlet_velocity") system/configDict # for surfaceNormalFixedValue

# further variables
foamDictionary -entry isTransient               -add $ccfg_is_transient                     system/configDict
foamDictionary -entry isDynamicMesh             -add $ccfg_is_dynamic_mesh                  system/configDict
foamDictionary -entry application               -add $ccfgi_solver_name                     system/configDict
foamDictionary -entry surfaceStructureType      -add $ccfg_surface_structure_type           system/configDict

foamDictionary -entry loadFieldName             -add $ccfg_load_field_name                  system/configDict
foamDictionary -entry dummyLoadFieldValue       -add $ccfg_dummy_load_field_value           system/configDict
foamDictionary -entry couplingStartTime         -add $ccfg_coupling_start_time              system/configDict
foamDictionary -entry isStrongCoupling          -add $ccfg_is_strong_coupling               system/configDict

foamDictionary -entry writeUnconvergedTimeSteps -add $ccfg_write_unconverged_time_steps     system/configDict

foamDictionary -entry adaptiveAitkenUrel        -add $ccfg_adaptive_aitken_urel             system/configDict
foamDictionary -entry deflectionTransferUrel    -add $ccfg_deflection_transfer_urel         system/configDict

foamDictionary -entry fluidKinematicViscosity   -add $ccfg_fluid_kinematic_viscosity        system/configDict

foamDictionary -entry smallValue                -add "1e-10"                                system/configDict

###############################################################################
# Now run the fully configured files                                          #
###############################################################################
printf "###############################################################################\n"
printf "Preparing Simulation...\n"

if [ $ccfg_mesh_name = "blockMesh" ]
then 
    runApplication blockMesh
    runApplication topoSet                      # create faceSets and Zones for createPatch
    runApplication createPatch -overwrite       # create inlet patch 
else 
    runApplication fluent3DMeshToFoam -noFunctionObjects fluentMeshes/$ccfg_mesh_name
fi

cp constant/faMesh/faMeshDefinition.${ccfg_mesh_name} constant/faMesh/faMeshDefinition
runApplication makeFaMesh

runApplication checkMesh -allGeometry -allTopology
runApplication checkFaMesh

printf "###############################################################################\n"
printf "Running the solver...\n"
runApplication $(getApplication)

###############################################################################
# Finally output some information regarding the simulation run                #
###############################################################################

allrun_runtime_seconds=$(($(date +%s) - ${allrun_start_seconds}))

# Print runtime, therefore the days have to be calculated separately because
# they start with one and not with zero
printf "###############################################################################\n"
printf "Allrun script finished on $(date)\n"
printf "Runtime was $(($(date -u -d @${allrun_runtime_seconds} +%d) - 1)) days and $(date -u -d @${allrun_runtime_seconds} +"%T") (HH:MM:SS)\n"

