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