6. Adjoint Gradients#
6.1. Shape Gradients#
- st_shape_adjoint_gradient(x, y, cost, bc, grads)#
Compute the shape gradient of a given cost functional.
The constrained optimization problem we are looking at is
\[\begin{split}\begin{cases} \min \mathcal{J}(\mathbf{X}), \\ \text{subject to the Stokes equations.} \end{cases}\end{split}\]This function computes the shape gradient for such a setup. However, most of the information is given by the user, while we just compute all the necessary forward and adjoint variables. The user must provide the cost functional in cost and all the boundary conditions and problem parameters in bc (directly passed to
st_repr_density_solution()).- Parameters:
x – target geometry struct.
y – source geometry struct.
cost – cost functional information. This is mainly used to construct all the necessary solutions.
bc – boundary conditions and parameters.
grads – a sum of all the gradients around gathered using
st_gradient_combine()or equivalent. If
- Returns:
the adjoint-based shape gradient of the cost functional.
- st_shape_finite_gradient(cost, x0, y0, bc, verbose)#
Compute the finite difference gradient of a cost functional.
This function computes:
\[\nabla \mathcal{J} \cdot \mathbf{h}_i \approx \frac{1}{\epsilon} (\mathcal{J}(\mathbf{X} + \epsilon \mathbf{h}_i) - \mathcal{J}(\mathbf{X}))\]where \(\mathbf{h}_i \equiv h_i \mathbf{n}\) and \(h_i\) is a bump function.
The cost argument should be a struct containing information about the cost functional evaluation procedure, as described in
st_shape_adjoint_gradient(). On top of that, it also requires the fieldseps (default
1.0e-7): finite difference step size.bump(x, y, i): a function handle that computes the bump \(h_i\) at the target position
i, see for examplest_shape_finite_bump().
- Parameters:
cost – cost functional information.
x0 – target point information.
y0 – source point information.
bc – boundary conditions for the Stokes problem.
verbose (default
false) – print debug information.
- Returns:
a tuple
(gradJ, st), wheregradJis a vector of sizentargetsandstcontains the Stokes solution on the unperturbed mesh.
- st_shape_finite_bump(cost, x, y, f)#
Smooth bump function for finite differencing shapes.
The bump function we use is a modulated exponential. The exact parameters can be attached to the cost struct. Namely, we have
bump_type: can be
'x'or'xi', so the bump is parametrized by the physical coordinates or the computational domain coordinates, respectively.sigma: gives the variance of the exponential. If not provided, a default is computed using
st_shape_finite_bump_sigma().
- Parameters:
cost – struct containing information about the bump function.
x – target geometry information.
y – source geometry information.
f – if it is a single integer, the bump function is evaluated at that target point. If it is an array, then it is convoluted with the bump function.
- st_shape_finite_bump_sigma(cost, x, y)#
Compute a grid-dependent spread of the bump function.
Meant as a companion to
st_shape_finite_bump()to ensure that the bump is sufficiently spread out for the interpolation to work. In particular, if the bump is too thin, it will resemble a delta function and give bad results.- Parameters:
cost – struct containing information about the bump function.
x – target point information.
y – source point information.
- Returns:
spread \(\sigma\).
6.2. Unsteady Gradients#
- st_ode_unsteady_adjoint(xf, yf, bc, forcing, cost, checkpoint, varargin)#
Solve adjoint system.
This function is a companion to
st_ode_unsteady()and takes very similar inputs.- Parameters:
xf – final target point information.
yf – final source point information.
bc – boundary conditions for the forward problem used to compute variables required in the adjoint gradient. They should follow the interface defined by
st_boundary_condition_options().forcing – source term for the forward problem. It should follow the interface defined by
st_forcing_options().cost – cost function information. It should follow the interface defined by
st_cost_options().fw – forward state information, as returned by
st_ode_unsteady(). This is mainly used to retrieve the appropriate checkpoints.checkpoint – a cache created using
st_cache_create(). This is used to save the adjoint solution.varargin – any additional time stepper ode that are passed in to
st_ode_options().
- Returns:
adjoint-based gradient.
6.3. Interface Operators#
- st_ops_mass(x, y, sigma)#
Construct the mass operator for the given geometry.
This function computes the mass operator
\[M_{ij} = \int_\Gamma \sigma \phi_i \phi_j \,\rho \mathrm{d}s,\]where \(\phi_i\) are the Lagrange polynomial basis functions.
- Parameters:
x – target geometry struct, as returned by
st_mesh_geometry().y – source geometry struct, as returned by
st_mesh_geometry().sigma – additional weight function.
- Returns:
the operator
Mas described above.
- st_ops_adjoint_normal(x, y, sigma)#
Construct the adjoint operator of the linearized normal vector.
Consider the shape derivative of the normal vector, as given in Lemma 5.5 in [Walker2015], and its corresponding adjoint operator defined by the relation
\[\int_\Sigma \mathbf{X}^* \cdot \mathbf{n}'[\mathbf{V}] \,\mathrm{d}S = \int_\Sigma n^*[\mathbf{X}^*] \mathbf{n} \cdot \mathbf{V} \,\mathrm{d}S.\]This function discretizes a parametrized version
\[g_{out} n^*[g_{in} X^*]\]of the operator. This allows building up the full operator for multiple cases, including the one above, which is built in
st_ops_adjoint_vector_normal().- Parameters:
x – target geometry struct, as returned by
st_mesh_geometry().y – source geometry struct, as returned by
st_mesh_geometry().sigma – coefficients evaluated at target points. This can be a struct containing the fields
g_in,g_outanddg_out, all of which are optional and default to \(1\).
- Returns:
the operator
Nas described above.
- st_ops_adjoint_curvature(x, y, sigma)#
Construct the adjoint operator of the linearized mean curvature.
See
st_ops_adjoint_normal()for some details on how the operators were derived.- Parameters:
x – target geometry struct, as returned by
st_mesh_geometry().y – source geometry struct, as returned by
st_mesh_geometry().sigma – coefficients evaluated at the target points. As for
st_ops_adjoint_normal(), this can be a struct containing the fieldsg_in,dg_in,g_outanddg_out, all of which are optional and default to \(1\).
- Returns:
the operators
(KX, KP), which are the adjoint operators of the first and second principal curvatures.
- st_ops_vector_mass(x, y, sigma)#
Construct a vector mass operator.
- Parameters:
x – target geometry struct, as returned by
st_mesh_geometry().y – source geometry struct, as returned by
st_mesh_geometry().sigma – weight.
- Returns:
the mass operator
M.
- st_ops_adjoint_vector_normal(x, y, sigma)#
Construct the adjoint normal vector operator.
This function builds the default adjoint normal vector operator, as described in
st_ops_adjoint_normal(). The operator is related to its scalar version implemented inst_ops_adjoint_normal()by\[\mathbf{n}^*[\mathbf{X}^*] = n^*[\mathbf{X}^* \cdot \mathbf{s}] \mathbf{n}\]The returned operator is block \(2 \times 2\). To apply it to a vector expressed as a complex array, we can do
w = st_array_stack(v); Nv = st_array_unstack(N * w);
- Parameters:
x – target geometry struct, as returned by
st_mesh_geometry().y – source geometry struct, as returned by
st_mesh_geometry().sigma – coefficient multiplying \(\mathbf{X}^*\)
- Returns:
the operator
Nas described above.
- st_ops_adjoint_vector_curvature(x, y, sigma)#
Construct the adjoint curvature vector operator.
The adjoint vector curvature operator is related to its scalar version implemented in
st_ops_adjoint_curvature()by\[\mathbf{k}^*[\mathbf{X}^*] = k^*[\mathbf{X}^* \cdot \mathbf{s}] \mathbf{n}\]as is the case for
st_ops_adjoint_vector_normal().- Parameters:
x – target geometry struct, as returned by
st_mesh_geometry().y – source geometry struct, as returned by
st_mesh_geometry().sigma – coefficient multiplying \(\mathbf{X}^*\)
- Returns:
the operator
KXandKPcorresponding to the first and second principal curvatures.
- st_ops_boundary(x, A, b, boundary_type, bc)#
Modify operator and right-hand side for boundary conditions
- Parameters:
A – matrix operator.
b – right-hand side vector.
boundary_type – type of the boundary: none, dirichlet or neumann.
bc – array with two values for the left and right boundary conditions.
- Returns:
a tuple
(A, b)with the modified matrix and right-hand side vector.
- st_ops_solve(x, A, b, boundary_type, bc, method)#
Solve a linear system.
- Parameters:
x – target point information, as obtained from
st_point_collocation().A – matrix operator.
b – right-hand side vector.
boundary_type – see
st_ops_boundary().bc – see
st_ops_boundary().
- st_ops_vector_solve(x, M, A, b, boundary_type)#
Solve a generalized system of equations.
This problem solves for \(y\) in
\[M y = A b\]where \(M\) is a block diagonal mass matrix, with each block being the scalar mass matrix obtained from
st_ops_mass(). The vectors \(y\) and \(b\) are passed as complex arrays, which can be stacked appropriately to give matching sizes in the above equation.- Parameters:
x – target point information.
M – scalar mass matrix.
A – vector operator.
b – right-hand side vector (complex array).
boundary_type – type of the boundary condition, see
st_ops_boundary().
- Returns:
a complex array that is the solution to the above system.