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