[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
kkt_birosghattas_preconditioners.hpp
1 #ifndef __KKT_BIROSGHATTAS_PRECONDITIONERS_H__
2 #define __KKT_BIROSGHATTAS_PRECONDITIONERS_H__
3 
4 #include "ROL_SecantStep.hpp"
5 
6 #include "ROL_Objective_SimOpt.hpp"
7 #include "ROL_Constraint_SimOpt.hpp"
8 #include "ROL_Vector_SimOpt.hpp"
9 
10 #include "flow_constraints.hpp"
11 
13 
15 template<typename Real = double>
17 {
18 protected:
20  const ROL::Ptr<ROL::Objective_SimOpt<Real>> objective_;
22  const ROL::Ptr<PHiLiP::FlowConstraints<PHILIP_DIM>> equal_constraints_;
23 
25  const ROL::Ptr<const ROL::Vector_SimOpt<Real>> design_variables_;
27  const ROL::Ptr<const ROL::Vector<Real>> lagrange_mult_;
28 
30  const ROL::Ptr<const ROL::Vector<Real>> simulation_variables_;
31 
33  const ROL::Ptr<const ROL::Vector<Real>> control_variables_;
34 
36  const ROL::Ptr<ROL::Secant<Real> > secant_;
37 
41 
42 protected:
43  const unsigned int mpi_rank;
44  dealii::ConditionalOStream pcout;
45 
46 public:
47 
50  const ROL::Ptr<ROL::Objective<Real>> objective,
51  const ROL::Ptr<ROL::Constraint<Real>> equal_constraints,
52  const ROL::Ptr<const ROL::Vector<Real>> design_variables,
53  const ROL::Ptr<const ROL::Vector<Real>> lagrange_mult,
54  const ROL::Ptr<ROL::Secant<Real> > secant,
55  const bool use_approximate_preconditioner = false)
56  : objective_
57  (ROL::makePtrFromRef<ROL::Objective_SimOpt<Real>>(dynamic_cast<ROL::Objective_SimOpt<Real>&>(*objective)))
58  , equal_constraints_
59  (ROL::makePtrFromRef<PHiLiP::FlowConstraints<PHILIP_DIM>>(dynamic_cast<PHiLiP::FlowConstraints<PHILIP_DIM>&>(*equal_constraints)))
60  , design_variables_
61  (ROL::makePtrFromRef<const ROL::Vector_SimOpt<Real>>(dynamic_cast<const ROL::Vector_SimOpt<Real>&>(*design_variables)))
62  , lagrange_mult_(lagrange_mult)
63  , simulation_variables_(design_variables_->get_1())
64  , control_variables_(design_variables_->get_2())
65  , secant_(secant)
66  , use_approximate_preconditioner_(use_approximate_preconditioner)
67  , mpi_rank(dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD))
68  , pcout(std::cout, mpi_rank==0)
69  {
70  if (use_approximate_preconditioner_) {
71  const int error_precond1 = equal_constraints_->construct_JacobianPreconditioner_1(*simulation_variables_, *control_variables_);
72  const int error_precond2 = equal_constraints_->construct_AdjointJacobianPreconditioner_1(*simulation_variables_, *control_variables_);
73  assert(error_precond1 == 0);
74  assert(error_precond2 == 0);
75  (void) error_precond1;
76  (void) error_precond2;
77  }
78  }
80  {
81  if (use_approximate_preconditioner_) {
82  equal_constraints_->destroy_JacobianPreconditioner_1();
83  equal_constraints_->destroy_AdjointJacobianPreconditioner_1();
84  }
85  };
86 
89  const dealiiSolverVectorWrappingROL<Real> &src) const
90  {
91  // Identity Preconditioner
92  dst.equ(1.0, src);
93  }
94 
96 
99  const dealiiSolverVectorWrappingROL<Real> &src) const
100  {
101  vmult(dst, src);
102  }
103 };
104 
106 
109 template<typename Real = double>
111 {
112 protected:
117 
122 
125 
128 
131 
135 
136 protected:
139 
140 public:
143  const ROL::Ptr<ROL::Objective<Real>> objective,
144  const ROL::Ptr<ROL::Constraint<Real>> equal_constraints,
145  const ROL::Ptr<const ROL::Vector<Real>> design_variables,
146  const ROL::Ptr<const ROL::Vector<Real>> lagrange_mult,
147  const ROL::Ptr<ROL::Secant<Real> > secant,
148  const bool use_approximate_preconditioner = false)
149  : BirosGhattasPreconditioner<Real>(objective, equal_constraints, design_variables, lagrange_mult, secant, use_approximate_preconditioner)
150  { }
151 
154  const dealiiSolverVectorWrappingROL<Real> &src) const override
155  {
156  static int number_of_times = 0;
157  number_of_times++;
158  pcout << "Number of P2_KKT vmult = " << number_of_times << std::endl;
159  Real tol = 1e-15;
160  //const Real one = 1.0;
161 
162  ROL::Ptr<ROL::Vector<Real>> dst_rol = dst.getVector();
163  auto &dst_split = dynamic_cast<ROL::Vector_SimOpt<Real>&>(*dst_rol);
164  ROL::Ptr<ROL::Vector<Real>> dst_design = dst_split.get_1();
165  auto &dst_design_split = dynamic_cast<ROL::Vector_SimOpt<Real>&>(*dst_design);
166 
167  ROL::Ptr<ROL::Vector<Real>> dst_1 = dst_design_split.get_1();
168  ROL::Ptr<ROL::Vector<Real>> dst_2 = dst_design_split.get_2();
169  ROL::Ptr<ROL::Vector<Real>> dst_3 = dst_split.get_2();
170 
171  const ROL::Ptr<const ROL::Vector<Real>> src_rol = src.getVector();
172  const auto &src_split = dynamic_cast<const ROL::Vector_SimOpt<Real>&>(*src_rol);
173  const ROL::Ptr<const ROL::Vector<Real>> src_design = src_split.get_1();
174  const auto &src_design_split = dynamic_cast<const ROL::Vector_SimOpt<Real>&>(*src_design);
175 
176  const ROL::Ptr<const ROL::Vector<Real>> src_1 = src_design_split.get_1();
177  const ROL::Ptr<const ROL::Vector<Real>> src_2 = src_design_split.get_2();
178  const ROL::Ptr<const ROL::Vector<Real>> src_3 = src_split.get_2();
179 
180  ROL::Ptr<ROL::Vector<Real>> rhs_1 = src_1->clone();
181  ROL::Ptr<ROL::Vector<Real>> rhs_2 = src_2->clone();
182  ROL::Ptr<ROL::Vector<Real>> rhs_3 = src_3->clone();
184  equal_constraints_->applyInverseAdjointJacobianPreconditioner_1(*dst_3, *rhs_1, *simulation_variables_, *control_variables_, tol);
185  } else {
186  equal_constraints_->applyInverseAdjointJacobian_1(*dst_3, *rhs_1, *simulation_variables_, *control_variables_, tol);
187  }
188 
189  equal_constraints_->applyAdjointJacobian_2(*rhs_2, *dst_3, *simulation_variables_, *control_variables_, tol);
190  rhs_2->scale(-1.0);
191  rhs_2->plus(*src_2);
192  // Need to apply Hessian inverse on dst_2
193  secant_->applyH( *dst_2, *rhs_2);
194  // Identity
195  //dst_2->set(*rhs_2);
196 
197  equal_constraints_->applyJacobian_2(*rhs_3, *dst_2, *simulation_variables_, *control_variables_, tol);
198  rhs_3->scale(-1.0);
199  rhs_3->plus(*src_3);
201  equal_constraints_->applyInverseJacobianPreconditioner_1(*dst_1, *rhs_3, *simulation_variables_, *control_variables_, tol);
202  } else {
203  equal_constraints_->applyInverseJacobian_1(*dst_1, *rhs_3, *simulation_variables_, *control_variables_, tol);
204  }
205 
206  if (mpi_rank == 0) {
207  dealii::deallog.depth_console(99);
208  } else {
209  dealii::deallog.depth_console(0);
210  }
211 
212  }
213 
214 };
215 
217 
220 template<typename Real = double>
222 {
223 protected:
228 
233 
236 
239 
242 
246 
247 protected:
250 
251 public:
254  const ROL::Ptr<ROL::Objective<Real>> objective,
255  const ROL::Ptr<ROL::Constraint<Real>> equal_constraints,
256  const ROL::Ptr<const ROL::Vector<Real>> design_variables,
257  const ROL::Ptr<const ROL::Vector<Real>> lagrange_mult,
258  const ROL::Ptr<ROL::Secant<Real> > secant,
259  const bool use_approximate_preconditioner = false)
260  : BirosGhattasPreconditioner<Real>(objective, equal_constraints, design_variables, lagrange_mult, secant, use_approximate_preconditioner)
261  { };
262 
265  const dealiiSolverVectorWrappingROL<Real> &src) const override
266  {
267  static int number_of_times = 0;
268  number_of_times++;
269  pcout << "Number of P4_KKT vmult = " << number_of_times << std::endl;
270  Real tol = 1e-15;
271  //const Real one = 1.0;
272 
273  ROL::Ptr<ROL::Vector<Real>> dst_rol = dst.getVector();
274  auto &dst_split = dynamic_cast<ROL::Vector_SimOpt<Real>&>(*dst_rol);
275  ROL::Ptr<ROL::Vector<Real>> dst_design = dst_split.get_1();
276  auto &dst_design_split = dynamic_cast<ROL::Vector_SimOpt<Real>&>(*dst_design);
277 
278  ROL::Ptr<ROL::Vector<Real>> dst_1 = dst_design_split.get_1();
279  ROL::Ptr<ROL::Vector<Real>> dst_2 = dst_design_split.get_2();
280  ROL::Ptr<ROL::Vector<Real>> dst_3 = dst_split.get_2();
281 
282  const ROL::Ptr<const ROL::Vector<Real>> src_rol = src.getVector();
283  const auto &src_split = dynamic_cast<const ROL::Vector_SimOpt<Real>&>(*src_rol);
284  const ROL::Ptr<const ROL::Vector<Real>> src_design = src_split.get_1();
285  const auto &src_design_split = dynamic_cast<const ROL::Vector_SimOpt<Real>&>(*src_design);
286 
287  const ROL::Ptr<const ROL::Vector<Real>> src_1 = src_design_split.get_1();
288  const ROL::Ptr<const ROL::Vector<Real>> src_2 = src_design_split.get_2();
289  const ROL::Ptr<const ROL::Vector<Real>> src_3 = src_split.get_2();
290 
291  ROL::Ptr<ROL::Vector<Real>> rhs_1 = src_1->clone();
292  ROL::Ptr<ROL::Vector<Real>> rhs_2 = src_2->clone();
293  ROL::Ptr<ROL::Vector<Real>> rhs_3 = src_3->clone();
294 
295  ROL::Ptr<ROL::Vector<Real>> y_1 = src_3->clone();
296  ROL::Ptr<ROL::Vector<Real>> y_2 = src_2->clone();
297  ROL::Ptr<ROL::Vector<Real>> y_3 = src_3->clone();
298 
299  y_1->set(*src_3);
300 
301  auto Asinv_y_1 = y_1->clone();
302  auto temp_1 = y_1->clone();
304  equal_constraints_->applyInverseJacobianPreconditioner_1(*Asinv_y_1, *y_1, *simulation_variables_, *control_variables_, tol);
305  } else {
306  equal_constraints_->applyInverseJacobian_1(*Asinv_y_1, *y_1, *simulation_variables_, *control_variables_, tol);
307  }
308 
309  y_3->set(*src_1);
310  equal_constraints_->applyAdjointHessian_11 (*temp_1, *lagrange_mult_, *Asinv_y_1, *simulation_variables_, *control_variables_, tol);
311  y_3->axpy(-1.0, *temp_1);
312  objective_->hessVec_11(*temp_1, *Asinv_y_1, *simulation_variables_, *control_variables_, tol);
313  y_3->axpy(-1.0, *temp_1);
314 
315  auto AsTinv_y_3 = y_3->clone();
317  equal_constraints_->applyInverseAdjointJacobianPreconditioner_1(*AsTinv_y_3, *y_3, *simulation_variables_, *control_variables_, tol);
318  } else {
319  equal_constraints_->applyInverseAdjointJacobian_1(*AsTinv_y_3, *y_3, *simulation_variables_, *control_variables_, tol);
320  }
321  equal_constraints_->applyAdjointJacobian_2(*y_2, *AsTinv_y_3, *simulation_variables_, *control_variables_, tol);
322  y_2->scale(-1.0);
323  y_2->plus(*src_2);
324 
325  auto temp_2 = y_2->clone();
326  equal_constraints_->applyAdjointHessian_12(*temp_2, *lagrange_mult_, *Asinv_y_1, *simulation_variables_, *control_variables_, tol);
327  y_2->axpy(-1.0,*temp_2);
328  objective_->hessVec_21(*temp_2, *Asinv_y_1, *simulation_variables_, *control_variables_, tol);
329  y_2->axpy(-1.0,*temp_2);
330 
331  secant_->applyH( *dst_2, *y_2);
332  //dst_2->set(*y_2);
333 
334  auto Asinv_Ad_dst_2 = y_1->clone();
335  equal_constraints_->applyJacobian_2(*temp_1, *dst_2, *simulation_variables_, *control_variables_, tol);
337  equal_constraints_->applyInverseJacobianPreconditioner_1(*Asinv_Ad_dst_2, *temp_1, *simulation_variables_, *control_variables_, tol);
338  } else {
339  equal_constraints_->applyInverseJacobian_1(*Asinv_Ad_dst_2, *temp_1, *simulation_variables_, *control_variables_, tol);
340  }
341 
342  dst_1->set(*Asinv_y_1);
343  dst_1->axpy(-1.0, *Asinv_Ad_dst_2);
344 
345  auto dst_3_rhs = y_3->clone();
346  equal_constraints_->applyAdjointHessian_11 (*temp_1, *lagrange_mult_, *Asinv_Ad_dst_2, *simulation_variables_, *control_variables_, tol);
347  dst_3_rhs->axpy(1.0, *temp_1);
348  objective_->hessVec_11(*temp_1, *Asinv_Ad_dst_2, *simulation_variables_, *control_variables_, tol);
349  dst_3_rhs->axpy(1.0, *temp_1);
350 
351  equal_constraints_->applyAdjointHessian_21 (*temp_1, *lagrange_mult_, *dst_2, *simulation_variables_, *control_variables_, tol);
352  dst_3_rhs->axpy(-1.0, *temp_1);
353  objective_->hessVec_12(*temp_1, *dst_2, *simulation_variables_, *control_variables_, tol);
354  dst_3_rhs->axpy(-1.0, *temp_1);
355 
357  equal_constraints_->applyInverseAdjointJacobianPreconditioner_1(*dst_3, *dst_3_rhs, *simulation_variables_, *control_variables_, tol);
358  } else {
359  equal_constraints_->applyInverseAdjointJacobian_1(*dst_3, *dst_3_rhs, *simulation_variables_, *control_variables_, tol);
360  }
361 
362  if (mpi_rank == 0) {
363  dealii::deallog.depth_console(99);
364  } else {
365  dealii::deallog.depth_console(0);
366  }
367 
368  }
369 
370 };
371 
373 template<typename Real = double>
375 {
376 public:
379  const ROL::Ptr<ROL::Objective<Real>> objective,
380  const ROL::Ptr<ROL::Constraint<Real>> equal_constraints,
381  const ROL::Ptr<const ROL::Vector<Real>> design_variables,
382  const ROL::Ptr<const ROL::Vector<Real>> lagrange_mult,
383  const ROL::Ptr<ROL::Secant<Real> > secant,
384  const bool use_approximate_preconditioner = false)
385  : BirosGhattasPreconditioner<Real>(objective, equal_constraints, design_variables, lagrange_mult, secant, use_approximate_preconditioner)
386  { }
387 
390  const dealiiSolverVectorWrappingROL<Real> &src) const override
391  {
392  dst.equ(1.0,src);
393  }
394 
395 };
396 
398 template<typename Real = double>
400 {
401 public:
403  static std::shared_ptr< BirosGhattasPreconditioner<Real> >
404  create_KKT_preconditioner( ROL::ParameterList &parlist,
405  ROL::Objective<Real> &objective,
406  ROL::Constraint<Real> &equal_constraints,
407  const ROL::Vector<Real> &design_variables,
408  const ROL::Vector<Real> &lagrange_mult,
409  const ROL::Ptr< ROL::Secant<Real> > secant_)
410  {
411  const std::string preconditioner_name_ = parlist.sublist("Full Space").get("Preconditioner","Identity");
412  const bool use_approximate_full_space_preconditioner_ = (preconditioner_name_ == "P2A" || preconditioner_name_ == "P4A");
413 
414  if (preconditioner_name_ == "P2" || preconditioner_name_ == "P2A") {
415  return std::make_shared<KKT_P2_Preconditioner<Real>> (
416  ROL::makePtrFromRef<ROL::Objective<Real>>(objective),
417  ROL::makePtrFromRef<ROL::Constraint<Real>>(equal_constraints),
418  ROL::makePtrFromRef<const ROL::Vector<Real>>(design_variables),
419  ROL::makePtrFromRef<const ROL::Vector<Real>>(lagrange_mult),
420  secant_,
421  use_approximate_full_space_preconditioner_);
422  } else if (preconditioner_name_ == "P4" || preconditioner_name_ == "P4A") {
423  return std::make_shared<KKT_P4_Preconditioner<Real>> (
424  ROL::makePtrFromRef<ROL::Objective<Real>>(objective),
425  ROL::makePtrFromRef<ROL::Constraint<Real>>(equal_constraints),
426  ROL::makePtrFromRef<const ROL::Vector<Real>>(design_variables),
427  ROL::makePtrFromRef<const ROL::Vector<Real>>(lagrange_mult),
428  secant_,
429  use_approximate_full_space_preconditioner_);
430  } else {
431  return std::make_shared<KKT_Identity_Preconditioner<Real>> (
432  ROL::makePtrFromRef<ROL::Objective<Real>>(objective),
433  ROL::makePtrFromRef<ROL::Constraint<Real>>(equal_constraints),
434  ROL::makePtrFromRef<const ROL::Vector<Real>>(design_variables),
435  ROL::makePtrFromRef<const ROL::Vector<Real>>(lagrange_mult),
436  secant_,
437  false);
438  }
439  }
440 };
441 
442 #endif
void vmult(dealiiSolverVectorWrappingROL< Real > &dst, const dealiiSolverVectorWrappingROL< Real > &src) const override
Application of KKT preconditionner on vector src outputted into dst.
const ROL::Ptr< ROL::Secant< Real > > secant_
Secant method used to precondition the reduced Hessian.
void vmult(dealiiSolverVectorWrappingROL< Real > &dst, const dealiiSolverVectorWrappingROL< Real > &src) const override
Application of KKT preconditionner on vector src outputted into dst.
P4 preconditioner from Biros & Ghattas 2005.
const ROL::Ptr< const ROL::Vector_SimOpt< Real > > design_variables_
Design variables.
Files for the baseline physics.
Definition: ADTypes.hpp:10
virtual void vmult(dealiiSolverVectorWrappingROL< Real > &dst, const dealiiSolverVectorWrappingROL< Real > &src) const
Application of KKT preconditionner on vector src outputted into dst.
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 override
Application of KKT preconditionner on vector src outputted into dst.
const ROL::Ptr< const ROL::Vector< Real > > control_variables_
Control design variables.
KKT_Identity_Preconditioner(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, const ROL::Ptr< ROL::Secant< Real > > secant, const bool use_approximate_preconditioner=false)
Constructor.
const ROL::Ptr< const ROL::Vector< Real > > lagrange_mult_
Lagrange multipliers.
Full-space system preconditioner based on the reduced-space.
const unsigned int mpi_rank
MPI rank used to reset the deallog depth.
void equ(const Real a, const dealiiSolverVectorWrappingROL &x)
Scaled assignment of a vector.
static std::shared_ptr< BirosGhattasPreconditioner< Real > > create_KKT_preconditioner(ROL::ParameterList &parlist, ROL::Objective< Real > &objective, ROL::Constraint< Real > &equal_constraints, const ROL::Vector< Real > &design_variables, const ROL::Vector< Real > &lagrange_mult, const ROL::Ptr< ROL::Secant< Real > > secant_)
Creates a derived preconditioner object, but returns it as BirosGhattasPreconditioner.
const ROL::Ptr< ROL::Objective_SimOpt< Real > > objective_
Objective function.
ROL::Ptr< ROL::Vector< Real > > getVector()
Accessor.
KKT_P2_Preconditioner(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, const ROL::Ptr< ROL::Secant< Real > > secant, const bool use_approximate_preconditioner=false)
< Parallel std::cout that only outputs on mpi_rank==0
KKT_P4_Preconditioner(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, const ROL::Ptr< ROL::Secant< Real > > secant, const bool use_approximate_preconditioner=false)
< Parallel std::cout that only outputs on mpi_rank==0
P2 preconditioner from Biros & Ghattas 2005.
const ROL::Ptr< const ROL::Vector< Real > > simulation_variables_
Simulation design variables.
virtual void Tvmult(dealiiSolverVectorWrappingROL< Real > &dst, const dealiiSolverVectorWrappingROL< Real > &src) const
Application of transposed KKT preconditioner on vector src outputted into dst.
BirosGhattasPreconditioner(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, const ROL::Ptr< ROL::Secant< Real > > secant, const bool use_approximate_preconditioner=false)
Constructor.
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
Full-space preconditioner from factory.
const ROL::Ptr< PHiLiP::FlowConstraints< PHILIP_DIM > > equal_constraints_
Equality constraints.