BET Disk#
This example script demonstrates setting up and running a steady-state simulation involving a Blade Element Theory (BET) disk using the Flow360 Python API. It covers loading rotor geometry and aerodynamic data from external files, configuring simulation parameters, submitting the case, retrieving results such as forces and radial distributions, performing unit conversions, and generating a visualization report.
1import os
2
3from pylab import show
4
5import flow360 as fl
6from flow360.examples import BETExampleData
7from flow360.plugins.report.report import ReportTemplate
8from flow360.plugins.report.report_items import (
9 Chart3D,
10 FrontCamera,
11 Inputs,
12 Settings,
13 Summary,
14)
15
16BETExampleData.get_files()
17
18project = fl.Project.from_volume_mesh(
19 BETExampleData.mesh_filename,
20 name="BET Disk results from Python",
21 length_unit="inch",
22)
23
24vm = project.volume_mesh
25
26bet = fl.BETDisk.from_file(BETExampleData.extra["disk0"])
27
28with fl.SI_unit_system:
29 params = fl.SimulationParams(
30 reference_geometry=fl.ReferenceGeometry(
31 area=16286.016316209487 * fl.u.inch**2,
32 moment_center=[450, 0, 0] * fl.u.inch,
33 moment_length=[72, 1200, 1200] * fl.u.inch,
34 ),
35 operating_condition=fl.AerospaceCondition.from_mach(mach=0.04),
36 time_stepping=fl.Steady(),
37 models=[
38 fl.Fluid(
39 navier_stokes_solver=fl.NavierStokesSolver(
40 absolute_tolerance=1e-11,
41 linear_solver=fl.LinearSolver(max_iterations=35),
42 kappa_MUSCL=0.33,
43 ),
44 turbulence_model_solver=fl.SpalartAllmaras(
45 absolute_tolerance=1e-10,
46 linear_solver=fl.LinearSolver(max_iterations=25),
47 update_jacobian_frequency=2,
48 equation_evaluation_frequency=1,
49 ),
50 ),
51 bet,
52 fl.Wall(surfaces=vm["fluid/body"]),
53 fl.Freestream(surfaces=vm["fluid/farfield"]),
54 ],
55 outputs=[
56 fl.SliceOutput(
57 slices=[fl.Slice(name="slice_x", normal=(1, 0, 0), origin=(0, 0, 0))],
58 output_fields=["betMetrics"],
59 )
60 ],
61 )
62
63case = project.run_case(params, "BET Disk case from Python")
64
65
66case.wait()
67
68results = case.results
69bet_forces_non_dim = results.bet_forces.as_dataframe()
70print(results.bet_forces)
71
72# convert results to SI system:
73results.bet_forces.to_base("SI")
74bet_forces_si = results.bet_forces.as_dataframe()
75print(results.bet_forces)
76
77bet_forces_radial_distribution = results.bet_forces_radial_distribution.as_dataframe()
78print(results.bet_forces_radial_distribution)
79
80bet_forces_radial_distribution.plot(
81 x="Disk0_All_Radius",
82 y=["Disk0_Blade0_All_ThrustCoeff", "Disk0_Blade0_All_TorqueCoeff"],
83 xlim=(0, 150),
84 xlabel="Radius",
85 figsize=(10, 7),
86 title="BET Disk radial distribution",
87)
88show()
89
90# download resuts:
91results.set_destination(use_case_name=True)
92results.download(bet_forces=True, bet_forces_radial_distribution=True, overwrite=True)
93
94# save converted results to a new CSV file:
95results.bet_forces.to_file(os.path.join(case.name, "bet_forces_in_SI.csv"))
96
97cases = [case]
98
99front_camera_slice = FrontCamera(dimension=350, dimension_dir="height")
100
101bet_slice_screenshot = Chart3D(
102 section_title="BET effective AoA",
103 items_in_row=2,
104 force_new_page=True,
105 show="slices",
106 include=["slice_x"],
107 field="betMetrics_AlphaDegrees",
108 limits=(-18, 0),
109 camera=front_camera_slice,
110 fig_name="slice_x",
111)
112
113report = ReportTemplate(
114 title="BET results screenshots",
115 items=[Summary(), Inputs(), bet_slice_screenshot],
116 settings=Settings(dpi=150),
117)
118
119report = report.create_in_cloud("BET, dpi=default", cases)
120
121report.wait()
122report.download("report.pdf")
Notes#
Rotor definition and aerodynamic coefficients are loaded using
fl.BETDisk.from_file.The
betMetricsoutput field allows visualization of BET-specific quantities like effective angle of attack on slices.Results objects like
results.bet_forcesandresults.bet_forces_radial_distributionprovide access to integrated and distributed BET performance data, supporting unit conversion via.to_base().