ROL
ROL_DynamicConstraint.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Rapid Optimization Library (ROL) Package
5 // Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 // Drew Kouri (dpkouri@sandia.gov) and
39 // Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 
45 #pragma once
46 #ifndef ROL_DYNAMICCONSTRAINT_HPP
47 #define ROL_DYNAMICCONSTRAINT_HPP
48 
49 
51 #include "ROL_Types.hpp"
52 #include "ROL_DynamicFunction.hpp"
55 
56 namespace ROL {
57 
58 template<typename Real>
60 
61 template<typename Real>
63 }
64 
67 
85 namespace ROL {
86 
87 template<typename Real>
88 class DynamicConstraint : public DynamicFunction<Real> {
89 private:
90  // Additional vector storage for solve
91  Ptr<Vector<Real>> unew_;
92  Ptr<Vector<Real>> jv_;
93 
94  // Default parameters for solve (backtracking Newton)
95  const Real DEFAULT_atol_;
96  const Real DEFAULT_rtol_;
97  const Real DEFAULT_stol_;
98  const Real DEFAULT_factor_;
99  const Real DEFAULT_decr_;
100  const int DEFAULT_maxit_;
101  const bool DEFAULT_print_;
102  const bool DEFAULT_zero_;
104 
105  // User-set parameters for solve (backtracking Newton)
106  Real atol_;
107  Real rtol_;
108  Real stol_;
109  Real factor_;
110  Real decr_;
111  int maxit_;
112  bool print_;
113  bool zero_;
115 
116  // Flag to initialize vector storage in solve
118 
119 public:
120 
121  using V = Vector<Real>;
124 
125  virtual ~DynamicConstraint() {}
126 
127  DynamicConstraint( std::initializer_list<std::string> zero_deriv_terms={} ):
128  DynamicFunction<Real>(zero_deriv_terms),
129  unew_ ( nullPtr ),
130  jv_ ( nullPtr ),
131  DEFAULT_atol_ ( 1e-4*std::sqrt(ROL_EPSILON<Real>()) ),
132  DEFAULT_rtol_ ( 1e0 ),
133  DEFAULT_stol_ ( std::sqrt(ROL_EPSILON<Real>()) ),
134  DEFAULT_factor_ ( 0.5 ),
135  DEFAULT_decr_ ( 1e-4 ),
136  DEFAULT_maxit_ ( 500 ),
137  DEFAULT_print_ ( false ),
138  DEFAULT_zero_ ( false ),
139  DEFAULT_solverType_ ( 0 ),
140  atol_ ( DEFAULT_atol_ ),
141  rtol_ ( DEFAULT_rtol_ ),
142  stol_ ( DEFAULT_stol_ ),
144  decr_ ( DEFAULT_decr_ ),
147  zero_ ( DEFAULT_zero_ ),
149  firstSolve_ ( true ) {}
150 
151 
152 
153  virtual void update( const V& uo, const V& un, const V& z, const TS& ts ) {
154  update_uo( uo, ts );
155  update_un( un, ts );
156  update_z( z, ts );
157  }
158 
162 
163  virtual void value( V& c, const V& uo, const V& un,
164  const V& z, const TS& ts ) const = 0;
165 
166  virtual void solve( V& c, const V& uo, V& un,
167  const V& z, const TS& ts ) {
168  if ( zero_ ) un.zero();
169  Ptr<std::ostream> stream = makeStreamPtr(std::cout, print_);
170  update(uo,un,z,ts);
171  value(c,uo,un,z,ts);
172  Real cnorm = c.norm();
173  const Real ctol = std::min(atol_, rtol_*cnorm);
174  if (solverType_==0 || solverType_==3 || solverType_==4) {
175  if ( firstSolve_ ) {
176  unew_ = un.clone();
177  jv_ = un.clone();
178  firstSolve_ = false;
179  }
180  Real alpha(1), tmp(0);
181  int cnt = 0;
182  if ( print_ ) {
183  *stream << " Default DynamicConstraint::solve" << std::endl;
184  *stream << " ";
185  *stream << std::setw(6) << std::left << "iter";
186  *stream << std::setw(15) << std::left << "rnorm";
187  *stream << std::setw(15) << std::left << "alpha";
188  *stream << std::endl;
189  }
190  for (cnt = 0; cnt < maxit_; ++cnt) {
191  // Compute Newton step
192  applyInverseJacobian_un(*jv_,c,uo,un,z,ts);
193  unew_->set(un);
194  unew_->axpy(-alpha, *jv_);
195  //update_un(*unew_,ts);
196  update(uo,*unew_,z,ts);
197  value(c,uo,*unew_,z,ts);
198  tmp = c.norm();
199  // Perform backtracking line search
200  while ( tmp > (1.0-decr_*alpha)*cnorm &&
201  alpha > stol_ ) {
202  alpha *= factor_;
203  unew_->set(un);
204  unew_->axpy(-alpha,*jv_);
205  //update_un(*unew_,ts);
206  update(uo,*unew_,z,ts);
207  value(c,uo,*unew_,z,ts);
208  tmp = c.norm();
209  }
210  if ( print_ ) {
211  *stream << " ";
212  *stream << std::setw(6) << std::left << cnt;
213  *stream << std::scientific << std::setprecision(6);
214  *stream << std::setw(15) << std::left << tmp;
215  *stream << std::scientific << std::setprecision(6);
216  *stream << std::setw(15) << std::left << alpha;
217  *stream << std::endl;
218  }
219  // Update iterate
220  cnorm = tmp;
221  un.set(*unew_);
222  if (cnorm <= ctol) { // = covers the case of identically zero residual
223  break;
224  }
225  update(uo,un,z,ts);
226  alpha = 1.0;
227  }
228  }
229  if (solverType_==1 || (solverType_==3 && cnorm > ctol)) {
230  Ptr<DynamicConstraint<Real>> con = makePtrFromRef(*this);
231  Ptr<Objective<Real>> obj
232  = makePtr<NonlinearLeastSquaresObjective_Dynamic<Real>>(con,c,makePtrFromRef(uo),makePtrFromRef(z),makePtrFromRef(ts),true);
233  ParameterList parlist;
234  parlist.sublist("General").set("Output Level",1);
235  parlist.sublist("General").sublist("Krylov").set("Iteration Limit",100);
236  parlist.sublist("Step").sublist("Trust Region").set("Subproblem Solver","Truncated CG");
237  parlist.sublist("Status Test").set("Gradient Tolerance",ctol);
238  parlist.sublist("Status Test").set("Step Tolerance",stol_);
239  parlist.sublist("Status Test").set("Iteration Limit",maxit_);
240  Ptr<TypeU::Algorithm<Real>> algo = makePtr<TypeU::TrustRegionAlgorithm<Real>>(parlist);
241  algo->run(un,*obj,*stream);
242  value(c,uo,un,z,ts);
243  }
244  if (solverType_==2 || (solverType_==4 && cnorm > ctol)) {
245  Ptr<Constraint<Real>> con
246  = makePtr<Constraint_DynamicState<Real>>(makePtrFromRef(*this),makePtrFromRef(uo),makePtrFromRef(z),makePtrFromRef(ts));
247  Ptr<Objective<Real>> obj = makePtr<Objective_FSsolver<Real>>();
248  Ptr<Vector<Real>> l = c.dual().clone();
249  ParameterList parlist;
250  parlist.sublist("General").set("Output Level",1);
251  parlist.sublist("Status Test").set("Constraint Tolerance",ctol);
252  parlist.sublist("Status Test").set("Step Tolerance",stol_);
253  parlist.sublist("Status Test").set("Iteration Limit",maxit_);
254  Ptr<TypeE::Algorithm<Real>> algo = makePtr<TypeE::AugmentedLagrangianAlgorithm<Real>>(parlist);
255  algo->run(un,*obj,*con,*l,*stream);
256  value(c,uo,un,z,ts);
257  }
258  if (solverType_ > 4 || solverType_ < 0) {
259  ROL_TEST_FOR_EXCEPTION(true, std::invalid_argument,
260  ">>> ERROR (ROL:DynamicConstraint:solve): Invalid solver type!");
261  }
262  }
263 
284  virtual void setSolveParameters(ParameterList &parlist) {
285  ParameterList & list = parlist.sublist("Dynamic Constraint").sublist("Solve");
286  atol_ = list.get("Absolute Residual Tolerance", DEFAULT_atol_);
287  rtol_ = list.get("Relative Residual Tolerance", DEFAULT_rtol_);
288  maxit_ = list.get("Iteration Limit", DEFAULT_maxit_);
289  decr_ = list.get("Sufficient Decrease Tolerance", DEFAULT_decr_);
290  stol_ = list.get("Step Tolerance", DEFAULT_stol_);
291  factor_ = list.get("Backtracking Factor", DEFAULT_factor_);
292  print_ = list.get("Output Iteration History", DEFAULT_print_);
293  zero_ = list.get("Zero Initial Guess", DEFAULT_zero_);
294  solverType_ = list.get("Solver Type", DEFAULT_solverType_);
295  }
296 
297  //----------------------------------------------------------------------------
298  // Partial Jacobians
299  virtual void applyJacobian_uo( V& jv, const V& vo, const V& uo,
300  const V& un, const V& z,
301  const TS& ts ) const {}
302 
303  virtual void applyJacobian_un( V& jv, const V& vn, const V& uo,
304  const V& un, const V& z,
305  const TS& ts ) const {}
306 
307  virtual void applyJacobian_z( V& jv, const V& vz, const V& uo,
308  const V& un, const V& z,
309  const TS& ts ) const {}
310 
311  //----------------------------------------------------------------------------
312  // Adjoint partial Jacobians
313  virtual void applyAdjointJacobian_uo( V& ajv, const V& dualv, const V& uo,
314  const V& un, const V& z,
315  const TS& ts ) const {}
316 
317  virtual void applyAdjointJacobian_un( V& ajv, const V& dualv, const V& uo,
318  const V& un, const V& z,
319  const TS& ts ) const {}
320 
321  virtual void applyAdjointJacobian_z( V& ajv, const V& dualv, const V& uo,
322  const V& un, const V& z,
323  const TS& ts ) const {}
324 
325  //----------------------------------------------------------------------------
326  // Inverses
327  virtual void applyInverseJacobian_un( V& ijv, const V& vn, const V& uo,
328  const V& un, const V& z,
329  const TS& ts ) const {}
330 
331  virtual void applyInverseAdjointJacobian_un( V& iajv, const V& vn, const V& uo,
332  const V& un, const V& z,
333  const TS& ts ) const {}
334 
335  //----------------------------------------------------------------------------
336  // Adjoint Hessian components
337  virtual void applyAdjointHessian_un_un( V& ahwv, const V& wn, const V& vn,
338  const V& uo, const V& un,
339  const V& z, const TS& ts ) const {
340  ahwv.zero();
341  }
342 
343  virtual void applyAdjointHessian_un_uo( V& ahwv, const V& w, const V& vn,
344  const V& uo, const V& un,
345  const V& z, const TS& ts ) const {
346  ahwv.zero();
347  }
348 
349  virtual void applyAdjointHessian_un_z( V& ahwv, const V& w, const V& vn,
350  const V& uo, const V& un,
351  const V& z, const TS& ts ) const {
352  ahwv.zero();
353  }
354 
355  virtual void applyAdjointHessian_uo_un( V& ahwv, const V& w, const V& vo,
356  const V& uo, const V& un,
357  const V& z, const TS& ts ) const {
358  ahwv.zero();
359  }
360 
361  virtual void applyAdjointHessian_uo_uo( V& ahwv, const V& w, const V& v,
362  const V& uo, const V& un,
363  const V& z, const TS& ts ) const {
364  ahwv.zero();
365  }
366 
367  virtual void applyAdjointHessian_uo_z( V& ahwv, const V& w, const V& vo,
368  const V& uo, const V& un,
369  const V& z, const TS& ts ) const {
370  ahwv.zero();
371  }
372 
373  virtual void applyAdjointHessian_z_un( V& ahwv, const V& w, const V& vz,
374  const V& uo, const V& un,
375  const V& z, const TS& ts ) const {
376  ahwv.zero();
377  }
378 
379  virtual void applyAdjointHessian_z_uo( V& ahwv, const V& w, const V& vz,
380  const V& uo, const V& un,
381  const V& z, const TS& ts ) const {
382  ahwv.zero();
383  }
384 
385  virtual void applyAdjointHessian_z_z( V& ahwv, const V& w, const V& vz,
386  const V& uo, const V& un,
387  const V& z, const TS& ts ) const {
388  ahwv.zero();
389  }
390 
391 }; // DynamicConstraint
392 
393 
394 } // namespace ROL
395 
396 
397 #endif // ROL_DYNAMICCONSTRAINT_HPP
398 
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:226
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
virtual void zero()
Set to zero vector.
Definition: ROL_Vector.hpp:167
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
Ptr< ostream > makeStreamPtr(ostream &os, bool noSuppressOutput=true)
Definition: ROL_Stream.hpp:75
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)
DynamicConstraint(std::initializer_list< std::string > zero_deriv_terms={})
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:209
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
virtual void update_un(const V &x, const TS &ts)