32#include "libmesh/libmesh.h"
33#include "libmesh/mesh.h"
34#include "libmesh/mesh_generation.h"
35#include "libmesh/exodusII_io.h"
36#include "libmesh/equation_systems.h"
37#include "libmesh/fe.h"
38#include "libmesh/quadrature_gauss.h"
39#include "libmesh/dof_map.h"
40#include "libmesh/sparse_matrix.h"
41#include "libmesh/numeric_vector.h"
42#include "libmesh/dense_matrix.h"
43#include "libmesh/dense_vector.h"
44#include "libmesh/elem.h"
45#include "libmesh/boundary_info.h"
46#include "libmesh/string_to_enum.h"
47#include "libmesh/getpot.h"
48#include "libmesh/zero_function.h"
49#include "libmesh/dirichlet_boundaries.h"
50#include "libmesh/optimization_system.h"
51#include "libmesh/optimization_solver.h"
52#include "libmesh/parallel.h"
177 fe->attach_quadrature_rule (&qrule);
179 const std::vector<Real> & JxW = fe->get_JxW();
180 const std::vector<std::vector<Real>> & phi = fe->get_phi();
181 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
183 std::vector<dof_id_type> dof_indices;
188 for (
const auto & elem :
mesh.active_local_element_ptr_range())
192 const unsigned int n_dofs = dof_indices.size();
196 Ke.
resize (n_dofs, n_dofs);
199 for (
unsigned int qp=0; qp<qrule.n_points(); qp++)
201 for (
unsigned int dof_i=0; dof_i<n_dofs; dof_i++)
203 for (
unsigned int dof_j=0; dof_j<n_dofs; dof_j++)
205 Ke(dof_i, dof_j) += JxW[qp] * (dphi[dof_j][qp]* dphi[dof_i][qp]);
207 Fe(dof_i) += JxW[qp] * phi[dof_i][qp];
222 std::unique_ptr<NumericVector<Number>> AxU = soln.
zero_clone();
225 Number UTxAxU = AxU->dot(soln);
229 return 0.5 * UTxAxU - UTxF;
259 Number lambda_ineq_0 = 0.;
260 unsigned int lambda_rank = 0;
261 if ((sys.
lambda_ineq->first_local_index() <= ineq_index) &&
262 (ineq_index < sys.lambda_ineq->last_local_index()))
273 H_f.
add(200, 200, 2. * lambda_ineq_0);
282 std::unique_ptr<NumericVector<Number>> X_localized =
287 std::vector<Number> constraint_values(3);
288 constraint_values[0] = (*X_localized)(17);
289 constraint_values[1] = (*X_localized)(23);
290 constraint_values[2] = (*X_localized)(98) + (*X_localized)(185);
292 for (std::size_t i=0; i<constraint_values.size(); i++)
295 C_eq.
set(i, constraint_values[i]);
304 std::vector<std::vector<Number>> constraint_jac_values(3);
305 std::vector<std::vector<dof_id_type>> constraint_jac_indices(3);
307 constraint_jac_values[0].resize(1);
308 constraint_jac_indices[0].resize(1);
309 constraint_jac_values[0][0] = 1.;
310 constraint_jac_indices[0][0] = 17;
312 constraint_jac_values[1].resize(1);
313 constraint_jac_indices[1].resize(1);
314 constraint_jac_values[1][0] = 1.;
315 constraint_jac_indices[1][0] = 23;
317 constraint_jac_values[2].resize(2);
318 constraint_jac_indices[2].resize(2);
319 constraint_jac_values[2][0] = 1.;
320 constraint_jac_values[2][1] = 1.;
321 constraint_jac_indices[2][0] = 98;
322 constraint_jac_indices[2][1] = 185;
324 for (std::size_t i=0; i<constraint_jac_values.size(); i++)
325 for (std::size_t j=0; j<constraint_jac_values[i].size(); j++)
326 if ((sys.
C_eq->first_local_index() <= i) &&
327 (i < sys.C_eq->last_local_index()))
329 dof_id_type col_index = constraint_jac_indices[i][j];
341 std::unique_ptr<NumericVector<Number>> X_localized =
346 std::vector<Number> constraint_values(1);
347 constraint_values[0] = (*X_localized)(200)*(*X_localized)(200) + (*X_localized)(201) - 5.;
349 for (std::size_t i=0; i<constraint_values.size(); i++)
351 C_ineq.
set(i, constraint_values[i]);
360 std::unique_ptr<NumericVector<Number>> X_localized =
365 std::vector<std::vector<Number>> constraint_jac_values(1);
366 std::vector<std::vector<dof_id_type>> constraint_jac_indices(1);
368 constraint_jac_values[0].resize(2);
369 constraint_jac_indices[0].resize(2);
370 constraint_jac_values[0][0] = 2.* (*X_localized)(200);
371 constraint_jac_values[0][1] = 1.;
372 constraint_jac_indices[0][0] = 200;
373 constraint_jac_indices[0][1] = 201;
375 for (std::size_t i=0; i<constraint_jac_values.size(); i++)
376 for (std::size_t j=0; j<constraint_jac_values[i].size(); j++)
377 if ((sys.
C_ineq->first_local_index() <= i) &&
378 (i < sys.
C_ineq->last_local_index()))
380 dof_id_type col_index = constraint_jac_indices[i][j];
382 C_ineq_jac.
set(i, col_index,
value);
396int main (
int argc,
char ** argv)
400#ifndef LIBMESH_HAVE_PETSC_TAO
402 libmesh_example_requires(
false,
"PETSc >= 3.5.0 with built-in TAO support");
404#elif LIBMESH_USE_COMPLEX_NUMBERS
409 libmesh_example_requires(
false,
"PETSc >= 3.5.0 with built-in TAO support & real-numbers only");
414 libmesh_example_requires(LIBMESH_DIM > 1,
"--disable-1D-only");
417 if (init.comm().size() != 1)
419 libMesh::out <<
"This example can currently only be run in serial." << std::endl;
423 GetPot infile(
"optimization_ex2.in");
424 const std::string approx_order = infile(
"approx_order",
"FIRST");
425 const std::string fe_family = infile(
"fe_family",
"LAGRANGE");
426 const unsigned int n_elem = infile(
"n_elem", 10);
446 const std::string optimization_solver_type = infile(
"optimization_solver_type",
448 SolverPackage sp = Utility::string_to_enum<SolverPackage>(optimization_solver_type);
449 std::unique_ptr<OptimizationSolver<Number>> new_solver =
462 Utility::string_to_enum<Order> (approx_order),
463 Utility::string_to_enum<FEFamily>(fe_family));
484 equation_systems.
init();
490 std::vector<std::set<numeric_index_type>> constraint_jac_sparsity;
491 std::set<numeric_index_type> sparsity_row;
492 sparsity_row.insert(17);
493 constraint_jac_sparsity.push_back(sparsity_row);
494 sparsity_row.clear();
496 sparsity_row.insert(23);
497 constraint_jac_sparsity.push_back(sparsity_row);
498 sparsity_row.clear();
500 sparsity_row.insert(98);
501 sparsity_row.insert(185);
502 constraint_jac_sparsity.push_back(sparsity_row);
508 std::vector<std::set<numeric_index_type>> constraint_jac_sparsity;
509 std::set<numeric_index_type> sparsity_row;
510 sparsity_row.insert(200);
511 sparsity_row.insert(201);
512 constraint_jac_sparsity.push_back(sparsity_row);
528 std::stringstream filename;
This class encapsulate all functionality required for assembling the objective function,...
virtual void hessian(const NumericVector< Number > &soln, SparseMatrix< Number > &H_f, OptimizationSystem &)
Evaluate the Hessian.
virtual void inequality_constraints(const NumericVector< Number > &X, NumericVector< Number > &C_ineq, OptimizationSystem &)
Evaluate the inequality constraints.
virtual void equality_constraints(const NumericVector< Number > &X, NumericVector< Number > &C_eq, OptimizationSystem &)
Evaluate the equality constraints.
virtual Number objective(const NumericVector< Number > &soln, OptimizationSystem &)
Evaluate the objective function.
virtual void inequality_constraints_jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &C_ineq_jac, OptimizationSystem &)
Evaluate the inequality constraints Jacobian.
NumericVector< Number > * F_vector
Vector for storing F.
OptimizationSystem & _sys
Keep a reference to the OptimizationSystem.
virtual void gradient(const NumericVector< Number > &soln, NumericVector< Number > &grad_f, OptimizationSystem &)
Evaluate the gradient.
virtual void gradient(const NumericVector< Number > &soln, NumericVector< Number > &grad_f, OptimizationSystem &)
Evaluate the gradient.
virtual void hessian(const NumericVector< Number > &soln, SparseMatrix< Number > &H_f, OptimizationSystem &)
Evaluate the Hessian.
virtual Number objective(const NumericVector< Number > &soln, OptimizationSystem &)
Evaluate the objective function.
virtual void lower_and_upper_bounds(OptimizationSystem &sys)
Evaluate the lower and upper bounds vectors.
AssembleOptimization(OptimizationSystem &sys_in)
Constructor.
void assemble_A_and_F()
The optimization problem we consider here is: min_U 0.5*U^T A U - U^T F.
virtual void equality_constraints_jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &C_eq_jac, OptimizationSystem &)
Evaluate the equality constraints Jacobian.
SparseMatrix< Number > * A_matrix
Sparse matrix for storing the matrix A.
processor_id_type rank() const
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
Defines a dense matrix for use in Finite Element-type computations.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
dof_id_type first_dof(const processor_id_type proc) const
dof_id_type end_dof(const processor_id_type proc) const
This class handles the numbering of degrees of freedom on a mesh.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
const FEType & variable_type(const unsigned int i) const
This is the EquationSystems class.
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
virtual void init()
Initialize all the systems.
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
virtual void write_equation_systems(const std::string &fname, const EquationSystems &es, const std::set< std::string > *system_names=nullptr) override
Writes out the solution for no specific time or timestep.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Order default_quadrature_order() const
const SparseMatrix< Number > & get_system_matrix() const
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
This is the MeshBase class.
unsigned int mesh_dimension() const
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
virtual void set(const numeric_index_type i, const T value)=0
Sets v(i) = value.
virtual numeric_index_type last_local_index() const =0
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual T dot(const NumericVector< T > &v) const =0
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
virtual void localize(std::vector< T > &v_local) const =0
Creates a copy of the global vector in the local vector v_local.
virtual void zero()=0
Set all entries to zero.
virtual numeric_index_type size() const =0
virtual std::unique_ptr< NumericVector< T > > zero_clone() const =0
virtual void add(const numeric_index_type i, const T value)=0
Adds value to the vector entry specified by i.
virtual numeric_index_type first_local_index() const =0
static std::unique_ptr< OptimizationSolver< T > > build(sys_type &s, const SolverPackage solver_package=libMesh::default_solver_package())
Builds an OptimizationSolver using the package specified by solver_package.
Abstract base class to be used to calculate the Jacobian of the equality constraints.
Abstract base class to be used to calculate the equality constraints.
Abstract base class to be used to calculate the gradient of an objective function.
Abstract base class to be used to calculate the Hessian of an objective function.
Abstract base class to be used to calculate the Jacobian of the inequality constraints.
Abstract base class to be used to calculate the inequality constraints.
Abstract base class to be used to calculate the lower and upper bounds for all dofs in the system.
Abstract base class to be used to calculate the objective function for optimization.
This System subclass enables us to assemble an objective function, gradient, Hessian and bounds for o...
std::unique_ptr< NumericVector< Number > > C_ineq
The vector that stores inequality constraints.
void initialize_equality_constraints_storage(const std::vector< std::set< numeric_index_type > > &constraint_jac_sparsity)
Initialize storage for the equality constraints, and the corresponding Jacobian.
std::unique_ptr< NumericVector< Number > > lambda_ineq
virtual void solve() override
Solves the optimization problem.
std::unique_ptr< NumericVector< Number > > C_eq
The vector that stores equality constraints.
void initialize_inequality_constraints_storage(const std::vector< std::set< numeric_index_type > > &constraint_jac_sparsity)
Initialize storage for the inequality constraints, as per initialize_equality_constraints_storage.
std::unique_ptr< OptimizationSolver< Number > > optimization_solver
The OptimizationSolver that is used for performing the optimization.
const Parallel::Communicator & comm() const
This class implements specific orders of Gauss quadrature.
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
void vector_mult(NumericVector< T > &dest, const NumericVector< T > &arg) const
Multiplies the matrix by the NumericVector arg and stores the result in NumericVector dest.
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
virtual void zero()=0
Set all entries to 0.
virtual void add(const numeric_index_type i, const numeric_index_type j, const T value)=0
Add value to the element (i,j).
virtual void set(const numeric_index_type i, const numeric_index_type j, const T value)=0
Set the element (i,j) to value.
SparseMatrix< Number > & add_matrix(std::string_view mat_name, ParallelType type=PARALLEL, MatrixBuildType mat_build_type=MatrixBuildType::AUTOMATIC)
Adds the additional matrix mat_name to this system.
const SparseMatrix< Number > & get_matrix(std::string_view mat_name) const
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
NumericVector< Number > & add_vector(std::string_view vec_name, const bool projections=true, const ParallelType type=PARALLEL)
Adds the additional vector vec_name to this system.
unsigned int variable_number(std::string_view var) const
const DofMap & get_dof_map() const
const NumericVector< Number > & get_vector(std::string_view vec_name) const
const MeshBase & get_mesh() const
The libMesh namespace provides an interface to certain functionality in the library.
SolverPackage
Defines an enum for various linear solver packages.