Actuator Disk

Contents

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 via fl.ForcePerArea.

  • Post-simulation analysis involves accessing the results.actuator_disks object to obtain, plot, and export performance metrics such as forces, moments, and power.