53 #include "Teuchos_oblackholestream.hpp"
54 #include "Teuchos_GlobalMPISession.hpp"
55 #include "Teuchos_XMLParameterListHelpers.hpp"
56 #include "Teuchos_LAPACK.hpp"
80 case 1: val = ((x<0.5) ? 1.0 : 0.0);
break;
81 case 2: val = 1.0;
break;
82 case 3: val = std::abs(std::sin(8.0*M_PI*x));
break;
83 case 4: val = std::exp(-0.5*(x-0.5)*(x-0.5));
break;
89 return std::sqrt(this->
dot(r,r));
92 Real
dot(
const std::vector<Real> &x,
const std::vector<Real> &y) {
94 Real c = (((int)x.size()==this->
nx_) ? 4.0 : 2.0);
95 for (
unsigned i=0; i<x.size(); i++) {
97 ip += this->
dx_/6.0*(c*x[i] + x[i+1])*y[i];
99 else if ( i == x.size()-1 ) {
100 ip += this->
dx_/6.0*(x[i-1] + c*x[i])*y[i];
103 ip += this->
dx_/6.0*(x[i-1] + 4.0*x[i] + x[i+1])*y[i];
109 void update(std::vector<Real> &u,
const std::vector<Real> &s,
const Real alpha=1.0) {
110 for (
unsigned i=0; i<u.size(); i++) {
115 void scale(std::vector<Real> &u,
const Real alpha=0.0) {
116 for (
unsigned i=0; i<u.size(); i++) {
121 void apply_mass(std::vector<Real> &Mu,
const std::vector<Real> &u ) {
122 Mu.resize(u.size(),0.0);
123 Real c = (((int)u.size()==this->
nx_) ? 4.0 : 2.0);
124 for (
unsigned i=0; i<u.size(); i++) {
126 Mu[i] = this->
dx_/6.0*(c*u[i] + u[i+1]);
128 else if ( i == u.size()-1 ) {
129 Mu[i] = this->
dx_/6.0*(u[i-1] + c*u[i]);
132 Mu[i] = this->
dx_/6.0*(u[i-1] + 4.0*u[i] + u[i+1]);
138 const std::vector<Real> &z,
const std::vector<Real> ¶m) {
140 r.resize(this->
nx_,0.0);
141 Real nu = std::pow(10.0,param[0]-2.0);
142 Real f = param[1]/100.0;
143 Real u0 = 1.0+param[2]/1000.0;
144 Real u1 = param[3]/1000.0;
145 for (
int i=0; i<this->
nx_; i++) {
148 r[i] = nu/this->
dx_*(2.0*u[i]-u[i+1]);
150 else if (i==this->nx_-1) {
151 r[i] = nu/this->
dx_*(2.0*u[i]-u[i-1]);
154 r[i] = nu/this->
dx_*(2.0*u[i]-u[i-1]-u[i+1]);
158 r[i] += u[i+1]*(u[i]+u[i+1])/6.0;
161 r[i] -= u[i-1]*(u[i-1]+u[i])/6.0;
164 r[i] -= this->
dx_/6.0*(z[i]+4.0*z[i+1]+z[i+2]);
169 r[0] -= u0*u[ 0]/6.0 + u0*u0/6.0 + nu*u0/this->
dx_;
170 r[this->nx_-1] += u1*u[this->nx_-1]/6.0 + u1*u1/6.0 - nu*u1/this->
dx_;
174 const std::vector<Real> &u,
const std::vector<Real> ¶m) {
175 Real nu = std::pow(10.0,param[0]-2.0);
176 Real u0 = 1.0+param[2]/1000.0;
177 Real u1 = param[3]/1000.0;
180 d.resize(this->
nx_,nu*2.0/this->
dx_);
182 dl.resize(this->
nx_-1,-nu/this->
dx_);
184 du.resize(this->
nx_-1,-nu/this->
dx_);
186 for (
int i=0; i<this->
nx_; i++) {
188 dl[i] += (-2.0*u[i]-u[i+1])/6.0;
193 du[i-1] += (u[i-1]+2.0*u[i])/6.0;
198 d[this->nx_-1] += u1/6.0;
201 void add_pde_hessian(std::vector<Real> &r,
const std::vector<Real> &u,
const std::vector<Real> &p,
202 const std::vector<Real> &s, Real alpha = 1.0) {
203 for (
int i=0; i<this->
nx_; i++) {
206 r[i] += alpha*(p[i]*s[i+1] - p[i+1]*(2.0*s[i]+s[i+1]))/6.0;
209 r[i] += alpha*(p[i-1]*(s[i-1]+2.0*s[i]) - p[i]*s[i-1])/6.0;
214 void linear_solve(std::vector<Real> &u, std::vector<Real> &dl, std::vector<Real> &d, std::vector<Real> &du,
215 const std::vector<Real> &r,
const bool transpose =
false) {
216 u.assign(r.begin(),r.end());
218 Teuchos::LAPACK<int,Real> lp;
219 std::vector<Real> du2(this->
nx_-2,0.0);
220 std::vector<int> ipiv(this->
nx_,0);
224 lp.GTTRF(this->
nx_,&dl[0],&d[0],&du[0],&du2[0],&ipiv[0],&info);
229 lp.GTTRS(trans,this->
nx_,nhrs,&dl[0],&d[0],&du[0],&du2[0],&ipiv[0],&u[0],ldb,&info);
232 void run_newton(std::vector<Real> &u,
const std::vector<Real> &z,
const std::vector<Real> ¶m) {
234 std::vector<Real> r(u.size(),0.0);
241 std::vector<Real> d(this->
nx_,0.0);
242 std::vector<Real> dl(this->
nx_-1,0.0);
243 std::vector<Real> du(this->
nx_-1,0.0);
245 Real alpha = 1.0, tmp = 0.0;
246 std::vector<Real> s(this->
nx_,0.0);
247 std::vector<Real> utmp(this->
nx_,0.0);
248 for (
int i=0; i<maxit; i++) {
257 utmp.assign(u.begin(),u.end());
258 this->
update(utmp,s,-alpha);
261 while ( rnorm > (1.0-1.e-4*alpha)*tmp && alpha > std::sqrt(
ROL::ROL_EPSILON) ) {
263 utmp.assign(u.begin(),u.end());
264 this->
update(utmp,s,-alpha);
269 u.assign(utmp.begin(),utmp.end());
282 dx_ = 1.0/((Real)nx+1.0);
285 void solve_state(std::vector<Real> &u,
const std::vector<Real> &z,
const std::vector<Real> ¶m) {
287 u.resize(this->
nx_,1.0);
291 void solve_adjoint(std::vector<Real> &p,
const std::vector<Real> &u,
const std::vector<Real> ¶m) {
296 std::vector<Real> d(this->
nx_,0.0);
297 std::vector<Real> du(this->
nx_-1,0.0);
298 std::vector<Real> dl(this->
nx_-1,0.0);
301 std::vector<Real> r(this->
nx_,0.0);
302 std::vector<Real> diff(this->
nx_,0.0);
303 for (
int i=0; i<this->
nx_; i++) {
312 const std::vector<Real> &z,
const std::vector<Real> ¶m) {
317 std::vector<Real> d(this->
nx_,0.0);
318 std::vector<Real> dl(this->
nx_-1,0.0);
319 std::vector<Real> du(this->
nx_-1,0.0);
322 std::vector<Real> r(this->
nx_,0.0);
323 for (
int i=0; i<this->
nx_; i++) {
324 r[i] = this->
dx_/6.0*(z[i]+4.0*z[i+1]+z[i+2]);
331 const std::vector<Real> &p,
const std::vector<Real> &v,
332 const std::vector<Real> &z,
const std::vector<Real> ¶m) {
337 std::vector<Real> d(this->
nx_,0.0);
338 std::vector<Real> dl(this->
nx_-1,0.0);
339 std::vector<Real> du(this->
nx_-1,0.0);
342 std::vector<Real> r(this->
nx_,0.0);
351 Teuchos::RCP<const std::vector<Real> > zp =
354 std::vector<Real> param(4,0.0);
358 Real val = this->
alpha_*0.5*this->
dot(*zp,*zp);
359 Real res = 0.0, res1 = 0.0, res2 = 0.0, res3 = 0.0;
360 for (
int i=0; i<this->
nx_; i++) {
364 res = this->
dx_/6.0*(4.0*res1 + res2)*res1;
366 else if ( i == this->nx_-1 ) {
369 res = this->dx_/6.0*(res1 + 4.0*res2)*res2;
375 res = this->dx_/6.0*(res1 + 4.0*res2 + res3)*res2;
383 Teuchos::RCP<const std::vector<Real> > zp =
385 Teuchos::RCP<std::vector<Real> > gp =
386 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(g)).getVector());
388 std::vector<Real> param(4,0.0);
395 for (
int i=0; i<this->
nx_+2; i++) {
397 (*gp)[i] = this->
alpha_*this->
dx_/6.0*(2.0*(*zp)[i]+(*zp)[i+1]);
398 (*gp)[i] -= this->
dx_/6.0*(p[i]);
400 else if (i==this->nx_+1) {
401 (*gp)[i] = this->
alpha_*this->
dx_/6.0*(2.0*(*zp)[i]+(*zp)[i-1]);
402 (*gp)[i] -= this->
dx_/6.0*(p[i-2]);
405 (*gp)[i] = this->
alpha_*this->
dx_/6.0*((*zp)[i-1]+4.0*(*zp)[i]+(*zp)[i+1]);
407 (*gp)[i] -= this->
dx_/6.0*(4.0*p[i-1]+p[i]);
409 else if (i==this->nx_) {
410 (*gp)[i] -= this->
dx_/6.0*(4.0*p[i-1]+p[i-2]);
413 (*gp)[i] -= this->
dx_/6.0*(p[i-2]+4.0*p[i-1]+p[i]);
420 Teuchos::RCP<const std::vector<Real> > zp =
422 Teuchos::RCP<const std::vector<Real> > vp =
424 Teuchos::RCP<std::vector<Real> > hvp =
425 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(hv)).getVector());
427 std::vector<Real> param(4,0.0);
440 for (
int i=0; i<this->
nx_+2; i++) {
442 (*hvp)[i] = this->
alpha_*this->
dx_/6.0*(2.0*(*vp)[i]+(*vp)[i+1]);
443 (*hvp)[i] -= this->
dx_/6.0*(q[i]);
445 else if (i==this->nx_+1) {
446 (*hvp)[i] = this->
alpha_*this->
dx_/6.0*(2.0*(*vp)[i]+(*vp)[i-1]);
447 (*hvp)[i] -= this->
dx_/6.0*(q[i-2]);
450 (*hvp)[i] = this->
alpha_*this->
dx_/6.0*((*vp)[i-1]+4.0*(*vp)[i]+(*vp)[i+1]);
452 (*hvp)[i] -= this->
dx_/6.0*(4.0*q[i-1]+q[i]);
454 else if (i==this->nx_) {
455 (*hvp)[i] -= this->
dx_/6.0*(4.0*q[i-1]+q[i-2]);
458 (*hvp)[i] -= this->
dx_/6.0*(q[i-2]+4.0*q[i-1]+q[i]);
478 Teuchos::RCP<const std::vector<Real> > ex =
482 for (
int i = 0; i < this->
dim_; i++ ) {
483 if ( (*ex)[i] >= this->
x_lo_[i] && (*ex)[i] <= this->
x_up_[i] ) { cnt *= 1; }
486 if ( cnt == 0 ) { val =
false; }
490 Teuchos::RCP<std::vector<Real> > ex =
491 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(x)).getVector());
492 for (
int i = 0; i < this->
dim_; i++ ) {
493 (*ex)[i] = std::max(this->
x_lo_[i],std::min(this->
x_up_[i],(*ex)[i]));
497 Teuchos::RCP<const std::vector<Real> > ex =
499 Teuchos::RCP<std::vector<Real> > ev =
500 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(v)).getVector());
501 Real epsn = std::min(eps,this->
min_diff_);
502 for (
int i = 0; i < this->
dim_; i++ ) {
503 if ( ((*ex)[i] <= this->
x_lo_[i]+epsn) ) {
509 Teuchos::RCP<const std::vector<Real> > ex =
511 Teuchos::RCP<std::vector<Real> > ev =
512 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(v)).getVector());
513 Real epsn = std::min(eps,this->
min_diff_);
514 for (
int i = 0; i < this->
dim_; i++ ) {
515 if ( ((*ex)[i] >= this->
x_up_[i]-epsn) ) {
521 Teuchos::RCP<const std::vector<Real> > ex =
523 Teuchos::RCP<const std::vector<Real> > eg =
525 Teuchos::RCP<std::vector<Real> > ev =
526 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(v)).getVector());
527 Real epsn = std::min(eps,this->
min_diff_);
528 for (
int i = 0; i < this->
dim_; i++ ) {
529 if ( ((*ex)[i] <= this->
x_lo_[i]+epsn && (*eg)[i] > 0.0) ){
535 Teuchos::RCP<const std::vector<Real> > ex =
537 Teuchos::RCP<const std::vector<Real> > eg =
539 Teuchos::RCP<std::vector<Real> > ev =
540 Teuchos::rcp_const_cast<std::vector<Real> >((Teuchos::dyn_cast<
ROL::StdVector<Real> >(v)).getVector());
541 Real epsn = std::min(eps,this->
min_diff_);
542 for (
int i = 0; i < this->
dim_; i++ ) {
543 if ( ((*ex)[i] >= this->
x_up_[i]-epsn && (*eg)[i] < 0.0) ) {
549 Teuchos::RCP<std::vector<Real> > us = Teuchos::rcp(
new std::vector<Real>(this->
dim_,0.0) );
550 us->assign(this->
x_up_.begin(),this->
x_up_.end());
555 Teuchos::RCP<std::vector<Real> > ls = Teuchos::rcp(
new std::vector<Real>(this->
dim_,0.0) );
556 ls->assign(this->
x_lo_.begin(),this->
x_lo_.end());
564 int main(
int argc,
char *argv[]) {
566 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
569 int iprint = argc - 1;
570 Teuchos::RCP<std::ostream> outStream;
571 Teuchos::oblackholestream bhs;
573 outStream = Teuchos::rcp(&std::cout,
false);
575 outStream = Teuchos::rcp(&bhs,
false);
587 Teuchos::RCP<std::vector<RealT> > x_rcp = Teuchos::rcp(
new std::vector<RealT> (nx+2, 1.0) );
588 Teuchos::RCP<std::vector<RealT> > y_rcp = Teuchos::rcp(
new std::vector<RealT> (nx+2, 0.0) );
589 for (
int i=0; i<nx+2; i++) {
602 Teuchos::ParameterList parlist;
604 parlist.set(
"Absolute Krylov Tolerance", 1.e-8);
605 parlist.set(
"Relative Krylov Tolerance", 1.e-4);
606 parlist.set(
"Maximum Number of Krylov Iterations", 50);
608 parlist.set(
"PDAS Relative Step Tolerance", 1.e-10);
609 parlist.set(
"PDAS Relative Gradient Tolerance", 1.e-8);
610 parlist.set(
"PDAS Maximum Number of Iterations", 10);
611 parlist.set(
"PDAS Dual Scaling", (alpha>0.0) ? alpha : 1.e-4 );
623 algo_pdas.
run(x, obj, icon,
true, *outStream);
625 std::ofstream file_pdas;
626 file_pdas.open(
"control_PDAS.txt");
627 for (
unsigned i = 0; i < (unsigned)nx+2; i++ ) {
628 file_pdas << (*x_rcp)[i] <<
"\n";
633 std::string filename =
"input.xml";
634 Teuchos::RCP<Teuchos::ParameterList> parlist_tr = Teuchos::rcp(
new Teuchos::ParameterList() );
635 Teuchos::updateParametersFromXmlFile( filename, Teuchos::Ptr<Teuchos::ParameterList>(&*parlist_tr) );
642 algo_tr.
run(y,obj,icon,
true,*outStream);
644 std::ofstream file_tr;
645 file_tr.open(
"control_TR.txt");
646 for (
unsigned i = 0; i < (unsigned)nx+2; i++ ) {
647 file_tr << (*y_rcp)[i] <<
"\n";
651 std::vector<RealT> u(nx,0.0);
652 std::vector<RealT> param(4,0.0);
655 file.open(
"state.txt");
656 for (
unsigned i=0; i<(unsigned)nx; i++) {
657 file << i/((
RealT)(nx+1)) <<
" " << u[i] <<
"\n";
661 Teuchos::RCP<ROL::Vector<RealT> > diff = x.
clone();
664 RealT error = diff->norm();
665 *outStream <<
"\nError between PDAS solution and TR solution is " << error <<
"\n";
668 catch (std::logic_error err) {
669 *outStream << err.what() <<
"\n";
674 std::cout <<
"End Result: TEST FAILED\n";
676 std::cout <<
"End Result: TEST PASSED\n";
Implements the computation of optimization steps with the Newton primal-dual active set method...
Provides the interface to evaluate objective functions.
void pruneUpperActive(ROL::Vector< Real > &v, const ROL::Vector< Real > &x, Real eps)
Set variables to zero if they correspond to the upper -active set.
Real evaluate_target(Real x)
void solve_adjoint_sensitivity(std::vector< Real > &q, const std::vector< Real > &u, const std::vector< Real > &p, const std::vector< Real > &v, const std::vector< Real > &z, const std::vector< Real > ¶m)
void solve_state(std::vector< Real > &u, const std::vector< Real > &z, const std::vector< Real > ¶m)
void run_newton(std::vector< Real > &u, const std::vector< Real > &z, const std::vector< Real > ¶m)
void pruneUpperActive(ROL::Vector< Real > &v, const ROL::Vector< Real > &g, const ROL::Vector< Real > &x, Real eps)
Set variables to zero if they correspond to the upper -binding set.
Contains definitions of custom data types in ROL.
void solve_state_sensitivity(std::vector< Real > &v, const std::vector< Real > &u, const std::vector< Real > &z, const std::vector< Real > ¶m)
virtual void zero()
Set to zero vector.
void compute_residual(std::vector< Real > &r, const std::vector< Real > &u, const std::vector< Real > &z, const std::vector< Real > ¶m)
Defines the linear algebra or vector space interface.
void pruneLowerActive(ROL::Vector< Real > &v, const ROL::Vector< Real > &g, const ROL::Vector< Real > &x, Real eps)
Set variables to zero if they correspond to the lower -binding set.
virtual std::vector< std::vector< Real > > checkGradient(const Vector< Real > &x, const Vector< Real > &d, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS, const int order=1)
Finite-difference gradient check.
Teuchos::RCP< Vector< Real > > clone() const
Clone to make a new (uninitialized) vector.
void hessVec(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &z, Real &tol)
Apply Hessian approximation to vector.
Provides the std::vector implementation of the ROL::Vector interface.
virtual std::vector< std::string > run(Vector< Real > &x, Objective< Real > &obj, bool print=false, std::ostream &outStream=std::cout)
Run algorithm on unconstrained problems (Type-U). This is the primary Type-U interface.
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)
std::vector< Real > x_lo_
Real dot(const std::vector< Real > &x, const std::vector< Real > &y)
Objective_BurgersControl(Real alpha=1.e-4, int nx=128)
void pruneLowerActive(ROL::Vector< Real > &v, const ROL::Vector< Real > &x, Real eps)
Set variables to zero if they correspond to the lower -active set.
void compute_pde_jacobian(std::vector< Real > &dl, std::vector< Real > &d, std::vector< Real > &du, const std::vector< Real > &u, const std::vector< Real > ¶m)
Provides an interface to check status of optimization algorithms.
void update(std::vector< Real > &u, const std::vector< Real > &s, const Real alpha=1.0)
std::vector< Real > x_up_
void setVectorToLowerBound(ROL::Vector< Real > &l)
Set the input vector to the lower bound.
Provides the interface to apply upper and lower bound constraints.
void add_pde_hessian(std::vector< Real > &r, const std::vector< Real > &u, const std::vector< Real > &p, const std::vector< Real > &s, Real alpha=1.0)
void solve_adjoint(std::vector< Real > &p, const std::vector< Real > &u, const std::vector< Real > ¶m)
int main(int argc, char *argv[])
void project(ROL::Vector< Real > &x)
Project optimization variables onto the bounds.
Real value(const ROL::Vector< Real > &z, Real &tol)
Compute value.
void apply_mass(std::vector< Real > &Mu, const std::vector< Real > &u)
virtual std::vector< std::vector< Real > > checkHessVec(const Vector< Real > &x, const Vector< Real > &v, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS, const int order=1)
Finite-difference Hessian-applied-to-vector check.
virtual void set(const Vector &x)
Set where .
void gradient(ROL::Vector< Real > &g, const ROL::Vector< Real > &z, Real &tol)
Compute gradient.
bool isFeasible(const ROL::Vector< Real > &x)
Check if the vector, v, is feasible.
BoundConstraint_BurgersControl(int dim)
void setVectorToUpperBound(ROL::Vector< Real > &u)
Set the input vector to the upper bound.
Real compute_norm(const std::vector< Real > &r)
Provides the interface to compute optimization steps with trust regions.
void scale(std::vector< Real > &u, const Real alpha=0.0)
static const double ROL_EPSILON
Platform-dependent machine epsilon.