dragonfly_sim.core.windtunnel_model

Classes

DG_windtunnel_model

Module Contents

class dragonfly_sim.core.windtunnel_model.DG_windtunnel_model(mesh, boundary_dict, shape_parameterization=None, moments=None, mesh_inner_bdry_function=None, wall_tags=None, symmetry_tags=None, poly_order=1, gamma=1.4, filename_suffix='test', asm_overlap=None, ilu_levels=None, model_class=CompressibleEulerModel, model_kwargs=None, reduced_order_model=None, compute_all_adjoint_errors=False)

Bases: csdl_alpha.experimental.CustomImplicitOperation

_adjoint_cache_matches(state_key)
static _adjoint_state_key(u_vec, alpha, mesh_node_motions)

What the adjoint’s matrix depends on: the state, alpha and the mesh motion.

_condensed_adjoint(d_outputs, d_residuals, state_key)

The adjoint solve for a model whose dR/dU is a condensed product (a reconstructed gradient): the model’s own transposed linearized solve (CompressibleEulerModel.linearized_solver). The transposed matrix and the preconditioned KSP are built once per state and reused by the adjoint solves of all outputs at it.

_evaluate_outputs(solution)

Every output of the postprocessor for a flow state: ({name: value}, (c_d, c_l, c_m_1, …)). The names are DG_postprocessor.evaluate’s (L, D, c_l, c_d, M_<name>, c_m_<name>); the tuple is the layout of the *_force_coefficients records, one moment per moment spec, in order.

_first_order_adjoint_guess(ksp, A, rhs, sol)

Fill sol with the first-order adjoint solution of rhs: the solution of P x = rhs, P the transposed compact part A_UU of the Jacobian (the KSP’s preconditioning matrix), to a relative tolerance first_order_adjoint_rtol. The KSP is switched to operator P for the solve, which keeps its preconditioner (P’s factors), and back to (A, P) afterwards, with its tolerances. Returns False, leaving sol zero, if the first-order solve did not converge. The residual of the exact system at the guess, |rhs - A guess| / |rhs|, the iterations and the time are logged and kept in self._last_first_order_guess. Collective.

_fom_adjoint(input_vals, u_vec, alpha, mesh_node_motions, d_outputs, d_residuals, start_time, log=True)

The full-order adjoint psi = (dR/dU)^-T d_outputs[‘u_vec’] at the model’s current state, written to d_residuals[‘u_vec’]. log=False leaves it out of data_store.adjoint_solves (the reference solve of compute_all_adjoint_errors).

_log_adjoint(kind, start_time)
_log_adjoint_error(input_vals, u_vec, alpha, mesh_node_motions, d_outputs, psi_rom)

Record the error of the ROM adjoint psi_rom against the full-order adjoint at the same state, design and right-hand side: (eval_idx, output row, absolute 2-norm error, relative error, ||psi_fom||) in data_store.adjoint_errors. The row is the order of the adjoint solves within the evaluation, i.e. of CSDL’s derivative rows. Collective.

_log_memory(stage)
_log_rom_error(rom_forces)
_log_rom_solve(result)
_log_rom_state_error(solution_rom, solution_fom)
_moment_log_string(coefficients)
static _parameter_vector(shape_parameters, alpha)

The ROM snapshot parameter vector of an evaluation: the flat shape parameters (if any), then alpha.

_release_adjoint_cache()

Free what the adjoint of the last state keeps: the transposed matrices and KSP, the cached jacvec operators and the derived fields’ cached Jacobians.

_run_fom_solve()
_solve(parameter_vector)

The accepted flow solution of one evaluation: (owned solution entries, converged).

Without a reduced-order model this is the full-order (FOM) solve from the warm start. With one, the ROM is tried first (once it holds enough snapshots), from the warm start projected onto the basis, and its solution is accepted when eta = ||R||/||u|| < eta_threshold; the ROM then holds the adjoint of that solution (rom.adjoint), which apply_inverse_jacobian uses. Otherwise the FOM solves from the warm start exactly as without a ROM, and its solution, if converged and finite, becomes a snapshot at parameter_vector.

A re-evaluation of the design the FOM solved last skips the ROM: the FOM restarts from its own solution (no Newton steps if that converged), so the design keeps the FOM solution and the full-order adjoint. CSDL re-runs the model before every derivative evaluation, and by then the ROM would reproduce that solution, now a snapshot, and accept it.

_state_keys_equal(key0, key)
apply_inverse_jacobian(input_vals, outputs, d_outputs, d_residuals, mode)
compute_jacvec_product(input_vals, outputs, d_inputs, d_outputs, d_residuals, mode)
deform_mesh()

Mesh node motions (CSDL) for the shape parameterization’s current wall displacement: the first input of evaluate(). Call after the shape design variables are declared.

evaluate(mesh_node_motions: csdl_alpha.Variable = None, shape_parameters: csdl_alpha.Variable = None, alpha: csdl_alpha.Variable = None)

The flow state u_vec as a CSDL output.

Shape optimization (a shape parameterization was given): evaluate(mesh_node_motions, shape_parameters, alpha), with mesh_node_motions from deform_mesh() and shape_parameters the flat shape parameter vector. Forward analysis on the fixed mesh: evaluate(alpha=alpha). alpha is always required.

set_adjoint_options(cell_centre_matrix=False, cache_jacobians=False, structured_gradient=False, matrix_free=False, cache_jacvec_operators=False)

Switch the speed-ups of the adjoint of a model with a condensed Jacobian (all exact reformulations; each off by default). Frees every cache.

cell_centre_matrix build the constant cell-centre matrix dc/dx vectorized, once cache_jacobians keep the Green-Gauss Jacobians dG/dU, dG/dalpha, dG/dx

while the state, alpha and the mesh are unchanged

structured_gradient apply dG/dU as W (x) I plus a boundary part instead of an

assembled matrix

matrix_free the adjoint operator without forming A or A_UG B cache_jacvec_operators build the dR/dx operator and dR/dalpha once per design

set_up_sim()
solve_forward(alpha=None, snapshot=True)

One flow solve on the current (undeformed) mesh, without CSDL: set alpha (radians; default: the boundary dictionary’s), solve, print the coefficients. Warm-starts from the previous solve. Call set_up_sim() first. Returns (u_vec array, converged, forces), forces being DG_postprocessor.forces_and_coefficients (L, D, c_l, c_d, the moments, and the friction drag for a viscous model).

The ROM (if any) stores the solve as a snapshot at the parameter vector (alpha). With shape parameters that vector is longer, so a solve for a baseline that is not a design of the optimization passes snapshot=False.

solve_residual_equations(input_vals, output_vals)
wall_geometry()

Geometric constraint quantities of the FFD-deformed wall (area/volume, thickness, planform); the shape parameterization’s shape_parameterization.WallGeometry.

Built on first use. Collective: call it on every rank.

FARFIELD_TAG = 6
SYMMETRY_TAG = 5
WALL_TAG = 2
_adjoint_cache = None
_adjoint_row = (None, 0)
_dRdalpha_cache = None
_dRdx_cache = None
_fom_design = None
_last_first_order_guess = None
_last_written_design = None
adjoint_first_order_guess = False
adjoint_ksp_options = None
adjoint_matrix_free = False
asm_overlap = None
boundary_condition_dict
cache_jacvec_operators = False
compute_all_adjoint_errors = False
data_store
euler_residual_conv_limit = 1e-09
eval_idx = 0
property ffd

The shape parameterization’s FFD block (None without one, or before set_up_sim).

filename_suffix = 'test'
first_order_adjoint_rtol = 0.01
gamma: float = 1.4
ilu_levels = None
linear_residual_accept_limit = 1e-10
linear_solver_atol = 1e-11
linear_solver_max_it = 1000
linear_solver_rtol = 1e-20
max_newton_iterations = 100
mesh
mesh_node_match_tol = 1e-10
mesh_warper = None
moments = None
ordered_callbacks = True
poly_order: int = 1
previous_solution = None
reduced_order_model = None
release_solver_memory = False
shape_parameterization = None
shape_parameterized
write_mesh_deformation = True
write_once_per_design = False