Skip to content

Commit 0007ad9

Browse files
committed
Add content to postprocessing page
1 parent ea3be96 commit 0007ad9

File tree

1 file changed

+190
-5
lines changed

1 file changed

+190
-5
lines changed

tutorial/postprocessing.rst

+190-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,194 @@
11
Postprocessing
22
==============
33

4-
To Do:
4+
Having the numerical results computed by the simulation run,
5+
the next step is to generate some plots to interpretate the results.
6+
This task is generally referred to as 'post-processing'.
57

6-
* How to get 2D results and tables
7-
* How to create a cutting plane view
8-
* How to create an animation
9-
* How to download 3D result fields
8+
In the SimScale platform, the results are stored in the cloud, and the SDK
9+
provides the methods to query and download the results. In this example we
10+
will generate a report from the results, including a cutting-plane view
11+
of the 3D fields.
12+
13+
To begin, let's obtain the meta-data from the solution fields:
14+
15+
16+
.. code-block:: python
17+
18+
solution_fields_result = simulation_run_api.get_simulation_run_results(
19+
project_id,
20+
simulation_id,
21+
simulation_run_id,
22+
category="SOLUTION"
23+
)
24+
25+
print(f"{solution_fields_result=}")
26+
27+
If we examine this object, we find that it contains the property ``embedded``
28+
with a list of results. We will use the first value in the list, and download
29+
the actual results data for later use:
30+
31+
32+
.. code-block:: python
33+
34+
solution_info = solution_fields_result.embedded[0]
35+
36+
37+
Now we can use the data in ``solution_info`` to perform our tasks.
38+
39+
Create an Animation
40+
-------------------
41+
42+
We will create a simulation report using the SDK, which will contain an
43+
animation of the velocity field results. In order to do so, we need to first
44+
create a series of configuration objects:
45+
46+
47+
.. code-block:: python
48+
49+
scalar_field = sim.ScalarField(
50+
field_name="Velocity",
51+
component="Magnitude",
52+
data_type="CELL"
53+
)
54+
55+
model_settings = sim.ModelSettings(
56+
parts=[],
57+
sacalar_field=scalar_field,
58+
)
59+
60+
cutting_plane = sim.CuttingPlane(
61+
name="velocity-plane",
62+
scalar_field=scalar_field,
63+
center=sim.Vector3D(x=0, y=0, z=0),
64+
normal=sim.Vector3D(x=1, y=0, z=0),
65+
opacity=1,
66+
clipping=True,
67+
render_mode=sim.RenderMode.SURFACES,
68+
)
69+
70+
filters = sim.Filters(
71+
cutting_planes=[cutting_plane],
72+
)
73+
74+
camera_settings = sim.TopViewPredefinedCameraSettings(
75+
projection_type=sim.ProjectionType.ORTHOGONAL,
76+
direction_specifier="X_POSITIVE",
77+
)
78+
79+
output_settings = sim.TimeStepAnimationOutputSettings(
80+
type="TIME_STEP",
81+
name="Output 1",
82+
format="MP4",
83+
resolution=sim.ResolutionInfo(x=1440, y=1080),
84+
from_frame_index=0,
85+
to_frame_index=5,
86+
skip_frames=0,
87+
show_legend=True,
88+
show_cube=False,
89+
)
90+
91+
report_properties = sim.AnimationReportProperties(
92+
model_settings=model_settings,
93+
filters=filters,
94+
camera_settings=camera_settings,
95+
output_settings=output_settings,
96+
)
97+
98+
99+
You can see how each object controls one part of the animation:
100+
101+
* ``ScalarField`` selects which result field is to be displayed
102+
* ``CuttingPlane`` specifies a cutting plane to look inside the volume
103+
* ``CameraSettings`` specify the view direction
104+
* ``TimeStepAnimationOutputSettings`` control the animation
105+
* ``AnimationReportProperties`` links all of the other configurations
106+
107+
Then we can request the creation of the animation and launch the job, which
108+
happens in the platform:
109+
110+
111+
.. code-block:: python
112+
113+
report_req = sim.ReportRequest(
114+
name="Report 1",
115+
description="Simulation report",
116+
result_ids=[solution_info.result_id],
117+
report_properties=report_properties,
118+
)
119+
120+
reports_api = sim.ReportsApi(api_client)
121+
122+
create_report_res = reports_api.create_report(
123+
project_id,
124+
report_request,
125+
)
126+
127+
report_id = create_report_res.report_id
128+
129+
report_job = reports_api.start_report_job(
130+
project_id,
131+
report_id,
132+
)
133+
134+
report = reports_api.get_report(
135+
project_id,
136+
report_id,
137+
)
138+
139+
while report.status not in ("FINISHED", "CANCELED", "FAILED"):
140+
141+
time.sleep(30)
142+
143+
report = reports_api.get_report(
144+
project_id,
145+
report_id,
146+
)
147+
148+
print(f"Report creation finished with status {report.status}")
149+
150+
151+
Now that the report is successfuly created in the platform, we can
152+
download and store it locally:
153+
154+
155+
.. code-block:: python
156+
157+
report_res = api_client.rest_client.GET(
158+
url=report.download.url,
159+
headers={"X-API-KEY": API_KEY},
160+
)
161+
162+
file_name = f"report.{report.download.format}"
163+
164+
with open(file_name, "wb") as file:
165+
file.write(report_res.data)
166+
167+
168+
You should be able to open the video file with your preferred player.
169+
170+
171+
Download 3D Fields
172+
------------------
173+
174+
Another option to use the result fields is to get the full numerical fields,
175+
and process them locally. As the results are in VTK format, the pocessing
176+
can be performed with a library such as `PyVista <https://pyvista.org/>`_
177+
or with a GUI application like `Paraview <https://www.paraview.org/>`_.
178+
179+
In order to download the results we can do as follows:
180+
181+
182+
.. code-block:: python
183+
184+
solution_res = api_client.rest_client.GET(
185+
url=solution_info.download.url,
186+
headers={"X-API-KEY": API_KEY},
187+
)
188+
189+
with open("solution.zip", "wb") as file:
190+
file.write(solution_res.data)
191+
192+
193+
The results are stored in a zip archive, and can be extracted manually with
194+
the file explorer or programatically with the ``zip`` library.

0 commit comments

Comments
 (0)