Post-process simulation results#

Post-processing tools visualize and export simulation results. They are accessible in the EasyFEA.Utilities namespace: Display for static matplotlib figures, PyVista for interactive 3D views, and Paraview / Vizir / GLTF / USD for external export.

Display

Module containing functions used to display simulations and meshes with matplotlib (https://matplotlib.org/).

PyVista

Module providing an interface with PyVista (https://docs.pyvista.org/version/stable/).

Paraview

This module allows you to save a simulation's results on Paraview (https://www.paraview.org/).

Vizir

Module providing functions used to save FEM-solutions for vizir (https://pyamg.saclay.inria.fr/vizir4.html).

USD

Module providing an interface with Universal Scene Description Format (USD) using usd-core (https://pypi.org/project/usd-core/).

GLTF

Module providing an interface with Graphics Library Transmission Format (GLTF) using pygltflib (https://pypi.org/project/pygltflib/).


Query available results#

Each simulation exposes the list of computable result fields via Results_Available():

print(simu.Results_Available())
# e.g. ['ux', 'uy', 'uz', 'displacement_norm', 'Exx', 'Eyy', 'Sxx', 'Syy', 'Svm', ...]

A scalar or vector field can then be retrieved as a NumPy array via Result():

uy  = simu.Result("uy")                        # nodal values, shape (Nn,)
Svm = simu.Result("Svm", nodeValues=False)     # element values, shape (Ne,)

Plot with matplotlib (Display)#

Display uses matplotlib and is the primary tool for 2D and 3D result visualization.

Plot a scalar field#

Plot_Result() plots any result field on the mesh:

from EasyFEA import Display

Display.Plot_Result(simu, "uy")
Display.Plot_Result(simu, "Svm", plotMesh=True, ncolors=11)

Key options:

Parameter

Description

deformFactor

Scale factor to display deformed geometry (0 = undeformed)

nodeValues

True for nodal interpolation, False for element-constant

plotMesh

Overlay the mesh edges

ncolors

Number of discrete color levels in the colorbar

clim

Fix colorbar range, e.g. clim=(0, 1)

coef

Multiply the result by a constant (e.g. unit conversion)

folder / filename

Save the figure to disk

Plot the mesh#

Plot_Mesh() plots the mesh:

Display.Plot_Mesh(simu)                   # current state
Display.Plot_Mesh(simu, deformFactor=10)  # amplified deformation
Display.Plot_Mesh(mesh)                   # mesh object directly

Plot boundary conditions#

Plot_BoundaryConditions() visualizes the applied loads and constraints:

Display.Plot_BoundaryConditions(simu)

Plot tags#

Plot_Tags() shows the physical groups and tags defined on the mesh:

Display.Plot_Tags(mesh)

Plot energy and iteration history#

Display.Plot_Energy(simu, folder=folder_save)
Display.Plot_Iter_Summary(simu, folder=folder_save)

Save a figure#

Save_fig() saves the current matplotlib figure to disk:

Display.Save_fig(folder_save, "my_figure")

Create an animation#

Movie_Simu() generates an animation directly from a named result field:

Display.Movie_Simu(simu, "uy", folder=folder_save, filename="animation.gif")

For custom frame content, use Movie_func() with a user-defined function. The function receives the matplotlib figure and the frame index i:

import numpy as np

iterations = np.arange(0, simu.Niter, max(1, simu.Niter // 20))
fig = Display.Init_Axes()

def Func(fig, i):
    fig.clear()
    ax = fig.add_subplot(111)
    simu.Set_Iter(iterations[i])
    Display.Plot_Result(simu, "uy", ax=ax)

Display.Movie_func(Func, fig, iterations.size, folder_save, "animation.gif")

Interactive 3D visualization (PyVista)#

PyVista provides interactive 3D rendering powered by PyVista.

Plot() renders a result field in an interactive window:

from EasyFEA import PyVista

PyVista.Plot(simu, "uy")
PyVista.Plot(simu, "Svm", plotMesh=True, clim=(0, 500))
PyVista.Plot_Mesh(simu)
PyVista.Plot_BoundaryConditions(simu)
PyVista.Plot_Tags(simu)

Create an animation#

Movie_simu() generates an animation directly from a named result field:

PyVista.Movie_simu(simu, "uy", folder=folder_save, filename="animation.gif")

For custom frame content, use Movie_func() with a user-defined function. The function receives the PyVista plotter and the frame index i:

import numpy as np

iterations = np.arange(0, simu.Niter, max(1, simu.Niter // 20))

def Func(plotter, i):
    simu.Set_Iter(iterations[i])
    PyVista.Plot(simu, "damage", plotter=plotter, clim=(0, 1))

PyVista.Movie_func(Func, iterations.size, folder_save, "damage.gif")

Export to ParaView#

Save_simu() generates a .pvd timeline and .vtu files that ParaView reads directly:

from EasyFEA import Paraview

Paraview.Save_simu(simu, folder_save, N=200)

N controls the maximum number of iterations exported — EasyFEA selects up to N equally-spaced snapshots from the full iteration history. Open the resulting Paraview/simulation.pvd file in ParaView to browse the timeline.

See Run simulations in parallel with MPI for parallel ParaView export across MPI ranks.


Export to Vizir#

Save_simu() exports results to the Vizir format, a high-order FEM visualization tool developed by INRIA:

from EasyFEA import Vizir

command = Vizir.Save_simu(simu, results=["uy", "Svm"], types=[1, 1], folder=folder_save)
print(command)  # prints the vizir command to run for visualization


Export to USD (Pixar Universal Scene Description)#

Save_simu() exports to the USD format, compatible with Omniverse, USD Composer, and other DCC tools:

from EasyFEA import USD

USD.Save_simu(simu, ["uy", "Svm"], folder_save)

Save and reload a simulation#

A completed simulation (including all iteration history) can be saved to disk and reloaded later without re-running via Save() and Load_Simu():

from EasyFEA import Simulations

# Save
simu.Save(folder_save)

# Reload
simu = Simulations.Load_Simu(folder_save)

Iteration results are stored in Results/results{N}.pickle files when simu.folder is set. Only primary unknowns are stored (e.g. displacement, damage); derived quantities are recomputed on demand.