57 #include "ROL_ParameterList.hpp"
60 #include "Teuchos_GlobalMPISession.hpp"
61 #include "Teuchos_LAPACK.hpp"
85 return std::sqrt(
dot(r,r));
88 Real
dot(
const std::vector<Real> &x,
const std::vector<Real> &y) {
90 Real c = ((x.size()==
nx_) ? 4.0 : 2.0);
91 for (
unsigned i = 0; i < x.size(); i++) {
93 ip +=
dx_/6.0*(c*x[i] + x[i+1])*y[i];
95 else if ( i == x.size()-1 ) {
96 ip +=
dx_/6.0*(x[i-1] + c*x[i])*y[i];
99 ip +=
dx_/6.0*(x[i-1] + 4.0*x[i] + x[i+1])*y[i];
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++) {
113 void scale(std::vector<Real> &u,
const Real alpha=0.0) {
114 for (
unsigned i = 0; i < u.size(); i++) {
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) {
123 for (
unsigned n = 0; n <
nx_; n++) {
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;
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;
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]);
156 const std::vector<Real> &u) {
165 for (
unsigned n = 0; n <
nx_; n++) {
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;
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;
181 bool adjoint =
false) {
185 for (
unsigned n = 0; n <
nx_; n++) {
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]);
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]);
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]);
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]);
206 jv[0] -= 0.5*
dt_*
u0_/6.0*v[0];
211 bool adjoint =
false) {
215 for (
unsigned n = 0; n <
nx_; n++) {
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]);
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]);
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]);
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]);
236 jv[0] -= 0.5*
dt_*
u0_/6.0*v[0];
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) {
245 for (
unsigned n = 0; n <
nx_; n++) {
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]);
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]);
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]);
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]);
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]);
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]);
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]);
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]);
273 jv[0] -= 0.5*
dt_*
u0_/6.0*vnew[0];
274 jv[0] -= 0.5*
dt_*
u0_/6.0*vold[0];
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) {
283 for (
unsigned n = 0; n <
nx_; n++) {
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);
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);
297 unsigned dim = ((adjoint ==
true) ?
nx_+2 :
nx_);
299 for (
unsigned n = 0; n < dim; n++) {
302 jv[n] = -0.5*
dt_*
dx_/6.0*v[n];
305 jv[n] = -0.5*
dt_*
dx_/6.0*(4.0*v[n-1]+v[n]);
307 else if ( n ==
nx_ ) {
308 jv[n] = -0.5*
dt_*
dx_/6.0*(4.0*v[n-1]+v[n-2]);
310 else if ( n ==
nx_+1 ) {
311 jv[n] = -0.5*
dt_*
dx_/6.0*v[n-2];
314 jv[n] = -0.5*
dt_*
dx_/6.0*(v[n-2]+4.0*v[n-1]+v[n]);
318 jv[n] -= 0.5*
dt_*
dx_/6.0*(v[n]+4.0*v[n+1]+v[n+2]);
323 void run_newton(std::vector<Real> &u,
const std::vector<Real> &znew,
324 const std::vector<Real> &uold,
const std::vector<Real> &zold) {
328 std::vector<Real> r(
nx_,0.0);
332 Real rtol = 1.e2*ROL::ROL_EPSILON<Real>();
333 unsigned maxit = 500;
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);
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++) {
351 utmp.assign(u.begin(),u.end());
355 while ( rnorm > (1.0-1.e-4*alpha)*tmp && alpha > std::sqrt(ROL::ROL_EPSILON<Real>()) ) {
357 utmp.assign(u.begin(),u.end());
363 u.assign(utmp.begin(),utmp.end());
364 if ( rnorm < rtol ) {
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;
375 u.assign(r.begin(),r.end());
377 std::vector<Real> Dl(dl);
378 std::vector<Real> Du(du);
379 std::vector<Real> D(d);
381 Teuchos::LAPACK<int,Real> lp;
382 std::vector<Real> Du2(
nx_-2,0.0);
383 std::vector<int> ipiv(
nx_,0);
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);
394 unsigned maxit = 100;
395 Real rtol = std::min(1.e-12,1.e-4*std::sqrt(
dot(r,r)));
398 Real rnorm = 10.0*rtol;
399 for (
unsigned i = 0; i < maxit; i++) {
400 for (
unsigned n = 0; n <
nx_; n++) {
403 u[n] -= ((transpose ==
false) ? du[n] : dl[n])*u[n+1]/d[n];
406 u[n] -= ((transpose ==
false) ? dl[n-1] : du[n-1])*u[n-1]/d[n];
411 for (
unsigned n = 0; n <
nx_; n++) {
412 resid = r[n] - d[n]*u[n];
414 resid -= ((transpose ==
false) ? du[n] : dl[n])*u[n+1];
417 resid -= ((transpose ==
false) ? dl[n-1] : du[n-1])*u[n-1];
419 rnorm += resid*resid;
421 rnorm = std::sqrt(rnorm);
422 if ( rnorm < rtol ) {
433 Real nu = 1.e-2, Real u0 = 0.0, Real u1 = 0.0, Real f = 0.0)
435 dx_ = 1.0/((Real)nx+1.0);
440 for (
unsigned n = 0; n <
nx_; n++) {
442 u_init_[n] = ((x <= 0.5) ? 1.0 : 0.0);
447 ROL::Ptr<std::vector<Real> > cp =
449 ROL::Ptr<const std::vector<Real> > up =
451 ROL::Ptr<const std::vector<Real> > zp =
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);
460 for (
unsigned n = 0; n <
nx_+2; n++) {
464 for (
unsigned t = 0; t <
nt_; t++) {
466 for (
unsigned n = 0; n <
nx_; n++) {
467 unew[n] = (*up)[t*
nx_+n];
470 for (
unsigned n = 0; n <
nx_+2; n++) {
471 znew[n] = (*zp)[(t+1)*(
nx_+2)+n];
476 for (
unsigned n = 0; n <
nx_; n++) {
477 (*cp)[t*
nx_+n] = C[n];
480 uold.assign(unew.begin(),unew.end());
481 zold.assign(znew.begin(),znew.end());
486 ROL::Ptr<std::vector<Real> > up =
488 up->assign(up->size(),z.
norm()/up->size());
489 ROL::Ptr<const std::vector<Real> > zp =
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);
497 for (
unsigned n = 0; n <
nx_+2; n++) {
501 for (
unsigned t = 0; t <
nt_; t++) {
503 for (
unsigned n = 0; n <
nx_+2; n++) {
504 znew[n] = (*zp)[(t+1)*(
nx_+2)+n];
509 for (
unsigned n = 0; n <
nx_; n++) {
510 (*up)[t*
nx_+n] = unew[n];
513 uold.assign(unew.begin(),unew.end());
514 zold.assign(znew.begin(),znew.end());
521 ROL::Ptr<std::vector<Real> > jvp =
523 ROL::Ptr<const std::vector<Real> > vp =
525 ROL::Ptr<const std::vector<Real> > up =
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];
538 for (
unsigned n = 0; n <
nx_; n++) {
539 (*jvp)[t*
nx_+n] = J[n];
541 vold.assign(vnew.begin(),vnew.end());
542 uold.assign(unew.begin(),unew.end());
548 ROL::Ptr<std::vector<Real> > jvp =
550 ROL::Ptr<const std::vector<Real> > vp =
552 ROL::Ptr<const std::vector<Real> > zp =
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++) {
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];
567 for (
unsigned n = 0; n <
nx_; n++) {
569 (*jvp)[t*
nx_+n] = jnew[n] + jold[n];
571 jold.assign(jnew.begin(),jnew.end());
577 ROL::Ptr<std::vector<Real> > ijvp =
579 ROL::Ptr<const std::vector<Real> > vp =
581 ROL::Ptr<const std::vector<Real> > up =
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++) {
593 for (
unsigned n = 0; n <
nx_; n++) {
594 r[n] = (*vp)[t*
nx_+n];
595 unew[n] = (*up)[t*
nx_+n];
604 for (
unsigned n = 0; n <
nx_; n++) {
605 (*ijvp)[t*
nx_+n] = s[n];
607 uold.assign(unew.begin(),unew.end());
613 ROL::Ptr<std::vector<Real> > jvp =
615 ROL::Ptr<const std::vector<Real> > vp =
617 ROL::Ptr<const std::vector<Real> > up =
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];
629 for (
unsigned n = 0; n <
nx_; n++) {
630 (*jvp)[(t-1)*
nx_+n] = J[n];
632 vold.assign(vnew.begin(),vnew.end());
638 ROL::Ptr<std::vector<Real> > jvp =
640 ROL::Ptr<const std::vector<Real> > vp =
642 ROL::Ptr<const std::vector<Real> > zp =
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++) {
651 vnew[n] = (*vp)[(t-2)*
nx_+n];
658 for (
unsigned n = 0; n <
nx_+2; n++) {
660 (*jvp)[(t-1)*(
nx_+2)+n] = jnew[n] + jold[n];
662 jold.assign(jnew.begin(),jnew.end());
668 ROL::Ptr<std::vector<Real> > ijvp =
670 ROL::Ptr<const std::vector<Real> > vp =
672 ROL::Ptr<const std::vector<Real> > up =
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--) {
683 for (
unsigned n = 0; n <
nx_; n++) {
684 r[n] = (*vp)[(t-1)*
nx_+n];
685 unew[n] = (*up)[(t-1)*
nx_+n];
694 for (
unsigned n = 0; n <
nx_; n++) {
695 (*ijvp)[(t-1)*
nx_+n] = s[n];
702 ROL::Ptr<std::vector<Real> > hwvp =
704 ROL::Ptr<const std::vector<Real> > wp =
706 ROL::Ptr<const std::vector<Real> > vp =
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];
718 for (
unsigned n = 0; n <
nx_; n++) {
719 (*hwvp)[(t-1)*
nx_+n] = snew[n];
721 wold.assign(wnew.begin(),wnew.end());
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;
765 Real
dot(
const std::vector<Real> &x,
const std::vector<Real> &y) {
767 Real c = ((x.size()==
nx_) ? 4.0 : 2.0);
768 for (
unsigned i=0; i<x.size(); i++) {
770 ip +=
dx_/6.0*(c*x[i] + x[i+1])*y[i];
772 else if ( i == x.size()-1 ) {
773 ip +=
dx_/6.0*(x[i-1] + c*x[i])*y[i];
776 ip +=
dx_/6.0*(x[i-1] + 4.0*x[i] + x[i+1])*y[i];
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++) {
787 Mu[i] =
dx_/6.0*(c*u[i] + u[i+1]);
789 else if ( i == u.size()-1 ) {
790 Mu[i] =
dx_/6.0*(u[i-1] + c*u[i]);
793 Mu[i] =
dx_/6.0*(u[i-1] + 4.0*u[i] + u[i+1]);
805 dx_ = 1.0/((Real)nx+1.0);
810 ROL::Ptr<const std::vector<Real> > up =
812 ROL::Ptr<const std::vector<Real> > zp =
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++) {
823 for (
unsigned t = 0; t <
nt_; t++) {
825 for (
unsigned n = 0; n <
nx_; n++) {
829 val += 0.5*ss*
dot(U,U);
830 val -= 0.5*ss*
dot(G,G);
831 for (
unsigned n = 0; n <
nx_+2; n++) {
832 Z[n] = (*zp)[(t+1)*(
nx_+2)+n];
840 ROL::Ptr<std::vector<Real> > gp =
842 ROL::Ptr<const std::vector<Real> > up =
845 std::vector<Real> U(
nx_,0.0);
846 std::vector<Real> M(
nx_,0.0);
848 for (
unsigned t = 0; t <
nt_; t++) {
850 for (
unsigned n = 0; n <
nx_; n++) {
854 for (
unsigned n = 0; n <
nx_; n++) {
855 (*gp)[t*
nx_+n] = ss*M[n];
861 ROL::Ptr<std::vector<Real> > gp =
863 ROL::Ptr<const std::vector<Real> > zp =
866 std::vector<Real> Z(
nx_+2,0.0);
867 std::vector<Real> M(
nx_+2,0.0);
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];
875 for (
unsigned n = 0; n <
nx_+2; n++) {
883 ROL::Ptr<std::vector<Real> > hvp =
885 ROL::Ptr<const std::vector<Real> > vp =
888 std::vector<Real>
V(
nx_,0.0);
889 std::vector<Real> M(
nx_,0.0);
891 for (
unsigned t = 0; t <
nt_; t++) {
893 for (
unsigned n = 0; n <
nx_; n++) {
894 V[n] = (*vp)[t*
nx_+n];
897 for (
unsigned n = 0; n <
nx_; n++) {
898 (*hvp)[t*
nx_+n] = ss*M[n];
915 ROL::Ptr<std::vector<Real> > hvp = ROL::constPtrCast<std::vector<Real> >(
917 ROL::Ptr<const std::vector<Real> > vp =
920 std::vector<Real>
V(
nx_+2,0.0);
921 std::vector<Real> M(
nx_+2,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];
929 for (
unsigned n = 0; n <
nx_+2; n++) {