Neko-TOP
A portable framework for high-order spectral element flow toplogy optimization.
Loading...
Searching...
No Matches
Objectives and constraints

Neko-top allows the user to solve constrained optimization problems, often times but not limited to, topology optimization problems involving fluid mechanics.

Objectives and constraints enter the .case file in neko-top as lists

{
"version": 1.0
"case": {},
"optimization": {
"objectives": [],
"constraints": []
}
}

In neko-top multiple objectives can be prescribed in a list, resulting in a multi-objective optimization problem which is handled by a weighted sum of all prescribed objectives

\[ \mathcal{F} = \sum_i w_i \mathcal{F}_i, \]

where \(\mathcal{F}i\) is an objective value \(w_i\) is a prescribed weight.

Multiple constraints on the other hand are also entered in a list but are handled through the MMA functionality discussed in The Method of Moving Asymptotes (MMA).

The following objectives

  1. Viscous dissipation
  2. Brinkman dissipation
  3. Scalar mixing

and constraints

  1. Volume constraint

have currently been implemented in neko-topยท

Objectives

Time integration for unsteady objectives

For unsteady simulations, the instantaneous objective is averaged over time,

\[ \mathcal{F} = \frac{1}{|W|} \int_W f(t) \, dt, \]

where \(W\) is the objective's own time window and \(|W|\) its length. Averaging rather than integrating keeps the objective on the same scale as the instantaneous quantity it is built from.

The window can be restricted with the optional input parameters start_time and end_time. Their defaults are 0.0 and +\infty, so the full simulated horizon is used unless a smaller window is prescribed.

The objective is sampled once per completed timestep, and \(|W|\) is the total length of time actually sampled. A window is therefore truncated to the part of it that was simulated, and the reported number is the mean over what was simulated. In particular the average is normalised by the window, not by the length of the run, so a windowed objective does not change when the run is made longer: an objective windowed to \([2.5, 6.0]\) reports the same value whether the simulation stops at \(t = 6\) or continues to \(t = 20\).

A window that never overlaps the simulated interval accumulates nothing. The objective then reports zero and a warning is written to the log.

Warning
Setting end_time to exactly the simulation's own end_time is not the same as leaving it at its +\infty default. The adjoint forcing terms that objectives register are gated by source_term_t's time window, which compares against the simulation time without a tolerance, so the final step – where the accumulated time lands a few ULP above the prescribed end_time – silently loses its forcing and the sensitivity is wrong. Leave end_time unset unless a genuinely shorter window is wanted.

The window only applies to unsteady problems. A steady problem evaluates its objectives once, on the converged field, so start_time and end_time have no effect there.

The two paths agree wherever they are asking the same question. Once a problem has reached a steady state, an unsteady objective averaged over a window inside the converged part of the run reports what the steady path reports for the same problem: the field no longer changes, so its average over the window is its converged value. tests/unit/objectives/steady_unsteady_converged is exactly this check, and it holds to the iterative solvers' own round-off. Note that steady_simcomp freezes the fluid on convergence but not the scalar, so set scalar_coupled when a scalar objective is involved, or the objective may be evaluated on a scalar that has not settled.

They also agree trivially at the end of any run, converged or not: an unsteady objective windowed to the final timestep alone reports exactly what the steady path reports, because a one-sample average is the sample. Selecting that single step is easier than it looks. The time loop stops at the first step reaching the simulation's end_time, so unless end_time falls exactly on a step, the run overshoots it by up to one dt – with end_time \(0.0475\) and dt \(0.005\) it takes ten steps and finishes at \(t = 0.05\). A window whose start_time is the simulation's own end_time therefore captures precisely that last step and nothing before it. Keeping end_time off a step boundary also removes any dependence on which side of the comparison round-off in the accumulated time falls, which otherwise decides whether the run takes ten steps or eleven.

For example,

{
"type": "scalar_mixing",
"weight": 1.0,
"start_time": 2.5,
"end_time": 6.0
}

accumulates the scalar-mixing objective only over the interval \(2.5 \le t \le 6.0\), and reports its mean over that interval.

For the underlying adjoint formulation and how objective functions generate adjoint forcing terms, please refer to Adjoint sensitivity analysis.

Viscous dissipation

This objective is used to either minimize or maximize the viscous dissipation. It takes the form

\[ \mathcal{F} = \frac{1}{|\Omega_\text{obj}|}\int_{\Omega_\text{obj}} \frac{\mu}{2} |\nabla \mathbf{u}|^2 d\Omega, \]

where \(\mathbf{u}\) is the fluid velocity, \(\Omega_\text{obj}\) is the objective domain, \(\mu\) is the dynamic viscosity, and \(|\nabla \mathbf{u}|^2\) denotes the Frobenius norm of the velocity gradient. Here \(|\Omega_\text{obj}|\) denotes the volume of the objective domain.

The objective can be selected by prescribing "type": "viscous_dissipation" and has the following input parameters:

Name Description Admissible values Default value
weight The weight used in the objective. Real 1.0
mask_name The name of the point_zone indicating \(\Omega_\text{obj}\). String ""
name The name that will appear in objective_data.csv String Dissipation
start_time Start of the active time window for unsteady accumulation. Real 0.0
end_time End of the active time window for unsteady accumulation. Real +\infty

Brinkman dissipation

In the works of A. Gersborg-Hansen et al. (2005) an objective function of the form

\[ \mathcal{F} = \frac{1}{|\Omega_\text{obj}|}\int \frac{1}{2} \left[ \underset{I}{\nabla \mathbf{u} \cdot \left(\nabla \mathbf{u} + (\nabla \mathbf{u})^T \right)} + \underset{II}{\chi \mathbf{u} \cdot \mathbf{u} } \right] d\Omega, \]

where \(\mathbf{u}\) is the fluid velocity and \(\chi\) the Brinkman amplitude was used, claiming:

‍Term I is half of the part of the dissipation function that is associated with the in-plane components of the stretching tensor (cf. Currie (2003)), while term II is half the part associated with the out-of-plane components. The latter part arises from the parabolic velocity profile in the lubrication theory (2). From an optimization perspective, term II links the cost function directly to the two-dimensional velocity field.

Later works have argued that this second term can also be used to penalize intermediate values of the design indicator and promote binary designs. Hence, this second term is considered a "velocity penalty" in neko-top and takes the form

\[ \mathcal{F} = \frac{1}{|\Omega_\text{obj}|}\int_{\Omega_\text{obj}} \frac{1}{2} \chi \mathbf{u}^2 d\Omega. \]

The objective can be selected by prescribing "type": "brinkman_dissipation" and has the following input parameters:

Note
the naming convention of "brinkman_dissipation" comes from the original claim based on lubrication theory written by Gersborg-Hansen et al.
Name Description Admissible values Default value
weight The weight used in the objective. Real 1.0
mask_name The name of the point_zone indicating \(\Omega_\text{obj}\). String ""
name The name that will appear in objective_data.csv String Out of plane stresses
dealias_forcing If dealiasing should be applied to adjoint forcing term logical .true.
dealias_sensitivity If dealiasing should be applied to sensitivity contribution logical .true.
start_time Start of the active time window for unsteady accumulation. Real 0.0
end_time End of the active time window for unsteady accumulation. Real +\infty

Scalar mixing

This objective is used to either minimize or maximize the mixing of a passive scalar. It takes the form

\[ \mathcal{F} = \frac{1}{|\Omega_\text{obj}|}\int_{\Omega_\text{obj}} \frac{1}{2} (\phi - \phi_\text{ref})^2 d\Omega, \]

where \(\phi\) is the scalar field, \(\Omega_\text{obj}\) is the objective domain, \(|\Omega_\text{obj}|\) denotes the volume of the objective domain and \( \phi_\text{ref}\) is a target concentration.

The objective can be selected by prescribing "type": "scalar_mixing" and has the following input parameters:

Name Description Admissible values Default value
weight The weight used in the objective. Real 1.0
mask_name The name of the point_zone indicating \(\Omega_\text{obj}\). String ""
target_concentration \(\phi_\text{ref}\) in the above equation. Real 0.5
name The name that will appear in objective_data.csv String Scalar Mixing
start_time Start of the active time window for unsteady accumulation. Real 0.0
end_time End of the active time window for unsteady accumulation. Real +\infty

Constraints

Volume constraint

This constraint is used to constrain the volume of the design in the domain. It takes the form

\[ \mathcal{C} = \frac{1}{|\Omega_\text{opt}|}\int_{\Omega_\text{opt}} \rho d\Omega, \]

where \(\rho\) is the material indicator, \(\Omega_\text{opt}\) is the optimization domain and \(|\Omega_\text{opt}|\) denotes the volume of the optimization domain.

The constraint can be used to enforce either a minimum or maximum volume, i.e. \( \mathcal{C} > \mathcal{C}_\text{min} \) or \( \mathcal{C} < \mathcal{C}_\text{max} \).

Note
Currently the volume constraint can only be applied to the unfiltered material indicator function, but in the future we aim to allow it to be prescribed to intermediate stages of the mapping cascade.

The constraint can be selected by prescribing "type": "volume" and has the following input parameters:

Name Description Admissible values Default value
limit \( \mathcal{C}_\text{min} \) or \( \mathcal{C}_\text{max} \) in the above equation Real -
is_max Indicate whether a minimum or maximum volume constraint should be applied. .true. or .false. .false.
mask_name The name of the point_zone indicating \(\Omega_\text{obj}\). String ""
name The name that will appear in objective_data.csv String Volume constraint
mapping A potential to, for instance, compute the volume based on a filtered design. For more information please refer to Mapping cascade Json ""