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 in out_vec. If the preconditioner is nonlinear, evaluate the application using the design and state vectors provided in at_design and at_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 in out_vec. If the preconditioner is nonlinear, evaluate the application using the design and state vectors provided in at_design and at_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 in at_state. Store the result in store_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 in at_state. Store the result in store_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 at at_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 in at_state. Put the residual vector in store_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 and at_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 to True.

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.
get_rank()[source]

Rank of current process is needed purely for purposes of printing to screen

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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 in out_vec. The product should be evaluated at the given design and state vectors, at_design and at_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 and at_state.

Store the solution in result.

Note

If the solver uses factor_linear_system(), ignore the at_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 and at_state.

Store the solution in result.

Note

If the solver uses factor_linear_system(), ignore the at_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 in result.

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.