-
Notifications
You must be signed in to change notification settings - Fork 247
How to interact with a simulation to visualize real time results
This tutorial introduces one alternative for effectively interacting with a Kratos simulation to modify some of its parameters and observe the effect of such a modification on the results in real-time. Admittedly, this can be done for any of the simulations available in Kratos, however, it is particularly suitable for fast simulations, like the ones achieved by using Reduced Order Models ROM. Therefore, this tutorial focuses on an example using the RomApplication. The Python module vedo is used for the interactive visualization.
(vedo) is a lightweight and powerful python module for scientific analysis and visualization of 3D objects. It is based on numpy and VTK, with no other dependencies.
The following section guides the user toward the setting up of the Kratos applications and installation of vedo to run the example case.
Install vedo by doing
# installing vedo
pip3 install vedo
Make sure to install the applications required. In this example the RomApplication and the StructuralMechanicsApplication are used. Therefore, add both these application to the Kratos configure file.
Linux:
add_app ${KRATOS_APP_DIR}/StructuralMechanicsApplication
add_app ${KRATOS_APP_DIR}/RomApplication
Windows:
CALL :add_app %KRATOS_APP_DIR%/StructuralMechanicsApplication
CALL :add_app %KRATOS_APP_DIR%/RomApplication
In this section, a simple example is used to illustrate the approach taken to interactively modify the parameters of a simulation in Kratos. Download the files for this example here .
A static structural example has been chosen for demonstrating the integration of vedo into the simulation. The selected geometry is the Stanford bunny. As can be seen, displacement constraints are being applied to the base and a varying pressure is applied to the face of the bunny.
The original model from which this Reduced Order Model was obtained contained 30.000 elements, therefore it was too slow for solving it in real time. On the other hand, the ROM only requires the evaluation of 50 elements to obtain the results.
Thanks to the Python interface of Kratos, the vedo module can be used by simply calling it inside a derived class in the original MainKratos.py.
We start now analyzing how vedo is defined inside our code. First of all we observe the import statement
#Import visualization tool
import vedo
In order to change the magnitude of the load applied, we will use an on-screen slider; for which we define the slider class. Notice that we are going to apply this pressure in MPa, but Kratos is expecting a pressure in Pa, therefore we take into account the 1e6 factor here.
#Slider class
class Slider():
def __init__(self, InitialValue):
self.value = InitialValue
def GenericSlider(self,widget, event):
value = widget.GetRepresentation().GetValue()*1e6
self.value = value
Inside a class derived from StructuralMechanicsAnalysisROM and which we have called InteractiveSimulation in this example, we define the Plotter object as an attribute of InteractiveSimulation. Moreover, we add to it the slider for modifying the pressure.
self.Plot = vedo.Plotter(title="Simulation Results",interactive=False)
self.Plot.addSlider2D(self.slider1.GenericSlider, -200, 400 , value = 0, pos=3, title="Pressure (MPa)")
self.Plot += vedo.Text2D('Move the slider to change the Pressure on the Face of the Bunny', s=1.2)
The method ApplyBoundaryConditions will capture the current position of the slider before each solve step, and will apply the corresponding pressure to the simulation by employing the AssignScalarVariableToConditionsProcess.
def ApplyBoundaryConditions(self):
super().ApplyBoundaryConditions()
Pressure = self.slider1.value
print(f'Pressure is {Pressure} Pa')
PressureSettings = KratosMultiphysics.Parameters("""
{
"model_part_name" : "Structure.COMPUTE_HROM.SurfacePressure3D_Pressure_on_surfaces_Auto4",
"variable_name" : "POSITIVE_FACE_PRESSURE",
"interval" : [0.0,"End"]
}
"""
)
PressureSettings.AddEmptyValue("value").SetDouble(Pressure)
AssignScalarVariableToConditionsProcess(self.model, PressureSettings).ExecuteInitializeSolutionStep()
Vedo allows the definition of generic buttons to perform some action on the visualization. For this example, we define 2 buttons: for pausing-continuing and for stopping the simulation.
self.PauseButton = self.Plot.addButton(
self.PauseButtonFunc,
pos=(0.9, .9), # x,y fraction from bottom left corner
states=["PAUSE", "CONTINUE"],
c=["w", "w"],
bc=["b", "g"], # colors of states
font="courier", # arial, courier, times
size=25,
bold=True,
italic=False,
)
self.StopButton = self.Plot.addButton(
self.StopButtonFunc,
pos=(0.1, .9), # x,y fraction from bottom left corner
states=["STOP"],
c=["w"],
bc=["r"], # colors of states
font="courier", # arial, courier, times
size=25,
bold=True,
italic=False,
)
self.Plot.show()
def PauseButtonFunc(self):
vedo.printc(self.PauseButton.status(), box="_", dim=True)
if self.PauseButton.status() == "PAUSE":
self.Plot.interactive = True
else:
self.Plot.interactive = False
self.PauseButton.switch() # change to next status
def StopButtonFunc(self):
vedo.printc(self.StopButton.status(), box="_", dim=True)
if self.StopButton.status() == "STOP":
self.Finalize()
self.Continue = False
Finally, the results to plot are retrived from the vtk_output folder after each solve step by calling the FinalizeSolutionStep method. In this method a mesh object of vedo has been defined (stored in self.a_mesh), and to this vedo mesh object, the new displacements are added in order to visualize the deformed configuration.
def FinalizeSolutionStep(self):
super().FinalizeSolutionStep()
if self.timestep>1.5:
if self.timestep==2:
self.a_mesh = vedo.load(f'./vtk_output/VISUALIZE_HROM_0_{self.timestep}.vtk').tomesh(fill=True, shrink=1)
displs = self.a_mesh.getPointArray("DISPLACEMENT")
if self.timestep>2:
b_mesh = vedo.load(f'./vtk_output/VISUALIZE_HROM_0_{self.timestep}.vtk').tomesh(fill=True, shrink=1)
newpoints = b_mesh.points()
displs = b_mesh.getPointArray("DISPLACEMENT")
self.a_mesh.points(newpoints+displs)
self.a_mesh.pointColors(vedo.mag(displs), cmap='jet',vmin = 0, vmax = 0.009).addScalarBar()
self.a_mesh.show(axes=1, viewup='z')
self.timestep +=1
We can proceed to run the example with the usual command
python3 MainKratos.py
Then, the terminal will show the usual output of a Kratos simulation while a vedo window will appear showing the real-time solution. Grab and hold the slider to modify the load applied on the face of the Stanford Bunny. You will observe the corresponding deformation immediately.
Pressing the PAUSE button will interrupt the loop over this static simulation. After pressing PAUSE, the button will display CONTINUE. Press CONTINUE again to carry on with the simulation loop (You might need to press the spacebar after pressing CONTINUE).
Press the STOP button to call the Finalize method and finish the simulation.
- Getting Kratos (Last compiled Release)
- Compiling Kratos
- Running an example from GiD
- Kratos input files and I/O
- Data management
- Solving strategies
- Manipulating solution values
- Multiphysics
- Video tutorials
- Style Guide
- Authorship of Kratos files
- Configure .gitignore
- How to configure clang-format
- How to use smart pointer in Kratos
- How to define adjoint elements and response functions
- Visibility and Exposure
- Namespaces and Static Classes
Kratos structure
Conventions
Solvers
Debugging, profiling and testing
- Compiling Kratos in debug mode
- Debugging Kratos using GDB
- Cross-debugging Kratos under Windows
- Debugging Kratos C++ under Windows
- Checking memory usage with Valgind
- Profiling Kratos with MAQAO
- Creating unitary tests
- Using ThreadSanitizer to detect OMP data race bugs
- Debugging Memory with ASAN
HOW TOs
- How to create applications
- Python Tutorials
- Kratos For Dummies (I)
- List of classes and variables accessible via python
- How to use Logger
- How to Create a New Application using cmake
- How to write a JSON configuration file
- How to Access DataBase
- How to use quaternions in Kratos
- How to do Mapping between nonmatching meshes
- How to use Clang-Tidy to automatically correct code
- How to use the Constitutive Law class
- How to use Serialization
- How to use GlobalPointerCommunicator
- How to use PointerMapCommunicator
- How to use the Geometry
- How to use processes for BCs
- How to use Parallel Utilities in futureproofing the code
- Porting to Pybind11 (LEGACY CODE)
- Porting to AMatrix
- How to use Cotire
- Applications: Python-modules
- How to run multiple cases using PyCOMPSs
- How to apply a function to a list of variables
- How to use Kratos Native sparse linear algebra
Utilities
Kratos API
Kratos Structural Mechanics API