ROL
ROL_DynamicConstraint.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #pragma once
11 #ifndef ROL_DYNAMICCONSTRAINT_HPP
12 #define ROL_DYNAMICCONSTRAINT_HPP
13 
14 
16 #include "ROL_Types.hpp"
17 #include "ROL_DynamicFunction.hpp"
20 
21 namespace ROL {
22 
23 template<typename Real>
25 
26 template<typename Real>
28 }
29 
32 
50 namespace ROL {
51 
52 template<typename Real>
53 class DynamicConstraint : public DynamicFunction<Real> {
54 private:
55  // Additional vector storage for solve
56  Ptr<Vector<Real>> unew_;
57  Ptr<Vector<Real>> jv_;
58 
59  // Default parameters for solve (backtracking Newton)
60  const Real DEFAULT_atol_;
61  const Real DEFAULT_rtol_;
62  const Real DEFAULT_stol_;
63  const Real DEFAULT_factor_;
64  const Real DEFAULT_decr_;
65  const int DEFAULT_maxit_;
66  const bool DEFAULT_print_;
67  const bool DEFAULT_zero_;
69 
70  // User-set parameters for solve (backtracking Newton)
71  Real atol_;
72  Real rtol_;
73  Real stol_;
74  Real factor_;
75  Real decr_;
76  int maxit_;
77  bool print_;
78  bool zero_;
80 
81  // Flag to initialize vector storage in solve
83 
84 public:
85 
86  using V = Vector<Real>;
89 
90  virtual ~DynamicConstraint() {}
91 
93 
94  DynamicConstraint( std::initializer_list<std::string> zero_deriv_terms ):
95  DynamicFunction<Real>(zero_deriv_terms),
96  unew_ ( nullPtr ),
97  jv_ ( nullPtr ),
98  DEFAULT_atol_ ( 1e-4*std::sqrt(ROL_EPSILON<Real>()) ),
99  DEFAULT_rtol_ ( 1e0 ),
100  DEFAULT_stol_ ( std::sqrt(ROL_EPSILON<Real>()) ),
101  DEFAULT_factor_ ( 0.5 ),
102  DEFAULT_decr_ ( 1e-4 ),
103  DEFAULT_maxit_ ( 500 ),
104  DEFAULT_print_ ( false ),
105  DEFAULT_zero_ ( false ),
106  DEFAULT_solverType_ ( 0 ),
107  atol_ ( DEFAULT_atol_ ),
108  rtol_ ( DEFAULT_rtol_ ),
109  stol_ ( DEFAULT_stol_ ),
111  decr_ ( DEFAULT_decr_ ),
114  zero_ ( DEFAULT_zero_ ),
116  firstSolve_ ( true ) {}
117 
118 
119 
120  virtual void update( const V& uo, const V& un, const V& z, const TS& ts ) {
121  update_uo( uo, ts );
122  update_un( un, ts );
123  update_z( z, ts );
124  }
125 
129 
130  virtual void value( V& c, const V& uo, const V& un,
131  const V& z, const TS& ts ) const = 0;
132 
133  virtual void solve( V& c, const V& uo, V& un,
134  const V& z, const TS& ts ) {
135  if ( zero_ ) un.zero();
136  Ptr<std::ostream> stream = makeStreamPtr(std::cout, print_);
137  update(uo,un,z,ts);
138  value(c,uo,un,z,ts);
139  Real cnorm = c.norm();
140  const Real ctol = std::min(atol_, rtol_*cnorm);
141  if (solverType_==0 || solverType_==3 || solverType_==4) {
142  if ( firstSolve_ ) {
143  unew_ = un.clone();
144  jv_ = un.clone();
145  firstSolve_ = false;
146  }
147  Real alpha(1), tmp(0);
148  int cnt = 0;
149  if ( print_ ) {
150  *stream << " Default DynamicConstraint::solve" << std::endl;
151  *stream << " ";
152  *stream << std::setw(6) << std::left << "iter";
153  *stream << std::setw(15) << std::left << "rnorm";
154  *stream << std::setw(15) << std::left << "alpha";
155  *stream << std::endl;
156  }
157  for (cnt = 0; cnt < maxit_; ++cnt) {
158  // Compute Newton step
159  applyInverseJacobian_un(*jv_,c,uo,un,z,ts);
160  unew_->set(un);
161  unew_->axpy(-alpha, *jv_);
162  //update_un(*unew_,ts);
163  update(uo,*unew_,z,ts);
164  value(c,uo,*unew_,z,ts);
165  tmp = c.norm();
166  // Perform backtracking line search
167  while ( tmp > (1.0-decr_*alpha)*cnorm &&
168  alpha > stol_ ) {
169  alpha *= factor_;
170  unew_->set(un);
171  unew_->axpy(-alpha,*jv_);
172  //update_un(*unew_,ts);
173  update(uo,*unew_,z,ts);
174  value(c,uo,*unew_,z,ts);
175  tmp = c.norm();
176  }
177  if ( print_ ) {
178  *stream << " ";
179  *stream << std::setw(6) << std::left << cnt;
180  *stream << std::scientific << std::setprecision(6);
181  *stream << std::setw(15) << std::left << tmp;
182  *stream << std::scientific << std::setprecision(6);
183  *stream << std::setw(15) << std::left << alpha;
184  *stream << std::endl;
185  }
186  // Update iterate
187  cnorm = tmp;
188  un.set(*unew_);
189  if (cnorm <= ctol) { // = covers the case of identically zero residual
190  break;
191  }
192  update(uo,un,z,ts);
193  alpha = 1.0;
194  }
195  }
196  if (solverType_==1 || (solverType_==3 && cnorm > ctol)) {
197  Ptr<DynamicConstraint<Real>> con = makePtrFromRef(*this);
198  Ptr<Objective<Real>> obj
199  = makePtr<NonlinearLeastSquaresObjective_Dynamic<Real>>(con,c,makePtrFromRef(uo),makePtrFromRef(z),makePtrFromRef(ts),true);
200  ParameterList parlist;
201  parlist.sublist("General").set("Output Level",1);
202  parlist.sublist("General").sublist("Krylov").set("Iteration Limit",100);
203  parlist.sublist("Step").sublist("Trust Region").set("Subproblem Solver","Truncated CG");
204  parlist.sublist("Status Test").set("Gradient Tolerance",ctol);
205  parlist.sublist("Status Test").set("Step Tolerance",stol_);
206  parlist.sublist("Status Test").set("Iteration Limit",maxit_);
207  Ptr<TypeU::Algorithm<Real>> algo = makePtr<TypeU::TrustRegionAlgorithm<Real>>(parlist);
208  algo->run(un,*obj,*stream);
209  value(c,uo,un,z,ts);
210  }
211  if (solverType_==2 || (solverType_==4 && cnorm > ctol)) {
212  Ptr<Constraint<Real>> con
213  = makePtr<Constraint_DynamicState<Real>>(makePtrFromRef(*this),makePtrFromRef(uo),makePtrFromRef(z),makePtrFromRef(ts));
214  Ptr<Objective<Real>> obj = makePtr<Objective_FSsolver<Real>>();
215  Ptr<Vector<Real>> l = c.dual().clone();
216  ParameterList parlist;
217  parlist.sublist("General").set("Output Level",1);
218  parlist.sublist("Status Test").set("Constraint Tolerance",ctol);
219  parlist.sublist("Status Test").set("Step Tolerance",stol_);
220  parlist.sublist("Status Test").set("Iteration Limit",maxit_);
221  Ptr<TypeE::Algorithm<Real>> algo = makePtr<TypeE::AugmentedLagrangianAlgorithm<Real>>(parlist);
222  algo->run(un,*obj,*con,*l,*stream);
223  value(c,uo,un,z,ts);
224  }
225  if (solverType_ > 4 || solverType_ < 0) {
226  ROL_TEST_FOR_EXCEPTION(true, std::invalid_argument,
227  ">>> ERROR (ROL:DynamicConstraint:solve): Invalid solver type!");
228  }
229  }
230 
251  virtual void setSolveParameters(ParameterList &parlist) {
252  ParameterList & list = parlist.sublist("Dynamic Constraint").sublist("Solve");
253  atol_ = list.get("Absolute Residual Tolerance", DEFAULT_atol_);
254  rtol_ = list.get("Relative Residual Tolerance", DEFAULT_rtol_);
255  maxit_ = list.get("Iteration Limit", DEFAULT_maxit_);
256  decr_ = list.get("Sufficient Decrease Tolerance", DEFAULT_decr_);
257  stol_ = list.get("Step Tolerance", DEFAULT_stol_);
258  factor_ = list.get("Backtracking Factor", DEFAULT_factor_);
259  print_ = list.get("Output Iteration History", DEFAULT_print_);
260  zero_ = list.get("Zero Initial Guess", DEFAULT_zero_);
261  solverType_ = list.get("Solver Type", DEFAULT_solverType_);
262  }
263 
264  //----------------------------------------------------------------------------
265  // Partial Jacobians
266  virtual void applyJacobian_uo( V& jv, const V& vo, const V& uo,
267  const V& un, const V& z,
268  const TS& ts ) const {}
269 
270  virtual void applyJacobian_un( V& jv, const V& vn, const V& uo,
271  const V& un, const V& z,
272  const TS& ts ) const {}
273 
274  virtual void applyJacobian_z( V& jv, const V& vz, const V& uo,
275  const V& un, const V& z,
276  const TS& ts ) const {}
277 
278  //----------------------------------------------------------------------------
279  // Adjoint partial Jacobians
280  virtual void applyAdjointJacobian_uo( V& ajv, const V& dualv, const V& uo,
281  const V& un, const V& z,
282  const TS& ts ) const {}
283 
284  virtual void applyAdjointJacobian_un( V& ajv, const V& dualv, const V& uo,
285  const V& un, const V& z,
286  const TS& ts ) const {}
287 
288  virtual void applyAdjointJacobian_z( V& ajv, const V& dualv, const V& uo,
289  const V& un, const V& z,
290  const TS& ts ) const {}
291 
292  //----------------------------------------------------------------------------
293  // Inverses
294  virtual void applyInverseJacobian_un( V& ijv, const V& vn, const V& uo,
295  const V& un, const V& z,
296  const TS& ts ) const {}
297 
298  virtual void applyInverseAdjointJacobian_un( V& iajv, const V& vn, const V& uo,
299  const V& un, const V& z,
300  const TS& ts ) const {}
301 
302  //----------------------------------------------------------------------------
303  // Adjoint Hessian components
304  virtual void applyAdjointHessian_un_un( V& ahwv, const V& wn, const V& vn,
305  const V& uo, const V& un,
306  const V& z, const TS& ts ) const {
307  ahwv.zero();
308  }
309 
310  virtual void applyAdjointHessian_un_uo( V& ahwv, const V& w, const V& vn,
311  const V& uo, const V& un,
312  const V& z, const TS& ts ) const {
313  ahwv.zero();
314  }
315 
316  virtual void applyAdjointHessian_un_z( V& ahwv, const V& w, const V& vn,
317  const V& uo, const V& un,
318  const V& z, const TS& ts ) const {
319  ahwv.zero();
320  }
321 
322  virtual void applyAdjointHessian_uo_un( V& ahwv, const V& w, const V& vo,
323  const V& uo, const V& un,
324  const V& z, const TS& ts ) const {
325  ahwv.zero();
326  }
327 
328  virtual void applyAdjointHessian_uo_uo( V& ahwv, const V& w, const V& v,
329  const V& uo, const V& un,
330  const V& z, const TS& ts ) const {
331  ahwv.zero();
332  }
333 
334  virtual void applyAdjointHessian_uo_z( V& ahwv, const V& w, const V& vo,
335  const V& uo, const V& un,
336  const V& z, const TS& ts ) const {
337  ahwv.zero();
338  }
339 
340  virtual void applyAdjointHessian_z_un( V& ahwv, const V& w, const V& vz,
341  const V& uo, const V& un,
342  const V& z, const TS& ts ) const {
343  ahwv.zero();
344  }
345 
346  virtual void applyAdjointHessian_z_uo( V& ahwv, const V& w, const V& vz,
347  const V& uo, const V& un,
348  const V& z, const TS& ts ) const {
349  ahwv.zero();
350  }
351 
352  virtual void applyAdjointHessian_z_z( V& ahwv, const V& w, const V& vz,
353  const V& uo, const V& un,
354  const V& z, const TS& ts ) const {
355  ahwv.zero();
356  }
357 
358 }; // DynamicConstraint
359 
360 
361 } // namespace ROL
362 
363 
364 #endif // ROL_DYNAMICCONSTRAINT_HPP
365 
DynamicFunction(std::initializer_list< std::string > zero_deriv_terms={})
Ptr< Vector< Real > > jv_
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
Definition: ROL_Vector.hpp:192
virtual void applyAdjointHessian_un_z(V &ahwv, const V &w, const V &vn, const V &uo, const V &un, const V &z, const TS &ts) const
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void solve(V &c, const V &uo, V &un, const V &z, const TS &ts)
Defines the time-dependent constraint operator interface for simulation-based optimization.
virtual void applyAdjointHessian_uo_un(V &ahwv, const V &w, const V &vo, const V &uo, const V &un, const V &z, const TS &ts) const
Defines the linear algebra of vector space on a generic partitioned vector.
virtual void applyAdjointHessian_z_z(V &ahwv, const V &w, const V &vz, const V &uo, const V &un, const V &z, const TS &ts) const
Provides update interface, casting and vector management to DynamicConstraint and DynamicObjective...
Ptr< Vector< Real > > unew_
Contains definitions of custom data types in ROL.
virtual void applyAdjointHessian_z_un(V &ahwv, const V &w, const V &vz, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyAdjointJacobian_un(V &ajv, const V &dualv, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyJacobian_uo(V &jv, const V &vo, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void update(const V &uo, const V &un, const V &z, const TS &ts)
virtual void applyInverseAdjointJacobian_un(V &iajv, const V &vn, const V &uo, const V &un, const V &z, const TS &ts) const
Ptr< std::ostream > makeStreamPtr(std::ostream &os, bool noSuppressOutput=true)
Definition: ROL_Stream.hpp:39
virtual void zero()
Set to zero vector.
Definition: ROL_Vector.hpp:133
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
Vector< Real > V
virtual void applyAdjointJacobian_z(V &ajv, const V &dualv, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void setSolveParameters(ParameterList &parlist)
Set solve parameters.
virtual void applyInverseJacobian_un(V &ijv, const V &vn, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void update_z(const V &x, const TS &ts)
virtual void value(V &c, const V &uo, const V &un, const V &z, const TS &ts) const =0
virtual void update_uo(const V &x, const TS &ts)
virtual void applyAdjointJacobian_uo(V &ajv, const V &dualv, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyJacobian_un(V &jv, const V &vn, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyJacobian_z(V &jv, const V &vz, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyAdjointHessian_un_uo(V &ahwv, const V &w, const V &vn, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyAdjointHessian_z_uo(V &ahwv, const V &w, const V &vz, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyAdjointHessian_uo_uo(V &ahwv, const V &w, const V &v, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
virtual Real norm() const =0
Returns where .
virtual void applyAdjointHessian_un_un(V &ahwv, const V &wn, const V &vn, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyAdjointHessian_uo_z(V &ahwv, const V &w, const V &vo, const V &uo, const V &un, const V &z, const TS &ts) const
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition: ROL_Types.hpp:57
virtual void update_un(const V &x, const TS &ts)