Post-Processing
Get results from a problem
In fedoo, most of the standard results are easily exportable using the
fedoo.Problem.get_results()
method of the problem class.
The get_results method returns a fedoo.DataSet
object which come
with several methods for plotting, saving and loading mesh dependent results.
To avoid a redundent call of the get_results function, especially for time
dependent problems, one can simply add some required output with the
fedoo.Problem.add_output()
method. This create a
MultiFrameDataSet
object associated to the problem.
Once the required outputs are defined for a given problem, a call to the
fedoo.Problem.save_results()
method allow to save all the defined
fields on disk using the choosen file format, and associate the saved file to
an iteration of the MultiFrameDataSet
. For non linear problems
solved using Problem.nlsolve()
, results are automatically saved at
some iterations dependending on the choosen parameters.
The MultiFrameDataSet
store the path of the saved files for each
iteration in the MultiFrameDataSet.list_data attribute. The method
MultiFrameDataSet.load()
is called to read the data
of a given iteration.
Class DataSet
|
Object to store, save, load and plot data associated to a mesh. |
Class MultiFrameDataSet
|
Save data to disk
Once a DataSet is created using for instance the
fedoo.Problem.get_results()
method, the data can easily be saved on
disk using for instance the fedoo.DataSet.save()
method.
- The available file types are:
‘fdz’: A zipped archive containing the mesh using the ‘vtk’ format named ‘_mesh_.vtk’, and data from several iterations named ‘iter_x.npz’ where x is the iteration number (x=0 for the 1st iteration).
‘vtk’: The vtk format contains the mesh and the data in a single files. The gauss points data are not included in the file. This format is efficient for a linear problem when we need only one time iteration. In case of multiple saved iterations, a directory is created and one vtk file is saved per iteration. The mesh is included in every file which is not memory efficient.
‘msh’: Format associated to gmsh. Have the same drawback as the vtk format for time depend results and missing gauss points data. The vtk format should be prefered.
‘npz’: Save data in a numpy file npz which doesn’t include the mesh. The mesh is generally saved beside in a raw vtk files without results.
‘npz_compressed’: Same as npz with a compression of the zip archive.
‘csv’: Save DataSet that contains only one type of data (ie Node, Element or Gauss point data) in a csv file (needs the library pandas installed). The mesh is not included and may be saved beside in a vtk file.
‘xlsx’: Same as csv but with the excel format.
Read data from disk
To read data saved on disk, use the function read_data()
.
Example
For example, defining and solving a very simple problem :
import fedoo as fd
fd.ModelingSpace("2Dstress")
mesh = fd.mesh.rectangle_mesh()
material = fd.constitutivelaw.ElasticIsotrop(2e5, 0.3)
wf = fd.weakform.StressEquilibrium(material)
assembly = fd.Assembly.create(wf, mesh)
# Define a new static problem
pb = fd.problem.Linear(assembly)
# Boundary conditions
pb.bc.add('Dirichlet', 'left', 'Disp', 0 )
pb.bc.add('Dirichlet', 'right', 'Disp', [0.2,0] )
# Solve problem
pb.solve()
Then, we can catch the Stress, Displacement and Strain fields using:
results = pb.get_results(assembly, ["Stress", "Disp", "Strain"])
# plot the sigma_xx averaged at nodes
results.plot("Stress", "Node", component='XX')

Alternatively, if we take the same problem, but accounting for geometric non linearities (nlgeom = True), we can automatically save results at specified time interval (here the results are saved on a file).
wf.nlgeom = True
pb_nl = fd.problem.NonLinear(assembly)
# Boundary conditions
pb_nl.bc = pb.bc
results_nl = pb_nl.add_output('nl_results', assembly, ["Stress", "Disp", "Strain"])
pb_nl.nlsolve(dt = 0.1, tmax = 1, interval_output = 0.2)
# plot the sigma_xx averaged at nodes at the last increment
results_nl.plot("Stress", "Node", component='XX')

Basic operations
Plotting results
A few convinient methods are proposed to generate image of movie from
DataSet
and MultiFrameDataSet
objects.
|
Plot a field on the surface of the associated mesh. |
|
Plot a field on the surface of the associated mesh. |
|
|
|
Generate a video of the MultiFrameDataSet object by loading iteratively every frame. |
Save results
|
Save data to a file. |
|
Write a npz file using the numpy savez function. |
|
Write a compressed npz file using the numpy savez_compressed function. |
|
Save the mesh using a vtk file. |
|
Write data in a csv file. |
|
Write data in a xlsx file (excel format). |
|
Write vtk file with the mesh and associated data. |
|
Write a msh (gmsh format) file with the mesh and associated data (gausspoint data not included). |
|
Save all data from MultiFrameDataSet. |
Read results
|
Read a file from a disk. |
|
|
|
Load data from a data object. |
|
Load data from a data object. |
Advanced operations
Write Movies
A very simple way to write a movie from a MultiFrameDataSet
is
to call the embedded method MultiFrameDataSet.write_movie()
.
Though this method comes with lots of options, one may sometimes want to fully control the movie rendering. This is easy to do by manualy writing the movie using the pyvista library.
Here is an exemple to animate the linear results obtained in the problem defined above. The idea is to use a scale_factor applied to the displacement (using the scale argument) and to the stress field (modifiying the results data).
results = pb.get_results(assembly, ['Stress', 'Disp'], 'Node')
stress = results.node_data['Stress']
clim = [stress[3].min(), stress[3].max()] # 3 -> xy in voigt notation
pl = pv.Plotter(window_size = [600,400])
pl.open_gif("my_movie.gif", fps=20)
sargs = dict(height=0.10, position_x=0.2, position_y=0.05)
for i in range(48):
scale_factor = (i + 1) / 48
results.node_data["Stress"] = scale_factor * stress
results.plot(
"Stress",
"XY",
plotter=pl,
scale=scale_factor,
clim=clim,
title=f"Iter: {i}",
title_size = 10,
scalar_bar_args=sargs,
)
pl.hide_axes()
pl.write_frame()
pl.close()

Multiplot feature
It is possible to create the plotter before calling the plot function. This allow for instance to use the pyvista multiplot capability. For instance, we can plot the stress results after the example Plate with hole in tension:
import pyvista as pv
pl = pv.Plotter(shape=(2,2))
# or using the backgroundplotter:
# from pyvistaqt import BackgroundPlotter
# pl = BackgroundPlotter(shape = (2,2))
results.plot('Stress', 'vm', 'Node', plotter=pl)
pl.subplot(1,0)
results.plot('Stress', 'XX', 'Node', plotter=pl)
pl.subplot(0,1)
results.plot('Stress', 'YY', 'Node', plotter=pl)
pl.subplot(1,1)
results.plot('Stress', 'XY', 'Node', plotter=pl)
pl.show()
