/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  plus                                  |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "system";
    object      controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#include "configDict"

startFrom           latestTime;
startTime           0;
stopAt              endTime;

purgeWrite          60;
writeFormat         binary;
writePrecision      8;
writeCompression    off;

timeFormat          fixed;
timePrecision       6;

runTimeModifiable   yes;

// ************************************************************************* //

DebugSwitches
{
    lduMatrix            1; // 1 by default. 2 shows the Normalization factor in Addition
    SolverPerformance    1; // 1 by default. 2 shows the drop of residuals for each iteration
    pimpleControl        0; // display residuals information
    solutionControl      0;
    writeOptionalEntries 1; // 0 by default. Shows data read using lookupOrDefault()
    cyclic               2;
}

OptimisationSwitches
{
    fileHandler uncollated;
    maxThreadFileBufferSize 2e9; // default 2e9
}

InfoSwitches
{
    allowProfiling      1;
}

profiling
{
    active  false;
    cpuInfo false;
    memInfo false;
    sysInfo false;
}


/*
 * Libraries that the functionObjects and boundary conditions require
 */
libs                    
( 
    "libfieldFunctionObjects.so" 
    "libutilityFunctionObjects.so" 
    "librunTimePostProcessing.so"
    "libsampling.so"
);


writeAndExecuteAtWriteTimeDefault
{
    enabled         true;
    log             true;
    executeControl  writeTime;
    writeControl    writeTime;
}


writeAndExecuteAtTimeStepDefault
{
    enabled         true;
    log             true;
    executeControl  timeStep;
    executeInterval 1;
    writeControl    timeStep;
    writeInterval   1;
}

writeAndExecuteAtProbeOutputTimeDefault
{
    $writeAndExecuteAtWriteTimeDefault;
    
    executeControl  ${:writeControl};
    executeInterval $probeOutputDeltaT;
    writeControl    ${:writeControl};
    writeInterval   $probeOutputDeltaT;
}

writeAndExecuteAtSampleOutputTimeDefault
{
    $writeAndExecuteAtWriteTimeDefault;
    
    executeControl  ${:writeControl};
    executeInterval $sampleOutputDeltaT;
    writeControl    ${:writeControl};
    writeInterval   $sampleOutputDeltaT;
}

writeAndExecuteAtImageOutputTimeDefault
{
    $writeAndExecuteAtWriteTimeDefault;
    
    executeControl  ${:writeControl};
    executeInterval $imageOutputDeltaT;
    writeControl    ${:writeControl};
    writeInterval   $imageOutputDeltaT;
}

writeAtWriteAndExecuteAtImageOutputTimeDefault
{
    $writeAndExecuteAtWriteTimeDefault;
    
    executeControl  ${:writeControl};
    executeInterval $imageOutputDeltaT;
}


/*
 * Some helper dictionaries for runTimePostProcessing
 */
runTimePostProcessingCrossSectionXYTextTimeConfig
{
    time
    {
        string          "Time[s] = ";
        position        (0.1 0.2);
        size            30;
        bold            no;
        visible         yes;
        timeStamp       true;
    }
}

runTimePostProcessingImpingementWallTextTimeConfig
{
    $runTimePostProcessingCrossSectionXYTextTimeConfig;
    
    time
    {
        position        (0.1 0.8);
        string          "Time[s] = ";
        size            30;
        bold            no;
        visible         yes;
        timeStamp       true;
    }
}

runTimePostProcessingCrossSectionXCameraConfig
{
    nFrameTotal         1;
    parallelProjection  yes;
    zoom                8;
    focalPoint          (  0 0  0 );
    up                  (  0 0 -1 );
    position            ( -1 0  0 );
}

runTimePostProcessingCrossSectionYCameraConfig
{
    $runTimePostProcessingCrossSectionXCameraConfig;
    
    position            ( 0 -1 0 );
}

runTimePostProcessingImpingementWallCameraConfig
{
    $runTimePostProcessingCrossSectionXCameraConfig;
    
    zoom                5;
    focalPoint          ( 0 0 0 );
    up                  ( 0 1 0 );
    position            ( 0 0 -1 );
}

runTimePostProcessingCrossSectionXDefaultConfig
{
    $writeAndExecuteAtImageOutputTimeDefault;
    
    type            runTimePostProcessing;
    
    // using only one background color should reduce image file size
    // background chosen light, so that black text is easily readable
    colours
    {
        background      (0.8 0.8 0.8);  
        //background2     (0.8 0.8 0.8);
        text            (0 0 0);
        edge            (1 0 0);
        surface         (0.5 0.5 0.5);
        line            (0 0 1);
    }
    
    output
    {
        name            image;
        width           900;
        height          600;
    }
    
    camera
    {
        $runTimePostProcessingCrossSectionXCameraConfig;
    }
    
    // Note that adding text entries later might overwrite this entry!
    text
    {
        $runTimePostProcessingCrossSectionXYTextTimeConfig;
    }
}

runTimePostProcessingCrossSectionYDefaultConfig
{
    $runTimePostProcessingCrossSectionXDefaultConfig;
    
    camera
    {
        $runTimePostProcessingCrossSectionYCameraConfig;
    }
}

runTimePostProcessingImpingementWallDefaultConfig
{
    $runTimePostProcessingCrossSectionXDefaultConfig;
    
    output
    {
        name            image;
        width           600;
        height          600;
    }
    
    camera
    {
        $runTimePostProcessingImpingementWallCameraConfig;
    }
    
    text
    {
        $runTimePostProcessingImpingementWallTextTimeConfig;
    }
}

runTimePostProcessingCrossSectionXYScalarBarConfig
{
    visible         yes;
    position        ( 0.1 0.25 ); // counted from image lower left to lower left edge of scalarBar (?)
    vertical        no;
    fontSize        10;
    title           "title";
    labelFormat     "%5.2f";
    numberOfLabels  7;
}

runTimePostProcessingImpingementWallScalarBarConfig
{
    $runTimePostProcessingCrossSectionXYScalarBarConfig;
    position        ( 0.1 0.85 ); // counted from image lower left to lower left edge of scalarBar (?)
}

// can be used for more than surfaces, but then you must overwrite some entries
runTimePostProcessingDefaultSurfaceConfig
{
    type            functionObjectSurface;
    colourMap       blueWhiteRed;
    representation  surface;
    visible         yes;
    featureEdges    no;
    colourBy        field;
    opacity         1;
}


/*
 * Function Object Definitions
 */
functions
{
    /* soft abort of the run as soon as given files appear */
    endWriteNow
    {
        type        abort;
        enabled     true;
        
        action      writeNow; // writeNow, nextWrite, endTime, noWriteNow
        file        "endWriteNow";
    }
    
    /* Only meaningful for transient simulations */
    CourantNumber
    {
        $writeAndExecuteAtWriteTimeDefault;
        
        enabled         $isTransient;
        type            CourantNo;    
        field           phi;
    }
    
    // on non-moving meshes this is the mass imbalance
    divPhi
    {
        $writeAndExecuteAtWriteTimeDefault;
        
        type            div;
        field           phi;
    }
    
    // Velocity and Acceleration of the deflection
    ddtFaWVolScalarField
    {
        $writeAtWriteAndExecuteAtImageOutputTimeDefault;
        
        // Must be executed every time step, otherwise the Acceleration
        // cannot be computed correctly
        executeControl  timeStep;
        executeInterval 1;
        
        type            ddt;
        field           faWVolScalarField;
    }
    
    d2dt2FaWVolScalarField
    {
        $ddtFaWVolScalarField;
        field           ddt(faWVolScalarField);
    }
    
    yPlusAllWalls
    {
        $writeAtWriteAndExecuteAtImageOutputTimeDefault;
        
        type            yPlus;
    }
    
    wallShearStressesFvSurfaceStructure
    {
        $writeAndExecuteAtWriteTimeDefault;
        enabled         false;
        
        type            wallShearStress;
        patches         ("fvSurfaceStructure");
    }
    
    outflowRate
    {
        $writeAndExecuteAtWriteTimeDefault;
            
        type            surfaceFieldValue;
        writeFields     false;
            
        regionType      patch;
        name            fvOutlet;
        fields          ( phi );
        operation       sum;
    }
    
    inflowRate
    {
        $writeAndExecuteAtWriteTimeDefault;
        //enabled         false;
            
        type            surfaceFieldValue;
        writeFields     false;
            
        regionType      patch;
        name            fvInlet;
        fields          ( phi );
        operation       sum;
    }
    
    inflowAverageVelocity
    {
        $inflowRate;
        enabled         false;
        
        fields          ( U );
        operation       areaAverage;
    }

    phiOverSurfaceStructure
    {
        $writeAndExecuteAtTimeStepDefault;
            
        type            surfaceFieldValue;
        writeFields     false;
            
        regionType      patch;
        name            fvSurfaceStructure;
        fields          ( phi );
        operation       sum;
    }
    
    
    /*
     * Probes
     */
    probePoints
    {
        $writeAndExecuteAtProbeOutputTimeDefault;
        
        type            patchProbes;
        patches         ("fvSurfaceStructure");
        fixedLocations  false;
        
        probeLocations
        (
            ( 0 0 0 )
            ( $meshProbesX 0 0 )
            ( 0 $meshProbesY 0 )
            ( $meshProbesX $meshProbesY 0 )
        );
        
        fields          ( p faWVolScalarField ddt(faWVolScalarField) ddt(ddt(faWVolScalarField)) dummyLoadField); 
        fixedLocations  false;
    }
    
    /*
     * Line Samples
     */
    sampleLines
    {
        $writeAndExecuteAtSampleOutputTimeDefault;
        
        // NOTE: Sampling does not work correctly, apparently snapping to the wall patch 
        // does not yield results for larger deformations or the inner-cell values are used,
        // which are zero for the faWVolScalarField
        enabled                 true; 
        
        type                    sets;
    
        fields                  ( p faWVolScalarField ddt(faWVolScalarField) ddt(ddt(faWVolScalarField)) );
        setFormat               csv; 
        interpolationScheme     cellPointWallModified;
        
        sets            
        ( 
            lineX
            { 
                type    uniform;
                axis    x;
                nPoints $meshCellsX;
                start   ( $meshSurfaceStructureXMinus 0 0 ); 
                end     ( $meshSurfaceStructureXPlus  0 0 ); 
            } 
            lineY
            { 
                type    uniform;
                axis    y;
                nPoints $meshCellsY;
                start   ( 0 $meshSurfaceStructureYMinus 0 ); 
                end     ( 0 $meshSurfaceStructureYPlus  0 ); 
            } 
        );
    }
    
    /*
     * Sampling surfaces, necessary for image output
     */
    planeY0
    {
        $writeAndExecuteAtImageOutputTimeDefault;
        
        type                surfaces;
        surfaceFormat       vtk;
        fields              ( p U );
        interpolationScheme cellPointFace;
        
        surfaces
        (
            surface1
            {
                type        plane;
                triangulate false;
                planeType   pointAndNormal;
                
                pointAndNormalDict
                {
                    point   (0 0 0);
                    normal  (0 1 0);
                }
                
                interpolate true; // true: generate values on points instead of faces (?)
            }
        );
    }
    
    planeX0
    {
        $planeY0;
        surfaceFormat       vtp;
        
        surfaces
        (
            surface1
            {
                type        plane;
                triangulate false;
                planeType   pointAndNormal;
                
                pointAndNormalDict
                {
                    point   (0 0 0);
                    normal  (1 0 0);
                }
                
                interpolate true; // true: generate values on points instead of faces (?)
            }
        );
    }
    
    patchImpingementWall
    {
        $planeY0;
        surfaceFormat       foam;
        
        fields          ( p yPlus faWVolScalarField ddt(faWVolScalarField) ddt(ddt(faWVolScalarField)) );
        
        surfaces
        (
            surface1
            {
                type        patch;
                triangulate false;
                patches     ( "fvSurfaceStructure" );
                
                interpolate false; // MUST BE SET TO FALSE FOR ACCESSING MOVING BOUNDARY DATA
            }
        );
    }
 
    
    /*
     * Definition of image output 
     */
    snapshotImageCrossSectionXUGlyphs
    {
        $runTimePostProcessingCrossSectionXDefaultConfig;

        // Surface data
        surfaces
        {
            surface1
            {
                $runTimePostProcessingDefaultSurfaceConfig;
                
                functionObject  planeX0;
                field           U;
                range           ( 0 $bcInletVelocity );
                
                scalarBar
                {
                    $runTimePostProcessingCrossSectionXYScalarBarConfig;
                    title   "Fluid Velocity [m/s]";
                }
            }
            
            glyphs1
            {                
                $runTimePostProcessingDefaultSurfaceConfig;
                
                functionObject  planeX0;
                representation  glyph;
                maxGlyphLength  0.018;
                field           U;
                range           ( 0 $bcInletVelocity );
                
                scalarBar
                {
                    $runTimePostProcessingCrossSectionXYScalarBarConfig;
                    visible     no;
                }
            }
        }
    }
    
    snapshotImageImpingementWallDeflection
    {
        $runTimePostProcessingImpingementWallDefaultConfig;

        // Surface data
        surfaces
        {
            surfaces1
            {
                $runTimePostProcessingDefaultSurfaceConfig;
                
                functionObject  patchImpingementWall;
                field           faWVolScalarField;
                range           ( -0.009 0.009 );
                
                scalarBar
                {
                    $runTimePostProcessingImpingementWallScalarBarConfig;
                    title           "Deflection [m]";
                }
            }
        }
    }
    
    snapshotImageImpingementWallVelocity
    {
        $runTimePostProcessingImpingementWallDefaultConfig;

        // Surface data
        surfaces
        {
            surfaces1
            {
                $runTimePostProcessingDefaultSurfaceConfig;
                
                functionObject  patchImpingementWall;
                field           ddt(faWVolScalarField);
                range           ( -0.5 0.5 );
                
                scalarBar
                {
                    $runTimePostProcessingImpingementWallScalarBarConfig;
                    title           "Surface Velocity [m/s]";
                }
            }
        }
    }
    
    snapshotImageImpingementWallAcceleration
    {
        $runTimePostProcessingImpingementWallDefaultConfig;

        // Surface data
        surfaces
        {
            surfaces1
            {
                $runTimePostProcessingDefaultSurfaceConfig;
                
                functionObject  patchImpingementWall;
                field           ddt(ddt(faWVolScalarField));
                range           ( -300 300 );
                
                scalarBar
                {
                    $runTimePostProcessingImpingementWallScalarBarConfig;
                    title           "Surface Acceleration [m/s]";
                }
            }
        }
    }
    
    snapshotImageImpingementWallYPlus
    {
        $runTimePostProcessingImpingementWallDefaultConfig;

        // Surface data
        surfaces
        {
            surfaces1
            {
                $runTimePostProcessingDefaultSurfaceConfig;
                
                functionObject  patchImpingementWall;
                field           yPlus ;
                range           ( 0 15 );
                
                scalarBar
                {
                    $runTimePostProcessingImpingementWallScalarBarConfig;
                    title           "yPlus";
                }
            }
        }
    }
    
    snapshotImageImpingementKinematicPressure
    {
        $runTimePostProcessingImpingementWallDefaultConfig;

        // Surface data
        surfaces
        {
            surfaces1
            {
                $runTimePostProcessingDefaultSurfaceConfig;
                
                functionObject  patchImpingementWall;
                field           p ;
                range           ( -40 40 );
                
                scalarBar
                {
                    $runTimePostProcessingImpingementWallScalarBarConfig;
                    title           "Kinematic Pressure";
                }
            }
        }
    }
}
