ROL
example_03.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
15#include "ROL_Algorithm.hpp"
17#include "ROL_CompositeStep.hpp"
18#include "ROL_Types.hpp"
19
20#include "ROL_StdVector.hpp"
21#include "ROL_Vector_SimOpt.hpp"
25#include "ROL_ParameterList.hpp"
26
27#include "ROL_Stream.hpp"
28#include "ROL_GlobalMPISession.hpp"
29
30#include <iostream>
31#include <algorithm>
32#include <ctime>
33
34template<class Real>
36private:
37 unsigned nx_;
38 unsigned nt_;
39
40 Real dx_;
41 Real T_;
42 Real dt_;
43
44 Real nu_;
45 Real u0_;
46 Real u1_;
47 Real f_;
48 std::vector<Real> u_init_;
49
50private:
51 Real compute_norm(const std::vector<Real> &r) {
52 return std::sqrt(dot(r,r));
53 }
54
55 Real dot(const std::vector<Real> &x, const std::vector<Real> &y) {
56 Real ip = 0.0;
57 Real c = ((x.size()==nx_) ? 4.0 : 2.0);
58 for (unsigned i = 0; i < x.size(); i++) {
59 if ( i == 0 ) {
60 ip += dx_/6.0*(c*x[i] + x[i+1])*y[i];
61 }
62 else if ( i == x.size()-1 ) {
63 ip += dx_/6.0*(x[i-1] + c*x[i])*y[i];
64 }
65 else {
66 ip += dx_/6.0*(x[i-1] + 4.0*x[i] + x[i+1])*y[i];
67 }
68 }
69 return ip;
70 }
71
73
74 void update(std::vector<Real> &u, const std::vector<Real> &s, const Real alpha=1.0) {
75 for (unsigned i = 0; i < u.size(); i++) {
76 u[i] += alpha*s[i];
77 }
78 }
79
80 void scale(std::vector<Real> &u, const Real alpha=0.0) {
81 for (unsigned i = 0; i < u.size(); i++) {
82 u[i] *= alpha;
83 }
84 }
85
86 void compute_residual(std::vector<Real> &r, const std::vector<Real> &uold, const std::vector<Real> &zold,
87 const std::vector<Real> &unew, const std::vector<Real> &znew) {
88 r.clear();
89 r.resize(nx_,0.0);
90 for (unsigned n = 0; n < nx_; n++) {
91 // Contribution from mass & stiffness term at time step t and t-1
92 r[n] += (4.0*dx_/6.0 + 0.5*dt_*2.0*nu_/dx_)*unew[n];
93 r[n] += (-4.0*dx_/6.0 + 0.5*dt_*2.0*nu_/dx_)*uold[n];
94 if ( n > 0 ) {
95 r[n] += (dx_/6.0 - 0.5*dt_*nu_/dx_)*unew[n-1];
96 r[n] -= (dx_/6.0 + 0.5*dt_*nu_/dx_)*uold[n-1];
97 }
98 if ( n < nx_-1 ) {
99 r[n] += (dx_/6.0 - 0.5*dt_*nu_/dx_)*unew[n+1];
100 r[n] -= (dx_/6.0 + 0.5*dt_*nu_/dx_)*uold[n+1];
101 }
102 // Contribution from nonlinear term
103 if ( n > 0 ) {
104 r[n] -= 0.5*dt_*unew[n-1]*(unew[n-1]+unew[n])/6.0;
105 r[n] -= 0.5*dt_*uold[n-1]*(uold[n-1]+uold[n])/6.0;
106 }
107 if ( n < nx_-1 ){
108 r[n] += 0.5*dt_*unew[n+1]*(unew[n]+unew[n+1])/6.0;
109 r[n] += 0.5*dt_*uold[n+1]*(uold[n]+uold[n+1])/6.0;
110 }
111 // Contribution from control
112 r[n] -= 0.5*dt_*dx_/6.0*(znew[n]+4.0*znew[n+1]+znew[n+2]);
113 r[n] -= 0.5*dt_*dx_/6.0*(zold[n]+4.0*zold[n+1]+zold[n+2]);
114 // Contribution from right-hand side
115 r[n] -= dt_*dx_*f_;
116 }
117 // Contribution from Dirichlet boundary terms
118 r[0] -= dt_*(0.5*u0_*(unew[ 0] + uold[ 0])/6.0 + u0_*u0_/6.0 + nu_*u0_/dx_);
119 r[nx_-1] += dt_*(0.5*u1_*(unew[nx_-1] + uold[nx_-1])/6.0 + u1_*u1_/6.0 - nu_*u1_/dx_);
120 }
121
122 void compute_pde_jacobian(std::vector<Real> &dl, std::vector<Real> &d, std::vector<Real> &du,
123 const std::vector<Real> &u) {
124 // Get Diagonal and Off-Diagonal Entries of linear PDE Jacobian
125 d.clear();
126 d.resize(nx_,4.0*dx_/6.0 + 0.5*dt_*nu_*2.0/dx_);
127 dl.clear();
128 dl.resize(nx_-1,dx_/6.0 - 0.5*dt_*nu_/dx_);
129 du.clear();
130 du.resize(nx_-1,dx_/6.0 - 0.5*dt_*nu_/dx_);
131 // Contribution from nonlinearity
132 for (unsigned n = 0; n < nx_; n++) {
133 if ( n < nx_-1 ) {
134 dl[n] += 0.5*dt_*(-2.0*u[n]-u[n+1])/6.0;
135 d[n] += 0.5*dt_*u[n+1]/6.0;
136 }
137 if ( n > 0 ) {
138 d[n] -= 0.5*dt_*u[n-1]/6.0;
139 du[n-1] += 0.5*dt_*(u[n-1]+2.0*u[n])/6.0;
140 }
141 }
142 // Contribution from Dirichlet boundary conditions
143 d[0] -= 0.5*dt_*u0_/6.0;
144 d[nx_-1] += 0.5*dt_*u1_/6.0;
145 }
146
147 void apply_pde_jacobian_new(std::vector<Real> &jv, const std::vector<Real> &v, const std::vector<Real> &u,
148 bool adjoint = false) {
149 jv.clear();
150 jv.resize(nx_,0.0);
151 // Fill Jacobian times a vector
152 for (unsigned n = 0; n < nx_; n++) {
153 jv[n] = (4.0*dx_/6.0 + 0.5*dt_*nu_/dx_*2.0)*v[n]; // Mass & Stiffness
154 if ( n > 0 ) {
155 jv[n] += dx_/6.0*v[n-1]-0.5*dt_*nu_/dx_*v[n-1]; // Mass & Stiffness
156 if ( adjoint ) {
157 jv[n] -= 0.5*dt_*(u[n-1]/6.0*v[n]-(u[n-1]+2.0*u[n])/6.0*v[n-1]); // Nonlinearity
158 }
159 else {
160 jv[n] -= 0.5*dt_*(u[n-1]/6.0*v[n]+(u[n]+2.0*u[n-1])/6.0*v[n-1]); // Nonlinearity
161 }
162 }
163 if ( n < nx_-1 ) {
164 jv[n] += dx_/6.0*v[n+1]-0.5*dt_*nu_/dx_*v[n+1]; // Mass & Stiffness
165 if ( adjoint ) {
166 jv[n] += 0.5*dt_*(u[n+1]/6.0*v[n]-(u[n+1]+2.0*u[n])/6.0*v[n+1]); // Nonlinearity
167 }
168 else {
169 jv[n] += 0.5*dt_*(u[n+1]/6.0*v[n]+(u[n]+2.0*u[n+1])/6.0*v[n+1]); // Nonlinearity
170 }
171 }
172 }
173 jv[0] -= 0.5*dt_*u0_/6.0*v[0]; // Nonlinearity
174 jv[nx_-1] += 0.5*dt_*u1_/6.0*v[nx_-1]; // Nonlinearity
175 }
176
177 void apply_pde_jacobian_old(std::vector<Real> &jv, const std::vector<Real> &v, const std::vector<Real> &u,
178 bool adjoint = false) {
179 jv.clear();
180 jv.resize(nx_,0.0);
181 // Fill Jacobian times a vector
182 for (unsigned n = 0; n < nx_; n++) {
183 jv[n] = (-4.0*dx_/6.0 + 0.5*dt_*nu_/dx_*2.0)*v[n]; // Mass & Stiffness
184 if ( n > 0 ) {
185 jv[n] += -dx_/6.0*v[n-1]-0.5*dt_*nu_/dx_*v[n-1]; // Mass & Stiffness
186 if ( adjoint ) {
187 jv[n] -= 0.5*dt_*(u[n-1]/6.0*v[n]-(u[n-1]+2.0*u[n])/6.0*v[n-1]); // Nonlinearity
188 }
189 else {
190 jv[n] -= 0.5*dt_*(u[n-1]/6.0*v[n]+(u[n]+2.0*u[n-1])/6.0*v[n-1]); // Nonlinearity
191 }
192 }
193 if ( n < nx_-1 ) {
194 jv[n] += -dx_/6.0*v[n+1]-0.5*dt_*nu_/dx_*v[n+1]; // Mass & Stiffness
195 if ( adjoint ) {
196 jv[n] += 0.5*dt_*(u[n+1]/6.0*v[n]-(u[n+1]+2.0*u[n])/6.0*v[n+1]); // Nonlinearity
197 }
198 else {
199 jv[n] += 0.5*dt_*(u[n+1]/6.0*v[n]+(u[n]+2.0*u[n+1])/6.0*v[n+1]); // Nonlinearity
200 }
201 }
202 }
203 jv[0] -= 0.5*dt_*u0_/6.0*v[0]; // Nonlinearity
204 jv[nx_-1] += 0.5*dt_*u1_/6.0*v[nx_-1]; // Nonlinearity
205 }
206
207 void apply_pde_jacobian(std::vector<Real> &jv, const std::vector<Real> &vold, const std::vector<Real> &uold,
208 const std::vector<Real> &vnew, const std::vector<Real> unew, bool adjoint = false) {
209 jv.clear();
210 jv.resize(nx_,0.0);
211 // Fill Jacobian times a vector
212 for (unsigned n = 0; n < nx_; n++) {
213 jv[n] += (4.0*dx_/6.0+0.5*dt_*nu_/dx_*2.0)*vnew[n]; // Mass & Stiffness
214 jv[n] -= (4.0*dx_/6.0-0.5*dt_*nu_/dx_*2.0)*vold[n]; // Mass & Stiffness
215 if ( n > 0 ) {
216 jv[n] += dx_/6.0*vnew[n-1]-0.5*dt_*nu_/dx_*vnew[n-1]; // Mass & Stiffness
217 jv[n] -= dx_/6.0*vold[n-1]+0.5*dt_*nu_/dx_*vold[n-1]; // Mass & Stiffness
218 if ( adjoint ) {
219 jv[n] -= 0.5*dt_*(unew[n-1]/6.0*vnew[n]-(unew[n-1]+2.0*unew[n])/6.0*vnew[n-1]); // Nonlinearity
220 jv[n] -= 0.5*dt_*(uold[n-1]/6.0*vold[n]-(uold[n-1]+2.0*uold[n])/6.0*vold[n-1]); // Nonlinearity
221 }
222 else {
223 jv[n] -= 0.5*dt_*(unew[n-1]/6.0*vnew[n]+(unew[n]+2.0*unew[n-1])/6.0*vnew[n-1]); // Nonlinearity
224 jv[n] -= 0.5*dt_*(uold[n-1]/6.0*vold[n]+(uold[n]+2.0*uold[n-1])/6.0*vold[n-1]); // Nonlinearity
225 }
226 }
227 if ( n < nx_-1 ) {
228 jv[n] += dx_/6.0*vnew[n+1]-0.5*dt_*nu_/dx_*vnew[n+1]; // Mass & Stiffness
229 jv[n] -= dx_/6.0*vold[n+1]+0.5*dt_*nu_/dx_*vold[n+1]; // Mass & Stiffness
230 if ( adjoint ) {
231 jv[n] += 0.5*dt_*(unew[n+1]/6.0*vnew[n]-(unew[n+1]+2.0*unew[n])/6.0*vnew[n+1]); // Nonlinearity
232 jv[n] += 0.5*dt_*(uold[n+1]/6.0*vold[n]-(uold[n+1]+2.0*uold[n])/6.0*vold[n+1]); // Nonlinearity
233 }
234 else {
235 jv[n] += 0.5*dt_*(unew[n+1]/6.0*vnew[n]+(unew[n]+2.0*unew[n+1])/6.0*vnew[n+1]); // Nonlinearity
236 jv[n] += 0.5*dt_*(uold[n+1]/6.0*vold[n]+(uold[n]+2.0*uold[n+1])/6.0*vold[n+1]); // Nonlinearity
237 }
238 }
239 }
240 jv[0] -= 0.5*dt_*u0_/6.0*vnew[0]; // Nonlinearity
241 jv[0] -= 0.5*dt_*u0_/6.0*vold[0]; // Nonlinearity
242 jv[nx_-1] += 0.5*dt_*u1_/6.0*vnew[nx_-1]; // Nonlinearity
243 jv[nx_-1] += 0.5*dt_*u1_/6.0*vold[nx_-1]; // Nonlinearity
244 }
245
246 void apply_pde_hessian(std::vector<Real> &hv, const std::vector<Real> &wold, const std::vector<Real> &vold,
247 const std::vector<Real> &wnew, const std::vector<Real> &vnew) {
248 hv.clear();
249 hv.resize(nx_,0.0);
250 for (unsigned n = 0; n < nx_; n++) {
251 if ( n > 0 ) {
252 hv[n] += 0.5*dt_*((wnew[n-1]*(vnew[n-1]+2.0*vnew[n]) - wnew[n]*vnew[n-1])/6.0);
253 hv[n] += 0.5*dt_*((wold[n-1]*(vold[n-1]+2.0*vold[n]) - wold[n]*vold[n-1])/6.0);
254 }
255 if ( n < nx_-1 ){
256 hv[n] += 0.5*dt_*((wnew[n]*vnew[n+1] - wnew[n+1]*(2.0*vnew[n]+vnew[n+1]))/6.0);
257 hv[n] += 0.5*dt_*((wold[n]*vold[n+1] - wold[n+1]*(2.0*vold[n]+vold[n+1]))/6.0);
258 }
259 }
260 }
261
262 void apply_control_jacobian(std::vector<Real> &jv, const std::vector<Real> &v, bool adjoint = false) {
263 jv.clear();
264 unsigned dim = ((adjoint == true) ? nx_+2 : nx_);
265 jv.resize(dim,0.0);
266 for (unsigned n = 0; n < dim; n++) {
267 if ( adjoint ) {
268 if ( n == 0 ) {
269 jv[n] = -0.5*dt_*dx_/6.0*v[n];
270 }
271 else if ( n == 1 ) {
272 jv[n] = -0.5*dt_*dx_/6.0*(4.0*v[n-1]+v[n]);
273 }
274 else if ( n == nx_ ) {
275 jv[n] = -0.5*dt_*dx_/6.0*(4.0*v[n-1]+v[n-2]);
276 }
277 else if ( n == nx_+1 ) {
278 jv[n] = -0.5*dt_*dx_/6.0*v[n-2];
279 }
280 else {
281 jv[n] = -0.5*dt_*dx_/6.0*(v[n-2]+4.0*v[n-1]+v[n]);
282 }
283 }
284 else {
285 jv[n] -= 0.5*dt_*dx_/6.0*(v[n]+4.0*v[n+1]+v[n+2]);
286 }
287 }
288 }
289
290 void run_newton(std::vector<Real> &u, const std::vector<Real> &znew,
291 const std::vector<Real> &uold, const std::vector<Real> &zold) {
292 u.clear();
293 u.resize(nx_,0.0);
294 // Compute residual and residual norm
295 std::vector<Real> r(nx_,0.0);
296 compute_residual(r,uold,zold,u,znew);
297 Real rnorm = compute_norm(r);
298 // Define tolerances
299 Real rtol = 1.e2*ROL::ROL_EPSILON<Real>();
300 unsigned maxit = 500;
301 // Initialize Jacobian storage
302 std::vector<Real> d(nx_,0.0);
303 std::vector<Real> dl(nx_-1,0.0);
304 std::vector<Real> du(nx_-1,0.0);
305 // Iterate Newton's method
306 Real alpha = 1.0, tmp = 0.0;
307 std::vector<Real> s(nx_,0.0);
308 std::vector<Real> utmp(nx_,0.0);
309 for (unsigned i = 0; i < maxit; i++) {
310 //std::cout << i << " " << rnorm << "\n";
311 // Get Jacobian
312 compute_pde_jacobian(dl,d,du,u);
313 // Solve Newton system
314 linear_solve(s,dl,d,du,r);
315 // Perform line search
316 tmp = rnorm;
317 alpha = 1.0;
318 utmp.assign(u.begin(),u.end());
319 update(utmp,s,-alpha);
320 compute_residual(r,uold,zold,utmp,znew);
321 rnorm = compute_norm(r);
322 while ( rnorm > (1.0-1.e-4*alpha)*tmp && alpha > std::sqrt(ROL::ROL_EPSILON<Real>()) ) {
323 alpha *= 0.5;
324 utmp.assign(u.begin(),u.end());
325 update(utmp,s,-alpha);
326 compute_residual(r,uold,zold,utmp,znew);
327 rnorm = compute_norm(r);
328 }
329 // Update iterate
330 u.assign(utmp.begin(),utmp.end());
331 if ( rnorm < rtol ) {
332 break;
333 }
334 }
335 }
336
337 void linear_solve(std::vector<Real> &u,
338 const std::vector<Real> &dl, const std::vector<Real> &d, const std::vector<Real> &du,
339 const std::vector<Real> &r, const bool transpose = false) {
340 bool useLAPACK = true;
341 if ( useLAPACK ) { // DIRECT SOLVE: USE LAPACK
342 u.assign(r.begin(),r.end());
343 // Store matrix diagonal & off-diagonals.
344 std::vector<Real> Dl(dl);
345 std::vector<Real> Du(du);
346 std::vector<Real> D(d);
347 // Perform LDL factorization
348 ROL::LAPACK<int,Real> lp;
349 std::vector<Real> Du2(nx_-2,0.0);
350 std::vector<int> ipiv(nx_,0);
351 int info;
352 int ldb = nx_;
353 int nhrs = 1;
354 lp.GTTRF(nx_,&Dl[0],&D[0],&Du[0],&Du2[0],&ipiv[0],&info);
355 char trans = ((transpose == true) ? 'T' : 'N');
356 lp.GTTRS(trans,nx_,nhrs,&Dl[0],&D[0],&Du[0],&Du2[0],&ipiv[0],&u[0],ldb,&info);
357 }
358 else { // ITERATIVE SOLVE: USE GAUSS-SEIDEL
359 u.clear();
360 u.resize(nx_,0.0);
361 unsigned maxit = 100;
362 Real rtol = std::min(1.e-12,1.e-4*std::sqrt(dot(r,r)));
363 //Real rtol = 1e-6;
364 Real resid = 0.0;
365 Real rnorm = 10.0*rtol;
366 for (unsigned i = 0; i < maxit; i++) {
367 for (unsigned n = 0; n < nx_; n++) {
368 u[n] = r[n]/d[n];
369 if ( n < nx_-1 ) {
370 u[n] -= ((transpose == false) ? du[n] : dl[n])*u[n+1]/d[n];
371 }
372 if ( n > 0 ) {
373 u[n] -= ((transpose == false) ? dl[n-1] : du[n-1])*u[n-1]/d[n];
374 }
375 }
376 // Compute Residual
377 rnorm = 0.0;
378 for (unsigned n = 0; n < nx_; n++) {
379 resid = r[n] - d[n]*u[n];
380 if ( n < nx_-1 ) {
381 resid -= ((transpose == false) ? du[n] : dl[n])*u[n+1];
382 }
383 if ( n > 0 ) {
384 resid -= ((transpose == false) ? dl[n-1] : du[n-1])*u[n-1];
385 }
386 rnorm += resid*resid;
387 }
388 rnorm = std::sqrt(rnorm);
389 if ( rnorm < rtol ) {
390 //std::cout << "\ni = " << i+1 << " rnorm = " << rnorm << "\n";
391 break;
392 }
393 }
394 }
395 }
396
397public:
398
399 Constraint_BurgersControl(int nx = 128, int nt = 100, Real T = 1,
400 Real nu = 1.e-2, Real u0 = 0.0, Real u1 = 0.0, Real f = 0.0)
401 : nx_((unsigned)nx), nt_((unsigned)nt), T_(T), nu_(nu), u0_(u0), u1_(u1), f_(f) {
402 dx_ = 1.0/((Real)nx+1.0);
403 dt_ = T/((Real)nt);
404 u_init_.clear();
405 u_init_.resize(nx_,0.0);
406 Real x = 0.0;
407 for (unsigned n = 0; n < nx_; n++) {
408 x = (Real)(n+1)*dx_;
409 u_init_[n] = ((x <= 0.5) ? 1.0 : 0.0);
410 }
411 }
412
413 void value(ROL::Vector<Real> &c, const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol) {
414 ROL::Ptr<std::vector<Real> > cp =
415 dynamic_cast<ROL::StdVector<Real>&>(c).getVector();
416 ROL::Ptr<const std::vector<Real> > up =
417 dynamic_cast<const ROL::StdVector<Real>&>(u).getVector();
418 ROL::Ptr<const std::vector<Real> > zp =
419 dynamic_cast<const ROL::StdVector<Real>&>(z).getVector();
420 // Initialize storage
421 std::vector<Real> C(nx_,0.0);
422 std::vector<Real> uold(u_init_);
423 std::vector<Real> unew(u_init_);
424 std::vector<Real> zold(nx_+2,0.0);
425 std::vector<Real> znew(nx_+2,0.0);
426 // Copy initial control
427 for (unsigned n = 0; n < nx_+2; n++) {
428 zold[n] = (*zp)[n];
429 }
430 // Evaluate residual
431 for (unsigned t = 0; t < nt_; t++) {
432 // Copy current state at time step t
433 for (unsigned n = 0; n < nx_; n++) {
434 unew[n] = (*up)[t*nx_+n];
435 }
436 // Copy current control at time step t
437 for (unsigned n = 0; n < nx_+2; n++) {
438 znew[n] = (*zp)[(t+1)*(nx_+2)+n];
439 }
440 // Compute residual at time step t
441 compute_residual(C,uold,zold,unew,znew);
442 // Store residual at time step t
443 for (unsigned n = 0; n < nx_; n++) {
444 (*cp)[t*nx_+n] = C[n];
445 }
446 // Copy previous state and control at time step t+1
447 uold.assign(unew.begin(),unew.end());
448 zold.assign(znew.begin(),znew.end());
449 }
450 }
451
452 void solve(ROL::Vector<Real> &c, ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol) {
453 ROL::Ptr<std::vector<Real> > up =
454 dynamic_cast<ROL::StdVector<Real>&>(u).getVector();
455 up->assign(up->size(),z.norm()/up->size());
456 ROL::Ptr<const std::vector<Real> > zp =
457 dynamic_cast<const ROL::StdVector<Real>&>(z).getVector();
458 // Initialize storage
459 std::vector<Real> uold(u_init_);
460 std::vector<Real> unew(u_init_);
461 std::vector<Real> zold(nx_+2,0.0);
462 std::vector<Real> znew(nx_+2,0.0);
463 // Copy initial control
464 for (unsigned n = 0; n < nx_+2; n++) {
465 zold[n] = (*zp)[n];
466 }
467 // Time step using the trapezoidal rule
468 for (unsigned t = 0; t < nt_; t++) {
469 // Copy current control at time step t
470 for (unsigned n = 0; n < nx_+2; n++) {
471 znew[n] = (*zp)[(t+1)*(nx_+2)+n];
472 }
473 // Solve nonlinear system at time step t
474 run_newton(unew,znew,uold,zold);
475 // store state at time step t
476 for (unsigned n = 0; n < nx_; n++) {
477 (*up)[t*nx_+n] = unew[n];
478 }
479 // Copy previous state and control at time step t+1
480 uold.assign(unew.begin(),unew.end());
481 zold.assign(znew.begin(),znew.end());
482 }
483 value(c,u,z,tol);
484 }
485
487 const ROL::Vector<Real> &z, Real &tol) {
488 ROL::Ptr<std::vector<Real> > jvp =
489 dynamic_cast<ROL::StdVector<Real>&>(jv).getVector();
490 ROL::Ptr<const std::vector<Real> > vp =
491 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
492 ROL::Ptr<const std::vector<Real> > up =
493 dynamic_cast<const ROL::StdVector<Real>&>(u).getVector();
494 std::vector<Real> J(nx_,0.0);
495 std::vector<Real> vold(nx_,0.0);
496 std::vector<Real> vnew(nx_,0.0);
497 std::vector<Real> uold(nx_,0.0);
498 std::vector<Real> unew(nx_,0.0);
499 for (unsigned t = 0; t < nt_; t++) {
500 for (unsigned n = 0; n < nx_; n++) {
501 unew[n] = (*up)[t*nx_+n];
502 vnew[n] = (*vp)[t*nx_+n];
503 }
504 apply_pde_jacobian(J,vold,uold,vnew,unew);
505 for (unsigned n = 0; n < nx_; n++) {
506 (*jvp)[t*nx_+n] = J[n];
507 }
508 vold.assign(vnew.begin(),vnew.end());
509 uold.assign(unew.begin(),unew.end());
510 }
511 }
512
514 const ROL::Vector<Real> &z, Real &tol) {
515 ROL::Ptr<std::vector<Real> > jvp =
516 dynamic_cast<ROL::StdVector<Real>&>(jv).getVector();
517 ROL::Ptr<const std::vector<Real> > vp =
518 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
519 ROL::Ptr<const std::vector<Real> > zp =
520 dynamic_cast<const ROL::StdVector<Real>&>(z).getVector();
521 std::vector<Real> vnew(nx_+2,0.0);
522 std::vector<Real> vold(nx_+2,0.0);
523 std::vector<Real> jnew(nx_,0.0);
524 std::vector<Real> jold(nx_,0.0);
525 for (unsigned n = 0; n < nx_+2; n++) {
526 vold[n] = (*vp)[n];
527 }
528 apply_control_jacobian(jold,vold);
529 for (unsigned t = 0; t < nt_; t++) {
530 for (unsigned n = 0; n < nx_+2; n++) {
531 vnew[n] = (*vp)[(t+1)*(nx_+2)+n];
532 }
533 apply_control_jacobian(jnew,vnew);
534 for (unsigned n = 0; n < nx_; n++) {
535 // Contribution from control
536 (*jvp)[t*nx_+n] = jnew[n] + jold[n];
537 }
538 jold.assign(jnew.begin(),jnew.end());
539 }
540 }
541
543 const ROL::Vector<Real> &z, Real &tol) {
544 ROL::Ptr<std::vector<Real> > ijvp =
545 dynamic_cast<ROL::StdVector<Real>&>(ijv).getVector();
546 ROL::Ptr<const std::vector<Real> > vp =
547 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
548 ROL::Ptr<const std::vector<Real> > up =
549 dynamic_cast<const ROL::StdVector<Real>&>(u).getVector();
550 std::vector<Real> J(nx_,0.0);
551 std::vector<Real> r(nx_,0.0);
552 std::vector<Real> s(nx_,0.0);
553 std::vector<Real> uold(nx_,0.0);
554 std::vector<Real> unew(nx_,0.0);
555 std::vector<Real> d(nx_,0.0);
556 std::vector<Real> dl(nx_-1,0.0);
557 std::vector<Real> du(nx_-1,0.0);
558 for (unsigned t = 0; t < nt_; t++) {
559 // Build rhs.
560 for (unsigned n = 0; n < nx_; n++) {
561 r[n] = (*vp)[t*nx_+n];
562 unew[n] = (*up)[t*nx_+n];
563 }
564 apply_pde_jacobian_old(J,s,uold);
565 update(r,J,-1.0);
566 // Build Jacobian.
567 compute_pde_jacobian(dl,d,du,unew);
568 // Solve linear system.
569 linear_solve(s,dl,d,du,r);
570 // Copy solution.
571 for (unsigned n = 0; n < nx_; n++) {
572 (*ijvp)[t*nx_+n] = s[n];
573 }
574 uold.assign(unew.begin(),unew.end());
575 }
576 }
577
579 const ROL::Vector<Real> &z, Real &tol) {
580 ROL::Ptr<std::vector<Real> > jvp =
581 dynamic_cast<ROL::StdVector<Real>&>(ajv).getVector();
582 ROL::Ptr<const std::vector<Real> > vp =
583 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
584 ROL::Ptr<const std::vector<Real> > up =
585 dynamic_cast<const ROL::StdVector<Real>&>(u).getVector();
586 std::vector<Real> J(nx_,0.0);
587 std::vector<Real> vold(nx_,0.0);
588 std::vector<Real> vnew(nx_,0.0);
589 std::vector<Real> unew(nx_,0.0);
590 for (unsigned t = nt_; t > 0; t--) {
591 for (unsigned n = 0; n < nx_; n++) {
592 unew[n] = (*up)[(t-1)*nx_+n];
593 vnew[n] = (*vp)[(t-1)*nx_+n];
594 }
595 apply_pde_jacobian(J,vold,unew,vnew,unew,true);
596 for (unsigned n = 0; n < nx_; n++) {
597 (*jvp)[(t-1)*nx_+n] = J[n];
598 }
599 vold.assign(vnew.begin(),vnew.end());
600 }
601 }
602
604 const ROL::Vector<Real> &z, Real &tol) {
605 ROL::Ptr<std::vector<Real> > jvp =
606 dynamic_cast<ROL::StdVector<Real>&>(jv).getVector();
607 ROL::Ptr<const std::vector<Real> > vp =
608 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
609 ROL::Ptr<const std::vector<Real> > zp =
610 dynamic_cast<const ROL::StdVector<Real>&>(z).getVector();
611 std::vector<Real> vnew(nx_,0.0);
612 std::vector<Real> vold(nx_,0.0);
613 std::vector<Real> jnew(nx_+2,0.0);
614 std::vector<Real> jold(nx_+2,0.0);
615 for (unsigned t = nt_+1; t > 0; t--) {
616 for (unsigned n = 0; n < nx_; n++) {
617 if ( t > 1 ) {
618 vnew[n] = (*vp)[(t-2)*nx_+n];
619 }
620 else {
621 vnew[n] = 0.0;
622 }
623 }
624 apply_control_jacobian(jnew,vnew,true);
625 for (unsigned n = 0; n < nx_+2; n++) {
626 // Contribution from control
627 (*jvp)[(t-1)*(nx_+2)+n] = jnew[n] + jold[n];
628 }
629 jold.assign(jnew.begin(),jnew.end());
630 }
631 }
632
634 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol) {
635 ROL::Ptr<std::vector<Real> > ijvp =
636 dynamic_cast<ROL::StdVector<Real>&>(ijv).getVector();
637 ROL::Ptr<const std::vector<Real> > vp =
638 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
639 ROL::Ptr<const std::vector<Real> > up =
640 dynamic_cast<const ROL::StdVector<Real>&>(u).getVector();
641 std::vector<Real> J(nx_,0.0);
642 std::vector<Real> r(nx_,0.0);
643 std::vector<Real> s(nx_,0.0);
644 std::vector<Real> unew(nx_,0.0);
645 std::vector<Real> d(nx_,0.0);
646 std::vector<Real> dl(nx_-1,0.0);
647 std::vector<Real> du(nx_-1,0.0);
648 for (unsigned t = nt_; t > 0; t--) {
649 // Build rhs.
650 for (unsigned n = 0; n < nx_; n++) {
651 r[n] = (*vp)[(t-1)*nx_+n];
652 unew[n] = (*up)[(t-1)*nx_+n];
653 }
654 apply_pde_jacobian_old(J,s,unew,true);
655 update(r,J,-1.0);
656 // Build Jacobian.
657 compute_pde_jacobian(dl,d,du,unew);
658 // Solve linear system.
659 linear_solve(s,dl,d,du,r,true);
660 // Copy solution.
661 for (unsigned n = 0; n < nx_; n++) {
662 (*ijvp)[(t-1)*nx_+n] = s[n];
663 }
664 }
665 }
666
668 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol) {
669 ROL::Ptr<std::vector<Real> > hwvp =
670 dynamic_cast<ROL::StdVector<Real>&>(hwv).getVector();
671 ROL::Ptr<const std::vector<Real> > wp =
672 dynamic_cast<const ROL::StdVector<Real>&>(w).getVector();
673 ROL::Ptr<const std::vector<Real> > vp =
674 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
675 std::vector<Real> snew(nx_,0.0);
676 std::vector<Real> wnew(nx_,0.0);
677 std::vector<Real> wold(nx_,0.0);
678 std::vector<Real> vnew(nx_,0.0);
679 for (unsigned t = nt_; t > 0; t--) {
680 for (unsigned n = 0; n < nx_; n++) {
681 vnew[n] = (*vp)[(t-1)*nx_+n];
682 wnew[n] = (*wp)[(t-1)*nx_+n];
683 }
684 apply_pde_hessian(snew,wold,vnew,wnew,vnew);
685 for (unsigned n = 0; n < nx_; n++) {
686 (*hwvp)[(t-1)*nx_+n] = snew[n];
687 }
688 wold.assign(wnew.begin(),wnew.end());
689 }
690 }
691
693 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol) {
694 ahwv.zero();
695 }
697 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol) {
698 ahwv.zero();
699 }
701 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol) {
702 ahwv.zero();
703 }
704};
705
706template<class Real>
708private:
709 Real alpha_; // Penalty Parameter
710
711 unsigned nx_; // Number of interior nodes
712 Real dx_; // Mesh spacing (i.e. 1/(nx+1))
713 unsigned nt_; // Number of time steps
714 Real dt_; // Time step size
715 Real T_; // Final time
716
717/***************************************************************/
718/********** BEGIN PRIVATE MEMBER FUNCTION DECLARATION **********/
719/***************************************************************/
720 Real evaluate_target(Real x) {
721 Real val = 0.0;
722 int example = 1;
723 switch (example) {
724 case 1: val = ((x<=0.5) ? 1.0 : 0.0); break;
725 case 2: val = 1.0; break;
726 case 3: val = std::abs(std::sin(8.0*M_PI*x)); break;
727 case 4: val = std::exp(-0.5*(x-0.5)*(x-0.5)); break;
728 }
729 return val;
730 }
731
732 Real dot(const std::vector<Real> &x, const std::vector<Real> &y) {
733 Real ip = 0.0;
734 Real c = ((x.size()==nx_) ? 4.0 : 2.0);
735 for (unsigned i=0; i<x.size(); i++) {
736 if ( i == 0 ) {
737 ip += dx_/6.0*(c*x[i] + x[i+1])*y[i];
738 }
739 else if ( i == x.size()-1 ) {
740 ip += dx_/6.0*(x[i-1] + c*x[i])*y[i];
741 }
742 else {
743 ip += dx_/6.0*(x[i-1] + 4.0*x[i] + x[i+1])*y[i];
744 }
745 }
746 return ip;
747 }
748
749 void apply_mass(std::vector<Real> &Mu, const std::vector<Real> &u ) {
750 Mu.resize(u.size(),0.0);
751 Real c = ((u.size()==nx_) ? 4.0 : 2.0);
752 for (unsigned i=0; i<u.size(); i++) {
753 if ( i == 0 ) {
754 Mu[i] = dx_/6.0*(c*u[i] + u[i+1]);
755 }
756 else if ( i == u.size()-1 ) {
757 Mu[i] = dx_/6.0*(u[i-1] + c*u[i]);
758 }
759 else {
760 Mu[i] = dx_/6.0*(u[i-1] + 4.0*u[i] + u[i+1]);
761 }
762 }
763 }
764/*************************************************************/
765/********** END PRIVATE MEMBER FUNCTION DECLARATION **********/
766/*************************************************************/
767
768public:
769
770 Objective_BurgersControl(Real alpha = 1.e-4, int nx = 128, int nt = 100, Real T = 1.0)
771 : alpha_(alpha), nx_((unsigned)nx), nt_((unsigned)nt), T_(T) {
772 dx_ = 1.0/((Real)nx+1.0);
773 dt_ = T/((Real)nt);
774 }
775
776 Real value( const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol ) {
777 ROL::Ptr<const std::vector<Real> > up =
778 dynamic_cast<const ROL::StdVector<Real>&>(u).getVector();
779 ROL::Ptr<const std::vector<Real> > zp =
780 dynamic_cast<const ROL::StdVector<Real>&>(z).getVector();
781 // COMPUTE RESIDUAL
782 std::vector<Real> U(nx_,0.0);
783 std::vector<Real> G(nx_,0.0);
784 std::vector<Real> Z(nx_+2,0.0);
785 for (unsigned n = 0; n < nx_+2; n++) {
786 Z[n] = (*zp)[n];
787 }
788 Real ss = 0.5*dt_;
789 Real val = 0.5*ss*alpha_*dot(Z,Z);
790 for (unsigned t = 0; t < nt_; t++) {
791 ss = ((t < nt_-1) ? dt_ : 0.5*dt_);
792 for (unsigned n = 0; n < nx_; n++) {
793 U[n] = (*up)[t*nx_+n]-evaluate_target((Real)(n+1)*dx_);
794 G[n] = evaluate_target((Real)(n+1)*dx_);
795 }
796 val += 0.5*ss*dot(U,U);
797 val -= 0.5*ss*dot(G,G); // subtract constant term
798 for (unsigned n = 0; n < nx_+2; n++) {
799 Z[n] = (*zp)[(t+1)*(nx_+2)+n];
800 }
801 val += 0.5*ss*alpha_*dot(Z,Z);
802 }
803 return val;
804 }
805
806 void gradient_1( ROL::Vector<Real> &g, const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol ) {
807 ROL::Ptr<std::vector<Real> > gp =
808 dynamic_cast<ROL::StdVector<Real>&>(g).getVector();
809 ROL::Ptr<const std::vector<Real> > up =
810 dynamic_cast<const ROL::StdVector<Real>&>(u).getVector();
811 // COMPUTE GRADIENT WRT U
812 std::vector<Real> U(nx_,0.0);
813 std::vector<Real> M(nx_,0.0);
814 Real ss = dt_;
815 for (unsigned t = 0; t < nt_; t++) {
816 ss = ((t < nt_-1) ? dt_ : 0.5*dt_);
817 for (unsigned n = 0; n < nx_; n++) {
818 U[n] = (*up)[t*nx_+n]-evaluate_target((Real)(n+1)*dx_);
819 }
820 apply_mass(M,U);
821 for (unsigned n = 0; n < nx_; n++) {
822 (*gp)[t*nx_+n] = ss*M[n];
823 }
824 }
825 }
826
827 void gradient_2( ROL::Vector<Real> &g, const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol ) {
828 ROL::Ptr<std::vector<Real> > gp =
829 dynamic_cast<ROL::StdVector<Real>&>(g).getVector();
830 ROL::Ptr<const std::vector<Real> > zp =
831 dynamic_cast<const ROL::StdVector<Real>&>(z).getVector();
832 // COMPUTE GRADIENT WRT Z
833 std::vector<Real> Z(nx_+2,0.0);
834 std::vector<Real> M(nx_+2,0.0);
835 Real ss = dt_;
836 for (unsigned t = 0; t < nt_+1; t++) {
837 ss = ((t < nt_ && t > 0) ? dt_ : 0.5*dt_);
838 for (unsigned n = 0; n < nx_+2; n++) {
839 Z[n] = (*zp)[t*(nx_+2)+n];
840 }
841 apply_mass(M,Z);
842 for (unsigned n = 0; n < nx_+2; n++) {
843 (*gp)[t*(nx_+2)+n] = ss*alpha_*M[n];
844 }
845 }
846 }
847
849 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol ) {
850 ROL::Ptr<std::vector<Real> > hvp =
851 dynamic_cast<ROL::StdVector<Real>&>(hv).getVector();
852 ROL::Ptr<const std::vector<Real> > vp =
853 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
854 // COMPUTE GRADIENT WRT U
855 std::vector<Real> V(nx_,0.0);
856 std::vector<Real> M(nx_,0.0);
857 Real ss = 0.5*dt_;
858 for (unsigned t = 0; t < nt_; t++) {
859 ss = ((t < nt_-1) ? dt_ : 0.5*dt_);
860 for (unsigned n = 0; n < nx_; n++) {
861 V[n] = (*vp)[t*nx_+n];
862 }
863 apply_mass(M,V);
864 for (unsigned n = 0; n < nx_; n++) {
865 (*hvp)[t*nx_+n] = ss*M[n];
866 }
867 }
868 }
869
871 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol ) {
872 hv.zero();
873 }
874
876 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol ) {
877 hv.zero();
878 }
879
881 const ROL::Vector<Real> &u, const ROL::Vector<Real> &z, Real &tol ) {
882 ROL::Ptr<std::vector<Real> > hvp = ROL::constPtrCast<std::vector<Real> >(
883 (dynamic_cast<const ROL::StdVector<Real>&>(hv)).getVector());
884 ROL::Ptr<const std::vector<Real> > vp =
885 dynamic_cast<const ROL::StdVector<Real>&>(v).getVector();
886 // COMPUTE GRADIENT WRT Z
887 std::vector<Real> V(nx_+2,0.0);
888 std::vector<Real> M(nx_+2,0.0);
889 Real ss = 0.0;
890 for (unsigned t = 0; t < nt_+1; t++) {
891 ss = ((t < nt_ && t > 0) ? dt_ : 0.5*dt_);
892 for (unsigned n = 0; n < nx_+2; n++) {
893 V[n] = (*vp)[t*(nx_+2)+n];
894 }
895 apply_mass(M,V);
896 for (unsigned n = 0; n < nx_+2; n++) {
897 (*hvp)[t*(nx_+2)+n] = ss*alpha_*M[n];
898 }
899 }
900 }
901};
Vector< Real > V
Defines a no-output stream class ROL::NullStream and a function makeStreamPtr which either wraps a re...
Contains definitions of custom data types in ROL.
void scale(std::vector< Real > &u, const Real alpha=0.0)
void applyAdjointHessian_22(ROL::Vector< Real > &ahwv, const ROL::Vector< Real > &w, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the optimization-space derivative of the adjoint of the constraint optimization-space Jacobian ...
void compute_residual(std::vector< Real > &r, const std::vector< Real > &uold, const std::vector< Real > &zold, const std::vector< Real > &unew, const std::vector< Real > &znew)
void compute_residual(std::vector< Real > &r, const std::vector< Real > &u, const std::vector< Real > &z)
void apply_pde_jacobian_new(std::vector< Real > &jv, const std::vector< Real > &v, const std::vector< Real > &u, bool adjoint=false)
void applyAdjointHessian_11(ROL::Vector< Real > &hwv, const ROL::Vector< Real > &w, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the simulation-space derivative of the adjoint of the constraint simulation-space Jacobian at ...
void apply_pde_jacobian(std::vector< Real > &jv, const std::vector< Real > &vold, const std::vector< Real > &uold, const std::vector< Real > &vnew, const std::vector< Real > unew, bool adjoint=false)
void applyInverseAdjointJacobian_1(ROL::Vector< Real > &ijv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the inverse of the adjoint of the partial constraint Jacobian at , , to the vector .
void applyAdjointJacobian_2(ROL::Vector< Real > &jv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the adjoint of the partial constraint Jacobian at , , to vector . This is the primary interface...
void applyAdjointJacobian_1(ROL::Vector< Real > &ajv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the adjoint of the partial constraint Jacobian at , , to the vector . This is the primary inter...
void compute_pde_jacobian(std::vector< Real > &dl, std::vector< Real > &d, std::vector< Real > &du, const std::vector< Real > &u)
void applyJacobian_2(ROL::Vector< Real > &jv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the partial constraint Jacobian at , , to the vector .
std::vector< Real > u_init_
Real compute_norm(const std::vector< Real > &r)
void apply_control_jacobian(std::vector< Real > &jv, const std::vector< Real > &v, bool adjoint=false)
void applyAdjointHessian_21(ROL::Vector< Real > &ahwv, const ROL::Vector< Real > &w, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the simulation-space derivative of the adjoint of the constraint optimization-space Jacobian at...
void update(std::vector< Real > &u, const std::vector< Real > &s, const Real alpha=1.0)
void apply_pde_hessian(std::vector< Real > &hv, const std::vector< Real > &wold, const std::vector< Real > &vold, const std::vector< Real > &wnew, const std::vector< Real > &vnew)
void run_newton(std::vector< Real > &u, const std::vector< Real > &znew, const std::vector< Real > &uold, const std::vector< Real > &zold)
void linear_solve(std::vector< Real > &u, const std::vector< Real > &dl, const std::vector< Real > &d, const std::vector< Real > &du, const std::vector< Real > &r, const bool transpose=false)
void applyInverseJacobian_1(ROL::Vector< Real > &ijv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the inverse partial constraint Jacobian at , , to the vector .
Constraint_BurgersControl(int nx=128, int nt=100, Real T=1, Real nu=1.e-2, Real u0=0.0, Real u1=0.0, Real f=0.0)
void value(ROL::Vector< Real > &c, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Evaluate the constraint operator at .
Real dot(const std::vector< Real > &x, const std::vector< Real > &y)
void applyAdjointHessian_12(ROL::Vector< Real > &ahwv, const ROL::Vector< Real > &w, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the optimization-space derivative of the adjoint of the constraint simulation-space Jacobian at...
void linear_solve(std::vector< Real > &u, std::vector< Real > &dl, std::vector< Real > &d, std::vector< Real > &du, const std::vector< Real > &r, const bool transpose=false)
void applyJacobian_1(ROL::Vector< Real > &jv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply the partial constraint Jacobian at , , to the vector .
void apply_pde_jacobian_old(std::vector< Real > &jv, const std::vector< Real > &v, const std::vector< Real > &u, bool adjoint=false)
void solve(ROL::Vector< Real > &c, ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Given , solve for .
Real dot(const std::vector< Real > &x, const std::vector< Real > &y)
void apply_mass(std::vector< Real > &Mu, const std::vector< Real > &u)
void hessVec_21(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
void gradient_1(ROL::Vector< Real > &g, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Compute gradient with respect to first component.
void hessVec_11(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Apply Hessian approximation to vector.
void hessVec_22(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
void gradient_2(ROL::Vector< Real > &g, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Compute gradient with respect to second component.
void hessVec_12(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Real value(const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Compute value.
Objective_BurgersControl(Real alpha=1.e-4, int nx=128, int nt=100, Real T=1.0)
Defines the constraint operator interface for simulation-based optimization.
Provides the interface to evaluate simulation-based objective functions.
Provides the ROL::Vector interface for scalar values, to be used, for example, with scalar constraint...
Defines the linear algebra or vector space interface.
virtual Real norm() const =0
Returns where .
virtual void zero()
Set to zero vector.
constexpr auto dim