BET eVTOL#
In this example we simulate multiple Blade Element Theory (BET) disks for an eVTOL (electric Vertical Take-Off and Landing) aircraft using the Flow360 Python API. It covers loading geometry, defining mesh refinements including axisymmetric refinement for multiple rotor regions, specifying operating conditions, creating multiple BET disks from cylinder entities defined for each of the blades and predefined BET disk files. To see how to create a BET disk directly from an xrotor file, check the BET Disk example.
1import flow360 as fl
2from flow360.examples import BETEVTOL
3
4BETEVTOL.get_files()
5
6project = fl.Project.from_geometry(BETEVTOL.geometry, name="BET eVTOL")
7
8geometry = project.geometry
9geometry.group_edges_by_tag("edgeId")
10geometry.group_faces_by_tag("faceId")
11
12
13with fl.SI_unit_system:
14 box1 = fl.Box(name="Box 1", center=[2, 0, 0.5], size=[12, 16, 4])
15 box2 = fl.Box(name="Box 2", center=[8, 0, 0.5], size=[24, 32, 8])
16 cylinder1 = fl.Cylinder(
17 name="BET 1", center=[-1.95, -6, 0.57], axis=[-1, 0, 0], outer_radius=1.5, height=0.2
18 )
19 cylinder2 = fl.Cylinder(
20 name="BET 2", center=[-1.95, -2.65, 0.51], axis=[-1, 0, 0], outer_radius=1.5, height=0.2
21 )
22 cylinder3 = fl.Cylinder(
23 name="BET 3", center=[-1.95, 2.65, 0.51], axis=[-1, 0, 0], outer_radius=1.5, height=0.2
24 )
25 cylinder4 = fl.Cylinder(
26 name="BET 4", center=[-1.95, 6, 0.57], axis=[-1, 0, 0], outer_radius=1.5, height=0.2
27 )
28 cylinder5 = fl.Cylinder(
29 name="BET 5", center=[2.7, -6, 1.06], axis=[0, 0, 1], outer_radius=1.5, height=0.2
30 )
31 cylinder6 = fl.Cylinder(
32 name="BET 6", center=[2.7, -2.65, 1.06], axis=[0, 0, 1], outer_radius=1.5, height=0.2
33 )
34 cylinder7 = fl.Cylinder(
35 name="BET 7", center=[2.7, 2.65, 1.06], axis=[0, 0, 1], outer_radius=1.5, height=0.2
36 )
37 cylinder8 = fl.Cylinder(
38 name="BET 8", center=[2.7, 6, 1.06], axis=[0, 0, 1], outer_radius=1.5, height=0.2
39 )
40 slices = [
41 fl.Slice(name=f"Slice BET {i+1}", normal=[0, 1, 0], origin=[0, originY, 0])
42 for i, originY in enumerate([-6, -2.65, 2.65, 6])
43 ]
44 farfield = fl.AutomatedFarfield(name="Farfield")
45 params = fl.SimulationParams(
46 meshing=fl.MeshingParams(
47 defaults=fl.MeshingDefaults(
48 surface_max_edge_length=0.05, boundary_layer_first_layer_thickness=0.01 * fl.u.mm
49 ),
50 volume_zones=[farfield],
51 refinements=[
52 fl.AxisymmetricRefinement(
53 name="BET refinement",
54 spacing_axial=0.01,
55 spacing_radial=0.03,
56 spacing_circumferential=0.03,
57 entities=[
58 cylinder1,
59 cylinder2,
60 cylinder3,
61 cylinder4,
62 cylinder5,
63 cylinder6,
64 cylinder7,
65 cylinder8,
66 ],
67 ),
68 fl.UniformRefinement(name="Uniform refinement 0.05", spacing=0.05, entities=box1),
69 fl.UniformRefinement(name="Uniform refinement 0.1", spacing=0.1, entities=box2),
70 ],
71 ),
72 reference_geometry=fl.ReferenceGeometry(
73 area=16.8, moment_center=[0, 0, 0], moment_length=[1.4, 1.4, 1.4]
74 ),
75 operating_condition=fl.AerospaceCondition(velocity_magnitude=70, alpha=15 * fl.u.deg),
76 models=[
77 fl.Wall(name="Wall", surfaces=[geometry["*"]]),
78 fl.Freestream(name="Freestream", surfaces=[farfield.farfield]),
79 fl.Fluid(
80 navier_stokes_solver=fl.NavierStokesSolver(relative_tolerance=0.01),
81 turbulence_model_solver=fl.SpalartAllmaras(
82 relative_tolerance=0.01,
83 rotation_correction=True,
84 hybrid_model=fl.DetachedEddySimulation(),
85 ),
86 ),
87 fl.BETDisk.from_file(BETEVTOL.extra["disk13"]),
88 fl.BETDisk.from_file(BETEVTOL.extra["disk24"]),
89 fl.BETDisk.from_file(BETEVTOL.extra["disk57"]),
90 fl.BETDisk.from_file(BETEVTOL.extra["disk68"]),
91 ],
92 time_stepping=fl.Unsteady(
93 steps=1000,
94 step_size=0.0004,
95 max_pseudo_steps=30,
96 CFL=fl.AdaptiveCFL(
97 min=1, max=3000, max_relative_change=50, convergence_limiting_factor=0.1
98 ),
99 ),
100 outputs=[
101 fl.SurfaceOutput(
102 name="Surface output",
103 output_fields=["Cp", "yPlus", "Cf", "CfVec"],
104 surfaces=[geometry["*"]],
105 ),
106 fl.SliceOutput(
107 name="Slice output", output_fields=["Cp", "Mach", "vorticity"], slices=[*slices]
108 ),
109 ],
110 )
111
112
113project.run_case(params, name="BET eVTOL case")
Notes#
There are 8 rotor disks arranged in a typical eVTOL configuration with both front and rear rotor positions.
BET disk parameters are loaded from external BET disk files for different rotor configurations.
AxisymmetricRefinement
is used to control mesh resolution within the cylindrical BET disk regions.