Go to the documentation of this file.
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"
90 void assemble_A_and_F();
175 std::unique_ptr<FEBase> fe (FEBase::build(
dim, fe_type));
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;
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()))
265 lambda_rank = sys.
comm().rank();
269 sys.
comm().sum(lambda_rank);
270 sys.
comm().broadcast(lambda_rank, lambda_rank);
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);
396 int 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 System subclass enables us to assemble an objective function, gradient, Hessian and bounds for o...
virtual void close()=0
Calls the SparseMatrix's internal assembly routines, ensuring that the values are consistent across p...
std::unique_ptr< NumericVector< Number > > C_ineq
The vector that stores inequality constraints.
virtual void zero()=0
Set all entries to zero.
SolverPackage
Defines an enum for various linear solver packages.
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.
virtual void add(const numeric_index_type i, const T value)=0
Adds value to each entry of the vector.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
virtual void gradient(const NumericVector< Number > &soln, NumericVector< Number > &grad_f, OptimizationSystem &)
Evaluate the gradient.
virtual System & add_system(const std::string &system_type, const std::string &name)
Add the system of type system_type named name to the systems array.
This class implements specific orders of Gauss quadrature.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
AssembleOptimization(OptimizationSystem &sys_in)
Constructor.
Abstract base class to be used to calculate the Jacobian of the inequality constraints.
OptimizationSystem & _sys
Keep a reference to the OptimizationSystem.
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
virtual void solve() override
Solves the optimization problem.
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 numeric_index_type last_local_index() const =0
The libMesh namespace provides an interface to certain functionality in the library.
Abstract base class to be used to calculate the inequality constraints.
virtual void lower_and_upper_bounds(OptimizationSystem &sys)
Evaluate the lower and upper bounds vectors.
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
SparseMatrix< Number > & add_matrix(const std::string &mat_name)
Adds the additional matrix mat_name to this system.
virtual void init(const numeric_index_type n, const numeric_index_type n_local, const bool fast=false, const ParallelType ptype=AUTOMATIC)=0
Change the dimension of the vector to n.
This class encapsulate all functionality required for assembling the objective function,...
virtual void inequality_constraints(const NumericVector< Number > &X, NumericVector< Number > &C_ineq, OptimizationSystem &)
Evaluate the inequality constraints.
const Parallel::Communicator & comm() const
Abstract base class to be used to calculate the Hessian of an objective function.
unsigned int mesh_dimension() const
dof_id_type first_dof(const processor_id_type proc) const
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
std::unique_ptr< NumericVector< Number > > lambda_ineq
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
virtual numeric_index_type size() const =0
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
virtual void inequality_constraints_jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &C_ineq_jac, OptimizationSystem &)
Evaluate the inequality constraints Jacobian.
std::unique_ptr< NumericVector< Number > > C_eq
The vector that stores equality constraints.
NumericVector< Number > * F_vector
Vector for storing F.
Abstract base class to be used to calculate the equality constraints.
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].
This is the MeshBase class.
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 hessian(const NumericVector< Number > &soln, SparseMatrix< Number > &H_f, OptimizationSystem &)
Evaluate the Hessian.
This base class can be inherited from to provide interfaces to optimization solvers from different pa...
Abstract base class to be used to calculate the lower and upper bounds for all dofs in the system.
void assemble_A_and_F()
The optimization problem we consider here is: min_U 0.5*U^T A U - U^T F.
const MeshBase & get_mesh() const
Abstract base class to be used to calculate the Jacobian of the equality constraints.
std::unique_ptr< OptimizationSolver< Number > > optimization_solver
The OptimizationSolver that is used for performing the optimization.
unsigned int add_variable(const std::string &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.
virtual void init()
Initialize all the systems.
SparseMatrix< Number > * matrix
The system matrix.
const FEType & variable_type(const unsigned int c) const
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Abstract base class to be used to calculate the objective function for optimization.
Abstract base class to be used to calculate the gradient of an objective function.
virtual void add(const numeric_index_type i, const numeric_index_type j, const T value)=0
Add value to the element (i,j).
void print_info(std::ostream &os=libMesh::out) const
Prints information about the equation systems, by default to libMesh::out.
This is the EquationSystems class.
virtual void write_equation_systems(const std::string &, const EquationSystems &, const std::set< std::string > *system_names=nullptr)
This method implements writing a mesh with data to a specified file where the data is taken from the ...
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.
void resize(const unsigned int n)
Resize the vector.
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.
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
int main(int argc, char **argv)
virtual void equality_constraints(const NumericVector< Number > &X, NumericVector< Number > &C_eq, OptimizationSystem &)
Evaluate the equality constraints.
virtual void set(const numeric_index_type i, const T value)=0
Sets v(i) = value.
This class handles the numbering of degrees of freedom on a mesh.
void print_info(std::ostream &os=libMesh::out) const
Prints relevant information about the mesh.
virtual Number objective(const NumericVector< Number > &soln, OptimizationSystem &)
Evaluate the objective function.
unsigned short int variable_number(const std::string &var) const
SparseMatrix< Number > * A_matrix
Sparse matrix for storing the matrix A.
NumericVector< Number > & add_vector(const std::string &vec_name, const bool projections=true, const ParallelType type=PARALLEL)
Adds the additional vector vec_name to this system.
const DofMap & get_dof_map() const
virtual void equality_constraints_jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &C_eq_jac, OptimizationSystem &)
Evaluate the equality constraints Jacobian.
virtual void set(const numeric_index_type i, const numeric_index_type j, const T value)=0
Set the element (i,j) to value.
Order default_quadrature_order() const
const SparseMatrix< Number > & get_matrix(const std::string &mat_name) const
const NumericVector< Number > & get_vector(const std::string &vec_name) const
virtual void zero()=0
Set all entries to 0.
virtual std::unique_ptr< NumericVector< T > > zero_clone() const =0
virtual T dot(const NumericVector< T > &v) const =0
dof_id_type end_dof(const processor_id_type proc) const
virtual numeric_index_type first_local_index() const =0