Worksheet 5 — Parameter Studies and ParaView Export
Prerequisites:
- Completed implementation of Worksheet 4, including the Qt GUI and
SolverThreadclass. - ParaView installed — download from paraview.org.
pyvtkPython package installed (pip install pyvtk).
Learning Objectives:
After completing this worksheet, you will be able to:
- Extend a Qt GUI with parameter study controls.
- Implement a parametric sweep over model inputs and collect results.
- Export finite element results to VTK format using
pyvtk. - Visualise time-series VTK results in ParaView.
General
This worksheet contains the following tasks:
- Add user interface controls for performing parameter studies
- Add input variables in the InputData-class for managing parameter studies.
- Implement a routine in the Solver-class to perform parameter studies.
- Implement a routine to export the results from a parameter study to ParaView using pyvtk.
User interface controls for the parameter study
Select 2 of the parameters in the interface and add controls to be able to select the start value, end value, number of steps to be simulated.
The following picture shows an example of how this can be done:

The following controls and associated names have been added:

Set good default values on all controls so that one can perform a calculation without having to fill in all values.
Connect an event method, on_execute_param_study to the Param study button. In order to handle parameter studies in our model, we must add a number of extra variables in our ModelParams class:
- param_d - Flag indicating whether parameter d should be varied.
- param_t - Flag indicating whether the parameter t should be varied.
- d_start - Starting value of d.
- d_end - Ending value of d.
- t_start - Start value of t.
- t_end - Ending value of t.
- param_filename - Variable controlling how filenames should be formatted.
- param_steps - Variable controlling the number of steps in the parameter study.
on_execute_param_study should have approximately the same structure as onActionExecute. At the beginning of the method, we add assigment of the new parameters based on the new controls. The following code illustrates this:
def on_execute_param_study(self):
"""Execute parameter study"""
# --- Update model from UI
self.update_model()
# --- Update filename
self.model_param.param_filename = "param_study"
# --- Create a solver
self.solver = sm.ModelSolver(self.model_params, self.model_results)
# --- Start a thread to run the calculation so that
# the interface does not freeze.
self.solverThread = SolverThread(self.solver, param_study = True)
self.solverThread.finished.connect(self.on_solver_finished)
self.solverThread.start()
The only change is that we pass the parameter, param_study=True, to the SolverThread class constructor. The SolverThread-class will be updated in later sections.
Update the Solver-class to handle parameter studies
In the ModelSolver class, we now add a routine, execute_param_study(...), which implements the mechanics to execute the parameter study.
def execute_param_study(self):
"""Run parameter study"""
# -- Store current values for the d and t parameters
old_d = self.model_params.d
old_t = self.model_params.t
i = 1
if self.model_params.param_d:
# --- Create a simulation range
d_range = np.linspace(self.model_params.d_start, self.model_params.d_end,
self.model_params.param_steps)
# --- Loop over the range
for d in d_range:
print("Executing for d = %g..." % d)
# --- Modify parameter in self.model_params
...
# --- Execute calculation
self.execute()
# --- Export to VTK
vtk_filename = "param_study_%02d.vtk" % i
self.export_vtk(vtk_filename) # <-- See next section
elif self.model_params.param_t:
...
# --- Restore previous values of d and t
self.model_params.d = old_d
self.model_params.t = old_t
Exporting results to VTK-files
In this worksheet, we will export the results and display them in the visualization software, ParaView. ParaView uses standardized file format with the extension .vtk. To create these files, we will use a special Python library, pyvtk, this library makes it easy to create these files.
First, we add the import directive at the top of our module:
In the next step, we will add a method in the ModelSolver-class, export_vtk(...) to perform the actual export.
pyvtk has a lot of data types. We will start from the primitive vtk.PolyData. This data type is well suited to managing unstructured elements that we have in this application. To be able to visualise this type of data, points and topology are needed. This information is available from the calculations. However, pyvtk does not handle NumPy arrays, so we have to do some tricks to convert these into the right format:
export_vtk(...) for scalar problems
def export_vtk(self, filename):
"""Export results to VTK"""
print("Exporting results to %s." % filename)
# --- Extract points and polygons
points = self.model_results.coords.tolist()
polygons = (self.model_results.edof-1).tolist()
# --- Create point data from a
point_data = vtk.PointData(
vtk.Scalars(self.model_results.a.tolist(), name="pressure")
)
# --- Create cell data from max_flow and flow
cell_data = vtk.CellData(
vtk.Scalars(self.model_results.max_flow, name="max_flow"),
vtk.Vectors(self.model_results.flow, "flow")
)
# --- Create structure
structure = vtk.PolyData(points=points, polygons=polygons)
# --- Export to vtk
vtk_data = vtk.VtkData(structure, point_data, cell_data)
vtk_data.tofile(filename, "ascii")
export_vtk(...) for vector problems (stress)
Modify the execute method to extract the node topology, topo:
def execute(self):
"""Metod för att utföra finita element beräkningen."""
...
# --- Mesh generation
el_type = 3
dofs_per_node = 2
geometry = self.model_params.geometry()
mesh = cfm.GmshMeshGenerator(geometry)
mesh.el_size_factor = el_size_factor # Factor that changes element sizes.
mesh.el_type = el_type
mesh.dofs_per_node = dofs_per_node
coords, edof, dofs, bdofs, elementmarkers = mesh.create()
self.model_results.topo = mesh.topo # <-- ADDED
The VTK export routine is shown below. Modify with your own variables.
def export_vtk(self, filename):
"""Export results to VTK"""
print("Exporting results to %s." % filename)
# --- Extract points and polygons
points = self.model_results.coords.tolist()
polygons = (self.model_results.topo-1).tolist()
# --- Create point data from a
displ = np.reshape(self.model_results.a, (len(points),2)).tolist()
pointData = vtk.PointData(vtk.Vectors(displ, name="displacements"))
# --- Create cell data from mises and principal stresses
von_mises = np.reshape(self.model_results.evm, (self.model_results.evm.shape[0],))
cellData = vtk.CellData(
vtk.Scalars(von_mises, name="vonmises"),
vtk.Vectors(self.model_results.ep1.tolist(), name="principal1"),
vtk.Vectors(self.model_results.ep2.tolist(), name="principal2")
)
# --- Create structure
structure = vtk.PolyData(points = points, polygons = polygons)
# --- Export to VTK
vtkData = vtk.VtkData(structure, cellData, pointData)
vtkData.tofile(filename, "ascii")
ParaView can automatically manage the results of the parameter study if the files are named param_study_01.vtk, param_study_02.vtk. The file can be opened as a file param_study in the application.
Updating the SolverThread-class
The SolverThread class needs to be updated to be able to run a parameter study as well. We define an additional class attribute, self.param_study, that indicates if a parameter study or a normal calculation should be performed:
class SolverThread(QThread):
"""Background calculation thread"""
def __init__(self, solver, param_study = False):
"""Constructor"""
super().__init__()
self.param_study = param_study # <-- ADDED
self.solver = solver
...
def run(self):
if self.param_study: # <-- UPDATED
self.solver.execute_param_study()
else:
self.solver.execute()
Submission and reporting
What to do in this worksheet is:
- Implement interface controls and buttons for parameter study functionality
- Update the ModelSolver class to manage parameter studies.
- Implement the export_vtk(...) function in the ModelSolver class.
- The method execute_param_study(...) for each calculation must write a vtk file with the model filename with an added number. That is, [filename]_01.vtk, [filename]_02.vtk.
- Import the vtk files into ParaView for visualization.
The submission must consist of a zip file (or other archive format) consisting of:
- All Python files. (.Py files)
- Pictures from ParaView visualizations.