Dynamic Derivatives

Contents

Dynamic Derivatives#

This example demonstrates the computation of dynamic stability derivatives for an airfoil undergoing pitching oscillations. It employs a sliding mesh approach, where the airfoil is enclosed within a rotating cylindrical interface. The simulation strategy involves two stages: first, a steady-state simulation is performed to establish a baseline flow field, followed by an unsteady simulation where the sliding interface oscillates according to a specified sinusoidal motion to capture the dynamic effects. The script showcases the setup for both the steady initialization and the subsequent unsteady, oscillating simulation using the Flow360 Python API.

  1import math
  2
  3import flow360 as fl
  4from flow360.examples import TutorialDynamicDerivatives
  5
  6TutorialDynamicDerivatives.get_files()
  7project = fl.Project.from_geometry(
  8    TutorialDynamicDerivatives.geometry,
  9    name="Tutorial Calculating Dynamic Derivatives using Sliding Interfaces from Python",
 10)
 11geometry = project.geometry
 12
 13
 14# show face groupings
 15geometry.show_available_groupings(verbose_mode=True)
 16geometry.group_faces_by_tag("faceName")
 17geometry.group_edges_by_tag("edgeName")
 18
 19with fl.SI_unit_system:
 20    cylinder = fl.Cylinder(
 21        name="cylinder",
 22        axis=[0, 1, 0],
 23        center=[0, 0, 0],
 24        inner_radius=0,
 25        outer_radius=1.0,
 26        height=2.5,
 27    )
 28    sliding_interface = fl.RotationCylinder(
 29        spacing_axial=0.04,
 30        spacing_radial=0.04,
 31        spacing_circumferential=0.04,
 32        entities=cylinder,
 33        enclosed_entities=geometry["wing"],
 34    )
 35    farfield = fl.AutomatedFarfield()
 36    params = fl.SimulationParams(
 37        meshing=fl.MeshingParams(
 38            defaults=fl.MeshingDefaults(
 39                surface_max_edge_length=0.03 * fl.u.m,
 40                curvature_resolution_angle=8 * fl.u.deg,
 41                surface_edge_growth_rate=1.15,
 42                boundary_layer_first_layer_thickness=1e-6,
 43                boundary_layer_growth_rate=1.15,
 44            ),
 45            refinement_factor=1.0,
 46            volume_zones=[sliding_interface, farfield],
 47            refinements=[
 48                fl.SurfaceEdgeRefinement(
 49                    name="leadingEdge",
 50                    method=fl.AngleBasedRefinement(value=1 * fl.u.degree),
 51                    edges=geometry["leadingEdge"],
 52                ),
 53                fl.SurfaceEdgeRefinement(
 54                    name="trailingEdge",
 55                    method=fl.HeightBasedRefinement(value=0.001),
 56                    edges=geometry["trailingEdge"],
 57                ),
 58            ],
 59        ),
 60        reference_geometry=fl.ReferenceGeometry(
 61            moment_center=[0, 0, 0],
 62            moment_length=[1, 1, 1],
 63            area=2,
 64        ),
 65        operating_condition=fl.AerospaceCondition(
 66            velocity_magnitude=50,
 67        ),
 68        time_stepping=fl.Steady(
 69            max_steps=10000, CFL=fl.RampCFL(initial=1, final=100, ramp_steps=1000)
 70        ),
 71        outputs=[
 72            fl.VolumeOutput(
 73                output_fields=[
 74                    "Mach",
 75                ],
 76            ),
 77            fl.SurfaceOutput(
 78                surfaces=geometry["*"],
 79                output_fields=[
 80                    "Cp",
 81                    "CfVec",
 82                ],
 83            ),
 84        ],
 85        models=[
 86            fl.Rotation(
 87                volumes=cylinder,
 88                spec=fl.AngularVelocity(0 * fl.u.rad / fl.u.s),
 89            ),
 90            fl.Freestream(surfaces=farfield.farfield),
 91            fl.Wall(surfaces=geometry["wing"]),
 92            fl.Fluid(
 93                navier_stokes_solver=fl.NavierStokesSolver(
 94                    absolute_tolerance=1e-9,
 95                    linear_solver=fl.LinearSolver(max_iterations=35),
 96                ),
 97                turbulence_model_solver=fl.SpalartAllmaras(
 98                    absolute_tolerance=1e-8,
 99                    linear_solver=fl.LinearSolver(max_iterations=25),
100                ),
101            ),
102        ],
103    )
104
105# Run steady case with a fixed sliding interface for initializing the flow field.
106project.run_case(
107    params=params,
108    name="Tutorial Calculating Dynamic Derivatives using Sliding Interfaces (Steady)",
109)
110parent_case = fl.Case.from_cloud(project.case.id)
111
112# Update the parameters for the unsteady case.
113with fl.SI_unit_system:
114    params.time_stepping = fl.Unsteady(
115        max_pseudo_steps=80,
116        steps=400,
117        step_size=0.01 * 2.0 * math.pi / 20.0 * fl.u.s,
118        CFL=fl.RampCFL(initial=1, final=1e8, ramp_steps=20),
119    )
120    params.models[0].spec = fl.AngleExpression("0.0349066 * sin(0.05877271 * t)")
121
122# Run unsteady case with an oscillating sliding interface for collecting the data.
123project.run_case(
124    params=params,
125    name="Tutorial Calculating Dynamic Derivatives using Sliding Interfaces (Unsteady)",
126    fork_from=parent_case,
127)

Notes#

  • Two-Stage Simulation: A steady-state case initializes the flow field before the unsteady simulation begins, utilizing fork_from to inherit the flow field solution.

  • Sliding Interface Oscillation: The pitching motion is modeled using a RotationCylinder sliding interface. Its angular position over time is defined via AngleExpression, incorporating nondimensional time (t) and frequency.