Geometry Report

Contents

Geometry Report#

This script showcases the generation of a simulation report using the Flow360 Python API’s reporting plugin. It involves defining a simulation setup for an airplane geometry, performing a parameter sweep over the angle of attack, and then utilizing various report items like tables, 2D charts, and 3D visualizations to compile the results into a PDF report.

  1import flow360 as fl
  2from flow360 import u
  3from flow360.examples import Airplane
  4from flow360.plugins.report.report import ReportTemplate
  5from flow360.plugins.report.report_items import (
  6    Camera,
  7    Chart2D,
  8    Chart3D,
  9    Inputs,
 10    Settings,
 11    Summary,
 12    Table,
 13)
 14from flow360.plugins.report.utils import Average, DataItem, Delta
 15
 16project_id = None  # if running for the first time
 17
 18# then replace it with your project ID to avoid re-creation of projects. You can find project ID on web GUI:
 19# project_id = "prj-...."
 20
 21if project_id is not None:
 22    project = fl.Project.from_cloud(project_id)
 23else:
 24    project = fl.Project.from_geometry(
 25        Airplane.geometry, name="Python Project (Geometry, from file) - for Report"
 26    )
 27
 28geo = project.geometry
 29geo.group_faces_by_tag("groupName")
 30
 31
 32def simulation_params(angle_of_attack):
 33    with fl.SI_unit_system:
 34        far_field_zone = fl.AutomatedFarfield()
 35        params = fl.SimulationParams(
 36            meshing=fl.MeshingParams(
 37                defaults=fl.MeshingDefaults(
 38                    boundary_layer_first_layer_thickness=0.001,
 39                    surface_max_edge_length=1,
 40                ),
 41                volume_zones=[far_field_zone],
 42            ),
 43            reference_geometry=fl.ReferenceGeometry(area=1, moment_length=1),
 44            operating_condition=fl.AerospaceCondition(
 45                velocity_magnitude=100,
 46                alpha=angle_of_attack * fl.u.deg,
 47            ),
 48            time_stepping=fl.Steady(max_steps=1000),
 49            models=[
 50                fl.Wall(
 51                    surfaces=[geo["*"]],
 52                ),
 53                fl.Freestream(
 54                    surfaces=[far_field_zone.farfield],
 55                ),
 56            ],
 57            outputs=[
 58                fl.SurfaceOutput(
 59                    surfaces=geo["*"],
 60                    output_fields=[
 61                        "Cp",
 62                        "Cf",
 63                        "yPlus",
 64                        "CfVec",
 65                        "primitiveVars",
 66                    ],
 67                ),
 68            ],
 69        )
 70    return params
 71
 72
 73cases: list[fl.Case] = []
 74for alpha in [0, 2, 4]:
 75    case = project.run_case(params=simulation_params(alpha), name=f"Case for report, alpha={alpha}")
 76    cases.append(case)
 77
 78[print(case.short_description()) for case in cases]
 79
 80# waiting explicitly for all the cases to finish (report pipeline will not wait for cases)
 81[case.wait() for case in cases]
 82
 83
 84top_camera = Camera(
 85    position=(0, 0, 1),
 86    look_at=(0, 0, 0),
 87    pan_target=(5, 0, 0),
 88    up=(0, 1, 0),
 89    dimension=15,
 90    dimension_dir="width",
 91)
 92side_camera = Camera(
 93    position=(0, -1, 0),
 94    look_at=(0, 0, 0),
 95    pan_target=(5, 0, 0),
 96    up=(0, 0, 1),
 97    dimension=12,
 98    dimension_dir="width",
 99)
100front_left_bottom_camera = Camera(
101    position=(-1, -1, -1),
102    look_at=(0, 0, 0),
103    pan_target=(4, 0, 0),
104    up=(0, 0, 1),
105    dimension=15,
106    dimension_dir="width",
107)
108rear_right_bottom_camera = Camera(
109    position=(1, 1, -1),
110    look_at=(0, 0, 0),
111    pan_target=(4, 0, 0),
112    up=(0, 0, 1),
113    dimension=15,
114    dimension_dir="width",
115)
116
117cameras_geo = [
118    top_camera,
119    side_camera,
120    front_left_bottom_camera,
121    rear_right_bottom_camera,
122]
123
124avg = Average(fraction=0.1)
125
126CL = DataItem(data="surface_forces/totalCL", title="CL", operations=avg)
127
128CD = DataItem(data="surface_forces/totalCD", title="CD", operations=avg)
129
130statistical_data = [
131    "params/operating_condition/alpha",
132    "params/reference_geometry/area",
133    CL,
134    Delta(data=CL),
135    CD,
136    "volume_mesh/stats/n_nodes",
137    "params/time_stepping/max_steps",
138]
139statistical_table = Table(
140    data=statistical_data,
141    section_title="Statistical data",
142    formatter=[
143        (
144            None
145            if d
146            in [
147                "params/reference_geometry/area",
148                "volume_mesh/stats/n_nodes",
149                "params/time_stepping/max_steps",
150            ]
151            else ".4f"
152        )
153        for d in statistical_data
154    ],
155)
156
157geometry_screenshots = [
158    Chart3D(
159        section_title="Geometry",
160        items_in_row=2,
161        force_new_page=True,
162        show="boundaries",
163        camera=camera,
164        fig_name=f"geo_{i}",
165    )
166    for i, camera in enumerate(cameras_geo)
167]
168
169report = ReportTemplate(
170    title="Geometry to report",
171    items=[
172        Summary(),
173        Inputs(),
174        statistical_table,
175        Chart2D(
176            x="total_forces/pseudo_step",
177            y="total_forces/CL",
178            section_title="Lift Coefficient",
179            fig_name="cl_fig",
180            focus_x=(1 / 3, 1),
181        ),
182        *geometry_screenshots,
183    ],
184    settings=Settings(dpi=150),
185)
186
187
188report = report.create_in_cloud(
189    f"Geometry to report - Report, dpi=150",
190    cases,
191)
192
193report.wait()
194report.download("report.pdf")

Notes#

  • Multiple simulation cases are executed sequentially, and their completion is explicitly awaited using case.wait() before initiating the report generation process.

  • The ReportTemplate class orchestrates the report structure, incorporating elements like Table, Chart2D, and Chart3D.

  • Data post-processing, such as averaging force coefficients (DataItem with Average), can be defined directly within the report configuration.