[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
kkt_operator.hpp
1 #ifndef __KKT_OPERATOR_H__
2 #define __KKT_OPERATOR_H__
3 
4 #include "ROL_Types.hpp"
5 #include "ROL_Objective.hpp"
6 #include "ROL_Constraint.hpp"
7 #include "ROL_Vector_SimOpt.hpp"
8 
10 template<typename Real = double>
12 {
13 protected:
14 
16  const ROL::Ptr<ROL::Objective<Real>> objective_;
18  const ROL::Ptr<ROL::Constraint<Real>> equal_constraints_;
19 
21  const ROL::Ptr<const ROL::Vector<Real>> design_variables_;
23  const ROL::Ptr<const ROL::Vector<Real>> lagrange_mult_;
24 
25 
26 private:
27 
29  const ROL::Ptr<ROL::Vector<Real>> temp_design_variables_size_vector_;
30 
31 public:
34  const ROL::Ptr<ROL::Objective<Real>> objective,
35  const ROL::Ptr<ROL::Constraint<Real>> equal_constraints,
36  const ROL::Ptr<const ROL::Vector<Real>> design_variables,
37  const ROL::Ptr<const ROL::Vector<Real>> lagrange_mult)
38  : objective_(objective)
39  , equal_constraints_(equal_constraints)
40  , design_variables_(design_variables)
41  , lagrange_mult_(lagrange_mult)
42  , temp_design_variables_size_vector_(design_variables->clone())
43  { };
44 
46  unsigned int size()
47  {
48  return (design_variables_->dimension() + lagrange_mult_->dimension());
49  }
50 
53  const dealiiSolverVectorWrappingROL<Real> &src) const
54  {
55  dst *= 0.0;
56 
57  static int number_of_times = 0;
58  number_of_times++;
59  std::cout << "Number of KKT vmult = " << number_of_times << std::endl;
60  Real tol = 1e-15;
61  const Real one = 1.0;
62 
63  ROL::Ptr<ROL::Vector<Real>> dst_rol = dst.getVector();
64  const ROL::Ptr<const ROL::Vector<Real>> src_rol = src.getVector();
65 
66  auto &dst_split = dynamic_cast<ROL::Vector_SimOpt<Real>&>(*dst_rol);
67  const auto &src_split = dynamic_cast<const ROL::Vector_SimOpt<Real>&>(*src_rol);
68 
69  ROL::Ptr<ROL::Vector<Real>> dst_design = dst_split.get_1();
70  ROL::Ptr<ROL::Vector<Real>> dst_constraints = dst_split.get_2();
71  dst_design->zero();
72  dst_constraints->zero();
73 
74  const ROL::Ptr<const ROL::Vector<Real>> src_design = src_split.get_1();
75  const ROL::Ptr<const ROL::Vector<Real>> src_constraints = src_split.get_2();
76 
77  // Top left block times top vector
78  {
79  objective_->hessVec(*dst_design, *src_design, *design_variables_, tol);
80  equal_constraints_->applyAdjointHessian(*temp_design_variables_size_vector_, *lagrange_mult_, *src_design, *design_variables_, tol);
81  dst_design->axpy(one, *temp_design_variables_size_vector_);
82 
83  }
84  {
85  // Pretend Lagrangian Hessian is identity.
86  //dst_design->set(*src_design);
87  }
88 
89  // Top right block times bottom vector
90  equal_constraints_->applyAdjointJacobian(*temp_design_variables_size_vector_, *src_constraints, *design_variables_, tol);
91  dst_design->axpy(one, *temp_design_variables_size_vector_);
92 
93  // Bottom left left block times top vector
94  equal_constraints_->applyJacobian(*dst_constraints, *src_design, *design_variables_, tol);
95 
96  // Bottom right block times bottom vector
97  // 0 block in KKT
98  dealii::deallog.depth_console(99);
99  }
100 
102 
105  const dealiiSolverVectorWrappingROL<Real> &src) const
106  {
107  vmult(dst, src);
108  }
109 
111 
114  void print(const dealiiSolverVectorWrappingROL<Real> &vector_format)
115  {
116  const int do_full_matrix = (1 == dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD));
117  std::cout << "do_full_matrix: " << do_full_matrix << std::endl;
118  if (do_full_matrix) {
119  dealiiSolverVectorWrappingROL<Real> column_of_kkt_operator;
120  column_of_kkt_operator.reinit(vector_format);
121  dealii::FullMatrix<double> fullA(vector_format.size());
122  for (int i = 0; i < vector_format.size(); ++i) {
123  std::cout << "COLUMN NUMBER: " << i+1 << " OUT OF " << vector_format.size() << std::endl;
124  auto basis = vector_format.basis(i);
125  MPI_Barrier(MPI_COMM_WORLD);
126  this->vmult(column_of_kkt_operator,*basis);
127  if (do_full_matrix) {
128  for (int j = 0; j < vector_format.size(); ++j) {
129  fullA[i][j] = column_of_kkt_operator[j];
130  }
131  }
132  }
133  std::cout<<"Dense matrix:"<<std::endl;
134  fullA.print_formatted(std::cout, 14, true, 10, "0", 1., 0.);
135  std::abort();
136  }
137  }
138 };
139 
140 #endif
KKT_Operator(const ROL::Ptr< ROL::Objective< Real >> objective, const ROL::Ptr< ROL::Constraint< Real >> equal_constraints, const ROL::Ptr< const ROL::Vector< Real >> design_variables, const ROL::Ptr< const ROL::Vector< Real >> lagrange_mult)
Constructor.
void Tvmult(dealiiSolverVectorWrappingROL< Real > &dst, const dealiiSolverVectorWrappingROL< Real > &src) const
Application of transposed KKT matrix on vector src outputted into dst.
const ROL::Ptr< const ROL::Vector< Real > > design_variables_
Design variables.
void reinit(const dealiiSolverVectorWrappingROL &model_vector, const bool leave_elements_uninitialized=false)
Wrap the ROL vector into a vector that can be used by deal.II&#39;s solver.
void vmult(dealiiSolverVectorWrappingROL< Real > &dst, const dealiiSolverVectorWrappingROL< Real > &src) const
Application of KKT matrix on vector src outputted into dst.
void print(const dealiiSolverVectorWrappingROL< Real > &vector_format)
Print the KKT system if the program is run with 1 MPI process.
ROL::Ptr< ROL::Vector< Real > > getVector()
Accessor.
const ROL::Ptr< ROL::Objective< Real > > objective_
Objective function.
const ROL::Ptr< ROL::Vector< Real > > temp_design_variables_size_vector_
Used to perform the Lagrangian Hessian in two steps.
unsigned int size()
Returns the size of the KKT system.
const ROL::Ptr< const ROL::Vector< Real > > lagrange_mult_
Lagrange multipliers.
KKT_Operator to be used with dealii::SolverBase class.
const ROL::Ptr< ROL::Constraint< Real > > equal_constraints_
Equality constraints.
int size() const
Obtain vector size.
Teuchos::RCP< dealiiSolverVectorWrappingROL > basis(int i) const
Returns a vector of the same size with zero entries except for the ith entry being one...