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
.
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.
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_average
— Functionfunction 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
To calculate pressure and viscous forces, the following functions are available:
XCALibre.Postprocess.pressure_force
— Functionpressure_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 aSymbol
)p::ScalarField
pressure fieldrho
density. Set to 1 for incompressible solvers
XCALibre.Postprocess.viscous_force
— Functionviscous_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 aSymbol
)U::VectorField
pressure fieldrho
density. Set to 1 for incompressible solversν
laminar viscosity of the fluidνt
eddy viscosity from turbulence models. Pass ConstantScalar(0) for laminar flows