UserSolver¶
-
class
kona.user.
UserSolver
(num_design, num_state=0, num_eq=0, num_ineq=0)[source]¶ Bases:
object
Base class for Kona objective functions, designed to be a template for any objective functions intended to be used for
kona.Optimize()
.This class provides some standard mathematical functionality via NumPy arrays and operators. However, attributes of the derived classes can have different data types. In these cases, the user must redefine the mathematical operation methods for these non-standard data types.
This solver wrapper is not initialized by Kona. The user must initialize it before handing it over to Kona’s optimizer. Therefore the intialization implementation details are left up to the user entirely. Below is just an example used by Kona’s own test problems.
Parameters: - num_design (int) – Design space size
- num_state (int, optional) – State space size.
- num_eq (int, optional) – Number of equality constraints
- num_ineq (int, optional) – Number of inequality constraints
Variables: - num_design (int) – Size of the design space
- num_state (int) – Number of state variables
- num_eq (int) – Number of equality constraints
- num_ineq (int) – Number of inequality constraints
-
allocate_state
(num_vecs)[source]¶ Allocate the requested number of state-space BaseVectors and return them in a plain array.
Parameters: num_vecs (int) – Number of state vectors requested. Returns: Stack of BaseVectors in the state space Return type: list of BaseVector
-
apply_precond
(at_design, at_state, in_vec, out_vec)[source]¶ Apply the preconditioner to the vector at
in_vec
and store the result inout_vec
. If the preconditioner is nonlinear, evaluate the application using the design and state vectors provided inat_design
andat_state
.Note
If the solver uses
factor_linear_system()
, ignore the (design, state) evaluation point and use the previously factored preconditioner.Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
- in_vec (BaseVector) – Vector to be operated on.
- out_vec (BaseVector) – Location where user should store the result.
Returns: Number of preconditioner calls required for the operation.
Return type: int
-
apply_precond_T
(at_design, at_state, in_vec, out_vec)[source]¶ Apply the transposed preconditioner to the vector at
in_vec
and store the result inout_vec
. If the preconditioner is nonlinear, evaluate the application using the design and state vectors provided inat_design
andat_state
.Note
If the solver uses
factor_linear_system()
, ignore the (design, state) evaluation point and use the previously factored preconditioner.Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
- in_vec (BaseVector) – Vector to be operated on.
- out_vec (BaseVector) – Location where user should store the result.
Returns: Number of preconditioner calls required for the operation.
Return type: int
-
current_solution
(num_iter, curr_design, curr_state, curr_adj, curr_eq, curr_ineq, curr_slack)[source]¶ Kona will evaluate this method at every outer/nonlinear optimization iteration. It can be used to print out useful information to monitor the process, or to save design points of the intermediate iterations.
The current design vector, current state vector and current adjoint vector have been made available to the user via the arguments.
Parameters: - num_iter (int) – Current outer/nonlinear iteration number.
- curr_design (numpy.ndarray) – Current design point.
- curr_state (BaseVector) – Current state variables.
- curr_adj (BaseVector) – Currently adjoint variables for the Lagrangian.
- curr_eq (numpy.ndarray) – Current Lagrange multipliers for equality constraints.
- curr_ineq (numpy.ndarray) – Current Lagrange multipliers for inequality constraints.
- curr_slack (numpy.ndarray) – Current slack variables associated with inequality constraints.
Returns: A string that that Kona will write into its info file.
Return type: string, optional
-
eval_dFdU
(at_design, at_state, store_here)[source]¶ Evaluate the partial of the objective w.r.t. state variable at the design point stored in
at_design
and the state variables stored inat_state
. Store the result instore_here
.Note
If there are no state variables, a zero vector must be stored.
Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
- store_here (BaseVector) – Location where user should store the result.
-
eval_dFdX
(at_design, at_state)[source]¶ Evaluate the partial of the objective w.r.t. design variables at the design point stored in
at_design
and the state variables stored inat_state
. Store the result instore_here
.Note
This method must be implemented for any problem type.
Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
Returns: Gradient vector.
Return type: numpy.ndarray
-
eval_eq_cnstr
(at_design, at_state)[source]¶ Evaluate the vector of equality constraints using the given design and state vectors.
The constraints must have the form (c - c_target). In other words, the constraint value should be zero at feasibility.
- For inequality constraints, the constraint value should be greater than zero when feasible.
Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
Returns: result – Array of equality constraints.
Return type: numpy.ndarray
-
eval_ineq_cnstr
(at_design, at_state)[source]¶ Evaluate the vector of inequality constraints using the given design and state vectors.
The constraints must have the form (c - c_target) > 0. In other words, the constraint value should be greater than zero when feasible.
Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
Returns: result – Array of equality constraints.
Return type: numpy.ndarray
-
eval_obj
(at_design, at_state)[source]¶ Evaluate the objective function using the design variables stored at
at_design
and the state variables stored atat_state
.Note
This method must be implemented for any problem type.
Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
Returns: Result of the operation. Contains the objective value as the first element, and the number of preconditioner calls used as the second.
Return type: tuple
-
eval_residual
(at_design, at_state, store_here)[source]¶ Evaluate the governing equations (discretized PDE residual) at the design variables stored in
at_design
and the state variables stored inat_state
. Put the residual vector instore_here
.Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
- result (BaseVector) – Location where user should store the result.
-
factor_linear_system
(at_design, at_state)[source]¶ OPTIONAL: Build/factor the dR/dU matrix and its preconditioner at the given design and state vectors,
at_design
andat_state
. These matrices are then used to perform forward solves, adjoint solves and forward/transpose preconditioner applications.This routine is only used by matrix-based solvers where matrix factorizations are costly and should be done only once per optimization iteration. The optimization options dictionary must have the
matrix_explicit
key set toTrue
.Note
If the user chooses to leverage this factorization, the (design, state) evaluation points should be ignored for preconditioner application, linear solve, and adjoint solve calls.
Parameters: - at_design (numpy.ndarray) – Current design vector.
- at_state (BaseVector) – Current state vector.
-
init_design
()[source]¶ Initialize the first design point. Store the design vector at
store_here
. The optimization will start from this point.Note
This method must be implemented for any problem type.
Returns: Initial design vector. Return type: numpy.ndarray
-
multiply_dCEQdU
(at_design, at_state, in_vec)[source]¶ Evaluate the matrix-vector product for the state-jacobian of the equality constraints. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]rac{partial C_{eq}(at_design, at_state)}{partial U} in_vec = out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : BaseVector
- Vector to be operated on.
- numpy.ndarray
- Result of the product
-
multiply_dCEQdU_T
(at_design, at_state, in_vec, out_vec)[source]¶ Evaluate the transposed matrix-vector product for the state-jacobian of the equality constraints. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]- rac{partial C_{eq}(at_design, at_state)}{partial U}^T in_vec =
- out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : numpy.ndarray
- Vector to be operated on.
- out_vec : BaseVector
- Location where user should store the result.
-
multiply_dCEQdX
(at_design, at_state, in_vec)[source]¶ Evaluate the matrix-vector product for the design-jacobian of the equality constraints. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]rac{partial C_{eq}(at_design, at_state)}{partial X} in_vec = out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : numpy.ndarray
- Vector to be operated on.
- numpy.ndarray
- Result of the product.
-
multiply_dCEQdX_T
(at_design, at_state, in_vec)[source]¶ Evaluate the transposed matrix-vector product for the design-jacobian of the equality constraints. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]- rac{partial C_{eq}(at_design, at_state)}{partial X}^T in_vec =
- out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : numpy.ndarray
- Vector to be operated on.
- numpy.ndarray
- Result of the product.
-
multiply_dCINdU
(at_design, at_state, in_vec)[source]¶ Evaluate the matrix-vector product for the state-jacobian of the inequality constraints. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]rac{partial C_{eq}(at_design, at_state)}{partial U} in_vec = out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : BaseVector
- Vector to be operated on.
- numpy.ndarray
- Result of the product
-
multiply_dCINdU_T
(at_design, at_state, in_vec, out_vec)[source]¶ Evaluate the transposed matrix-vector product for the state-jacobian of the inequality constraints. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]- rac{partial C_{ineq}(at_design, at_state)}{partial U}^T in_vec =
- out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : numpy.ndarray
- Vector to be operated on.
- out_vec : BaseVector
- Location where user should store the result.
-
multiply_dCINdX
(at_design, at_state, in_vec)[source]¶ Evaluate the matrix-vector product for the design-jacobian of the inequality constraints. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]rac{partial C_{ineq}(at_design, at_state)}{partial X} in_vec = out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : numpy.ndarray
- Vector to be operated on.
- numpy.ndarray
- Result of the product.
-
multiply_dCINdX_T
(at_design, at_state, in_vec)[source]¶ Evaluate the transposed matrix-vector product for the design-jacobian of the inequality constraints. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]- rac{partial C_{ineq}(at_design, at_state)}{partial X}^T in_vec =
- out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : numpy.ndarray
- Vector to be operated on.
- numpy.ndarray
- Result of the product.
-
multiply_dRdU
(at_design, at_state, in_vec, out_vec)[source]¶ Evaluate the matrix-vector product for the state-jacobian of the PDE residual. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]rac{partial R(at_design, at_state)}{partial U} in_vec = out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : BaseVector
- Vector to be operated on.
- out_vec : BaseVector
- Location where user should store the result.
-
multiply_dRdU_T
(at_design, at_state, in_vec, out_vec)[source]¶ Evaluate the transposed matrix-vector product for the state-jacobian of the PDE residual. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]- rac{partial R(at_design, at_state)}{partial U}^T in_vec =
- out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : BaseVector
- Vector to be operated on.
- out_vec : BaseVector
- Location where user should store the result.
-
multiply_dRdX
(at_design, at_state, in_vec, out_vec)[source]¶ Evaluate the matrix-vector product for the design-jacobian of the PDE residual. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]rac{partial R(at_design, at_state)}{partial X} in_vec = out_vec
Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : numpy.ndarray
- Vector to be operated on.
- out_vec : BaseVector
- Location where user should store the result.
-
multiply_dRdX_T
(at_design, at_state, in_vec)[source]¶ Evaluate the transposed matrix-vector product for the design-jacobian of the PDE residual. The multiplying vector is
in_vec
and the result should be stored inout_vec
. The product should be evaluated at the given design and state vectors,at_design
andat_state
respectively.\[\]- rac{partial R(at_design, at_state)}{partial X}^T in_vec =
- out_vec
Note
Must always store a result even when it isn’t implemented. Use a zero vector of length
self.num_design
for this purpose.Note
This jacobian is a partial. No total derivatives, gradients or jacobians should be evaluated by any UserSolver implementation.
- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector
- Current state vector.
- in_vec : BaseVector
- Vector to be operated on.
- numpy.ndarray
- Result of the operation
-
solve_adjoint
(at_design, at_state, rhs_vec, tol, result)[source]¶ Solve the linear system defined by the transposed state-jacobian of the PDE residual, to the specified absolute tolerance
tol
.\[\]- rac{partial R(at_design, at_state)}{partial U}^T result =
- rhs_vec
The jacobian should be evaluated at the given (design, state) point,
at_design
andat_state
.Store the solution in
result
.Note
If the solver uses
factor_linear_system()
, ignore theat_design
evaluation point and use the previously factored preconditioner.- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector-line
- Current state vector.
- rhs_vec : BaseVector
- Right hand side vector.
- rel_tol : float
- Tolerance that the linear system should be solved to.
- result : BaseVector
- Location where user should store the result.
- int
- Number of preconditioner calls required for the solution.
-
solve_linear
(at_design, at_state, rhs_vec, rel_tol, result)[source]¶ Solve the linear system defined by the state-jacobian of the PDE residual, to the specified absolute tolerance
tol
.\[\]rac{partial R(at_design, at_state)}{partial U} result = rhs_vec
The jacobian should be evaluated at the given (design, state) point,
at_design
andat_state
.Store the solution in
result
.Note
If the solver uses
factor_linear_system()
, ignore theat_design
evaluation point and use the previously factored preconditioner.- at_design : numpy.ndarray
- Current design vector.
- at_state : BaseVector-line
- Current state vector.
- rhs_vec : BaseVector
- Right hand side vector.
- rel_tol : float
- Tolerance that the linear system should be solved to.
- result : BaseVector
- Location where user should store the result.
- int
- Number of preconditioner calls required for the solution.
-
solve_nonlinear
(at_design, result)[source]¶ Compute the state variables at the given design point,
at_design
. Store the resulting state variables inresult
.For linear problems, this can be a simple linear system solution:
\[\mathcal{K}(x)\mathbf{u} = \mathbf{F}(x)\]For nonlinear problems, this can involve Newton iterations:
\[\]- rac{partial R(x, u_{guess})}{partual u} Delta u =
- -R(x, u_{guess})
If the solution fails to converge, the user should return a negative integer in order to help Kona intelligently backtrack in the optimization.
Similarly, in the case of correct convergence, the user is encouraged to return the number of preconditioner calls it took to solve the nonlinear system. Kona uses this information to track the computational cost of the optimization. If the number of preconditioner calls is not available, return a 1 (one).
- at_design : numpy.ndarray
- Current design vector.
- result : BaseVector
- Location where user should store the result.
- int
- Number of preconditioner calls required for the solution.