Convergence#
This example demonstrates how to retrieve, process, and visualize convergence data from a completed Flow360 simulation using the Python API. It outlines the procedure for setting up a basic steady-state case, running it, and subsequently accessing and plotting convergence metrics such as nonlinear residuals and CFL numbers.
1from pylab import show
2
3import flow360 as fl
4from flow360.examples import OM6wing
5
6OM6wing.get_files()
7
8project = fl.Project.from_volume_mesh(
9 OM6wing.mesh_filename,
10 name="Convergence results from Python",
11)
12
13vm = project.volume_mesh
14
15with fl.SI_unit_system:
16 params = fl.SimulationParams(
17 reference_geometry=fl.ReferenceGeometry(
18 area=1.15315, moment_center=[0, 0, 0], moment_length=[1.47602, 0.801672, 1.47602]
19 ),
20 operating_condition=fl.AerospaceCondition(velocity_magnitude=286, alpha=3.06 * fl.u.deg),
21 time_stepping=fl.Steady(
22 max_steps=5000, CFL=fl.RampCFL(initial=1, final=100, ramp_steps=1000)
23 ),
24 models=[
25 fl.Fluid(
26 navier_stokes_solver=fl.NavierStokesSolver(
27 absolute_tolerance=1e-9, linear_solver=fl.LinearSolver(max_iterations=35)
28 ),
29 turbulence_model_solver=fl.SpalartAllmaras(
30 absolute_tolerance=1e-8, linear_solver=fl.LinearSolver(max_iterations=25)
31 ),
32 ),
33 fl.Wall(surfaces=vm["2"]),
34 fl.SlipWall(surfaces=vm["1"]),
35 fl.Freestream(surfaces=vm["3"]),
36 ],
37 outputs=[
38 fl.SurfaceOutput(surfaces=vm["1"], output_fields=["Cp", "CfVec"]),
39 fl.VolumeOutput(output_fields=["Cp", "Mach", "qcriterion"]),
40 ],
41 )
42
43case = project.run_case(params, "Convergence case from Python")
44
45
46# wait until the case finishes execution
47case.wait()
48
49results = case.results
50
51# nonlinear residuals contain convergence information
52nonlinear_residuals = results.nonlinear_residuals.as_dataframe()
53print(nonlinear_residuals)
54
55nonlinear_residuals.plot(
56 x="pseudo_step",
57 y=["0_cont", "1_momx", "2_momy", "3_momz", "4_energ", "5_nuHat"],
58 xlim=(0, None),
59 xlabel="Pseudo Step",
60 secondary_y=["5_nuHat"],
61 figsize=(10, 7),
62 title="Nonlinear residuals",
63)
64
65max_residual_location = results.max_residual_location.as_dataframe()
66print(max_residual_location)
67
68max_residual_location.plot(
69 x="pseudo_step",
70 y=[
71 "max_cont_res",
72 "max_momx_res",
73 "max_momy_res",
74 "max_momz_res",
75 "max_energ_res",
76 "max_nuHat_res",
77 ],
78 xlabel="Pseudo Step",
79 xlim=(0, None),
80 ylim=(-25, None),
81 secondary_y=["max_nuHat_res"],
82 figsize=(10, 7),
83 title="Max residual location",
84)
85show()
86
87cfl = results.cfl.as_dataframe()
88print(cfl)
89
90cfl.plot(
91 x="pseudo_step",
92 y=["0_NavierStokes_cfl", "1_SpalartAllmaras_cfl"],
93 xlim=(0, None),
94 xlabel="Pseudo Step",
95 figsize=(10, 7),
96 title="CFL",
97)
98show()
99
100results.set_destination(use_case_name=True)
101results.download(
102 nonlinear_residuals=True,
103 linear_residuals=True,
104 cfl=True,
105 minmax_state=True,
106 max_residual_location=True,
107)
Notes#
The script utilizes
case.wait()
to pause execution until the simulation completes, ensuring that results are available for post-processing.Convergence history, including nonlinear residuals (
results.nonlinear_residuals
), maximum residual locations (results.max_residual_location
), and CFL values (results.cfl
), are accessed via theresults
object. These are converted to pandas DataFrames using.as_dataframe()
for convenient analysis and plotting.Specific convergence-related files can be downloaded using the
results.download()
method by specifying the desired data types (e.g.,nonlinear_residuals=True
,cfl=True
).