libMesh
Classes | Functions
optimization_ex2.C File Reference

Go to the source code of this file.

Classes

class  AssembleOptimization
 This class encapsulate all functionality required for assembling the objective function, gradient, and hessian. More...
 

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 396 of file optimization_ex2.C.

References AssembleOptimization::A_matrix, libMesh::System::add_matrix(), libMesh::EquationSystems::add_system(), libMesh::System::add_variable(), libMesh::System::add_vector(), AssembleOptimization::assemble_A_and_F(), libMesh::MeshTools::Generation::build_square(), libMesh::SparseMatrix< T >::close(), AssembleOptimization::F_vector, libMesh::System::get_matrix(), libMesh::ImplicitSystem::get_system_matrix(), libMesh::System::get_vector(), libMesh::TriangleWrapper::init(), libMesh::EquationSystems::init(), libMesh::OptimizationSystem::initialize_equality_constraints_storage(), libMesh::OptimizationSystem::initialize_inequality_constraints_storage(), mesh, libMesh::MeshTools::n_elem(), libMesh::OptimizationSystem::optimization_solver, libMesh::out, libMesh::EquationSystems::print_info(), libMesh::MeshBase::print_info(), libMesh::QUAD9, libMesh::OptimizationSystem::solve(), and libMesh::ExodusII_IO::write_equation_systems().

397 {
398  LibMeshInit init (argc, argv);
399 
400 #ifndef LIBMESH_HAVE_PETSC_TAO
401 
402  libmesh_example_requires(false, "PETSc >= 3.5.0 with built-in TAO support");
403 
404 #elif LIBMESH_USE_COMPLEX_NUMBERS
405 
406  // According to
407  // http://www.mcs.anl.gov/research/projects/tao/documentation/installation.html
408  // TAO & PETSc-complex are currently mutually exclusive
409  libmesh_example_requires(false, "PETSc >= 3.5.0 with built-in TAO support & real-numbers only");
410 
411 #endif
412 
413  // We use a 2D domain.
414  libmesh_example_requires(LIBMESH_DIM > 1, "--disable-1D-only");
415 
416  // TAO is giving us problems in parallel?
417  if (init.comm().size() != 1)
418  {
419  libMesh::out << "This example can currently only be run in serial." << std::endl;
420  return 77;
421  }
422 
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);
427 
428  Mesh mesh(init.comm());
430  n_elem,
431  n_elem,
432  -1., 1.,
433  -1., 1.,
434  QUAD9);
435 
436  mesh.print_info();
437 
438  EquationSystems equation_systems (mesh);
439 
440  OptimizationSystem & system =
441  equation_systems.add_system<OptimizationSystem> ("Optimization");
442 
443  // The default is to use PETSc/Tao solvers, but let the user change
444  // the optimization solver package on the fly.
445  {
446  const std::string optimization_solver_type = infile("optimization_solver_type",
447  "PETSC_SOLVERS");
448  SolverPackage sp = Utility::string_to_enum<SolverPackage>(optimization_solver_type);
449  std::unique_ptr<OptimizationSolver<Number>> new_solver =
451  system.optimization_solver.reset(new_solver.release());
452  }
453 
454  // Set tolerances and maximum iteration counts directly on the optimization solver.
455  system.optimization_solver->max_objective_function_evaluations = 128;
456  system.optimization_solver->objective_function_relative_tolerance = 1.e-4;
457  system.optimization_solver->verbose = true;
458 
459  AssembleOptimization assemble_opt(system);
460 
461  system.add_variable("u",
462  Utility::string_to_enum<Order> (approx_order),
463  Utility::string_to_enum<FEFamily>(fe_family));
464 
465  system.optimization_solver->objective_object = &assemble_opt;
466  system.optimization_solver->gradient_object = &assemble_opt;
467  system.optimization_solver->hessian_object = &assemble_opt;
468  system.optimization_solver->equality_constraints_object = &assemble_opt;
469  system.optimization_solver->equality_constraints_jacobian_object = &assemble_opt;
470  system.optimization_solver->inequality_constraints_object = &assemble_opt;
471  system.optimization_solver->inequality_constraints_jacobian_object = &assemble_opt;
472  system.optimization_solver->lower_and_upper_bounds_object = &assemble_opt;
473 
474  // system.matrix and system.rhs are used for the gradient and Hessian,
475  // so in this case we add an extra matrix and vector to store A and F.
476  // This makes it easy to write the code for evaluating the objective,
477  // gradient, and hessian.
478  system.add_matrix("A_matrix");
479  system.add_vector("F_vector");
480  assemble_opt.A_matrix = &system.get_matrix("A_matrix");
481  assemble_opt.F_vector = &system.get_vector("F_vector");
482 
483 
484  equation_systems.init();
485  equation_systems.print_info();
486 
487  assemble_opt.assemble_A_and_F();
488 
489  {
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();
495 
496  sparsity_row.insert(23);
497  constraint_jac_sparsity.push_back(sparsity_row);
498  sparsity_row.clear();
499 
500  sparsity_row.insert(98);
501  sparsity_row.insert(185);
502  constraint_jac_sparsity.push_back(sparsity_row);
503 
504  system.initialize_equality_constraints_storage(constraint_jac_sparsity);
505  }
506 
507  {
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);
513 
514  system.initialize_inequality_constraints_storage(constraint_jac_sparsity);
515  }
516 
517  // We need to close the matrix so that we can use it to store the
518  // Hessian during the solve.
519  system.get_system_matrix().close();
520  system.solve();
521 
522  // Print convergence information
523  system.optimization_solver->print_converged_reason();
524 
525  // Write the solution to file if the optimization solver converged
526  if (system.optimization_solver->get_converged_reason() > 0)
527  {
528  std::stringstream filename;
529  ExodusII_IO (mesh).write_equation_systems("optimization_soln.exo",
530  equation_systems);
531  }
532 
533  return 0;
534 }
This is the EquationSystems class.
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.
dof_id_type n_elem(const MeshBase::const_element_iterator &begin, const MeshBase::const_element_iterator &end)
Count up the number of elements of a specific type (as defined by an iterator range).
Definition: mesh_tools.C:969
The ExodusII_IO class implements reading meshes in the ExodusII file format from Sandia National Labs...
Definition: exodusII_io.h:52
virtual void solve() override
Solves the optimization problem.
MeshBase & mesh
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.
Definition: system.C:768
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
The LibMeshInit class, when constructed, initializes the dependent libraries (e.g.
Definition: libmesh.h:90
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, gradient, and hessian.
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.
Definition: exodusII_io.C:2033
This System subclass enables us to assemble an objective function, gradient, Hessian and bounds for o...
void print_info(std::ostream &os=libMesh::out, const unsigned int verbosity=0, const bool global=true) const
Prints relevant information about the mesh.
Definition: mesh_base.C:1562
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
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.
Definition: system.C:1357
std::unique_ptr< OptimizationSolver< Number > > optimization_solver
The OptimizationSolver that is used for performing the optimization.
virtual void close()=0
Calls the SparseMatrix&#39;s internal assembly routines, ensuring that the values are consistent across p...
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.
This base class can be inherited from to provide interfaces to optimization solvers from different pa...
OStreamProxy out
SolverPackage
Defines an enum for various linear solver packages.
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
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.
Definition: system.C:1010
const SparseMatrix< Number > & get_matrix(std::string_view mat_name) const
Definition: system.C:1124
const SparseMatrix< Number > & get_system_matrix() const
const NumericVector< Number > & get_vector(std::string_view vec_name) const
Definition: system.C:943