14 #include "Teuchos_LAPACK.hpp"
15 #include "Teuchos_SerialDenseMatrix.hpp"
34 FEM(
int nx = 128, Real kl = 0.1, Real kr = 10.0) :
nx_(nx),
kl_(kl),
kr_(kr) {
38 pts_[0] = -0.9061798459386640;
39 pts_[1] = -0.5384693101056831;
41 pts_[3] = 0.5384693101056831;
42 pts_[4] = 0.9061798459386640;
45 wts_[0] = 0.2369268850561891;
46 wts_[1] = 0.4786286704993665;
47 wts_[2] = 0.5688888888888889;
48 wts_[3] = 0.4786286704993665;
49 wts_[4] = 0.2369268850561891;
52 for (
int i = 0; i < 5; i++) {
56 for (
int i = 0; i < 5; i++) {
64 void build_mesh(std::vector<Real> &x,
const std::vector<Real> ¶m) {
68 Real xp = 0.1*param[0];
84 Real dx1 = (xp+1.0)/(Real)nx1;
85 Real dx2 = (1.0-xp)/(Real)nx2;
88 x.resize(n1+n2+3,0.0);
89 for (
int k = 0; k < n1+n2+3; k++) {
90 x[k] = ((k < nx1) ? (Real)k*dx1-1.0 : ((k==nx1) ? xp : (Real)(k-nx1)*dx2+xp));
102 for (
int i = 0; i < rem; i++ ) {
103 if ( i%4 == 0 ) { nz3++; }
104 else if ( i%4 == 1 ) { nz1++; }
105 else if ( i%4 == 2 ) { nz4++; }
106 else if ( i%4 == 3 ) { nz2++; }
110 for (
int k = 0; k <
nz(); k++) {
112 x[k] = 0.25*(Real)k/(Real)(nz1-1) - 1.0;
114 if ( k >= nz1 && k < nz1+nz2 ) {
115 x[k] = 0.5*(Real)(k-nz1+1)/(Real)nz2 - 0.75;
117 if ( k >= nz1+nz2 && k < nz1+nz2+nz3 ) {
118 x[k] = 0.5*(Real)(k-nz1-nz2+1)/(Real)nz3 - 0.25;
120 if ( k >= nz1+nz2+nz3-1 ) {
121 x[k] = 0.75*(Real)(k-nz1-nz2-nz3+1)/(Real)nz4 + 0.25;
134 void build_force(std::vector<Real> &F,
const std::vector<Real> ¶m) {
136 std::vector<Real> x(
nu()+2,0.0);
140 F.resize(x.size()-2,0.0);
142 int size =
static_cast<int>(x.size());
143 for (
int i = 0; i < size-2; i++) {
144 for (
int j = 0; j < 5; j++) {
146 pt = (x[i+1]-x[i])*
pts_[j] + x[i];
147 F[i] +=
wts_[j]*(pt-x[i])*std::exp(-std::pow(pt-0.5*param[1],2.0));
149 pt = (x[i+2]-x[i+1])*
pts_[j] + x[i+1];
150 F[i] +=
wts_[j]*(x[i+2]-pt)*std::exp(-std::pow(pt-0.5*param[1],2.0));
157 const std::vector<Real> ¶m) {
159 std::vector<Real> x(
nu()+2,0.0);
162 int xsize =
static_cast<int>(x.size());
164 d.resize(xsize-2,0.0);
165 for (
int i = 0; i < xsize-2; i++ ) {
166 if ( x[i+1] < 0.1*param[0] ) {
167 d[i] =
kl_/(x[i+1]-x[i]) +
kl_/(x[i+2]-x[i+1]);
169 else if ( x[i+1] > 0.1*param[0] ) {
170 d[i] =
kr_/(x[i+1]-x[i]) +
kr_/(x[i+2]-x[i+1]);
173 d[i] =
kl_/(x[i+1]-x[i]) +
kr_/(x[i+2]-x[i+1]);
179 dl.resize(xsize-3,0.0);
180 for (
int i = 0; i < xsize-3; i++ ) {
181 if ( x[i+2] <= 0.1*param[0] ) {
182 dl[i] = -
kl_/(x[i+2]-x[i+1]);
184 else if ( x[i+2] > 0.1*param[0] ) {
185 dl[i] = -
kr_/(x[i+2]-x[i+1]);
190 du.assign(dl.begin(),dl.end());
194 void apply_jacobian_1(std::vector<Real> &jv,
const std::vector<Real> &v,
const std::vector<Real> ¶m) {
196 std::vector<Real> dl(
nu()-1,0.0);
197 std::vector<Real> d(
nu(),0.0);
198 std::vector<Real> du(
nu()-1,0.0);
202 jv.resize(d.size(),0.0);
203 int size =
static_cast<int>(d.size());
204 for (
int i = 0; i < size; ++i ) {
206 jv[i] += ((i>0) ? dl[i-1]*v[i-1] : 0.0);
207 jv[i] += ((i<size-1) ? du[i]*v[i+1] : 0.0);
211 void apply_jacobian_2(std::vector<Real> &jv,
const std::vector<Real> &v,
const std::vector<Real> ¶m) {
213 std::vector<Real> xu(
nu()+2,0.0);
216 std::vector<Real> xz(
nz(),0.0);
219 std::vector<Real> x(xu.size()+xz.size(),0.0);
220 typename std::vector<Real>::iterator it;
221 it = std::set_union(xu.begin(),xu.end(),xz.begin(),xz.end(),x.begin());
222 x.resize(it-x.begin());
224 std::vector<Real> vi;
225 int xzsize =
static_cast<int>(xz.size());
226 for (it=x.begin(); it!=x.end(); it++) {
227 for (
int i = 0; i < xzsize-1; i++) {
228 if ( *it >= xz[i] && *it <= xz[i+1] ) {
229 vi.push_back(v[i+1]*(*it-xz[i])/(xz[i+1]-xz[i]) + v[i]*(xz[i+1]-*it)/(xz[i+1]-xz[i]));
234 int xsize =
static_cast<int>(x.size());
236 std::vector<Real> Mv(xsize,0.0);
237 for (
int i = 0; i < xsize; i++) {
238 Mv[i] += ((i>0) ? (x[i]-x[i-1])/6.0*vi[i-1] + (x[i]-x[i-1])/3.0*vi[i] : 0.0);
239 Mv[i] += ((i<xsize-1) ? (x[i+1]-x[i])/3.0*vi[i] + (x[i+1]-x[i])/6.0*vi[i+1] : 0.0);
242 int xusize =
static_cast<int>(xu.size());
244 jv.resize(xusize-2,0.0);
245 for (
int i = 0; i < xusize-2; i++) {
246 for (
int j = 0; j < xsize-1; j++) {
247 jv[i] += (((x[j]>=xu[i ]) && (x[j]< xu[i+1])) ? Mv[j]*(x[j]-xu[i ])/(xu[i+1]-xu[i ]) : 0.0);
248 jv[i] += (((x[j]>=xu[i+1]) && (x[j]<=xu[i+2])) ? Mv[j]*(xu[i+2]-x[j])/(xu[i+2]-xu[i+1]) : 0.0);
249 if ( x[j] > xu[i+2] ) {
break; }
255 const std::vector<Real> ¶m){
257 std::vector<Real> xu(
nu()+2,0.0);
260 std::vector<Real> xz(
nz(),0.0);
263 std::vector<Real> x(xu.size()+xz.size(),0.0);
264 typename std::vector<Real>::iterator it;
265 it = std::set_union(xu.begin(),xu.end(),xz.begin(),xz.end(),x.begin());
266 x.resize(it-x.begin());
268 std::vector<Real> vi;
270 int xusize =
static_cast<int>(xu.size());
271 for (it=x.begin(); it!=x.end(); it++) {
272 for (
int i = 0; i < xusize-1; i++) {
273 if ( *it >= xu[i] && *it <= xu[i+1] ) {
275 val += ((i!=0 ) ? v[i-1]*(xu[i+1]-*it)/(xu[i+1]-xu[i]) : 0.0);
276 val += ((i!=xusize-2) ? v[i ]*(*it-xu[i ])/(xu[i+1]-xu[i]) : 0.0);
283 int xsize =
static_cast<int>(x.size());
284 std::vector<Real> Mv(xsize,0.0);
285 for (
int i = 0; i < xsize; i++) {
286 Mv[i] += ((i>0) ? (x[i]-x[i-1])/6.0*vi[i-1] + (x[i]-x[i-1])/3.0*vi[i] : 0.0);
287 Mv[i] += ((i<xsize-1) ? (x[i+1]-x[i])/3.0*vi[i] + (x[i+1]-x[i])/6.0*vi[i+1] : 0.0);
292 int xzsize =
static_cast<int>(xz.size());
293 for (
int i = 0; i < xzsize; i++) {
294 for (
int j = 0; j < xsize; j++) {
296 jv[i] += (((x[j]>=xz[i ]) && (x[j]<=xz[i+1])) ? Mv[j]*(xz[i+1]-x[j])/(xz[i+1]-xz[i ]) : 0.0);
297 if ( x[j] > xz[i+1] ) {
break; }
299 else if ( i == xzsize-1 ) {
300 jv[i] += (((x[j]>=xz[i-1]) && (x[j]<=xz[i ])) ? Mv[j]*(x[j]-xz[i-1])/(xz[i ]-xz[i-1]) : 0.0);
303 jv[i] += (((x[j]>=xz[i-1]) && (x[j]< xz[i ])) ? Mv[j]*(x[j]-xz[i-1])/(xz[i ]-xz[i-1]) : 0.0);
304 jv[i] += (((x[j]>=xz[i ]) && (x[j]<=xz[i+1])) ? Mv[j]*(xz[i+1]-x[j])/(xz[i+1]-xz[i ]) : 0.0);
305 if ( x[j] > xz[i+1] ) {
break; }
311 void apply_mass_state(std::vector<Real> &Mv,
const std::vector<Real> &v,
const std::vector<Real> ¶m) {
316 int size =
static_cast<int>(x.size());
318 Mv.resize(size-2,0.0);
319 for (
int i = 0; i < size-2; i++) {
320 Mv[i] = (x[i+2]-x[i])/3.0*v[i];
322 Mv[i] += (x[i+1]-x[i])/6.0*v[i-1];
325 Mv[i] += (x[i+2]-x[i+1])/6.0*v[i+1];
332 std::vector<Real> x(
nz(),0.0);
335 int xsize =
static_cast<Real
>(x.size());
337 Mv.resize(xsize,0.0);
338 for (
int i = 0; i < xsize; i++) {
340 Mv[i] += (x[i]-x[i-1])/6.0*v[i-1] + (x[i]-x[i-1])/3.0*v[i];
343 Mv[i] += (x[i+1]-x[i])/3.0*v[i] + (x[i+1]-x[i])/6.0*v[i+1];
350 std::vector<Real> x(
nz(),0.0);
353 std::vector<Real> d(
nz(),0.0);
354 std::vector<Real> dl(
nz()-1,0.0);
355 std::vector<Real> du(
nz()-1,0.0);
356 for (
int i = 0; i <
nz(); i++) {
358 dl[i-1] = (x[i]-x[i-1])/6.0;
359 d[i] += (x[i]-x[i-1])/3.0;
362 d[i] += (x[i+1]-x[i])/3.0;
363 du[i] = (x[i+1]-x[i])/6.0;
374 void linear_solve(std::vector<Real> &u, std::vector<Real> &dl, std::vector<Real> &d,
375 std::vector<Real> &du,
const std::vector<Real> &r,
const bool transpose =
false) {
377 u.assign(r.begin(),r.end());
379 Teuchos::LAPACK<int,Real> lp;
380 std::vector<Real> du2(r.size()-2,0.0);
381 std::vector<int> ipiv(r.size(),0);
386 lp.GTTRF(n,&dl[0],&d[0],&du[0],&du2[0],&ipiv[0],&info);
391 lp.GTTRS(trans,n,nhrs,&dl[0],&d[0],&du[0],&du2[0],&ipiv[0],&u[0],ldb,&info);
402 case 1: val = ((x[i]<0.5) ? 1.0 : 0.0);
break;
403 case 2: val = 1.0;
break;
404 case 3: val = std::abs(std::sin(8.0*M_PI*x[i]));
break;
405 case 4: val = std::exp(-0.5*(x[i]-0.5)*(x[i]-0.5));
break;
414 const ROL::Ptr<FEM<Real> >
FEM_;
422 void plus(std::vector<Real> &u,
const std::vector<Real> &s,
const Real alpha=1.0) {
423 int size =
static_cast<int>(u.size());
424 for (
int i=0; i<size; i++) {
430 void scale(std::vector<Real> &u,
const Real alpha=0.0) {
431 int size =
static_cast<int>(u.size());
432 for (
int i=0; i<size; i++) {
449 ROL::Ptr<const std::vector<Real> > up =
dynamic_cast<const ROL::StdVector<Real>&
>(u).getVector();
450 ROL::Ptr<const std::vector<Real> > zp =
dynamic_cast<const ROL::StdVector<Real>&
>(z).getVector();
454 std::vector<Real> F(
FEM_->nu(),0.0);
456 std::vector<Real> Bz(
FEM_->nu(),0.0);
466 ROL::Ptr<const std::vector<Real> > zp =
dynamic_cast<const ROL::StdVector<Real>&
>(z).getVector();
468 std::vector<Real> dl(
FEM_->nu()-1,0.0);
469 std::vector<Real> d(
FEM_->nu(),0.0);
470 std::vector<Real> du(
FEM_->nu()-1,0.0);
473 std::vector<Real> F(
FEM_->nu(),0.0);
475 std::vector<Real> Bz(
FEM_->nu(),0.0);
479 FEM_->linear_solve(*up,dl,d,du,F);
488 ROL::Ptr<const std::vector<Real> > vp =
dynamic_cast<const ROL::StdVector<Real>&
>(v).getVector();
495 ROL::Ptr<const std::vector<Real> > vp =
dynamic_cast<const ROL::StdVector<Real>&
>(v).getVector();
503 ROL::Ptr<const std::vector<Real> > vp =
dynamic_cast<const ROL::StdVector<Real>&
>(v).getVector();
505 std::vector<Real> dl(
FEM_->nu()-1,0.0);
506 std::vector<Real> d(
FEM_->nu(),0.0);
507 std::vector<Real> du(
FEM_->nu()-1,0.0);
510 FEM_->linear_solve(*jvp,dl,d,du,*vp);
522 ROL::Ptr<const std::vector<Real> > vp =
dynamic_cast<const ROL::StdVector<Real>&
>(v).getVector();
558 const ROL::Ptr<FEM<Real> >
FEM_;
565 Real
dot(
const std::vector<Real> &x,
const std::vector<Real> &y) {
567 int size =
static_cast<int>(x.size());
568 for (
int i=0; i<size; i++) {
575 void scale(std::vector<Real> &u,
const Real alpha=0.0) {
576 int size =
static_cast<int>(u.size());
577 for (
int i=0; i<size; i++) {
590 ROL::Ptr<const std::vector<Real> > up =
dynamic_cast<const ROL::StdVector<Real>&
>(u).getVector();
591 ROL::Ptr<const std::vector<Real> > zp =
dynamic_cast<const ROL::StdVector<Real>&
>(z).getVector();
592 int nz =
FEM_->nz(), nu =
FEM_->nu();
594 std::vector<Real> Mz(nz);
595 FEM_->apply_mass_control(Mz,*zp);
598 std::vector<Real> diff(nu);
599 for (
int i=0; i<nu; i++) {
602 std::vector<Real> Mu(nu);
604 Real uval = 0.5*
dot(Mu,diff);
610 ROL::Ptr<const std::vector<Real> > up =
dynamic_cast<const ROL::StdVector<Real>&
>(u).getVector();
613 std::vector<Real> diff(nu);
614 for (
int i=0; i<nu; i++) {
622 ROL::Ptr<const std::vector<Real> > zp =
dynamic_cast<const ROL::StdVector<Real>&
>(z).getVector();
624 FEM_->apply_mass_control(*gp,*zp);
631 ROL::Ptr<const std::vector<Real> > vp =
dynamic_cast<const ROL::StdVector<Real>&
>(v).getVector();
649 ROL::Ptr<const std::vector<Real> > vp =
dynamic_cast<const ROL::StdVector<Real>&
>(v).getVector();
651 FEM_->apply_mass_control(*hvp,*vp);
Provides the interface to evaluate simulation-based objective functions.
void scale(std::vector< Real > &u, const Real alpha=0.0)
void plus(std::vector< Real > &u, const std::vector< Real > &s, const Real alpha=1.0)
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 build_mesh(std::vector< Real > &x)
void apply_adjoint_jacobian_2(std::vector< Real > &jv, const std::vector< Real > &v, const std::vector< Real > ¶m)
Contains definitions of custom data types in ROL.
DiffusionConstraint(const ROL::Ptr< FEM< Real > > &FEM)
const std::vector< Real > getParameter(void) const
void value(ROL::Vector< Real > &c, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Evaluate the constraint operator at .
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 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_jacobian_2(std::vector< Real > &jv, const std::vector< Real > &v, const std::vector< Real > ¶m)
Real dot(const std::vector< Real > &x, const std::vector< Real > &y)
virtual void zero()
Set to zero vector.
Defines the linear algebra or vector space interface.
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 build_mesh(std::vector< Real > &x, const std::vector< Real > ¶m)
void applyAdjointHessian_11(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 simulation-space Jacobian at ...
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.
int getNumSolves(void) const
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...
FEM(int nx=128, Real kl=0.1, Real kr=10.0)
void applyInverseAdjointJacobian_1(ROL::Vector< Real > &jv, 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 ...
DiffusionObjective(const ROL::Ptr< FEM< Real > > fem, const Real alpha=1.e-4)
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 applyInverseJacobian_1(ROL::Vector< Real > &jv, 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 .
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 .
void apply_mass_control(std::vector< Real > &Mv, const std::vector< Real > &v)
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 scale(std::vector< Real > &u, const Real alpha=0.0)
void apply_jacobian_1(std::vector< Real > &jv, const std::vector< Real > &v, const std::vector< Real > ¶m)
void hessVec_21(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
const std::vector< Real > getParameter(void) const
void solve(ROL::Vector< Real > &c, ROL::Vector< Real > &u, const ROL::Vector< Real > &z, Real &tol)
Given , solve for .
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.
Defines the constraint operator interface for simulation-based optimization.
const ROL::Ptr< FEM< Real > > FEM_
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 build_jacobian_1(std::vector< Real > &dl, std::vector< Real > &d, std::vector< Real > &du, const std::vector< Real > ¶m)
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 apply_mass_state(std::vector< Real > &Mv, const std::vector< Real > &v, const std::vector< Real > ¶m)
void apply_inverse_mass_control(std::vector< Real > &Mv, const std::vector< Real > &v)
void applyAdjointJacobian_1(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 the vector . This is the primary inter...
const ROL::Ptr< FEM< Real > > FEM_
void build_force(std::vector< Real > &F, const std::vector< Real > ¶m)
Real evaluate_target(int i, const std::vector< Real > ¶m)