Actuator Disk#
This example demonstrates the configuration and analysis of a simulation incorporating an actuator disk model using the Flow360 Python API. The script initializes a project from a volume mesh, defines an actuator disk using a cylindrical entity and specified force distributions, sets up the simulation parameters including the operating conditions and turbulence model, and executes the case. Furthermore, it illustrates post-processing techniques to retrieve, visualize, and save the actuator disk performance data.
1import os
2
3from pylab import show
4
5import flow360 as fl
6from flow360.examples import ActuatorDisk
7
8ActuatorDisk.get_files()
9
10project = fl.Project.from_volume_mesh(
11 ActuatorDisk.mesh_filename,
12 name="Actuator disk results from Python",
13 length_unit="inch",
14)
15
16vm = project.volume_mesh
17
18with fl.SI_unit_system:
19 actuator_disk = fl.Cylinder(
20 name="Actuator Cylinder",
21 center=[0, 0, 0],
22 axis=[-1, 0, 0],
23 height=30 * fl.u.inch,
24 outer_radius=150 * fl.u.inch,
25 )
26 params = fl.SimulationParams(
27 reference_geometry=fl.ReferenceGeometry(
28 area=16286.016316209487 * fl.u.inch**2,
29 moment_center=[450, 0, 0] * fl.u.inch,
30 moment_length=[72, 1200, 1200] * fl.u.inch,
31 ),
32 operating_condition=fl.AerospaceCondition.from_mach(mach=0.04),
33 time_stepping=fl.Steady(),
34 models=[
35 fl.Fluid(
36 navier_stokes_solver=fl.NavierStokesSolver(
37 absolute_tolerance=1e-11,
38 linear_solver=fl.LinearSolver(max_iterations=35),
39 kappa_MUSCL=0.33,
40 ),
41 turbulence_model_solver=fl.SpalartAllmaras(
42 absolute_tolerance=1e-10,
43 linear_solver=fl.LinearSolver(max_iterations=25),
44 update_jacobian_frequency=2,
45 equation_evaluation_frequency=1,
46 ),
47 ),
48 fl.ActuatorDisk(
49 name="ActuatorDisk",
50 force_per_area=fl.ForcePerArea(
51 radius=[
52 6.541490006056935e-06,
53 1.176559660811629e01,
54 2.348576620230164e01,
55 3.502422774076318e01,
56 4.635372501514235e01,
57 5.740157480314961e01,
58 6.809963658388855e01,
59 7.837522713506966e01,
60 8.816929133858268e01,
61 9.741823137492429e01,
62 1.060675348273773e02,
63 1.140626892792247e02,
64 1.213537250151423e02,
65 1.278952150211993e02,
66 1.336508176862508e02,
67 1.385841913991520e02,
68 1.426589945487583e02,
69 1.458570563294973e02,
70 1.481511205330103e02,
71 1.495366444579043e02,
72 1.500000000000000e02,
73 ]
74 * fl.u.inch,
75 thrust=[
76 4.575739438020081686e-03,
77 5.344520067175258585e-03,
78 7.032044311381894543e-03,
79 8.710826002579061603e-03,
80 1.000951815124362203e-02,
81 1.093101144022547849e-02,
82 1.157119193478976620e-02,
83 1.201254985284840558e-02,
84 1.230866858381426607e-02,
85 1.248422468860116950e-02,
86 1.253851312261157827e-02,
87 1.244967750332181926e-02,
88 1.217471011028209080e-02,
89 1.166002755407952347e-02,
90 1.085486662369139835e-02,
91 9.723270044643288201e-03,
92 8.260302504752431441e-03,
93 6.493108221024028980e-03,
94 4.476116636387995722e-03,
95 2.283286929126045455e-03,
96 0.000000000000000000e00,
97 ]
98 * fl.u.psi,
99 circumferential=[
100 -5.531604620568226207e-12,
101 -2.000974664192053335e-03,
102 -2.952277367252184072e-03,
103 -3.088901336796338881e-03,
104 -2.903625904926704273e-03,
105 -2.643040675210779362e-03,
106 -2.392185737959950324e-03,
107 -2.173054219978886453e-03,
108 -1.986979038043627539e-03,
109 -1.827962066661991498e-03,
110 -1.688538971888151399e-03,
111 -1.560312378033051808e-03,
112 -1.435018201085241484e-03,
113 -1.304645611220716511e-03,
114 -1.162530024559274696e-03,
115 -1.004486082424148200e-03,
116 -8.291008930327343910e-04,
117 -6.375074356446677401e-04,
118 -4.326781146705185031e-04,
119 -2.186783262772103913e-04,
120 -0.000000000000000000e00,
121 ]
122 * fl.u.psi,
123 ),
124 volumes=actuator_disk,
125 ),
126 fl.Wall(surfaces=vm["fluid/body"]),
127 fl.Freestream(surfaces=vm["fluid/farfield"]),
128 ],
129 )
130
131case = project.run_case(params, "Actuator disk case from Python")
132
133
134case.wait()
135
136results = case.results
137
138actuator_disk_non_dim = results.actuator_disks.as_dataframe()
139print(actuator_disk_non_dim)
140
141actuator_disk_non_dim.plot(
142 x="pseudo_step",
143 y=["Disk0_Power", "Disk0_Force", "Disk0_Moment"],
144 xlim=(0, 200),
145 xlabel="Pseudo Step",
146 figsize=(10, 7),
147 subplots=True,
148 title="Actuator Disk non-dimensional",
149)
150show()
151
152results.actuator_disks.to_base("SI")
153actuator_disk_si = results.actuator_disks.as_dataframe()
154print(actuator_disk_si)
155
156actuator_disk_si.plot(
157 x="pseudo_step",
158 y=["Disk0_Power", "Disk0_Force", "Disk0_Moment"],
159 xlim=(0, 200),
160 xlabel="Pseudo Step",
161 figsize=(10, 7),
162 subplots=True,
163 title="Actuator Disk scaled to SI",
164)
165show()
166
167# download resuts:
168results.set_destination(use_case_name=True)
169results.download(actuator_disks=True, overwrite=True)
170
171# save converted results to a new CSV file:
172results.actuator_disks.to_file(os.path.join(case.name, "actuator_disk_in_SI.csv"))
Notes#
The propellerβs influence is modeled using
fl.ActuatorDisk
, which applies forces based on specified thrust and circumferential distributions per unit area viafl.ForcePerArea
.Post-simulation analysis involves accessing the
results.actuator_disks
object to obtain, plot, and export performance metrics such as forces, moments, and power.