ROL
gross-pitaevskii/example_01.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 
36 #include <iostream>
37 
38 #include "ROL_Stream.hpp"
39 #include "Teuchos_GlobalMPISession.hpp"
40 
41 #include "ROL_ParameterList.hpp"
42 #include "ROL_StdVector.hpp"
43 #include "ROL_Objective.hpp"
44 #include "ROL_Constraint.hpp"
45 #include "ROL_Algorithm.hpp"
46 #include "ROL_CompositeStep.hpp"
48 
49 
50 using namespace ROL;
51 
52 template<class Real>
53 class Objective_GrossPitaevskii : public Objective<Real> {
54 
55  typedef std::vector<Real> vector;
56  typedef Vector<Real> V;
58 
59  typedef typename vector::size_type uint;
60 
61 private:
62 
63 
65  Real g_;
66 
69 
71  Real dx_;
72 
74  ROL::Ptr<const vector> Vp_;
75 
76  ROL::Ptr<const vector> getVector( const V& x ) {
77 
78  return dynamic_cast<const SV&>(x).getVector();
79  }
80 
81  ROL::Ptr<vector> getVector( V& x ) {
82 
83  return dynamic_cast<SV&>(x).getVector();
84  }
85 
86 
87 
89 
91  void applyK(const Vector<Real> &v, Vector<Real> &kv) {
92 
93  using namespace Teuchos;
94 
95  // Pointer to direction vector
96  ROL::Ptr<const vector> vp = getVector(v);
97 
98  // Pointer to action of Hessian on direction vector
99  ROL::Ptr<vector> kvp = getVector(kv);
100 
101  Real dx2 = dx_*dx_;
102 
103  (*kvp)[0] = (2.0*(*vp)[0]-(*vp)[1])/dx2;
104 
105  for(uint i=1;i<nx_-1;++i) {
106  (*kvp)[i] = (2.0*(*vp)[i]-(*vp)[i-1]-(*vp)[i+1])/dx2;
107  }
108 
109  (*kvp)[nx_-1] = (2.0*(*vp)[nx_-1]-(*vp)[nx_-2])/dx2;
110  }
111 
112  public:
113 
114  Objective_GrossPitaevskii(const Real &g, const Vector<Real> &V) : g_(g),
115  Vp_(getVector(V)) {
116  nx_ = Vp_->size();
117  dx_ = (1.0/(1.0+nx_));
118  }
119 
121 
125  Real value( const Vector<Real> &psi, Real &tol ) {
126 
127 
128 
129  // Pointer to opt vector
130  ROL::Ptr<const vector> psip = getVector(psi);
131 
132  // Pointer to K applied to opt vector
133  ROL::Ptr<V> kpsi = psi.clone();
134  ROL::Ptr<vector> kpsip = getVector(*kpsi);
135 
136  Real J = 0;
137 
138  this->applyK(psi,*kpsi);
139 
140  for(uint i=0;i<nx_;++i) {
141  J += (*psip)[i]*(*kpsip)[i] + (*Vp_)[i]*pow((*psip)[i],2) + g_*pow((*psip)[i],4);
142  }
143 
144  // Rescale for numerical integration by trapezoidal rule
145  J *= 0.5*dx_;
146 
147  return J;
148  }
149 
151 
152  void gradient( Vector<Real> &g, const Vector<Real> &psi, Real &tol ) {
153 
154 
155 
156  // Pointer to opt vector
157  ROL::Ptr<const vector> psip = getVector(psi);
158 
159  // Pointer to gradient vector
160  ROL::Ptr<vector> gp = getVector(g);
161 
162  // Pointer to K applied to opt vector
163  ROL::Ptr<V> kpsi = psi.clone();
164  ROL::Ptr<vector> kpsip = getVector(*kpsi);
165 
166  applyK(psi,*kpsi);
167 
168  for(uint i=0;i<nx_;++i) {
169  (*gp)[i] = ((*kpsip)[i] + (*Vp_)[i]*(*psip)[i] + 2.0*g_*pow((*psip)[i],3))*dx_;
170  }
171 
172  }
173 
174 
175 
177 
178  void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &psi, Real &tol ) {
179 
180 
181 
182  // Pointer to opt vector
183  ROL::Ptr<const vector> psip = getVector(psi);
184 
185  // Pointer to direction vector
186  ROL::Ptr<const vector> vp = getVector(v);
187 
188  // Pointer to action of Hessian on direction vector
189  ROL::Ptr<vector> hvp = getVector(hv);
190 
191  applyK(v,hv);
192 
193  for(uint i=0;i<nx_;++i) {
194  (*hvp)[i] *= dx_;
195  (*hvp)[i] += ( (*Vp_)[i] + 6.0*g_*pow((*psip)[i],2) )*(*vp)[i]*dx_;
196  }
197  }
198 
199 };
200 
201 
202 template<class Real>
203 class Normalization_Constraint : public Constraint<Real> {
204 
205  typedef std::vector<Real> vector;
206  typedef Vector<Real> V;
208 
209  typedef typename vector::size_type uint;
210 
211 
212 private:
214  Real dx_;
215 
216  ROL::Ptr<const vector> getVector( const V& x ) {
217 
218  return dynamic_cast<const SV&>(x).getVector();
219  }
220 
221  ROL::Ptr<vector> getVector( V& x ) {
222 
223  return dynamic_cast<SV&>(x).getVector();
224  }
225 
226 public:
227  Normalization_Constraint(int n, Real dx) : nx_(n), dx_(dx) {}
228 
230 
234  void value(Vector<Real> &c, const Vector<Real> &psi, Real &tol){
235 
236 
237 
238  // Pointer to constraint vector (only one element)
239  ROL::Ptr<vector> cp = getVector(c);
240 
241  // Pointer to optimization vector
242  ROL::Ptr<const vector> psip = getVector(psi);
243 
244  (*cp)[0] = -1.0;
245  for(uint i=0;i<nx_;++i) {
246  (*cp)[0] += dx_*pow((*psip)[i],2);
247  }
248  }
249 
251 
253  void applyJacobian(Vector<Real> &jv, const Vector<Real> &v, const Vector<Real> &psi, Real &tol){
254 
255 
256 
257  // Pointer to action of Jacobian of constraint on direction vector (yields scalar)
258  ROL::Ptr<vector> jvp = getVector(jv);
259 
260  // Pointer to direction vector
261  ROL::Ptr<const vector> vp = getVector(v);
262 
263  // Pointer to optimization vector
264  ROL::Ptr<const vector> psip = getVector(psi);
265 
266  (*jvp)[0] = 0;
267  for(uint i=0;i<nx_;++i) {
268  (*jvp)[0] += 2.0*dx_*(*psip)[i]*(*vp)[i];
269  }
270  }
271 
273 
275  void applyAdjointJacobian(Vector<Real> &ajv, const Vector<Real> &v, const Vector<Real> &psi, Real &tol){
276 
277 
278 
279  // Pointer to action of adjoint of Jacobian of constraint on direction vector (yields vector)
280  ROL::Ptr<vector> ajvp = getVector(ajv);
281 
282  // Pointer to direction vector
283  ROL::Ptr<const vector> vp = getVector(v);
284 
285  // Pointer to optimization vector
286  ROL::Ptr<const vector> psip = getVector(psi);
287 
288  for(uint i=0;i<nx_;++i) {
289  (*ajvp)[i] = 2.0*dx_*(*psip)[i]*(*vp)[0];
290  }
291  }
292 
294 
298  const Vector<Real> &psi, Real &tol){
299 
300 
301 
302  // The pointer to action of constraint Hessian in u,v inner product
303  ROL::Ptr<vector> ahuvp = getVector(ahuv);
304 
305  // Pointer to direction vector u
306  ROL::Ptr<const vector> up = getVector(u);
307 
308  // Pointer to direction vector v
309  ROL::Ptr<const vector> vp = getVector(v);
310 
311  // Pointer to optimization vector
312  ROL::Ptr<const vector> psip = getVector(psi);
313 
314  for(uint i=0;i<nx_;++i) {
315  (*ahuvp)[i] = 2.0*dx_*(*vp)[i]*(*up)[0];
316  }
317  }
318 };
319 
320 
Provides the interface to evaluate objective functions.
typename PV< Real >::size_type size_type
Real value(const Vector< Real > &psi, Real &tol)
Evaluate .
ROL::Ptr< const vector > getVector(const V &x)
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
void applyAdjointJacobian(Vector< Real > &ajv, const Vector< Real > &v, const Vector< Real > &psi, Real &tol)
Evaluate .
void value(Vector< Real > &c, const Vector< Real > &psi, Real &tol)
Evaluate .
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &psi, Real &tol)
Evaluate .
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
Defines a no-output stream class ROL::NullStream and a function makeStreamPtr which either wraps a re...
void applyJacobian(Vector< Real > &jv, const Vector< Real > &v, const Vector< Real > &psi, Real &tol)
Evaluate .
void applyK(const Vector< Real > &v, Vector< Real > &kv)
Apply finite difference operator.
ROL::Ptr< const vector > getVector(const V &x)
void gradient(Vector< Real > &g, const Vector< Real > &psi, Real &tol)
Evaluate .
Objective_GrossPitaevskii(const Real &g, const Vector< Real > &V)
Defines the general constraint operator interface.
void applyAdjointHessian(Vector< Real > &ahuv, const Vector< Real > &u, const Vector< Real > &v, const Vector< Real > &psi, Real &tol)
Evaluate .