Alpha Sweep#
This example demonstrates how to configure and manage a series of simulations to perform an angle of attack (alpha) sweep for the ONERA M6 wing using the Flow360 Python API. It covers setting up a baseline simulation configuration, modifying the angle of attack across a specified range, submitting each case, retrieving results, and performing basic post-processing to calculate and plot aerodynamic coefficients.
1import os
2from typing import List
3
4from pylab import plot, show, xlabel, ylabel
5
6import flow360 as fl
7from flow360.examples import OM6wing
8
9OM6wing.get_files()
10
11project = fl.Project.from_volume_mesh(OM6wing.mesh_filename, name="Alpha sweep results from Python")
12
13vm = project.volume_mesh
14
15with fl.SI_unit_system:
16 params = fl.SimulationParams(
17 reference_geometry=fl.ReferenceGeometry(
18 area=1.15315084119231,
19 moment_center=[0, 0, 0],
20 moment_length=[1.47602, 0.801672958512342, 1.47602],
21 ),
22 operating_condition=fl.AerospaceCondition(velocity_magnitude=286, alpha=3.06 * fl.u.deg),
23 time_stepping=fl.Steady(max_steps=500),
24 models=[
25 fl.Wall(surfaces=vm["1"]),
26 fl.SlipWall(surfaces=vm["2"]),
27 fl.Freestream(surfaces=vm["3"]),
28 ],
29 )
30
31
32# ": List[fl.Case]" is just for type hints
33case_list: List[fl.Case] = []
34alpha_range = range(-6, 15, 2)
35for alpha in alpha_range:
36 params.operating_condition.alpha = alpha * fl.u.deg
37 case = project.run_case(params, f"alpha-sweep-OM6wing-alpha={alpha}")
38 case_list.append(case)
39
40project.print_project_tree()
41
42# wait for all cases to finish processing
43[case.wait() for case in case_list]
44
45
46# calculate average using dataframe structure and pandas functions
47def average_last_10_percent(df, column):
48 last_10_percent = df.tail(int(len(df) * 0.1))
49 average = last_10_percent[column].mean()
50 return average
51
52
53CL_list = []
54CD_list = []
55
56for case in case_list:
57 total_forces = case.results.total_forces
58
59 average_CL = average_last_10_percent(total_forces.as_dataframe(), "CL")
60 CL_list.append(average_CL)
61
62 average_CD = average_last_10_percent(total_forces.as_dataframe(), "CD")
63 CD_list.append(average_CD)
64
65# download all data:
66results_folder = "alpha_sweep_example"
67for case in case_list:
68 results = case.results
69 results.download(
70 total_forces=True,
71 nonlinear_residuals=True,
72 destination=os.path.join(results_folder, case.name),
73 )
74
75# plot CL / CD
76plot(CD_list, CL_list)
77xlabel("CD")
78ylabel("CL")
79show()
Notes#
The script iterates through a predefined range of angles of attack, updating the
operating_condition.alpha
within theSimulationParams
object for each iteration.Each angle of attack is submitted as an individual simulation case using
project.run_case
, allowing for parallel processing and organized results management within a single project structure.Basic post-processing is shown, calculating the mean lift (CL) and drag (CD) coefficients from the converged portion (last 10%) of the simulation history to generate an aerodynamic polar plot (CL vs. CD).