dragonfly_sim.utils.ffd_dv_utils
Construction of the FFD control-point-motion design variable and its bounds.
The design variable cp_motions has shape ffd_shape + (n_opt,), where the
trailing axis is a compressed index over the optimized spatial directions –
cp_motions[..., m] moves spatial component coord_idxs[m] of every control
point, and directions absent from coord_idxs stay at their baseline value.
See shape_parameterization.WallFFD.apply_cp_motions for the application of
that mapping.
Everything here is expressed through a single dv_spec dict, keyed by spatial
direction index, so the choice of optimized directions and the bounds on each of
them cannot drift apart:
- dv_spec = {
0: 0.02, # x: symmetric +/- 0.02 everywhere 2: (-0.05, 0.10), # z: asymmetric, uniform over control points
}
A value may also be a callable f(coords) -> (lower, upper) for bounds that
vary over the block; see spanwise_linear_bounds.
Sectional shape variables (shape_parameterization.SectionalShape) get their arrays from build_sectional_dv, and ShapeDVSet collects any mix of these into the ordered set of shape design variables a driver declares.
Numpy-only apart from ShapeDVSet’s variable creation, which imports csdl
lazily – so the bounds logic can be exercised without an MPI environment.
Callers pass their own printer (typically PETSc.Sys.Print) to
print_cp_motion_bounds.
Classes
Everything needed to declare |
|
The ordered set of shape design variables of a driver. |
Functions
|
One direction's bounds as a pair of (num_control_points,) arrays. |
|
Build the cp_motions design variable arrays from a dv_spec. |
|
Arrays for one sectional shape variable (twist, camber, ...). |
|
The optimized spatial components named by dv_spec, sorted ascending. |
|
Summarise a CPMotionDV, one line per optimized direction. |
|
A bound callable whose magnitude varies linearly with the spanwise coordinate. |
Module Contents
- class dragonfly_sim.utils.ffd_dv_utils.CPMotionDV
Bases:
NamedTupleEverything needed to declare
cp_motionsas a design variable.coord_idxs : (n_opt,) int array of optimized spatial components, ascending shape : ffd_shape + (n_opt,), the shape of the design variable value : initial value (zeros – the motions are deltas from baseline) lower/upper: bounds, in physical units, same shape as value scaler : per-entry scaler for set_as_design_variable, or None
- coord_idxs: numpy.ndarray
- lower: numpy.ndarray
- scaler: numpy.ndarray | None
- shape: tuple
- upper: numpy.ndarray
- value: numpy.ndarray
- class dragonfly_sim.utils.ffd_dv_utils.ShapeDVSet
The ordered set of shape design variables of a driver.
flat_variableconcatenates them, in declaration order and each variable flattened in C order, into the one vector the model takes as itscp_motion_inputs.- __getitem__(name)
- add(name, dv)
Create the csdl design variable for dv (a CPMotionDV) and return it.
- dv(name)
- flat_variable()
All shape variables as one csdl vector, in declaration order.
This is what the model takes as its
cp_motion_inputs. A single variable is returned as is.
- dvs = []
- names = []
- property shape
- property size
- variables = []
- dragonfly_sim.utils.ffd_dv_utils._resolve_direction_bounds(bound_spec, coords, direction)
One direction’s bounds as a pair of (num_control_points,) arrays.
- dragonfly_sim.utils.ffd_dv_utils.build_cp_motion_dv(baseline_controlpoints, dv_spec, scaler_mode='bounds')
Build the cp_motions design variable arrays from a dv_spec.
- baseline_controlpoints(*ffd_shape, ndim) control point coordinates, as
held by shape_parameterization.WallFFD.baseline_coefficients
dv_spec : {direction: bound_spec}, see the module docstring scaler_mode : ‘bounds’ derives a scaler of 1/half-range so every direction’s
box becomes +/-1 in the optimizer’s space; None emits no scaler.
Returns a CPMotionDV. CSDL flattens design variables and their bounds in C order (csdl_alpha/backends/simulator.py, build_opt_metadata), and this function reshapes in C order too, so no manual index bookkeeping is needed: entry [i, j, k, m] bounds the motion of baseline_controlpoints[i, j, k, coord_idxs[m]].
- dragonfly_sim.utils.ffd_dv_utils.build_sectional_dv(num_values, bounds, scaler_mode='bounds')
Arrays for one sectional shape variable (twist, camber, …).
- num_valuesentries of the variable – one per section, or fewer for a
B-spline profile over the sections (see SectionalShape)
- boundsa scalar symmetric half-range, a (lower, upper) pair, or a pair of
(num_values,) arrays. As for cp_motions the variable starts at zero (a delta from the baseline), so zero must lie inside the box; pin an entry with (0., 0.).
scaler_mode : as in build_cp_motion_dv
Returns a CPMotionDV with coord_idxs=None.
- dragonfly_sim.utils.ffd_dv_utils.cp_dv_directions(dv_spec)
The optimized spatial components named by dv_spec, sorted ascending.
Call this before constructing DG_windtunnel_model, which needs cp_coord_opt_idxs up front; build_cp_motion_dv (which needs the baseline control points, and so can only run after set_up_sim) derives the same array again and returns it for cross-checking.
Sorting is load-bearing: it makes the design variable’s column order independent of the order the dict literal happens to be written in, and shape_parameterization.validate_cp_coord_opt_idxs enforces the same strictly-increasing invariant.
- dragonfly_sim.utils.ffd_dv_utils.print_cp_motion_bounds(cp_dv, printer=print, axis_names=('x', 'y', 'z'))
Summarise a CPMotionDV, one line per optimized direction.
printer is called once per line; pass PETSc.Sys.Print from an MPI driver to keep the output on rank 0.
- dragonfly_sim.utils.ffd_dv_utils.spanwise_linear_bounds(base_bound, scale_at_root, scale_at_ref, y_ref, y_axis=1)
A bound callable whose magnitude varies linearly with the spanwise coordinate.
The bound is base_bound*scale_at_root at y = 0 and base_bound*scale_at_ref at y = y_ref, linearly interpolated in between and clipped to that range outside [0, y_ref] so the magnitude never changes sign. Bounds are symmetric: lower = -bound, upper = +bound.
Motivating case: a wing FFD block that tapers from root chord to tip chord, so a single scalar bound is a much larger fraction of the local chord at the tip than at the root. Shrinking the bound along the span keeps the allowed deformation a roughly constant fraction of the local chord.