# DynamicCoupled¶

class sharpy.solvers.dynamiccoupled.DynamicCoupled[source]

The DynamicCoupled solver couples the aerodynamic and structural solvers of choice to march forward in time the aeroelastic system’s solution.

Using the DynamicCoupled solver requires that an instance of the StaticCoupled solver is called in the SHARPy solution flow when defining the problem case.

Input data (from external controllers) can be received and data sent using the SHARPy network interface, specified through the setting network_settings of this solver. For more detail on how to send and receive data see the NetworkLoader documentation.

Changes to the structural properties or external forces that depend on the instantaneous situation of the system can be applied through runtime_generators. These runtime generators are parsed through dictionaries, with the key being the name of the generator and the value the settings for such generator. The currently available runtime_generators are ExternalForces and ModifyStructure.

The settings that this solver accepts are given by a dictionary, with the following key-value pairs:

Name

Type

Description

Default

Options

print_info

bool

Write status to screen

True

structural_solver

str

Structural solver to use in the coupled simulation

None

structural_solver_settings

dict

Dictionary of settings for the structural solver

None

aero_solver

str

Aerodynamic solver to use in the coupled simulation

None

aero_solver_settings

dict

Dictionary of settings for the aerodynamic solver

None

n_time_steps

int

Number of time steps for the simulation

None

dt

float

Time step

None

fsi_substeps

int

Max iterations in the FSI loop

70

fsi_tolerance

float

Convergence threshold for the FSI loop

1e-05

structural_substeps

int

Number of extra structural time steps per aero time step. 0 is a fully coupled simulation.

0

relaxation_factor

float

Relaxation parameter in the FSI iteration. 0 is no relaxation and -> 1 is very relaxed

0.2

final_relaxation_factor

float

Relaxation factor reached in relaxation_steps with dynamic_relaxation on

0.0

minimum_steps

int

Number of minimum FSI iterations before convergence

3

relaxation_steps

int

Length of the relaxation factor ramp between relaxation_factor and final_relaxation_factor with dynamic_relaxation on

100

dynamic_relaxation

bool

Controls if relaxation factor is modified during the FSI iteration process

False

postprocessors

list(str)

List of the postprocessors to run at the end of every time step

[]

postprocessors_settings

dict

Dictionary with the applicable settings for every postprocessor. Every postprocessor needs its entry, even if empty

{}

controller_id

dict

Dictionary of id of every controller (key) and its type (value)

{}

controller_settings

dict

Dictionary with settings (value) of every controller id (key)

{}

cleanup_previous_solution

bool

Controls if previous timestep_info arrays are reset before running the solver

False

include_unsteady_force_contribution

bool

If on, added mass contribution is added to the forces. This depends on the time derivative of the bound circulation. Check filter_gamma_dot in the aero solver

False

steps_without_unsteady_force

int

Number of initial timesteps that don’t include unsteady forces contributions. This avoids oscillations due to no perfectly trimmed initial conditions

0

pseudosteps_ramp_unsteady_force

int

Length of the ramp with which unsteady force contribution is introduced every time step during the FSI iteration process

0

correct_forces_method

str

Function used to correct aerodynamic forces. See sharpy.generators.polaraeroforces

EfficiencyCorrection, PolarCorrection

correct_forces_settings

dict

Settings for corrected forces evaluation

{}

network_settings

dict

Network settings. See NetworkLoader for supported entries

{}

runtime_generators

dict

The dictionary keys are the runtime generators to be used. The dictionary values are dictionaries with the settings needed by each generator.

{}

convergence(k, tstep, previous_tstep, struct_solver, aero_solver, with_runtime_generators)[source]

Check convergence in the FSI loop.

Convergence is determined as:

$\epsilon_q^k = \frac{|| q^k - q^{k - 1} ||}{q^0}$
$\epsilon_\dot{q}^k = \frac{|| \dot{q}^k - \dot{q}^{k - 1} ||}{\dot{q}^0}$

FSI converged if $$\epsilon_q^k < \mathrm{FSI\ tolerance}$$ and $$\epsilon_\dot{q}^k < \mathrm{FSI\ tolerance}$$

get_g()[source]

Getter for g, the gravity value

get_rho()[source]

Getter for rho, the density value

initialise(data, custom_settings=None)[source]

Controls the initialisation process of the solver, including processing the settings and initialising the aero and structural solvers, postprocessors and controllers.

static interpolate_timesteps(step0, step1, out_step, coeff)[source]

Performs a linear interpolation between step0 and step1 based on coeff in [0, 1]. 0 means info in out_step == step0 and 1 out_step == step1.

Quantities interpolated: * steady_applied_forces * unsteady_applied_forces * velocity input in Lagrange constraints

process_controller_output(controlled_state)[source]

This function modified the solver properties and parameters as requested from the controller.

This keeps the main loop much cleaner, while allowing for flexibility

Please, if you add options in here, always code the possibility of that specific option not being there without the code complaining to the user.

If it possible, use the same Key for the new setting as for the setting in the solver. For example, if you want to modify the structural_substeps variable in settings, use that Key in the info dictionary.

As a convention: a value of None returns the value to the initial one specified in settings, while the key not being in the dict is ignored, so if any change was made before, it will stay there.

run()[source]

Run the time stepping procedure with controllers and postprocessors included.

set_g(new_g)[source]

Setter for g, the gravity value

set_rho(new_rho)[source]

Setter for rho, the density value