Post-processing

Information about postprocessing XCALibre.jl results

ParaView


All solvers in XCALibre.jl will write simulation results in formats that can be loaded directly in ParaView, which is the leading open-source project for scientific visualisation and postprocessing. More information about how to use ParaView can be found in the resources page on their website.

XCALibre.jl can output simulation results to either VTK compliant formats or OpenFOAM format. XCALibre.jl uses two different VTK formats depending on the type of flow solver used. For 2D simulations, the results are written to file using the .vtk file format. 3D simulations are written using the unstructured VTK file format, .vtu.

Note

A limitation of the current VTK writers in XCALibre.jl is that boundary information is stored along with internal mesh cell information, and results are stored at cell centres only. Thus, care must be taken when visualising results at boundary faces. Boundary information for fixedValue boundaries is displayed corrently when the results are saved in the OpenFOAM format.

Available functions


Although ParaView offers considerable flexibility for postprocessing results, users may also wish to carry out more advanced or different analyses on their CFD results. At present XCALibre.jl offers a limited set of pre-defined postprocessing functions, however, defining new custom postprocessing functions is reasonably straight-forward since these can be written in pure Julia. In this section, examples of postprocessing functions will be provided as an illustration.

Note

At present all postprocessing functions available in XCALibre.jl will only execute on CPUs and should be considered experimental. Once we settle on a "sensible" (maintainable and extensible) API, we plan to offer a larger selection of postprocessing tools which are likely to include options for runtime postprocessing.

Example: Calculate boundary average

In this example, a function is shown that can be used to calculate the average on a user-provided boundary.

XCALibre.Postprocess.boundary_averageFunction
function boundary_average(patch::Symbol, field, config; time=0)
    # Extract mesh object
    mesh = field.mesh

    # Determine ID (index) of the boundary patch 
    ID = boundary_index(mesh.boundaries, patch)
    @info "calculating average on patch: $patch at index $ID"
    boundary = mesh.boundaries[ID]
    (; IDs_range) = boundary

    # Create face field of same type provided by user (scalar or vector)
    sum = nothing
    if typeof(field) <: VectorField 
        faceField = FaceVectorField(mesh)
        sum = zeros(_get_float(mesh), 3) # create zero vector
    else
        faceField = FaceScalarField(mesh)
        sum = zero(_get_float(mesh)) # create zero
    end

    # Interpolate CFD results to boundary
    interpolate!(faceField, field, config)
    correct_boundaries!(faceField, field, field.BCs, time, config)

    # Calculate the average
    for fID ∈ IDs_range
        sum += faceField[fID]
    end
    ave = sum/length(IDs_range)

    # return average
    return ave
end
source

To calculate pressure and viscous forces, the following functions are available:

XCALibre.Postprocess.pressure_forceFunction
pressure_force(patch::Symbol, p::ScalarField, rho)

Function to calculate the pressure force acting on a given patch/boundary.

Input arguments

  • patch::Symbol name of the boundary of interest (as a Symbol)
  • p::ScalarField pressure field
  • rho density. Set to 1 for incompressible solvers
source
XCALibre.Postprocess.viscous_forceFunction
viscous_force(patch::Symbol, U::VectorField, rho, ν, νt)

Function to calculate the pressure force acting on a given patch/boundary.

Input arguments

  • patch::Symbol name of the boundary of interest (as a Symbol)
  • U::VectorField pressure field
  • rho density. Set to 1 for incompressible solvers
  • ν laminar viscosity of the fluid
  • νt eddy viscosity from turbulence models. Pass ConstantScalar(0) for laminar flows
source