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