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"
20
21namespace ROL {
22
23template<typename Real>
24class DynamicConstraint;
25
26template<typename Real>
27class Constraint_DynamicState;
28}
29
32
50namespace ROL {
51
52template<typename Real>
53class DynamicConstraint : public DynamicFunction<Real> {
54private:
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
84public:
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 ),
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
126 using DynamicFunction<Real>::update_uo;
127 using DynamicFunction<Real>::update_un;
128 using DynamicFunction<Real>::update_z;
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
Contains definitions of custom data types in ROL.
Defines the time-dependent constraint operator interface for simulation-based optimization.
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 setSolveParameters(ParameterList &parlist)
Set solve parameters.
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_uo_un(V &ahwv, const V &w, const V &vo, const V &uo, const V &un, const V &z, const TS &ts) const
Ptr< Vector< Real > > unew_
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 applyAdjointHessian_z_un(V &ahwv, const V &w, const V &vz, const V &uo, const V &un, const V &z, const TS &ts) const
DynamicConstraint(std::initializer_list< std::string > zero_deriv_terms)
virtual void applyInverseAdjointJacobian_un(V &iajv, 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 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 void solve(V &c, const V &uo, V &un, const V &z, const TS &ts)
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 value(V &c, const V &uo, const V &un, const V &z, const TS &ts) const =0
virtual void applyJacobian_uo(V &jv, const V &vo, const V &uo, const V &un, const V &z, const TS &ts) const
virtual void applyAdjointJacobian_uo(V &ajv, const V &dualv, 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 applyInverseJacobian_un(V &ijv, const V &vn, const V &uo, const V &un, const V &z, const TS &ts) const
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
virtual void applyJacobian_un(V &jv, const V &vn, 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 applyAdjointJacobian_z(V &ajv, const V &dualv, const V &uo, const V &un, const V &z, const TS &ts) const
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
Provides update interface, casting and vector management to DynamicConstraint and DynamicObjective.
virtual void update_uo(const V &x, const TS &ts)
virtual void update_z(const V &x, const TS &ts)
virtual void update_un(const V &x, const TS &ts)
Defines the linear algebra of vector space on a generic partitioned vector.
Defines the linear algebra or vector space interface.
virtual Real norm() const =0
Returns where .
virtual void set(const Vector &x)
Set where .
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
virtual void zero()
Set to zero vector.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition ROL_Types.hpp:57
Contains local time step information.