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
44 /*! \file assembler_def.hpp
45 \brief Finite element assembly class.
46 */
47
48 #ifndef ROL_PDEOPT_ASSEMBLER_DEF_H
49 #define ROL_PDEOPT_ASSEMBLER_DEF_H
50
51 #include "assembler.hpp"
52
53 /*****************************************************************************/
54 /******************* PUBLIC MEMBER FUNCTIONS *********************************/
55 /*****************************************************************************/
56 // Constuctor: Discretization set from ParameterList
57 template<class Real>
Assembler(const std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & basisPtrs,const ROL::Ptr<const Teuchos::Comm<int>> & comm,Teuchos::ParameterList & parlist,std::ostream & outStream)58 Assembler<Real>::Assembler(
59 const std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> &basisPtrs,
60 const ROL::Ptr<const Teuchos::Comm<int>> &comm,
61 Teuchos::ParameterList &parlist,
62 std::ostream &outStream)
63 : isJ1Transposed_(false), isJ2Transposed_(false),
64 isJuoTransposed_(false), isJunTransposed_(false), isJzfTransposed_(false) {
65 setCommunicator(comm,parlist,outStream);
66 setBasis(basisPtrs,basisPtrs,parlist,outStream);
67 setDiscretization(parlist,ROL::nullPtr,outStream);
68 setParallelStructure(parlist,outStream);
69 setCellNodes(outStream);
70 }
71
72 // Constructor: Discretization set from MeshManager input
73 template<class Real>
Assembler(const std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & basisPtrs,const ROL::Ptr<MeshManager<Real>> & meshMgr,const ROL::Ptr<const Teuchos::Comm<int>> & comm,Teuchos::ParameterList & parlist,std::ostream & outStream)74 Assembler<Real>::Assembler(
75 const std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> &basisPtrs,
76 const ROL::Ptr<MeshManager<Real>> &meshMgr,
77 const ROL::Ptr<const Teuchos::Comm<int>> &comm,
78 Teuchos::ParameterList &parlist,
79 std::ostream &outStream)
80 : isJ1Transposed_(false), isJ2Transposed_(false),
81 isJuoTransposed_(false), isJunTransposed_(false), isJzfTransposed_(false) {
82 setCommunicator(comm,parlist,outStream);
83 setBasis(basisPtrs,basisPtrs,parlist,outStream);
84 setDiscretization(parlist,meshMgr,outStream);
85 setParallelStructure(parlist,outStream);
86 setCellNodes(outStream);
87 }
88 // Constuctor: Discretization set from ParameterList
89 template<class Real>
Assembler(const std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & basisPtrs1,const std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & basisPtrs2,const ROL::Ptr<const Teuchos::Comm<int>> & comm,Teuchos::ParameterList & parlist,std::ostream & outStream)90 Assembler<Real>::Assembler(
91 const std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> &basisPtrs1,
92 const std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> &basisPtrs2,
93 const ROL::Ptr<const Teuchos::Comm<int>> &comm,
94 Teuchos::ParameterList &parlist,
95 std::ostream &outStream)
96 : isJ1Transposed_(false), isJ2Transposed_(false),
97 isJuoTransposed_(false), isJunTransposed_(false), isJzfTransposed_(false) {
98 setCommunicator(comm,parlist,outStream);
99 setBasis(basisPtrs1,basisPtrs2,parlist,outStream);
100 setDiscretization(parlist,ROL::nullPtr,outStream);
101 setParallelStructure(parlist,outStream);
102 setCellNodes(outStream);
103 }
104
105 // Constructor: Discretization set from MeshManager input
106 template<class Real>
Assembler(const std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & basisPtrs1,const std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & basisPtrs2,const ROL::Ptr<MeshManager<Real>> & meshMgr,const ROL::Ptr<const Teuchos::Comm<int>> & comm,Teuchos::ParameterList & parlist,std::ostream & outStream)107 Assembler<Real>::Assembler(
108 const std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> &basisPtrs1,
109 const std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> &basisPtrs2,
110 const ROL::Ptr<MeshManager<Real>> &meshMgr,
111 const ROL::Ptr<const Teuchos::Comm<int>> &comm,
112 Teuchos::ParameterList &parlist,
113 std::ostream &outStream)
114 : isJ1Transposed_(false), isJ2Transposed_(false),
115 isJuoTransposed_(false), isJunTransposed_(false), isJzfTransposed_(false) {
116 setCommunicator(comm,parlist,outStream);
117 setBasis(basisPtrs1,basisPtrs2,parlist,outStream);
118 setDiscretization(parlist,meshMgr,outStream);
119 setParallelStructure(parlist,outStream);
120 setCellNodes(outStream);
121 }
122
123 template<class Real>
setCellNodes(PDE<Real> & pde) const124 void Assembler<Real>::setCellNodes(PDE<Real> &pde) const {
125 // Set PDE cell nodes
126 pde.setFieldPattern(dofMgr1_->getFieldPattern(),dofMgr2_->getFieldPattern());
127 pde.setCellNodes(volCellNodes_, bdryCellNodes_, bdryCellLocIds_);
128 }
129
130 template<class Real>
setCellNodes(DynamicPDE<Real> & pde) const131 void Assembler<Real>::setCellNodes(DynamicPDE<Real> &pde) const {
132 // Set PDE cell nodes
133 pde.setFieldPattern(dofMgr1_->getFieldPattern(),dofMgr2_->getFieldPattern());
134 pde.setCellNodes(volCellNodes_, bdryCellNodes_, bdryCellLocIds_);
135 }
136
137 /***************************************************************************/
138 /* PDE assembly routines */
139 /***************************************************************************/
140 template<class Real>
assemblePDEResidual(ROL::Ptr<Tpetra::MultiVector<>> & r,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)141 void Assembler<Real>::assemblePDEResidual(ROL::Ptr<Tpetra::MultiVector<>> &r,
142 const ROL::Ptr<PDE<Real>> &pde,
143 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
144 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
145 const ROL::Ptr<const std::vector<Real>> & z_param) {
146 #ifdef ROL_TIMERS
147 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEResidual);
148 #endif
149 // Initialize residual vectors if not done so
150 if ( r == ROL::nullPtr ) { // Unique components of residual vector
151 r = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueResidualMap_, 1, true);
152 }
153 if ( pde_vecR_overlap_ == ROL::nullPtr ) { // Overlapping components of residual vector
154 pde_vecR_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapResidualMap_, 1, true);
155 }
156 // Get u_coeff from u and z_coeff from z
157 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
158 getCoeffFromStateVector(u_coeff,u);
159 getCoeffFromControlVector(z_coeff,z);
160 // Assemble
161 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
162 pde->residual(localVal,u_coeff,z_coeff,z_param);
163 assembleFieldVector( r, localVal, pde_vecR_overlap_, dofMgr1_ );
164 }
165
166 template<class Real>
assemblePDEJacobian1(ROL::Ptr<Tpetra::CrsMatrix<>> & J1,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)167 void Assembler<Real>::assemblePDEJacobian1(ROL::Ptr<Tpetra::CrsMatrix<>> &J1,
168 const ROL::Ptr<PDE<Real>> &pde,
169 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
170 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
171 const ROL::Ptr<const std::vector<Real>> & z_param) {
172 #ifdef ROL_TIMERS
173 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEJacobian1);
174 #endif
175 try {
176 // Get u_coeff from u and z_coeff from z
177 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
178 getCoeffFromStateVector(u_coeff,u);
179 getCoeffFromControlVector(z_coeff,z);
180 // Initialize Jacobian matrices
181 if ( J1 == ROL::nullPtr ) {
182 J1 = ROL::makePtr<Tpetra::CrsMatrix<>>(matJ1Graph_);
183 }
184 // Assemble
185 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
186 pde->Jacobian_1(localVal,u_coeff,z_coeff,z_param);
187 assembleFieldMatrix( J1, localVal, dofMgr1_, dofMgr1_ );
188 isJ1Transposed_ = false;
189 // Output
190 //Tpetra::MatrixMarket::Writer< Tpetra::CrsMatrix<>> matWriter;
191 //matWriter.writeSparseFile("jacobian_1.txt", J1);
192 }
193 catch ( Exception::Zero & ez ) {
194 throw Exception::Zero(">>> (Assembler::assemblePDEJacobian1): Jacobian is zero.");
195 }
196 catch ( Exception::NotImplemented & eni ) {
197 throw Exception::NotImplemented(">>> (Assembler::assemblePDEJacobian1): Jacobian not implemented.");
198 }
199 }
200
201 template<class Real>
assemblePDEJacobian2(ROL::Ptr<Tpetra::CrsMatrix<>> & J2,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)202 void Assembler<Real>::assemblePDEJacobian2(ROL::Ptr<Tpetra::CrsMatrix<>> &J2,
203 const ROL::Ptr<PDE<Real>> &pde,
204 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
205 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
206 const ROL::Ptr<const std::vector<Real>> & z_param) {
207 #ifdef ROL_TIMERS
208 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEJacobian2);
209 #endif
210 try {
211 // Get u_coeff from u and z_coeff from z
212 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
213 getCoeffFromStateVector(u_coeff,u);
214 getCoeffFromControlVector(z_coeff,z);
215 // Initialize Jacobian matrices
216 if ( J2 == ROL::nullPtr ) {
217 J2 = ROL::makePtr<Tpetra::CrsMatrix<>>(matJ2Graph_);
218 }
219 // Assemble
220 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
221 pde->Jacobian_2(localVal,u_coeff,z_coeff,z_param);
222 assembleFieldMatrix( J2, localVal, dofMgr1_, dofMgr2_ );
223 isJ2Transposed_ = false;
224 }
225 catch ( Exception::Zero & ez ) {
226 throw Exception::Zero(">>> (Assembler::assemblePDEJacobian2): Jacobian is zero.");
227 }
228 catch ( Exception::NotImplemented & eni ) {
229 throw Exception::NotImplemented(">>> (Assembler::assemblePDEJacobian2): Jacobian not implemented.");
230 }
231 }
232
233 template<class Real>
assemblePDEJacobian3(ROL::Ptr<Tpetra::MultiVector<>> & J3,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)234 void Assembler<Real>::assemblePDEJacobian3(ROL::Ptr<Tpetra::MultiVector<>> &J3,
235 const ROL::Ptr<PDE<Real>> &pde,
236 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
237 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
238 const ROL::Ptr<const std::vector<Real>> & z_param) {
239 #ifdef ROL_TIMERS
240 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEJacobian3);
241 #endif
242 if ( z_param != ROL::nullPtr ) {
243 try {
244 int size = static_cast<int>(z_param->size());
245 // Get u_coeff from u and z_coeff from z
246 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
247 getCoeffFromStateVector(u_coeff,u);
248 getCoeffFromControlVector(z_coeff,z);
249 // Initialize Jacobian storage if not done so already
250 if (J3 == ROL::nullPtr) {
251 J3 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueResidualMap_, size, true);
252 }
253 if ( pde_vecJ3_overlap_ == ROL::nullPtr) {
254 pde_vecJ3_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapResidualMap_, size, true);
255 }
256 // Assemble
257 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
258 pde->Jacobian_3(localVal,u_coeff,z_coeff,z_param);
259 assembleParamFieldMatrix( J3, localVal, pde_vecJ3_overlap_, dofMgr1_ );
260 }
261 catch ( Exception::Zero & ez ) {
262 throw Exception::Zero(">>> (Assembler::assemblePDEJacobian3): Jacobian is zero.");
263 }
264 catch ( Exception::NotImplemented & eni ) {
265 throw Exception::NotImplemented(">>> (Assembler::assemblePDEJacobian3): Jacobian not implemented.");
266 }
267 }
268 else {
269 throw Exception::NotImplemented(">>> (Assembler::assemblePDEJacobian3): Jacobian not implemented.");
270 }
271 }
272
273 template<class Real>
assemblePDEHessian11(ROL::Ptr<Tpetra::CrsMatrix<>> & H11,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)274 void Assembler<Real>::assemblePDEHessian11(ROL::Ptr<Tpetra::CrsMatrix<>> &H11,
275 const ROL::Ptr<PDE<Real>> &pde,
276 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
277 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
278 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
279 const ROL::Ptr<const std::vector<Real>> & z_param) {
280 #ifdef ROL_TIMERS
281 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian11);
282 #endif
283 try {
284 // Get u_coeff from u and z_coeff from z
285 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff, l_coeff;
286 getCoeffFromStateVector(u_coeff,u);
287 getCoeffFromControlVector(z_coeff,z);
288 getCoeffFromStateVector(l_coeff,l);
289 // Initialize Hessian storage if not done so already
290 if ( H11 == ROL::nullPtr ) {
291 H11 = ROL::makePtr<Tpetra::CrsMatrix<>>(matH11Graph_);
292 }
293 // Assemble
294 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
295 pde->Hessian_11(localVal,l_coeff,u_coeff,z_coeff,z_param);
296 assembleFieldMatrix( H11, localVal, dofMgr1_, dofMgr1_ );
297 }
298 catch (Exception::Zero &ez) {
299 throw Exception::Zero(">>> (Assembler::assemblePDEHessian11): Hessian is zero.");
300 }
301 catch (Exception::NotImplemented &eni) {
302 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian11): Hessian not implemented.");
303 }
304 }
305
306 template<class Real>
assemblePDEHessian12(ROL::Ptr<Tpetra::CrsMatrix<>> & H12,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)307 void Assembler<Real>::assemblePDEHessian12(ROL::Ptr<Tpetra::CrsMatrix<>> &H12,
308 const ROL::Ptr<PDE<Real>> &pde,
309 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
310 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
311 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
312 const ROL::Ptr<const std::vector<Real>> & z_param) {
313 #ifdef ROL_TIMERS
314 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian12);
315 #endif
316 try {
317 // Get u_coeff from u and z_coeff from z
318 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff, l_coeff;
319 getCoeffFromStateVector(u_coeff,u);
320 getCoeffFromControlVector(z_coeff,z);
321 getCoeffFromStateVector(l_coeff,l);
322 // Initialize Hessian storage if not done so already
323 if ( H12 == ROL::nullPtr ) {
324 H12 = ROL::makePtr<Tpetra::CrsMatrix<>>(matH12Graph_);
325 }
326 // Assemble
327 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
328 pde->Hessian_12(localVal,l_coeff,u_coeff,z_coeff,z_param);
329 assembleFieldMatrix( H12, localVal, dofMgr2_, dofMgr1_ );
330 }
331 catch (Exception::Zero &ez) {
332 throw Exception::Zero(">>> (Assembler::assemblePDEHessian12): Hessian is zero.");
333 }
334 catch (Exception::NotImplemented &eni) {
335 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian12): Hessian not implemented.");
336 }
337 }
338
339 template<class Real>
assemblePDEHessian13(ROL::Ptr<Tpetra::MultiVector<>> & H13,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)340 void Assembler<Real>::assemblePDEHessian13(ROL::Ptr<Tpetra::MultiVector<>> &H13,
341 const ROL::Ptr<PDE<Real>> &pde,
342 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
343 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
344 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
345 const ROL::Ptr<const std::vector<Real>> & z_param) {
346 #ifdef ROL_TIMERS
347 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian13);
348 #endif
349 if ( z_param != ROL::nullPtr ) {
350 try {
351 int size = static_cast<int>(z_param->size());
352 // Get u_coeff from u, z_coeff from z and l_coeff from l
353 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff, l_coeff;
354 getCoeffFromStateVector(u_coeff,u);
355 getCoeffFromControlVector(z_coeff,z);
356 getCoeffFromStateVector(l_coeff,l);
357 // Initialize Jacobian storage if not done so already
358 if (H13 == ROL::nullPtr) {
359 H13 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueStateMap_, size, true);
360 }
361 if ( pde_vecH13_overlap_ == ROL::nullPtr) {
362 pde_vecH13_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapStateMap_, size, true);
363 }
364 // Assemble
365 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
366 pde->Hessian_13(localVal,l_coeff,u_coeff,z_coeff,z_param);
367 assembleParamFieldMatrix( H13, localVal, pde_vecH13_overlap_, dofMgr1_ );
368 }
369 catch ( Exception::Zero & ez ) {
370 throw Exception::Zero(">>> (Assembler::assemblePDEHessian13): Hessian is zero.");
371 }
372 catch ( Exception::NotImplemented & eni ) {
373 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian13): Hessian not implemented.");
374 }
375 }
376 else {
377 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian13): Hessian not implemented.");
378 }
379 }
380
381 template<class Real>
assemblePDEHessian21(ROL::Ptr<Tpetra::CrsMatrix<>> & H21,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)382 void Assembler<Real>::assemblePDEHessian21(ROL::Ptr<Tpetra::CrsMatrix<>> &H21,
383 const ROL::Ptr<PDE<Real>> &pde,
384 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
385 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
386 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
387 const ROL::Ptr<const std::vector<Real>> & z_param) {
388 #ifdef ROL_TIMERS
389 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian21);
390 #endif
391 try {
392 // Get u_coeff from u and z_coeff from z
393 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff, l_coeff;
394 getCoeffFromStateVector(u_coeff,u);
395 getCoeffFromControlVector(z_coeff,z);
396 getCoeffFromStateVector(l_coeff,l);
397 // Initialize Hessian storage if not done so already
398 if ( H21 == ROL::nullPtr ) {
399 H21 = ROL::makePtr<Tpetra::CrsMatrix<>>(matH21Graph_);
400 }
401 // Assemble
402 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
403 pde->Hessian_21(localVal,l_coeff,u_coeff,z_coeff,z_param);
404 assembleFieldMatrix( H21, localVal, dofMgr1_, dofMgr2_ );
405 }
406 catch (Exception::Zero &ez) {
407 throw Exception::Zero(">>> (Assembler::assemblePDEHessian21): Hessian is zero.");
408 }
409 catch (Exception::NotImplemented &eni) {
410 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian21): Hessian not implemented.");
411 }
412 }
413
414 template<class Real>
assemblePDEHessian22(ROL::Ptr<Tpetra::CrsMatrix<>> & H22,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)415 void Assembler<Real>::assemblePDEHessian22(ROL::Ptr<Tpetra::CrsMatrix<>> &H22,
416 const ROL::Ptr<PDE<Real>> &pde,
417 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
418 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
419 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
420 const ROL::Ptr<const std::vector<Real>> & z_param) {
421 #ifdef ROL_TIMERS
422 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian22);
423 #endif
424 try {
425 // Get u_coeff from u and z_coeff from z
426 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff, l_coeff;
427 getCoeffFromStateVector(u_coeff,u);
428 getCoeffFromControlVector(z_coeff,z);
429 getCoeffFromStateVector(l_coeff,l);
430 // Initialize Hessian storage if not done so already
431 if ( H22 == ROL::nullPtr ) {
432 H22 = ROL::makePtr<Tpetra::CrsMatrix<>>(matH22Graph_);
433 }
434 // Assemble
435 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
436 pde->Hessian_22(localVal,l_coeff,u_coeff,z_coeff,z_param);
437 assembleFieldMatrix( H22, localVal, dofMgr2_, dofMgr2_ );
438 }
439 catch (Exception::Zero &ez) {
440 throw Exception::Zero(">>> (Assembler::assemblePDEHessian22): Hessian is zero.");
441 }
442 catch (Exception::NotImplemented &eni) {
443 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian22): Hessian not implemented.");
444 }
445 }
446
447 template<class Real>
assemblePDEHessian23(ROL::Ptr<Tpetra::MultiVector<>> & H23,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)448 void Assembler<Real>::assemblePDEHessian23(ROL::Ptr<Tpetra::MultiVector<>> &H23,
449 const ROL::Ptr<PDE<Real>> &pde,
450 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
451 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
452 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
453 const ROL::Ptr<const std::vector<Real>> & z_param) {
454 #ifdef ROL_TIMERS
455 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian23);
456 #endif
457 if ( z_param != ROL::nullPtr ) {
458 try {
459 int size = static_cast<int>(z_param->size());
460 // Get u_coeff from u, z_coeff from z and l_coeff from l
461 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff, l_coeff;
462 getCoeffFromStateVector(u_coeff,u);
463 getCoeffFromControlVector(z_coeff,z);
464 getCoeffFromStateVector(l_coeff,l);
465 // Initialize Jacobian storage if not done so already
466 if (H23 == ROL::nullPtr) {
467 H23 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueControlMap_, size, true);
468 }
469 if ( pde_vecH23_overlap_ == ROL::nullPtr) {
470 pde_vecH23_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapControlMap_, size, true);
471 }
472 // Assemble
473 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
474 pde->Hessian_23(localVal,l_coeff,u_coeff,z_coeff,z_param);
475 assembleParamFieldMatrix( H23, localVal, pde_vecH23_overlap_, dofMgr2_ );
476 }
477 catch ( Exception::Zero & ez ) {
478 throw Exception::Zero(">>> (Assembler::assemblePDEHessian23): Hessian is zero.");
479 }
480 catch ( Exception::NotImplemented & eni ) {
481 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian23): Hessian not implemented.");
482 }
483 }
484 else {
485 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian23): Hessian not implemented.");
486 }
487 }
488
489 template<class Real>
assemblePDEHessian31(ROL::Ptr<Tpetra::MultiVector<>> & H31,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)490 void Assembler<Real>::assemblePDEHessian31(ROL::Ptr<Tpetra::MultiVector<>> &H31,
491 const ROL::Ptr<PDE<Real>> &pde,
492 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
493 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
494 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
495 const ROL::Ptr<const std::vector<Real>> & z_param) {
496 #ifdef ROL_TIMERS
497 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian31);
498 #endif
499 assemblePDEHessian13(H31,pde,l,u,z,z_param);
500 }
501
502 template<class Real>
assemblePDEHessian32(ROL::Ptr<Tpetra::MultiVector<>> & H32,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)503 void Assembler<Real>::assemblePDEHessian32(ROL::Ptr<Tpetra::MultiVector<>> &H32,
504 const ROL::Ptr<PDE<Real>> &pde,
505 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
506 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
507 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
508 const ROL::Ptr<const std::vector<Real>> & z_param) {
509 #ifdef ROL_TIMERS
510 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian32);
511 #endif
512 assemblePDEHessian23(H32,pde,l,u,z,z_param);
513 }
514
515 template<class Real>
assemblePDEHessian33(ROL::Ptr<std::vector<std::vector<Real>>> & H33,const ROL::Ptr<PDE<Real>> & pde,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)516 void Assembler<Real>::assemblePDEHessian33(ROL::Ptr<std::vector<std::vector<Real>>> &H33,
517 const ROL::Ptr<PDE<Real>> &pde,
518 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
519 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
520 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
521 const ROL::Ptr<const std::vector<Real>> & z_param) {
522 #ifdef ROL_TIMERS
523 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssemblePDEHessian33);
524 #endif
525 if ( z_param != ROL::nullPtr ) {
526 try {
527 int size = static_cast<int>(z_param->size());
528 // Get u_coeff from u, z_coeff from z and l_coeff from l
529 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff, l_coeff;
530 getCoeffFromStateVector(u_coeff,u);
531 getCoeffFromControlVector(z_coeff,z);
532 getCoeffFromStateVector(l_coeff,l);
533 // Initialize Jacobian storage if not done so already
534 if (H33 == ROL::nullPtr) {
535 std::vector<Real> col(size,static_cast<Real>(0));
536 H33 = ROL::makePtr<std::vector<std::vector<Real>>>(size,col);
537 }
538 // Assemble
539 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> tmp(size,ROL::nullPtr);
540 std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> localVal(size,tmp);
541 pde->Hessian_33(localVal,l_coeff,u_coeff,z_coeff,z_param);
542 assembleParamMatrix( H33, localVal, dofMgr1_ );
543 }
544 catch ( Exception::Zero & ez ) {
545 throw Exception::Zero(">>> (Assembler::assemblePDEHessian33): Hessian is zero.");
546 }
547 catch ( Exception::NotImplemented & eni ) {
548 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian33): Hessian not implemented.");
549 }
550 }
551 else {
552 throw Exception::NotImplemented(">>> (Assembler::assemblePDEHessian33): Hessian not implemented.");
553 }
554 }
555 /***************************************************************************/
556 /* End of PDE assembly routines. */
557 /***************************************************************************/
558
559 /***************************************************************************/
560 /* DynamicPDE assembly routines */
561 /***************************************************************************/
562 template<class Real>
assembleDynPDEResidual(ROL::Ptr<Tpetra::MultiVector<>> & r,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)563 void Assembler<Real>::assembleDynPDEResidual(ROL::Ptr<Tpetra::MultiVector<>> &r,
564 const ROL::Ptr<DynamicPDE<Real>> &pde,
565 const ROL::TimeStamp<Real> &ts,
566 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
567 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
568 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
569 const ROL::Ptr<const std::vector<Real>> &z_param) {
570 #ifdef ROL_TIMERS
571 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEResidual);
572 #endif
573 // Initialize residual vectors if not done so
574 if ( r == ROL::nullPtr ) { // Unique components of residual vector
575 r = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueResidualMap_, 1, true);
576 }
577 if ( pde_vecR_overlap_ == ROL::nullPtr ) { // Overlapping components of residual vector
578 pde_vecR_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapResidualMap_, 1, true);
579 }
580 // Get u_coeff from u and z_coeff from z
581 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff;
582 getCoeffFromStateVector(uo_coeff,uo);
583 getCoeffFromStateVector(un_coeff,un);
584 getCoeffFromControlVector(z_coeff,z);
585 // Assemble
586 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
587 pde->residual(localVal,ts,uo_coeff,un_coeff,z_coeff,z_param);
588 assembleFieldVector( r, localVal, pde_vecR_overlap_, dofMgr1_ );
589 }
590
591 template<class Real>
assembleDynPDEJacobian_uo(ROL::Ptr<Tpetra::CrsMatrix<>> & J,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)592 void Assembler<Real>::assembleDynPDEJacobian_uo(ROL::Ptr<Tpetra::CrsMatrix<>> &J,
593 const ROL::Ptr<DynamicPDE<Real>> &pde,
594 const ROL::TimeStamp<Real> &ts,
595 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
596 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
597 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
598 const ROL::Ptr<const std::vector<Real>> &z_param) {
599 #ifdef ROL_TIMERS
600 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEJacobian_uo);
601 #endif
602 try {
603 // Get u_coeff from u and z_coeff from z
604 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff;
605 getCoeffFromStateVector(uo_coeff,uo);
606 getCoeffFromStateVector(un_coeff,un);
607 getCoeffFromControlVector(z_coeff,z);
608 // Initialize Jacobian matrices
609 if ( J == ROL::nullPtr ) {
610 J = ROL::makePtr<Tpetra::CrsMatrix<>>(matJ1Graph_);
611 }
612 // Assemble
613 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
614 pde->Jacobian_uo(localVal,ts,uo_coeff,un_coeff,z_coeff,z_param);
615 assembleFieldMatrix( J, localVal, dofMgr1_, dofMgr1_ );
616 isJuoTransposed_ = false;
617 }
618 catch ( Exception::Zero & ez ) {
619 throw Exception::Zero(">>> (Assembler::assembleDynPDEJacobian_uo): Jacobian is zero.");
620 }
621 catch ( Exception::NotImplemented & eni ) {
622 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEJacobian_uo): Jacobian not implemented.");
623 }
624 }
625
626 template<class Real>
assembleDynPDEJacobian_un(ROL::Ptr<Tpetra::CrsMatrix<>> & J,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)627 void Assembler<Real>::assembleDynPDEJacobian_un(ROL::Ptr<Tpetra::CrsMatrix<>> &J,
628 const ROL::Ptr<DynamicPDE<Real>> &pde,
629 const ROL::TimeStamp<Real> &ts,
630 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
631 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
632 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
633 const ROL::Ptr<const std::vector<Real>> &z_param) {
634 #ifdef ROL_TIMERS
635 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEJacobian_un);
636 #endif
637 try {
638 // Get u_coeff from u and z_coeff from z
639 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff;
640 getCoeffFromStateVector(uo_coeff,uo);
641 getCoeffFromStateVector(un_coeff,un);
642 getCoeffFromControlVector(z_coeff,z);
643 // Initialize Jacobian matrices
644 if ( J == ROL::nullPtr ) {
645 J = ROL::makePtr<Tpetra::CrsMatrix<>>(matJ1Graph_);
646 }
647 // Assemble
648 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
649 pde->Jacobian_un(localVal,ts,uo_coeff,un_coeff,z_coeff,z_param);
650 assembleFieldMatrix( J, localVal, dofMgr1_, dofMgr1_ );
651 isJunTransposed_ = false;
652 }
653 catch ( Exception::Zero & ez ) {
654 throw Exception::Zero(">>> (Assembler::assembleDynPDEJacobian_un): Jacobian is zero.");
655 }
656 catch ( Exception::NotImplemented & eni ) {
657 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEJacobian_un): Jacobian not implemented.");
658 }
659 }
660
661 template<class Real>
assembleDynPDEJacobian_zf(ROL::Ptr<Tpetra::CrsMatrix<>> & J,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)662 void Assembler<Real>::assembleDynPDEJacobian_zf(ROL::Ptr<Tpetra::CrsMatrix<>> &J,
663 const ROL::Ptr<DynamicPDE<Real>> &pde,
664 const ROL::TimeStamp<Real> &ts,
665 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
666 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
667 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
668 const ROL::Ptr<const std::vector<Real>> &z_param) {
669 #ifdef ROL_TIMERS
670 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEJacobian_zf);
671 #endif
672 try {
673 // Get u_coeff from u and z_coeff from z
674 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff;
675 getCoeffFromStateVector(uo_coeff,uo);
676 getCoeffFromStateVector(un_coeff,un);
677 getCoeffFromControlVector(z_coeff,z);
678 // Initialize Jacobian matrices
679 if ( J == ROL::nullPtr ) {
680 J = ROL::makePtr<Tpetra::CrsMatrix<>>(matJ2Graph_);
681 }
682 // Assemble
683 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
684 pde->Jacobian_zf(localVal,ts,uo_coeff,un_coeff,z_coeff,z_param);
685 assembleFieldMatrix( J, localVal, dofMgr1_, dofMgr2_ );
686 isJzfTransposed_ = false;
687 }
688 catch ( Exception::Zero & ez ) {
689 throw Exception::Zero(">>> (Assembler::assembleDynPDEJacobian_zf): Jacobian is zero.");
690 }
691 catch ( Exception::NotImplemented & eni ) {
692 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEJacobian_zf): Jacobian not implemented.");
693 }
694 }
695
696 template<class Real>
assembleDynPDEJacobian_zp(ROL::Ptr<Tpetra::MultiVector<>> & J,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)697 void Assembler<Real>::assembleDynPDEJacobian_zp(ROL::Ptr<Tpetra::MultiVector<>> &J,
698 const ROL::Ptr<DynamicPDE<Real>> &pde,
699 const ROL::TimeStamp<Real> &ts,
700 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
701 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
702 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
703 const ROL::Ptr<const std::vector<Real>> & z_param) {
704 #ifdef ROL_TIMERS
705 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEJacobian_zp);
706 #endif
707 if ( z_param != ROL::nullPtr ) {
708 try {
709 int size = static_cast<int>(z_param->size());
710 // Get u_coeff from u and z_coeff from z
711 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff;
712 getCoeffFromStateVector(uo_coeff,uo);
713 getCoeffFromStateVector(un_coeff,un);
714 getCoeffFromControlVector(z_coeff,z);
715 // Initialize Jacobian storage if not done so already
716 if (J == ROL::nullPtr) {
717 J = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueResidualMap_, size, true);
718 }
719 if ( pde_vecJ3_overlap_ == ROL::nullPtr) {
720 pde_vecJ3_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapResidualMap_, size, true);
721 }
722 // Assemble
723 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
724 pde->Jacobian_zp(localVal,ts,uo_coeff,un_coeff,z_coeff,z_param);
725 assembleParamFieldMatrix( J, localVal, pde_vecJ3_overlap_, dofMgr1_ );
726 }
727 catch ( Exception::Zero & ez ) {
728 throw Exception::Zero(">>> (Assembler::assembleDynPDEJacobian_zp): Jacobian is zero.");
729 }
730 catch ( Exception::NotImplemented & eni ) {
731 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEJacobian_zp): Jacobian not implemented.");
732 }
733 }
734 else {
735 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEJacobian_zp): Jacobian not implemented.");
736 }
737 }
738
739 template<class Real>
assembleDynPDEHessian_uo_uo(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)740 void Assembler<Real>::assembleDynPDEHessian_uo_uo(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
741 const ROL::Ptr<DynamicPDE<Real>> &pde,
742 const ROL::TimeStamp<Real> &ts,
743 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
744 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
745 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
746 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
747 const ROL::Ptr<const std::vector<Real>> & z_param) {
748 #ifdef ROL_TIMERS
749 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_uo_uo);
750 #endif
751 try {
752 // Get u_coeff from u and z_coeff from z
753 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
754 getCoeffFromStateVector(uo_coeff,uo);
755 getCoeffFromStateVector(un_coeff,un);
756 getCoeffFromControlVector(z_coeff,z);
757 getCoeffFromStateVector(l_coeff,l);
758 // Initialize Hessian storage if not done so already
759 if ( H == ROL::nullPtr ) {
760 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH11Graph_);
761 }
762 // Assemble
763 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
764 pde->Hessian_uo_uo(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
765 assembleFieldMatrix( H, localVal, dofMgr1_, dofMgr1_ );
766 }
767 catch (Exception::Zero &ez) {
768 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_uo_uo): Hessian is zero.");
769 }
770 catch (Exception::NotImplemented &eni) {
771 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_uo_uo): Hessian not implemented.");
772 }
773 }
774
775 template<class Real>
assembleDynPDEHessian_uo_un(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)776 void Assembler<Real>::assembleDynPDEHessian_uo_un(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
777 const ROL::Ptr<DynamicPDE<Real>> &pde,
778 const ROL::TimeStamp<Real> &ts,
779 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
780 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
781 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
782 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
783 const ROL::Ptr<const std::vector<Real>> & z_param) {
784 #ifdef ROL_TIMERS
785 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_uo_un);
786 #endif
787 try {
788 // Get u_coeff from u and z_coeff from z
789 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
790 getCoeffFromStateVector(uo_coeff,uo);
791 getCoeffFromStateVector(un_coeff,un);
792 getCoeffFromControlVector(z_coeff,z);
793 getCoeffFromStateVector(l_coeff,l);
794 // Initialize Hessian storage if not done so already
795 if ( H == ROL::nullPtr ) {
796 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH11Graph_);
797 }
798 // Assemble
799 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
800 pde->Hessian_uo_un(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
801 assembleFieldMatrix( H, localVal, dofMgr1_, dofMgr1_ );
802 }
803 catch (Exception::Zero &ez) {
804 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_uo_un): Hessian is zero.");
805 }
806 catch (Exception::NotImplemented &eni) {
807 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_uo_un): Hessian not implemented.");
808 }
809 }
810
811 template<class Real>
assembleDynPDEHessian_uo_zf(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)812 void Assembler<Real>::assembleDynPDEHessian_uo_zf(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
813 const ROL::Ptr<DynamicPDE<Real>> &pde,
814 const ROL::TimeStamp<Real> &ts,
815 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
816 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
817 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
818 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
819 const ROL::Ptr<const std::vector<Real>> & z_param) {
820 #ifdef ROL_TIMERS
821 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_uo_zf);
822 #endif
823 try {
824 // Get u_coeff from u and z_coeff from z
825 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
826 getCoeffFromStateVector(uo_coeff,uo);
827 getCoeffFromStateVector(un_coeff,un);
828 getCoeffFromControlVector(z_coeff,z);
829 getCoeffFromStateVector(l_coeff,l);
830 // Initialize Hessian storage if not done so already
831 if ( H == ROL::nullPtr ) {
832 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH12Graph_);
833 }
834 // Assemble
835 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
836 pde->Hessian_uo_zf(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
837 assembleFieldMatrix( H, localVal, dofMgr1_, dofMgr2_ );
838 }
839 catch (Exception::Zero &ez) {
840 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_uo_zf): Hessian is zero.");
841 }
842 catch (Exception::NotImplemented &eni) {
843 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_uo_zf): Hessian not implemented.");
844 }
845 }
846
847 template<class Real>
assembleDynPDEHessian_uo_zp(ROL::Ptr<Tpetra::MultiVector<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)848 void Assembler<Real>::assembleDynPDEHessian_uo_zp(ROL::Ptr<Tpetra::MultiVector<>> &H,
849 const ROL::Ptr<DynamicPDE<Real>> &pde,
850 const ROL::TimeStamp<Real> &ts,
851 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
852 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
853 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
854 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
855 const ROL::Ptr<const std::vector<Real>> & z_param) {
856 #ifdef ROL_TIMERS
857 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_uo_zp);
858 #endif
859 if ( z_param != ROL::nullPtr ) {
860 try {
861 int size = static_cast<int>(z_param->size());
862 // Get u_coeff from u, z_coeff from z and l_coeff from l
863 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
864 getCoeffFromStateVector(uo_coeff,uo);
865 getCoeffFromStateVector(un_coeff,un);
866 getCoeffFromControlVector(z_coeff,z);
867 getCoeffFromStateVector(l_coeff,l);
868 // Initialize Jacobian storage if not done so already
869 if (H == ROL::nullPtr) {
870 H = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueStateMap_, size, true);
871 }
872 if ( pde_vecH13_overlap_ == ROL::nullPtr) {
873 pde_vecH13_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapStateMap_, size, true);
874 }
875 // Assemble
876 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
877 pde->Hessian_uo_zp(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
878 assembleParamFieldMatrix( H, localVal, pde_vecH13_overlap_, dofMgr1_ );
879 }
880 catch ( Exception::Zero & ez ) {
881 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_uo_zp): Hessian is zero.");
882 }
883 catch ( Exception::NotImplemented & eni ) {
884 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_uo_zp): Hessian not implemented.");
885 }
886 }
887 else {
888 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_uo_zp): Hessian not implemented.");
889 }
890 }
891
892 template<class Real>
assembleDynPDEHessian_un_uo(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)893 void Assembler<Real>::assembleDynPDEHessian_un_uo(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
894 const ROL::Ptr<DynamicPDE<Real>> &pde,
895 const ROL::TimeStamp<Real> &ts,
896 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
897 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
898 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
899 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
900 const ROL::Ptr<const std::vector<Real>> & z_param) {
901 #ifdef ROL_TIMERS
902 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_un_uo);
903 #endif
904 try {
905 // Get u_coeff from u and z_coeff from z
906 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
907 getCoeffFromStateVector(uo_coeff,uo);
908 getCoeffFromStateVector(un_coeff,un);
909 getCoeffFromControlVector(z_coeff,z);
910 getCoeffFromStateVector(l_coeff,l);
911 // Initialize Hessian storage if not done so already
912 if ( H == ROL::nullPtr ) {
913 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH11Graph_);
914 }
915 // Assemble
916 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
917 pde->Hessian_un_uo(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
918 assembleFieldMatrix( H, localVal, dofMgr1_, dofMgr1_ );
919 }
920 catch (Exception::Zero &ez) {
921 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_un_uo): Hessian is zero.");
922 }
923 catch (Exception::NotImplemented &eni) {
924 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_un_uo): Hessian not implemented.");
925 }
926 }
927
928 template<class Real>
assembleDynPDEHessian_un_un(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)929 void Assembler<Real>::assembleDynPDEHessian_un_un(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
930 const ROL::Ptr<DynamicPDE<Real>> &pde,
931 const ROL::TimeStamp<Real> &ts,
932 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
933 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
934 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
935 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
936 const ROL::Ptr<const std::vector<Real>> & z_param) {
937 #ifdef ROL_TIMERS
938 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_un_un);
939 #endif
940 try {
941 // Get u_coeff from u and z_coeff from z
942 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
943 getCoeffFromStateVector(uo_coeff,uo);
944 getCoeffFromStateVector(un_coeff,un);
945 getCoeffFromControlVector(z_coeff,z);
946 getCoeffFromStateVector(l_coeff,l);
947 // Initialize Hessian storage if not done so already
948 if ( H == ROL::nullPtr ) {
949 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH11Graph_);
950 }
951 // Assemble
952 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
953 pde->Hessian_un_un(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
954 assembleFieldMatrix( H, localVal, dofMgr1_, dofMgr1_ );
955 }
956 catch (Exception::Zero &ez) {
957 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_un_un): Hessian is zero.");
958 }
959 catch (Exception::NotImplemented &eni) {
960 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_un_un): Hessian not implemented.");
961 }
962 }
963
964 template<class Real>
assembleDynPDEHessian_un_zf(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)965 void Assembler<Real>::assembleDynPDEHessian_un_zf(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
966 const ROL::Ptr<DynamicPDE<Real>> &pde,
967 const ROL::TimeStamp<Real> &ts,
968 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
969 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
970 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
971 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
972 const ROL::Ptr<const std::vector<Real>> & z_param) {
973 #ifdef ROL_TIMERS
974 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_un_zf);
975 #endif
976 try {
977 // Get u_coeff from u and z_coeff from z
978 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
979 getCoeffFromStateVector(uo_coeff,uo);
980 getCoeffFromStateVector(un_coeff,un);
981 getCoeffFromControlVector(z_coeff,z);
982 getCoeffFromStateVector(l_coeff,l);
983 // Initialize Hessian storage if not done so already
984 if ( H == ROL::nullPtr ) {
985 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH12Graph_);
986 }
987 // Assemble
988 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
989 pde->Hessian_un_zf(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
990 assembleFieldMatrix( H, localVal, dofMgr1_, dofMgr2_ );
991 }
992 catch (Exception::Zero &ez) {
993 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_un_zf): Hessian is zero.");
994 }
995 catch (Exception::NotImplemented &eni) {
996 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_un_zf): Hessian not implemented.");
997 }
998 }
999
1000 template<class Real>
assembleDynPDEHessian_un_zp(ROL::Ptr<Tpetra::MultiVector<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1001 void Assembler<Real>::assembleDynPDEHessian_un_zp(ROL::Ptr<Tpetra::MultiVector<>> &H,
1002 const ROL::Ptr<DynamicPDE<Real>> &pde,
1003 const ROL::TimeStamp<Real> &ts,
1004 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1005 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1006 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1007 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1008 const ROL::Ptr<const std::vector<Real>> & z_param) {
1009 #ifdef ROL_TIMERS
1010 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_un_zp);
1011 #endif
1012 if ( z_param != ROL::nullPtr ) {
1013 try {
1014 int size = static_cast<int>(z_param->size());
1015 // Get u_coeff from u, z_coeff from z and l_coeff from l
1016 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
1017 getCoeffFromStateVector(uo_coeff,uo);
1018 getCoeffFromStateVector(un_coeff,un);
1019 getCoeffFromControlVector(z_coeff,z);
1020 getCoeffFromStateVector(l_coeff,l);
1021 // Initialize Jacobian storage if not done so already
1022 if (H == ROL::nullPtr) {
1023 H = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueStateMap_, size, true);
1024 }
1025 if ( pde_vecH13_overlap_ == ROL::nullPtr) {
1026 pde_vecH13_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapStateMap_, size, true);
1027 }
1028 // Assemble
1029 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
1030 pde->Hessian_un_zp(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
1031 assembleParamFieldMatrix( H, localVal, pde_vecH13_overlap_, dofMgr1_ );
1032 }
1033 catch ( Exception::Zero & ez ) {
1034 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_un_zp): Hessian is zero.");
1035 }
1036 catch ( Exception::NotImplemented & eni ) {
1037 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_un_zp): Hessian not implemented.");
1038 }
1039 }
1040 else {
1041 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_un_zp): Hessian not implemented.");
1042 }
1043 }
1044
1045 template<class Real>
assembleDynPDEHessian_zf_uo(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1046 void Assembler<Real>::assembleDynPDEHessian_zf_uo(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
1047 const ROL::Ptr<DynamicPDE<Real>> &pde,
1048 const ROL::TimeStamp<Real> &ts,
1049 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1050 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1051 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1052 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1053 const ROL::Ptr<const std::vector<Real>> & z_param) {
1054 #ifdef ROL_TIMERS
1055 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_zf_uo);
1056 #endif
1057 try {
1058 // Get u_coeff from u and z_coeff from z
1059 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
1060 getCoeffFromStateVector(uo_coeff,uo);
1061 getCoeffFromStateVector(un_coeff,un);
1062 getCoeffFromControlVector(z_coeff,z);
1063 getCoeffFromStateVector(l_coeff,l);
1064 // Initialize Hessian storage if not done so already
1065 if ( H == ROL::nullPtr ) {
1066 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH21Graph_);
1067 }
1068 // Assemble
1069 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1070 pde->Hessian_zf_uo(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
1071 assembleFieldMatrix( H, localVal, dofMgr2_, dofMgr1_ );
1072 }
1073 catch (Exception::Zero &ez) {
1074 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_zf_uo): Hessian is zero.");
1075 }
1076 catch (Exception::NotImplemented &eni) {
1077 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_zf_uo): Hessian not implemented.");
1078 }
1079 }
1080
1081 template<class Real>
assembleDynPDEHessian_zf_un(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1082 void Assembler<Real>::assembleDynPDEHessian_zf_un(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
1083 const ROL::Ptr<DynamicPDE<Real>> &pde,
1084 const ROL::TimeStamp<Real> &ts,
1085 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1086 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1087 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1088 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1089 const ROL::Ptr<const std::vector<Real>> & z_param) {
1090 #ifdef ROL_TIMERS
1091 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_zf_un);
1092 #endif
1093 try {
1094 // Get u_coeff from u and z_coeff from z
1095 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
1096 getCoeffFromStateVector(uo_coeff,uo);
1097 getCoeffFromStateVector(un_coeff,un);
1098 getCoeffFromControlVector(z_coeff,z);
1099 getCoeffFromStateVector(l_coeff,l);
1100 // Initialize Hessian storage if not done so already
1101 if ( H == ROL::nullPtr ) {
1102 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH21Graph_);
1103 }
1104 // Assemble
1105 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1106 pde->Hessian_zf_un(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
1107 assembleFieldMatrix( H, localVal, dofMgr2_, dofMgr1_ );
1108 }
1109 catch (Exception::Zero &ez) {
1110 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_zf_un): Hessian is zero.");
1111 }
1112 catch (Exception::NotImplemented &eni) {
1113 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_zf_un): Hessian not implemented.");
1114 }
1115 }
1116
1117 template<class Real>
assembleDynPDEHessian_zf_zf(ROL::Ptr<Tpetra::CrsMatrix<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1118 void Assembler<Real>::assembleDynPDEHessian_zf_zf(ROL::Ptr<Tpetra::CrsMatrix<>> &H,
1119 const ROL::Ptr<DynamicPDE<Real>> &pde,
1120 const ROL::TimeStamp<Real> &ts,
1121 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1122 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1123 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1124 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1125 const ROL::Ptr<const std::vector<Real>> & z_param) {
1126 #ifdef ROL_TIMERS
1127 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_zf_zf);
1128 #endif
1129 try {
1130 // Get u_coeff from u and z_coeff from z
1131 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
1132 getCoeffFromStateVector(uo_coeff,uo);
1133 getCoeffFromStateVector(un_coeff,un);
1134 getCoeffFromControlVector(z_coeff,z);
1135 getCoeffFromStateVector(l_coeff,l);
1136 // Initialize Hessian storage if not done so already
1137 if ( H == ROL::nullPtr ) {
1138 H = ROL::makePtr<Tpetra::CrsMatrix<>>(matH22Graph_);
1139 }
1140 // Assemble
1141 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1142 pde->Hessian_zf_zf(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
1143 assembleFieldMatrix( H, localVal, dofMgr2_, dofMgr2_ );
1144 }
1145 catch (Exception::Zero &ez) {
1146 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_zf_zf): Hessian is zero.");
1147 }
1148 catch (Exception::NotImplemented &eni) {
1149 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_zf_zf): Hessian not implemented.");
1150 }
1151 }
1152
1153 template<class Real>
assembleDynPDEHessian_zf_zp(ROL::Ptr<Tpetra::MultiVector<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1154 void Assembler<Real>::assembleDynPDEHessian_zf_zp(ROL::Ptr<Tpetra::MultiVector<>> &H,
1155 const ROL::Ptr<DynamicPDE<Real>> &pde,
1156 const ROL::TimeStamp<Real> &ts,
1157 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1158 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1159 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1160 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1161 const ROL::Ptr<const std::vector<Real>> & z_param) {
1162 #ifdef ROL_TIMERS
1163 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_zf_zp);
1164 #endif
1165 if ( z_param != ROL::nullPtr ) {
1166 try {
1167 int size = static_cast<int>(z_param->size());
1168 // Get u_coeff from u, z_coeff from z and l_coeff from l
1169 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
1170 getCoeffFromStateVector(uo_coeff,uo);
1171 getCoeffFromStateVector(un_coeff,un);
1172 getCoeffFromControlVector(z_coeff,z);
1173 getCoeffFromStateVector(l_coeff,l);
1174 // Initialize Jacobian storage if not done so already
1175 if (H == ROL::nullPtr) {
1176 H = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueControlMap_, size, true);
1177 }
1178 if ( pde_vecH23_overlap_ == ROL::nullPtr) {
1179 pde_vecH23_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapControlMap_, size, true);
1180 }
1181 // Assemble
1182 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
1183 pde->Hessian_zf_zp(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
1184 assembleParamFieldMatrix( H, localVal, pde_vecH23_overlap_, dofMgr2_ );
1185 }
1186 catch ( Exception::Zero & ez ) {
1187 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_zf_zp): Hessian is zero.");
1188 }
1189 catch ( Exception::NotImplemented & eni ) {
1190 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_zf_zp): Hessian not implemented.");
1191 }
1192 }
1193 else {
1194 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_zf_zp): Hessian not implemented.");
1195 }
1196 }
1197
1198 template<class Real>
assembleDynPDEHessian_zp_uo(ROL::Ptr<Tpetra::MultiVector<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1199 void Assembler<Real>::assembleDynPDEHessian_zp_uo(ROL::Ptr<Tpetra::MultiVector<>> &H,
1200 const ROL::Ptr<DynamicPDE<Real>> &pde,
1201 const ROL::TimeStamp<Real> &ts,
1202 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1203 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1204 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1205 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1206 const ROL::Ptr<const std::vector<Real>> & z_param) {
1207 #ifdef ROL_TIMERS
1208 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_zp_uo);
1209 #endif
1210 assembleDynPDEHessian_uo_zp(H,pde,ts,l,uo,un,z,z_param);
1211 }
1212
1213 template<class Real>
assembleDynPDEHessian_zp_un(ROL::Ptr<Tpetra::MultiVector<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1214 void Assembler<Real>::assembleDynPDEHessian_zp_un(ROL::Ptr<Tpetra::MultiVector<>> &H,
1215 const ROL::Ptr<DynamicPDE<Real>> &pde,
1216 const ROL::TimeStamp<Real> &ts,
1217 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1218 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1219 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1220 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1221 const ROL::Ptr<const std::vector<Real>> & z_param) {
1222 #ifdef ROL_TIMERS
1223 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_zp_un);
1224 #endif
1225 assembleDynPDEHessian_un_zp(H,pde,ts,l,uo,un,z,z_param);
1226 }
1227
1228 template<class Real>
assembleDynPDEHessian_zp_zf(ROL::Ptr<Tpetra::MultiVector<>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1229 void Assembler<Real>::assembleDynPDEHessian_zp_zf(ROL::Ptr<Tpetra::MultiVector<>> &H,
1230 const ROL::Ptr<DynamicPDE<Real>> &pde,
1231 const ROL::TimeStamp<Real> &ts,
1232 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1233 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1234 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1235 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1236 const ROL::Ptr<const std::vector<Real>> & z_param) {
1237 #ifdef ROL_TIMERS
1238 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_zp_zf);
1239 #endif
1240 assembleDynPDEHessian_zf_zp(H,pde,ts,l,uo,un,z,z_param);
1241 }
1242
1243 template<class Real>
assembleDynPDEHessian_zp_zp(ROL::Ptr<std::vector<std::vector<Real>>> & H,const ROL::Ptr<DynamicPDE<Real>> & pde,const ROL::TimeStamp<Real> & ts,const ROL::Ptr<const Tpetra::MultiVector<>> & l,const ROL::Ptr<const Tpetra::MultiVector<>> & uo,const ROL::Ptr<const Tpetra::MultiVector<>> & un,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1244 void Assembler<Real>::assembleDynPDEHessian_zp_zp(ROL::Ptr<std::vector<std::vector<Real>>> &H,
1245 const ROL::Ptr<DynamicPDE<Real>> &pde,
1246 const ROL::TimeStamp<Real> &ts,
1247 const ROL::Ptr<const Tpetra::MultiVector<>> &l,
1248 const ROL::Ptr<const Tpetra::MultiVector<>> &uo,
1249 const ROL::Ptr<const Tpetra::MultiVector<>> &un,
1250 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1251 const ROL::Ptr<const std::vector<Real>> & z_param) {
1252 #ifdef ROL_TIMERS
1253 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleDynPDEHessian_zp_zp);
1254 #endif
1255 if ( z_param != ROL::nullPtr ) {
1256 try {
1257 int size = static_cast<int>(z_param->size());
1258 // Get u_coeff from u, z_coeff from z and l_coeff from l
1259 ROL::Ptr<Intrepid::FieldContainer<Real>> uo_coeff, un_coeff, z_coeff, l_coeff;
1260 getCoeffFromStateVector(uo_coeff,uo);
1261 getCoeffFromStateVector(un_coeff,un);
1262 getCoeffFromControlVector(z_coeff,z);
1263 getCoeffFromStateVector(l_coeff,l);
1264 // Initialize Jacobian storage if not done so already
1265 if (H == ROL::nullPtr) {
1266 std::vector<Real> col(size,static_cast<Real>(0));
1267 H = ROL::makePtr<std::vector<std::vector<Real>>>(size,col);
1268 }
1269 // Assemble
1270 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> tmp(size,ROL::nullPtr);
1271 std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> localVal(size,tmp);
1272 pde->Hessian_zp_zp(localVal,ts,l_coeff,uo_coeff,un_coeff,z_coeff,z_param);
1273 assembleParamMatrix( H, localVal, dofMgr1_ );
1274 }
1275 catch ( Exception::Zero & ez ) {
1276 throw Exception::Zero(">>> (Assembler::assembleDynPDEHessian_zp_zp): Hessian is zero.");
1277 }
1278 catch ( Exception::NotImplemented & eni ) {
1279 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_zp_zp): Hessian not implemented.");
1280 }
1281 }
1282 else {
1283 throw Exception::NotImplemented(">>> (Assembler::assembleDynPDEHessian_zp_zp): Hessian not implemented.");
1284 }
1285 }
1286 /***************************************************************************/
1287 /* End of PDE assembly routines. */
1288 /***************************************************************************/
1289
1290 /***************************************************************************/
1291 /* QoI assembly routines */
1292 /***************************************************************************/
1293 template<class Real>
assembleQoIValue(const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1294 Real Assembler<Real>::assembleQoIValue(const ROL::Ptr<QoI<Real>> &qoi,
1295 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1296 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1297 const ROL::Ptr<const std::vector<Real>> & z_param) {
1298 #ifdef ROL_TIMERS
1299 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIValue);
1300 #endif
1301 Real val(0);
1302 try {
1303 // Get u_coeff from u and z_coeff from z
1304 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1305 getCoeffFromStateVector(u_coeff,u);
1306 getCoeffFromControlVector(z_coeff,z);
1307 // Assemble
1308 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1309 val = qoi->value(localVal,u_coeff,z_coeff,z_param);
1310 val += assembleScalar( localVal );
1311 }
1312 catch ( Exception::Zero & ez ) {
1313 val = static_cast<Real>(0);
1314 }
1315 catch ( Exception::NotImplemented & eni ) {
1316 throw Exception::NotImplemented(">>> (Assembler::assembleQoIValue): Value not implemented.");
1317 }
1318 return val;
1319 }
1320
1321 template<class Real>
assembleQoIGradient1(ROL::Ptr<Tpetra::MultiVector<>> & g1,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1322 void Assembler<Real>::assembleQoIGradient1(ROL::Ptr<Tpetra::MultiVector<>> &g1,
1323 const ROL::Ptr<QoI<Real>> &qoi,
1324 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1325 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1326 const ROL::Ptr<const std::vector<Real>> & z_param) {
1327 #ifdef ROL_TIMERS
1328 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIGradient1);
1329 #endif
1330 try {
1331 // Initialize state QoI gradient vectors
1332 if ( g1 == ROL::nullPtr ) {
1333 g1 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueStateMap_, 1, true);
1334 }
1335 if ( qoi_vecG1_overlap_ == ROL::nullPtr ) {
1336 qoi_vecG1_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapStateMap_, 1, true);
1337 }
1338 // Get u_coeff from u and z_coeff from z
1339 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1340 getCoeffFromStateVector(u_coeff,u);
1341 getCoeffFromControlVector(z_coeff,z);
1342 // Assemble
1343 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1344 qoi->gradient_1(localVal,u_coeff,z_coeff,z_param);
1345 assembleFieldVector( g1, localVal, qoi_vecG1_overlap_, dofMgr1_ );
1346 }
1347 catch ( Exception::Zero & ez ) {
1348 throw Exception::Zero(">>> (Assembler::assembleQoIGradient1): Gradient is zero.");
1349 }
1350 catch ( Exception::NotImplemented & eni ) {
1351 throw Exception::NotImplemented(">>> (Assembler::assembleQoIGradient1): Gradient not implemented.");
1352 }
1353 }
1354
1355 template<class Real>
assembleQoIGradient2(ROL::Ptr<Tpetra::MultiVector<>> & g2,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1356 void Assembler<Real>::assembleQoIGradient2(ROL::Ptr<Tpetra::MultiVector<>> &g2,
1357 const ROL::Ptr<QoI<Real>> &qoi,
1358 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1359 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1360 const ROL::Ptr<const std::vector<Real>> & z_param) {
1361 #ifdef ROL_TIMERS
1362 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIGradient2);
1363 #endif
1364 try {
1365 // Initialize control gradient vectors
1366 if ( g2 == ROL::nullPtr ) {
1367 g2 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueControlMap_, 1, true);
1368 }
1369 if ( qoi_vecG2_overlap_ == ROL::nullPtr ) {
1370 qoi_vecG2_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapControlMap_, 1, true);
1371 }
1372 // Get u_coeff from u and z_coeff from z
1373 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1374 getCoeffFromStateVector(u_coeff,u);
1375 getCoeffFromControlVector(z_coeff,z);
1376 // Assemble
1377 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1378 qoi->gradient_2(localVal,u_coeff,z_coeff,z_param);
1379 assembleFieldVector( g2, localVal, qoi_vecG2_overlap_, dofMgr2_ );
1380 }
1381 catch ( Exception::Zero & ez ) {
1382 throw Exception::Zero(">>> (Assembler::assembleQoIGradient2): Gradient is zero.");
1383 }
1384 catch ( Exception::NotImplemented & eni ) {
1385 throw Exception::NotImplemented(">>> (Assembler::assembleQoIGradient2): Gradient not implemented.");
1386 }
1387 }
1388
1389 template<class Real>
assembleQoIGradient3(ROL::Ptr<std::vector<Real>> & g3,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1390 void Assembler<Real>::assembleQoIGradient3(ROL::Ptr<std::vector<Real>> &g3,
1391 const ROL::Ptr<QoI<Real>> &qoi,
1392 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1393 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1394 const ROL::Ptr<const std::vector<Real>> & z_param) {
1395 #ifdef ROL_TIMERS
1396 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIGradient3);
1397 #endif
1398 if ( z_param != ROL::nullPtr ) {
1399 const int size = z_param->size();
1400 if ( g3 == ROL::nullPtr ) {
1401 g3 = ROL::makePtr<std::vector<Real>>(size,0);
1402 }
1403 try {
1404 // Get u_coeff from u and z_coeff from z
1405 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1406 getCoeffFromStateVector(u_coeff,u);
1407 getCoeffFromControlVector(z_coeff,z);
1408 // Assemble
1409 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
1410 std::vector<Real> g = qoi->gradient_3(localVal,u_coeff,z_coeff,z_param);
1411 assembleParamVector( g3, localVal );
1412 for (int i = 0; i < size; ++i) {
1413 (*g3)[i] += g[i];
1414 }
1415 }
1416 catch ( Exception::Zero & ez ) {
1417 g3->assign(size,0);
1418 }
1419 catch ( Exception::NotImplemented & eni ) {
1420 throw Exception::NotImplemented(">>> (Assembler::assembleQoIGradient3): Gradient not implemented.");
1421 }
1422 }
1423 else {
1424 throw Exception::NotImplemented(">>> (Assembler::assembleQoIGradient3): Gradient not implemented.");
1425 }
1426 }
1427
1428 template<class Real>
assembleQoIHessVec11(ROL::Ptr<Tpetra::MultiVector<>> & H11,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1429 void Assembler<Real>::assembleQoIHessVec11(ROL::Ptr<Tpetra::MultiVector<>> &H11,
1430 const ROL::Ptr<QoI<Real>> &qoi,
1431 const ROL::Ptr<const Tpetra::MultiVector<>> &v,
1432 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1433 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1434 const ROL::Ptr<const std::vector<Real>> & z_param) {
1435 #ifdef ROL_TIMERS
1436 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec11);
1437 #endif
1438 try {
1439 // Get u_coeff from u and z_coeff from z
1440 ROL::Ptr<Intrepid::FieldContainer<Real>> v_coeff, u_coeff, z_coeff;
1441 getCoeffFromStateVector(v_coeff,v);
1442 getCoeffFromStateVector(u_coeff,u);
1443 getCoeffFromControlVector(z_coeff,z);
1444 // Initialize state-state HessVec vectors
1445 if ( H11 == ROL::nullPtr ) {
1446 H11 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueStateMap_, 1, true);
1447 }
1448 if ( qoi_vecH11_overlap_ == ROL::nullPtr ) {
1449 qoi_vecH11_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapStateMap_, 1, true);
1450 }
1451 // Assemble
1452 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1453 qoi->HessVec_11(localVal,v_coeff,u_coeff,z_coeff,z_param);
1454 assembleFieldVector( H11, localVal, qoi_vecH11_overlap_, dofMgr1_ );
1455 }
1456 catch (Exception::Zero &ez) {
1457 throw Exception::Zero(">>> (Assembler::assembleQoIHessVec11): Hessian is zero.");
1458 }
1459 catch (Exception::NotImplemented &eni) {
1460 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec11): Hessian not implemented.");
1461 }
1462 }
1463
1464 template<class Real>
assembleQoIHessVec12(ROL::Ptr<Tpetra::MultiVector<>> & H12,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1465 void Assembler<Real>::assembleQoIHessVec12(ROL::Ptr<Tpetra::MultiVector<>> &H12,
1466 const ROL::Ptr<QoI<Real>> &qoi,
1467 const ROL::Ptr<const Tpetra::MultiVector<>> &v,
1468 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1469 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1470 const ROL::Ptr<const std::vector<Real>> & z_param) {
1471 #ifdef ROL_TIMERS
1472 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec12);
1473 #endif
1474 try {
1475 // Get u_coeff from u and z_coeff from z
1476 ROL::Ptr<Intrepid::FieldContainer<Real>> v_coeff, u_coeff, z_coeff;
1477 getCoeffFromControlVector(v_coeff,v);
1478 getCoeffFromStateVector(u_coeff,u);
1479 getCoeffFromControlVector(z_coeff,z);
1480 // Initialize state-control HessVec vectors
1481 if ( H12 == ROL::nullPtr ) {
1482 H12 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueStateMap_, 1, true);
1483 }
1484 if ( qoi_vecH12_overlap_ == ROL::nullPtr ) {
1485 qoi_vecH12_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapStateMap_, 1, true);
1486 }
1487 // Assemble
1488 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1489 qoi->HessVec_12(localVal,v_coeff,u_coeff,z_coeff,z_param);
1490 assembleFieldVector( H12, localVal, qoi_vecH12_overlap_, dofMgr1_ );
1491 }
1492 catch (Exception::Zero &ez) {
1493 throw Exception::Zero(">>> (Assembler::assembleQoIHessVec12): Hessian is zero.");
1494 }
1495 catch (Exception::NotImplemented &eni) {
1496 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec12): Hessian not implemented.");
1497 }
1498 }
1499
1500 template<class Real>
assembleQoIHessVec13(ROL::Ptr<Tpetra::MultiVector<>> & H13,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const std::vector<Real>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1501 void Assembler<Real>::assembleQoIHessVec13(ROL::Ptr<Tpetra::MultiVector<>> &H13,
1502 const ROL::Ptr<QoI<Real>> &qoi,
1503 const ROL::Ptr<const std::vector<Real>> &v,
1504 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1505 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1506 const ROL::Ptr<const std::vector<Real>> &z_param) {
1507 #ifdef ROL_TIMERS
1508 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec13);
1509 #endif
1510 if (z_param != ROL::nullPtr) {
1511 try {
1512 // Get u_coeff from u and z_coeff from z
1513 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1514 getCoeffFromStateVector(u_coeff,u);
1515 getCoeffFromControlVector(z_coeff,z);
1516 // Initialize state-control HessVec vectors
1517 if ( H13 == ROL::nullPtr ) {
1518 H13 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueStateMap_, 1, true);
1519 }
1520 if ( qoi_vecH13_overlap_ == ROL::nullPtr ) {
1521 qoi_vecH13_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapStateMap_, 1, true);
1522 }
1523 // Assemble
1524 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1525 qoi->HessVec_13(localVal,v,u_coeff,z_coeff,z_param);
1526 assembleFieldVector( H13, localVal, qoi_vecH13_overlap_, dofMgr1_ );
1527 }
1528 catch (Exception::Zero &ez) {
1529 throw Exception::Zero(">>> (Assembler::assembleQoIHessVec13): Hessian is zero.");
1530 }
1531 catch (Exception::NotImplemented &eni) {
1532 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec13): Hessian not implemented.");
1533 }
1534 }
1535 else {
1536 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec13): Hessian not implemented.");
1537 }
1538 }
1539
1540 template<class Real>
assembleQoIHessVec21(ROL::Ptr<Tpetra::MultiVector<>> & H21,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1541 void Assembler<Real>::assembleQoIHessVec21(ROL::Ptr<Tpetra::MultiVector<>> &H21,
1542 const ROL::Ptr<QoI<Real>> &qoi,
1543 const ROL::Ptr<const Tpetra::MultiVector<>> &v,
1544 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1545 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1546 const ROL::Ptr<const std::vector<Real>> & z_param) {
1547 #ifdef ROL_TIMERS
1548 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec21);
1549 #endif
1550 try {
1551 // Get u_coeff from u and z_coeff from z
1552 ROL::Ptr<Intrepid::FieldContainer<Real>> v_coeff, u_coeff, z_coeff;
1553 getCoeffFromStateVector(v_coeff,v);
1554 getCoeffFromStateVector(u_coeff,u);
1555 getCoeffFromControlVector(z_coeff,z);
1556 // Initialize control-state HessVec vectors
1557 if ( H21 == ROL::nullPtr ) {
1558 H21 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueControlMap_, 1, true);
1559 }
1560 if ( qoi_vecH21_overlap_ == ROL::nullPtr ) {
1561 qoi_vecH21_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapControlMap_, 1, true);
1562 }
1563 // Assemble
1564 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1565 qoi->HessVec_21(localVal,v_coeff,u_coeff,z_coeff,z_param);
1566 assembleFieldVector( H21, localVal, qoi_vecH21_overlap_, dofMgr2_ );
1567 }
1568 catch (Exception::Zero &ez) {
1569 throw Exception::Zero(">>> (Assembler::assembleQoIHessVec21): Hessian is zero.");
1570 }
1571 catch (Exception::NotImplemented &eni) {
1572 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec21): Hessian not implemented.");
1573 }
1574 }
1575
1576 template<class Real>
assembleQoIHessVec22(ROL::Ptr<Tpetra::MultiVector<>> & H22,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1577 void Assembler<Real>::assembleQoIHessVec22(ROL::Ptr<Tpetra::MultiVector<>> &H22,
1578 const ROL::Ptr<QoI<Real>> &qoi,
1579 const ROL::Ptr<const Tpetra::MultiVector<>> &v,
1580 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1581 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1582 const ROL::Ptr<const std::vector<Real>> & z_param) {
1583 #ifdef ROL_TIMERS
1584 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec22);
1585 #endif
1586 try {
1587 // Get u_coeff from u and z_coeff from z
1588 ROL::Ptr<Intrepid::FieldContainer<Real>> v_coeff, u_coeff, z_coeff;
1589 getCoeffFromControlVector(v_coeff,v);
1590 getCoeffFromStateVector(u_coeff,u);
1591 getCoeffFromControlVector(z_coeff,z);
1592 // Initialize control-control HessVec vectors
1593 if ( H22 == ROL::nullPtr ) {
1594 H22 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueControlMap_, 1, true);
1595 }
1596 if ( qoi_vecH22_overlap_ == ROL::nullPtr ) {
1597 qoi_vecH22_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapControlMap_, 1, true);
1598 }
1599 // Assemble
1600 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1601 qoi->HessVec_22(localVal,v_coeff,u_coeff,z_coeff,z_param);
1602 assembleFieldVector( H22, localVal, qoi_vecH22_overlap_, dofMgr2_ );
1603 }
1604 catch (Exception::Zero &ez) {
1605 throw Exception::Zero(">>> (Assembler::assembleQoIHessVec22): Hessian is zero.");
1606 }
1607 catch (Exception::NotImplemented &eni) {
1608 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec22): Hessian not implemented.");
1609 }
1610 }
1611
1612 template<class Real>
assembleQoIHessVec23(ROL::Ptr<Tpetra::MultiVector<>> & H23,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const std::vector<Real>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1613 void Assembler<Real>::assembleQoIHessVec23(ROL::Ptr<Tpetra::MultiVector<>> &H23,
1614 const ROL::Ptr<QoI<Real>> &qoi,
1615 const ROL::Ptr<const std::vector<Real>> &v,
1616 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1617 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1618 const ROL::Ptr<const std::vector<Real>> & z_param) {
1619 #ifdef ROL_TIMERS
1620 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec23);
1621 #endif
1622 if (z_param != ROL::nullPtr) {
1623 try {
1624 // Get u_coeff from u and z_coeff from z
1625 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1626 getCoeffFromStateVector(u_coeff,u);
1627 getCoeffFromControlVector(z_coeff,z);
1628 // Initialize control-control HessVec vectors
1629 if ( H23 == ROL::nullPtr ) {
1630 H23 = ROL::makePtr<Tpetra::MultiVector<>>(myUniqueControlMap_, 1, true);
1631 }
1632 if ( qoi_vecH23_overlap_ == ROL::nullPtr ) {
1633 qoi_vecH23_overlap_ = ROL::makePtr<Tpetra::MultiVector<>>(myOverlapControlMap_, 1, true);
1634 }
1635 // Assemble
1636 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1637 qoi->HessVec_23(localVal,v,u_coeff,z_coeff,z_param);
1638 assembleFieldVector( H23, localVal, qoi_vecH23_overlap_, dofMgr2_ );
1639 }
1640 catch (Exception::Zero &ez) {
1641 throw Exception::Zero(">>> (Assembler::assembleQoIHessVec23): Hessian is zero.");
1642 }
1643 catch (Exception::NotImplemented &eni) {
1644 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec23): Hessian not implemented.");
1645 }
1646 }
1647 else {
1648 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec23): Hessian not implemented.");
1649 }
1650
1651 }
1652
1653 template<class Real>
assembleQoIHessVec31(ROL::Ptr<std::vector<Real>> & H31,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1654 void Assembler<Real>::assembleQoIHessVec31(ROL::Ptr<std::vector<Real>> &H31,
1655 const ROL::Ptr<QoI<Real>> &qoi,
1656 const ROL::Ptr<const Tpetra::MultiVector<>> &v,
1657 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1658 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1659 const ROL::Ptr<const std::vector<Real>> & z_param) {
1660 #ifdef ROL_TIMERS
1661 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec31);
1662 #endif
1663 if ( z_param != ROL::nullPtr ) {
1664 const int size = z_param->size();
1665 if ( H31 == ROL::nullPtr ) {
1666 H31 = ROL::makePtr<std::vector<Real>>(size,0);
1667 }
1668 try {
1669 H31->assign(size,0);
1670 // Get u_coeff from u and z_coeff from z
1671 ROL::Ptr<Intrepid::FieldContainer<Real>> v_coeff, u_coeff, z_coeff;
1672 getCoeffFromStateVector(v_coeff,v);
1673 getCoeffFromStateVector(u_coeff,u);
1674 getCoeffFromControlVector(z_coeff,z);
1675 // Assemble
1676 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
1677 std::vector<Real> H = qoi->HessVec_31(localVal,v_coeff,u_coeff,z_coeff,z_param);
1678 assembleParamVector( H31, localVal );
1679 for (int i = 0; i < size; ++i) {
1680 (*H31)[i] += H[i];
1681 }
1682 }
1683 catch ( Exception::Zero & ez ) {
1684 H31->assign(size,0);
1685 }
1686 catch ( Exception::NotImplemented & eni ) {
1687 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec31): HessVec not implemented.");
1688 }
1689 }
1690 else {
1691 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec31): HessVec not implemented.");
1692 }
1693 }
1694
1695 template<class Real>
assembleQoIHessVec32(ROL::Ptr<std::vector<Real>> & H32,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1696 void Assembler<Real>::assembleQoIHessVec32(ROL::Ptr<std::vector<Real>> &H32,
1697 const ROL::Ptr<QoI<Real>> &qoi,
1698 const ROL::Ptr<const Tpetra::MultiVector<>> &v,
1699 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1700 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1701 const ROL::Ptr<const std::vector<Real>> & z_param) {
1702 #ifdef ROL_TIMERS
1703 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec32);
1704 #endif
1705 if ( z_param != ROL::nullPtr ) {
1706 const int size = z_param->size();
1707 if ( H32 == ROL::nullPtr ) {
1708 H32 = ROL::makePtr<std::vector<Real>>(size,0);
1709 }
1710 try {
1711 H32->assign(size,0);
1712 // Get u_coeff from u and z_coeff from z
1713 ROL::Ptr<Intrepid::FieldContainer<Real>> v_coeff, u_coeff, z_coeff;
1714 getCoeffFromControlVector(v_coeff,v);
1715 getCoeffFromStateVector(u_coeff,u);
1716 getCoeffFromControlVector(z_coeff,z);
1717 // Assemble
1718 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
1719 std::vector<Real> H = qoi->HessVec_32(localVal,v_coeff,u_coeff,z_coeff,z_param);
1720 assembleParamVector( H32, localVal );
1721 for (int i = 0; i < size; ++i) {
1722 (*H32)[i] += H[i];
1723 }
1724 }
1725 catch ( Exception::Zero & ez ) {
1726 H32->assign(size,0);
1727 }
1728 catch ( Exception::NotImplemented & eni ) {
1729 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec32): HessVec not implemented.");
1730 }
1731 }
1732 else {
1733 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec32): HessVec not implemented.");
1734 }
1735 }
1736
1737 template<class Real>
assembleQoIHessVec33(ROL::Ptr<std::vector<Real>> & H33,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const std::vector<Real>> & v,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1738 void Assembler<Real>::assembleQoIHessVec33(ROL::Ptr<std::vector<Real>> &H33,
1739 const ROL::Ptr<QoI<Real>> &qoi,
1740 const ROL::Ptr<const std::vector<Real>> &v,
1741 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1742 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1743 const ROL::Ptr<const std::vector<Real>> &z_param) {
1744 #ifdef ROL_TIMERS
1745 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessVec33);
1746 #endif
1747 if ( z_param != ROL::nullPtr ) {
1748 const int size = z_param->size();
1749 if ( H33 == ROL::nullPtr ) {
1750 H33 = ROL::makePtr<std::vector<Real>>(size,0);
1751 }
1752 try {
1753 H33->assign(size,0);
1754 // Get u_coeff from u and z_coeff from z
1755 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1756 getCoeffFromStateVector(u_coeff,u);
1757 getCoeffFromControlVector(z_coeff,z);
1758 // Assemble
1759 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> localVal(size,ROL::nullPtr);
1760 std::vector<Real> H = qoi->HessVec_33(localVal,v,u_coeff,z_coeff,z_param);
1761 assembleParamVector( H33, localVal );
1762 for (int i = 0; i < size; ++i) {
1763 (*H33)[i] += H[i];
1764 }
1765 }
1766 catch ( Exception::Zero & ez ) {
1767 H33->assign(size,0);
1768 }
1769 catch ( Exception::NotImplemented & eni ) {
1770 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec33): HessVec not implemented.");
1771 }
1772 }
1773 else {
1774 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessVec33): HessVec not implemented.");
1775 }
1776 }
1777
1778 template<class Real>
assembleQoIHessian11(ROL::Ptr<Tpetra::CrsMatrix<>> & H11,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1779 void Assembler<Real>::assembleQoIHessian11(ROL::Ptr<Tpetra::CrsMatrix<>> &H11,
1780 const ROL::Ptr<QoI<Real>> &qoi,
1781 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1782 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1783 const ROL::Ptr<const std::vector<Real>> & z_param) {
1784 #ifdef ROL_TIMERS
1785 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessian11);
1786 #endif
1787 try {
1788 // Get u_coeff from u and z_coeff from z
1789 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1790 getCoeffFromStateVector(u_coeff,u);
1791 getCoeffFromControlVector(z_coeff,z);
1792 // Initialize Jacobian matrices
1793 if ( H11 == ROL::nullPtr ) {
1794 H11 = ROL::makePtr<Tpetra::CrsMatrix<>>(matH11Graph_);
1795 }
1796 // Assemble
1797 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1798 qoi->Hessian_11(localVal,u_coeff,z_coeff,z_param);
1799 assembleFieldMatrix( H11, localVal, dofMgr1_, dofMgr1_ );
1800 }
1801 catch ( Exception::Zero & ez ) {
1802 throw Exception::Zero(">>> (Assembler::assembleQoIHessian11): Hessian is zero.");
1803 }
1804 catch ( Exception::NotImplemented & eni ) {
1805 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessian11): Hessian not implemented.");
1806 }
1807 }
1808
1809 template<class Real>
assembleQoIHessian12(ROL::Ptr<Tpetra::CrsMatrix<>> & H12,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1810 void Assembler<Real>::assembleQoIHessian12(ROL::Ptr<Tpetra::CrsMatrix<>> &H12,
1811 const ROL::Ptr<QoI<Real>> &qoi,
1812 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1813 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1814 const ROL::Ptr<const std::vector<Real>> & z_param) {
1815 #ifdef ROL_TIMERS
1816 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessian12);
1817 #endif
1818 try {
1819 // Get u_coeff from u and z_coeff from z
1820 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1821 getCoeffFromStateVector(u_coeff,u);
1822 getCoeffFromControlVector(z_coeff,z);
1823 // Initialize Jacobian matrices
1824 if ( H12 == ROL::nullPtr ) {
1825 H12 = ROL::makePtr<Tpetra::CrsMatrix<>>(matH12Graph_);
1826 }
1827 // Assemble
1828 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1829 qoi->Hessian_12(localVal,u_coeff,z_coeff,z_param);
1830 assembleFieldMatrix( H12, localVal, dofMgr1_, dofMgr2_ );
1831 }
1832 catch ( Exception::Zero & ez ) {
1833 throw Exception::Zero(">>> (Assembler::assembleQoIHessian12): Hessian is zero.");
1834 }
1835 catch ( Exception::NotImplemented & eni ) {
1836 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessian12): Hessian not implemented.");
1837 }
1838 }
1839
1840 template<class Real>
assembleQoIHessian21(ROL::Ptr<Tpetra::CrsMatrix<>> & H21,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1841 void Assembler<Real>::assembleQoIHessian21(ROL::Ptr<Tpetra::CrsMatrix<>> &H21,
1842 const ROL::Ptr<QoI<Real>> &qoi,
1843 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1844 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1845 const ROL::Ptr<const std::vector<Real>> & z_param) {
1846 #ifdef ROL_TIMERS
1847 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessian21);
1848 #endif
1849 try {
1850 // Get u_coeff from u and z_coeff from z
1851 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1852 getCoeffFromStateVector(u_coeff,u);
1853 getCoeffFromControlVector(z_coeff,z);
1854 // Initialize Jacobian matrices
1855 if ( H21 == ROL::nullPtr ) {
1856 H21 = ROL::makePtr<Tpetra::CrsMatrix<>>(matH21Graph_);
1857 }
1858 // Assemble
1859 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1860 qoi->Hessian_21(localVal,u_coeff,z_coeff,z_param);
1861 assembleFieldMatrix( H21, localVal, dofMgr2_, dofMgr1_ );
1862 }
1863 catch ( Exception::Zero & ez ) {
1864 throw Exception::Zero(">>> (Assembler::assembleQoIHessian21): Hessian is zero.");
1865 }
1866 catch ( Exception::NotImplemented & eni ) {
1867 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessian21): Hessian not implemented.");
1868 }
1869 }
1870
1871 template<class Real>
assembleQoIHessian22(ROL::Ptr<Tpetra::CrsMatrix<>> & H22,const ROL::Ptr<QoI<Real>> & qoi,const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<const Tpetra::MultiVector<>> & z,const ROL::Ptr<const std::vector<Real>> & z_param)1872 void Assembler<Real>::assembleQoIHessian22(ROL::Ptr<Tpetra::CrsMatrix<>> &H22,
1873 const ROL::Ptr<QoI<Real>> &qoi,
1874 const ROL::Ptr<const Tpetra::MultiVector<>> &u,
1875 const ROL::Ptr<const Tpetra::MultiVector<>> &z,
1876 const ROL::Ptr<const std::vector<Real>> & z_param) {
1877 #ifdef ROL_TIMERS
1878 Teuchos::TimeMonitor LocalTimer(*ROL::PDEOPT::AssembleQOIHessian22);
1879 #endif
1880 try {
1881 // Get u_coeff from u and z_coeff from z
1882 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff, z_coeff;
1883 getCoeffFromStateVector(u_coeff,u);
1884 getCoeffFromControlVector(z_coeff,z);
1885 // Initialize Jacobian matrices
1886 if ( H22 == ROL::nullPtr ) {
1887 H22 = ROL::makePtr<Tpetra::CrsMatrix<>>(matH11Graph_);
1888 }
1889 // Assemble
1890 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1891 qoi->Hessian_22(localVal,u_coeff,z_coeff,z_param);
1892 assembleFieldMatrix( H22, localVal, dofMgr2_, dofMgr2_ );
1893 }
1894 catch ( Exception::Zero & ez ) {
1895 throw Exception::Zero(">>> (Assembler::assembleQoIHessian22): Hessian is zero.");
1896 }
1897 catch ( Exception::NotImplemented & eni ) {
1898 throw Exception::NotImplemented(">>> (Assembler::assembleQoIHessian22): Hessian not implemented.");
1899 }
1900 }
1901 /***************************************************************************/
1902 /* End QoI assembly routines */
1903 /***************************************************************************/
1904
1905 /***************************************************************************/
1906 /* Assemble and apply Riesz operator corresponding to simulation variables */
1907 /***************************************************************************/
1908 template<class Real>
assemblePDERieszMap1(ROL::Ptr<Tpetra::CrsMatrix<>> & R1,const ROL::Ptr<PDE<Real>> & pde)1909 void Assembler<Real>::assemblePDERieszMap1(ROL::Ptr<Tpetra::CrsMatrix<>> &R1,
1910 const ROL::Ptr<PDE<Real>> &pde) {
1911 try {
1912 // Initialize Riesz matrix if not done so already
1913 if ( R1 == ROL::nullPtr ) {
1914 R1 = ROL::makePtr<Tpetra::CrsMatrix<>>(matR1Graph_);
1915 }
1916 // Assemble
1917 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1918 pde->RieszMap_1(localVal);
1919 assembleFieldMatrix( R1, localVal, dofMgr1_, dofMgr1_ );
1920 }
1921 catch ( Exception::NotImplemented & eni ) {
1922 //throw Exception::NotImplemented(">>> (Assembler::assemblePDERieszMap1): Riesz map not implemented!");
1923 }
1924 catch ( Exception::Zero & ez ) {
1925 //throw Exception::Zero(">>> (Assembler::assemblePDERieszMap1): Riesz map is zero!");
1926 }
1927 }
1928 template<class Real>
assembleDynPDERieszMap1(ROL::Ptr<Tpetra::CrsMatrix<>> & R1,const ROL::Ptr<DynamicPDE<Real>> & pde)1929 void Assembler<Real>::assembleDynPDERieszMap1(ROL::Ptr<Tpetra::CrsMatrix<>> &R1,
1930 const ROL::Ptr<DynamicPDE<Real>> &pde) {
1931 try {
1932 // Initialize Riesz matrix if not done so already
1933 if ( R1 == ROL::nullPtr ) {
1934 R1 = ROL::makePtr<Tpetra::CrsMatrix<>>(matR1Graph_);
1935 }
1936 // Assemble
1937 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1938 pde->RieszMap_1(localVal);
1939 assembleFieldMatrix( R1, localVal, dofMgr1_, dofMgr1_ );
1940 }
1941 catch ( Exception::NotImplemented & eni ) {
1942 //throw Exception::NotImplemented(">>> (Assembler::assemblePDERieszMap1): Riesz map not implemented!");
1943 }
1944 catch ( Exception::Zero & ez ) {
1945 //throw Exception::Zero(">>> (Assembler::assemblePDERieszMap1): Riesz map is zero!");
1946 }
1947 }
1948 /***************************************************************************/
1949 /* End of functions for Riesz operator of simulation variables. */
1950 /***************************************************************************/
1951
1952 /***************************************************************************/
1953 /* Assemble and apply Riesz operator corresponding to optimization */
1954 /* variables */
1955 /***************************************************************************/
1956 template<class Real>
assemblePDERieszMap2(ROL::Ptr<Tpetra::CrsMatrix<>> & R2,const ROL::Ptr<PDE<Real>> & pde)1957 void Assembler<Real>::assemblePDERieszMap2(ROL::Ptr<Tpetra::CrsMatrix<>> &R2,
1958 const ROL::Ptr<PDE<Real>> &pde) {
1959 try {
1960 // Initialize Riesz matrix if not done so already
1961 if ( R2 == ROL::nullPtr ) {
1962 R2 = ROL::makePtr<Tpetra::CrsMatrix<>>(matR2Graph_);
1963 }
1964 // Assemble
1965 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1966 pde->RieszMap_2(localVal);
1967 assembleFieldMatrix( R2, localVal, dofMgr2_, dofMgr2_ );
1968 }
1969 catch ( Exception::NotImplemented & eni ) {
1970 //throw Exception::NotImplemented(">>> (Assembler::assemblePDERieszMap2): Riesz map not implemented!");
1971 }
1972 catch ( Exception::Zero & ez ) {
1973 //throw Exception::Zero(">>> (Assembler::assemblePDERieszMap2): Riesz map is zero!");
1974 }
1975 }
1976 template<class Real>
assembleDynPDERieszMap2(ROL::Ptr<Tpetra::CrsMatrix<>> & R2,const ROL::Ptr<DynamicPDE<Real>> & pde)1977 void Assembler<Real>::assembleDynPDERieszMap2(ROL::Ptr<Tpetra::CrsMatrix<>> &R2,
1978 const ROL::Ptr<DynamicPDE<Real>> &pde) {
1979 try {
1980 // Initialize Riesz matrix if not done so already
1981 if ( R2 == ROL::nullPtr ) {
1982 R2 = ROL::makePtr<Tpetra::CrsMatrix<>>(matR2Graph_);
1983 }
1984 // Assemble
1985 ROL::Ptr<Intrepid::FieldContainer<Real>> localVal;
1986 pde->RieszMap_2(localVal);
1987 assembleFieldMatrix( R2, localVal, dofMgr2_, dofMgr2_ );
1988 }
1989 catch ( Exception::NotImplemented & eni ) {
1990 //throw Exception::NotImplemented(">>> (Assembler::assemblePDERieszMap2): Riesz map not implemented!");
1991 }
1992 catch ( Exception::Zero & ez ) {
1993 //throw Exception::Zero(">>> (Assembler::assemblePDERieszMap2): Riesz map is zero!");
1994 }
1995 }
1996 /***************************************************************************/
1997 /* End of functions for Riesz operator of optimization variables. */
1998 /***************************************************************************/
1999
2000 /***************************************************************************/
2001 /* Compute error routines. */
2002 /***************************************************************************/
2003 template<class Real>
computeStateError(const ROL::Ptr<const Tpetra::MultiVector<>> & soln,const ROL::Ptr<Solution<Real>> & trueSoln,const int cubDeg,const ROL::Ptr<FieldHelper<Real>> & fieldHelper) const2004 Real Assembler<Real>::computeStateError(const ROL::Ptr<const Tpetra::MultiVector<>> &soln,
2005 const ROL::Ptr<Solution<Real>> &trueSoln,
2006 const int cubDeg,
2007 const ROL::Ptr<FieldHelper<Real>> &fieldHelper) const {
2008 Real totalError(0);
2009 // populate inCoeffs
2010 ROL::Ptr<Intrepid::FieldContainer<Real>> inCoeffs0;
2011 getCoeffFromStateVector(inCoeffs0, soln);
2012 // split fields
2013 int numFields = 1;
2014 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> inCoeffs;
2015 if (fieldHelper != ROL::nullPtr) {
2016 numFields = fieldHelper->numFields();
2017 fieldHelper->splitFieldCoeff(inCoeffs,inCoeffs0);
2018 }
2019 else {
2020 inCoeffs.push_back(inCoeffs0);
2021 }
2022 // compute error
2023 for (int fn = 0; fn < numFields; ++fn) {
2024 // create fe object for error computation
2025 Intrepid::DefaultCubatureFactory<Real> cubFactory;
2026 shards::CellTopology cellType = basisPtrs1_[fn]->getBaseCellTopology();
2027 ROL::Ptr<Intrepid::Cubature<Real>> cellCub = cubFactory.create(cellType, cubDeg);
2028 ROL::Ptr<FE<Real>> fe
2029 = ROL::makePtr<FE<Real>>(volCellNodes_,basisPtrs1_[fn],cellCub);
2030
2031 // get dimensions
2032 int c = fe->gradN()->dimension(0);
2033 int p = fe->gradN()->dimension(2);
2034 int d = fe->gradN()->dimension(3);
2035
2036 // evaluate input coefficients on fe basis
2037 ROL::Ptr<Intrepid::FieldContainer<Real>> funcVals
2038 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p);
2039 fe->evaluateValue(funcVals, inCoeffs[fn]);
2040
2041 // subtract off true solution
2042 std::vector<Real> x(d);
2043 for (int i=0; i<c; ++i) {
2044 for (int j=0; j<p; ++j) {
2045 for (int k=0; k<d; ++k) {
2046 x[k] = (*fe->cubPts())(i, j, k);
2047 }
2048 (*funcVals)(i, j) -= trueSoln->evaluate(x,fn);
2049 }
2050 }
2051
2052 // compute norm squared of local error
2053 ROL::Ptr<Intrepid::FieldContainer<Real>> normSquaredError
2054 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c);
2055 fe->computeIntegral(normSquaredError, funcVals, funcVals, false);
2056
2057 Real localErrorSum(0);
2058 Real globalErrorSum(0);
2059 for (int i=0; i<numCells_; ++i) {
2060 localErrorSum += (*normSquaredError)(i);
2061 }
2062 Teuchos::reduceAll<int, Real>(*comm_, Teuchos::REDUCE_SUM, 1, &localErrorSum, &globalErrorSum);
2063 totalError += globalErrorSum;
2064 }
2065
2066 return std::sqrt(totalError);
2067 }
2068
2069 template<class Real>
computeControlError(const ROL::Ptr<const Tpetra::MultiVector<>> & soln,const ROL::Ptr<Solution<Real>> & trueSoln,const int cubDeg,const ROL::Ptr<FieldHelper<Real>> & fieldHelper) const2070 Real Assembler<Real>::computeControlError(const ROL::Ptr<const Tpetra::MultiVector<>> &soln,
2071 const ROL::Ptr<Solution<Real>> &trueSoln,
2072 const int cubDeg,
2073 const ROL::Ptr<FieldHelper<Real>> &fieldHelper) const {
2074 Real totalError(0);
2075 // populate inCoeffs
2076 ROL::Ptr<Intrepid::FieldContainer<Real>> inCoeffs0;
2077 getCoeffFromControlVector(inCoeffs0, soln);
2078 // split fields
2079 int numFields = 1;
2080 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> inCoeffs;
2081 if (fieldHelper != ROL::nullPtr) {
2082 numFields = fieldHelper->numFields();
2083 fieldHelper->splitFieldCoeff(inCoeffs,inCoeffs0);
2084 }
2085 else {
2086 inCoeffs.push_back(inCoeffs0);
2087 }
2088 // compute error
2089 for (int fn = 0; fn < numFields; ++fn) {
2090 // create fe object for error computation
2091 Intrepid::DefaultCubatureFactory<Real> cubFactory;
2092 shards::CellTopology cellType = basisPtrs2_[fn]->getBaseCellTopology();
2093 ROL::Ptr<Intrepid::Cubature<Real>> cellCub = cubFactory.create(cellType, cubDeg);
2094 ROL::Ptr<FE<Real>> fe
2095 = ROL::makePtr<FE<Real>>(volCellNodes_,basisPtrs2_[fn],cellCub);
2096
2097 // get dimensions
2098 int c = fe->gradN()->dimension(0);
2099 int p = fe->gradN()->dimension(2);
2100 int d = fe->gradN()->dimension(3);
2101
2102 // evaluate input coefficients on fe basis
2103 ROL::Ptr<Intrepid::FieldContainer<Real>> funcVals
2104 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c, p);
2105 fe->evaluateValue(funcVals, inCoeffs[fn]);
2106
2107 // subtract off true solution
2108 std::vector<Real> x(d);
2109 for (int i=0; i<c; ++i) {
2110 for (int j=0; j<p; ++j) {
2111 for (int k=0; k<d; ++k) {
2112 x[k] = (*fe->cubPts())(i, j, k);
2113 }
2114 (*funcVals)(i, j) -= trueSoln->evaluate(x,fn);
2115 }
2116 }
2117
2118 // compute norm squared of local error
2119 ROL::Ptr<Intrepid::FieldContainer<Real>> normSquaredError
2120 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c);
2121 fe->computeIntegral(normSquaredError, funcVals, funcVals, false);
2122
2123 Real localErrorSum(0);
2124 Real globalErrorSum(0);
2125 for (int i=0; i<numCells_; ++i) {
2126 localErrorSum += (*normSquaredError)(i);
2127 }
2128 Teuchos::reduceAll<int, Real>(*comm_, Teuchos::REDUCE_SUM, 1, &localErrorSum, &globalErrorSum);
2129 totalError += globalErrorSum;
2130 }
2131
2132 return std::sqrt(totalError);
2133 }
2134 /***************************************************************************/
2135 /* End of compute solution routines. */
2136 /***************************************************************************/
2137
2138 /***************************************************************************/
2139 /* Output routines. */
2140 /***************************************************************************/
2141 template<class Real>
printMeshData(std::ostream & outStream) const2142 void Assembler<Real>::printMeshData(std::ostream &outStream) const {
2143 ROL::Ptr<Intrepid::FieldContainer<Real>> nodesPtr = meshMgr_->getNodes();
2144 ROL::Ptr<Intrepid::FieldContainer<int>> cellToNodeMapPtr = meshMgr_->getCellToNodeMap();
2145 Intrepid::FieldContainer<Real> &nodes = *nodesPtr;
2146 Intrepid::FieldContainer<int> &cellToNodeMap = *cellToNodeMapPtr;
2147 if ( verbose_ && myRank_ == 0) {
2148 outStream << std::endl;
2149 outStream << "Number of nodes = " << meshMgr_->getNumNodes() << std::endl;
2150 outStream << "Number of cells = " << meshMgr_->getNumCells() << std::endl;
2151 outStream << "Number of edges = " << meshMgr_->getNumEdges() << std::endl;
2152 }
2153 // Print mesh to file.
2154 if ((myRank_ == 0)) {
2155 std::ofstream meshfile;
2156 meshfile.open("cell_to_node_quad.txt");
2157 for (int i=0; i<cellToNodeMap.dimension(0); ++i) {
2158 for (int j=0; j<cellToNodeMap.dimension(1); ++j) {
2159 meshfile << cellToNodeMap(i,j) << " ";
2160 }
2161 meshfile << std::endl;
2162 }
2163 meshfile.close();
2164
2165 // meshfile.open("cell_to_node_tri.txt");
2166 // for (int i=0; i<cellToNodeMap.dimension(0); ++i) {
2167 // for (int j=0; j<3; ++j) {
2168 // meshfile << cellToNodeMap(i,j) << " ";
2169 // }
2170 // meshfile << std::endl;
2171 // for (int j=2; j<5; ++j) {
2172 // meshfile << cellToNodeMap(i,j%4) << " ";
2173 // }
2174 // meshfile << std::endl;
2175 // }
2176 // meshfile.close();
2177
2178 meshfile.open("nodes.txt");
2179 meshfile.precision(16);
2180 for (int i=0; i<nodes.dimension(0); ++i) {
2181 for (int j=0; j<nodes.dimension(1); ++j) {
2182 meshfile << std::scientific << nodes(i,j) << " ";
2183 }
2184 meshfile << std::endl;
2185 }
2186 meshfile.close();
2187 }
2188 } // prinf function end
2189
2190 template<class Real>
outputTpetraVector(const ROL::Ptr<const Tpetra::MultiVector<>> & vec,const std::string & filename) const2191 void Assembler<Real>::outputTpetraVector(const ROL::Ptr<const Tpetra::MultiVector<>> &vec,
2192 const std::string &filename) const {
2193 Tpetra::MatrixMarket::Writer< Tpetra::CrsMatrix<>> vecWriter;
2194 vecWriter.writeDenseFile(filename, vec);
2195 std::string mapfile = "map_" + filename;
2196 vecWriter.writeMapFile(mapfile, *(vec->getMap()));
2197 }
2198
2199 template<class Real>
inputTpetraVector(ROL::Ptr<Tpetra::MultiVector<>> & vec,const std::string & filename) const2200 void Assembler<Real>::inputTpetraVector(ROL::Ptr<Tpetra::MultiVector<>> &vec,
2201 const std::string &filename) const {
2202 Tpetra::MatrixMarket::Reader< Tpetra::CrsMatrix<>> vecReader;
2203 auto map = vec->getMap();
2204 auto comm = map->getComm();
2205 auto vec_rcp = vecReader.readDenseFile(filename, comm, map);
2206 vec->scale(1.0, *vec_rcp);
2207 }
2208
2209 template<class Real>
serialPrintStateEdgeField(const ROL::Ptr<const Tpetra::MultiVector<>> & u,const ROL::Ptr<FieldHelper<Real>> & fieldHelper,const std::string & filename,const ROL::Ptr<FE_CURL<Real>> & fe) const2210 void Assembler<Real>::serialPrintStateEdgeField(const ROL::Ptr<const Tpetra::MultiVector<>> &u,
2211 const ROL::Ptr<FieldHelper<Real>> &fieldHelper,
2212 const std::string &filename,
2213 const ROL::Ptr<FE_CURL<Real>> &fe) const {
2214 const int c = fe->curlN()->dimension(0);
2215 const int f = fe->curlN()->dimension(1);
2216 const int p = 1, d = 3;
2217
2218 ROL::Ptr<Intrepid::FieldContainer<Real>> u_coeff;
2219 getCoeffFromStateVector(u_coeff,u);
2220
2221 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> U;
2222 fieldHelper->splitFieldCoeff(U, u_coeff);
2223 int numFields = U.size();
2224
2225 // Transform cell center to physical
2226 ROL::Ptr<Intrepid::FieldContainer<Real>> rx
2227 = ROL::makePtr<Intrepid::FieldContainer<Real>>(p,d);
2228 ROL::Ptr<Intrepid::FieldContainer<Real>> px
2229 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c,p,d);
2230 fe->mapRefPointsToPhysical(px,rx);
2231 // Transform reference values into physical space.
2232 ROL::Ptr<Intrepid::FieldContainer<Real>> cellJac
2233 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c,p,d,d);
2234 ROL::Ptr<Intrepid::FieldContainer<Real>> cellJacInv
2235 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c,p,d,d);
2236 ROL::Ptr<shards::CellTopology> cellTopo
2237 = ROL::makePtr<shards::CellTopology>(basisPtrs1_[0]->getBaseCellTopology());
2238 ROL::Ptr<Intrepid::FieldContainer<Real>> valReference
2239 = ROL::makePtr<Intrepid::FieldContainer<Real>>(f,p,d);
2240 basisPtrs1_[0]->getValues(*valReference,*rx,Intrepid::OPERATOR_VALUE);
2241 ROL::Ptr<Intrepid::FieldContainer<Real>> valPhysical
2242 = ROL::makePtr<Intrepid::FieldContainer<Real>>(c,f,p,d);
2243 Intrepid::CellTools<Real>::setJacobian(*cellJac,*rx,*volCellNodes_,*cellTopo);
2244 Intrepid::CellTools<Real>::setJacobianInv(*cellJacInv, *cellJac);
2245 Intrepid::FunctionSpaceTools::HCURLtransformVALUE<Real>(*valPhysical,
2246 *cellJacInv,
2247 *valReference);
2248
2249 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> uval(numFields);
2250 for (int k = 0; k < numFields; ++k) {
2251 uval[k] = ROL::makePtr<Intrepid::FieldContainer<Real>>(c,p,d);
2252 Intrepid::FunctionSpaceTools::evaluate<Real>(*uval[k], *U[k], *valPhysical);
2253 }
2254 // Print
2255 std::ofstream file;
2256 file.open(filename);
2257 for (int i = 0; i < c; ++i) {
2258 file << std::scientific << std::setprecision(15);
2259 for (int j = 0; j < d; ++j) {
2260 file << std::setw(25) << (*px)(i,0,j);
2261 }
2262 for (int k = 0; k < numFields; ++k) {
2263 for (int j = 0; j < d; ++j) {
2264 file << std::setw(25) << (*uval[k])(i,0,j);
2265 }
2266 }
2267 file << std::endl;
2268 }
2269 file.close();
2270 }
2271 /***************************************************************************/
2272 /* End of output routines. */
2273 /***************************************************************************/
2274
2275 /***************************************************************************/
2276 /* Vector generation routines. */
2277 /***************************************************************************/
2278 template<class Real>
getStateMap(void) const2279 const ROL::Ptr<const Tpetra::Map<>> Assembler<Real>::getStateMap(void) const {
2280 return myUniqueStateMap_;
2281 }
2282
2283 template<class Real>
getControlMap(void) const2284 const ROL::Ptr<const Tpetra::Map<>> Assembler<Real>::getControlMap(void) const {
2285 return myUniqueControlMap_;
2286 }
2287
2288 template<class Real>
getResidualMap(void) const2289 const ROL::Ptr<const Tpetra::Map<>> Assembler<Real>::getResidualMap(void) const {
2290 return myUniqueResidualMap_;
2291 }
2292
2293 template<class Real>
createStateVector(void) const2294 ROL::Ptr<Tpetra::MultiVector<>> Assembler<Real>::createStateVector(void) const {
2295 return ROL::makePtr<Tpetra::MultiVector<>>(myUniqueStateMap_, 1, true);
2296 }
2297
2298 template<class Real>
createControlVector(void) const2299 ROL::Ptr<Tpetra::MultiVector<>> Assembler<Real>::createControlVector(void) const {
2300 return ROL::makePtr<Tpetra::MultiVector<>>(myUniqueControlMap_, 1, true);
2301 }
2302
2303 template<class Real>
createResidualVector(void) const2304 ROL::Ptr<Tpetra::MultiVector<>> Assembler<Real>::createResidualVector(void) const {
2305 return ROL::makePtr<Tpetra::MultiVector<>>(myUniqueResidualMap_, 1, true);
2306 }
2307 /***************************************************************************/
2308 /* End of vector generation routines. */
2309 /***************************************************************************/
2310
2311 /***************************************************************************/
2312 /* Accessor routines. */
2313 /***************************************************************************/
2314 template<class Real>
getDofManager(void) const2315 const ROL::Ptr<DofManager<Real>> Assembler<Real>::getDofManager(void) const {
2316 return dofMgr1_;
2317 }
2318 template<class Real>
getDofManager2(void) const2319 const ROL::Ptr<DofManager<Real>> Assembler<Real>::getDofManager2(void) const {
2320 return dofMgr2_;
2321 }
2322
2323 template<class Real>
getCellIds(void) const2324 Teuchos::Array<typename Tpetra::Map<>::global_ordinal_type> Assembler<Real>::getCellIds(void) const {
2325 return myCellIds_;
2326 }
2327 /***************************************************************************/
2328 /* End of accessor routines. */
2329 /***************************************************************************/
2330
2331 /*****************************************************************************/
2332 /******************* PRIVATE MEMBER FUNCTIONS ********************************/
2333 /*****************************************************************************/
2334 template<class Real>
setCommunicator(const ROL::Ptr<const Teuchos::Comm<int>> & comm,Teuchos::ParameterList & parlist,std::ostream & outStream)2335 void Assembler<Real>::setCommunicator(const ROL::Ptr<const Teuchos::Comm<int>> &comm,
2336 Teuchos::ParameterList &parlist,
2337 std::ostream &outStream) {
2338 comm_ = comm;
2339 // Get number of processors and my rank
2340 myRank_ = comm->getRank();
2341 numProcs_ = comm->getSize();
2342 // Parse parameter list
2343 verbose_ = parlist.sublist("PDE FEM").get("Verbose Output",false);
2344 if (verbose_ && myRank_==0 ) {
2345 outStream << "Initialized communicator. " << std::endl;
2346 }
2347 if (verbose_ && myRank_==0 ) {
2348 outStream << "Total number of processors: " << numProcs_ << std::endl;
2349 }
2350 }
2351
2352 template<class Real>
setBasis(const std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & basisPtrs1,const std::vector<ROL::Ptr<Intrepid::Basis<Real,Intrepid::FieldContainer<Real>>>> & basisPtrs2,Teuchos::ParameterList & parlist,std::ostream & outStream)2353 void Assembler<Real>::setBasis(
2354 const std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> &basisPtrs1,
2355 const std::vector<ROL::Ptr<Intrepid::Basis<Real, Intrepid::FieldContainer<Real>>>> &basisPtrs2,
2356 Teuchos::ParameterList &parlist,
2357 std::ostream &outStream) {
2358 basisPtrs1_ = basisPtrs1;
2359 basisPtrs2_ = basisPtrs2;
2360 if (verbose_ && myRank_==0) {
2361 outStream << "Initialized PDE." << std::endl;
2362 }
2363 }
2364
2365 template<class Real>
setDiscretization(Teuchos::ParameterList & parlist,const ROL::Ptr<MeshManager<Real>> & meshMgr,std::ostream & outStream)2366 void Assembler<Real>::setDiscretization(Teuchos::ParameterList &parlist,
2367 const ROL::Ptr<MeshManager<Real>> &meshMgr,
2368 std::ostream &outStream) {
2369 if ( meshMgr != ROL::nullPtr ) {
2370 // Use MeshManager object if supplied
2371 meshMgr_ = meshMgr;
2372 }
2373 else {
2374 // Otherwise construct MeshManager objective from parameter list
2375 }
2376 dofMgr1_ = ROL::makePtr<DofManager<Real>>(meshMgr_,basisPtrs1_);
2377 dofMgr2_ = ROL::makePtr<DofManager<Real>>(meshMgr_,basisPtrs2_);
2378 if (verbose_ && myRank_==0) {
2379 outStream << "Initialized discretization (MeshManager and DofManager)." << std::endl;
2380 }
2381 }
2382
2383 template<class Real>
setParallelStructure(Teuchos::ParameterList & parlist,std::ostream & outStream)2384 void Assembler<Real>::setParallelStructure(Teuchos::ParameterList &parlist,
2385 std::ostream &outStream) {
2386 int cellSplit = parlist.sublist("Geometry").get<int>("Partition type");
2387 /****************************************************/
2388 /*** Build parallel communication infrastructure. ***/
2389 /****************************************************/
2390 // Partition the cells in the mesh. We use a basic quasi-equinumerous partitioning,
2391 // where the remainder, if any, is assigned to the last processor.
2392 Teuchos::Array<GO> myGlobalIds1, myGlobalIds2;
2393 cellOffsets_.assign(numProcs_, 0);
2394 int totalNumCells = meshMgr_->getNumCells();
2395 int cellsPerProc = totalNumCells / numProcs_;
2396 numCells_ = cellsPerProc;
2397 ROL::Ptr<std::vector<std::vector<int>>> procCellIds = meshMgr_->getProcCellIds();
2398 switch(cellSplit) {
2399 case 0:
2400 if (myRank_ == 0) {
2401 // remainder in the first
2402 numCells_ += totalNumCells % numProcs_;
2403 }
2404 for (int i=1; i<numProcs_; ++i) {
2405 cellOffsets_[i] = cellOffsets_[i-1] + cellsPerProc
2406 + (static_cast<int>(i==1))*(totalNumCells % numProcs_);
2407 }
2408 break;
2409 case 1:
2410 if (myRank_ == numProcs_-1) {
2411 // remainder in the last
2412 numCells_ += totalNumCells % numProcs_;
2413 }
2414 for (int i=1; i<numProcs_; ++i) {
2415 cellOffsets_[i] = cellOffsets_[i-1] + cellsPerProc;
2416 }
2417 break;
2418 case 2:
2419 if (myRank_ < (totalNumCells%numProcs_)) {
2420 // spread remainder, starting from the first
2421 numCells_++;
2422 }
2423 for (int i=1; i<numProcs_; ++i) {
2424 cellOffsets_[i] = cellOffsets_[i-1] + cellsPerProc
2425 + (static_cast<int>(i-1<(totalNumCells%numProcs_)));
2426 }
2427 break;
2428 case 3:
2429 // Define using MeshManager.
2430 numCells_ = (*procCellIds)[myRank_].size();
2431 break;
2432 }
2433
2434 Intrepid::FieldContainer<int> &cellDofs1 = *(dofMgr1_->getCellDofs());
2435 Intrepid::FieldContainer<int> &cellDofs2 = *(dofMgr2_->getCellDofs());
2436 int numLocalDofs1 = cellDofs1.dimension(1);
2437 int numLocalDofs2 = cellDofs2.dimension(1);
2438 if (verbose_) {
2439 outStream << "Cell offsets across processors: " << cellOffsets_
2440 << std::endl;
2441 }
2442 switch(cellSplit) {
2443 case 0:
2444 case 1:
2445 case 2:
2446 for (int i=0; i<numCells_; ++i) {
2447 myCellIds_.push_back(cellOffsets_[myRank_]+i);
2448 for (int j=0; j<numLocalDofs1; ++j) {
2449 myGlobalIds1.push_back( cellDofs1(cellOffsets_[myRank_]+i,j) );
2450 }
2451 for (int j=0; j<numLocalDofs2; ++j) {
2452 myGlobalIds2.push_back( cellDofs2(cellOffsets_[myRank_]+i,j) );
2453 }
2454 }
2455 break;
2456 case 3:
2457 for (int i=0; i<numCells_; ++i) {
2458 myCellIds_.push_back((*procCellIds)[myRank_][i]);
2459 for (int j=0; j<numLocalDofs1; ++j) {
2460 myGlobalIds1.push_back( cellDofs1((*procCellIds)[myRank_][i],j) );
2461 }
2462 for (int j=0; j<numLocalDofs2; ++j) {
2463 myGlobalIds2.push_back( cellDofs2((*procCellIds)[myRank_][i],j) );
2464 }
2465 }
2466 break;
2467 }
2468 std::sort(myGlobalIds1.begin(), myGlobalIds1.end());
2469 myGlobalIds1.erase( std::unique(myGlobalIds1.begin(),myGlobalIds1.end()),myGlobalIds1.end() );
2470 std::sort(myGlobalIds2.begin(), myGlobalIds2.end());
2471 myGlobalIds2.erase( std::unique(myGlobalIds2.begin(),myGlobalIds2.end()),myGlobalIds2.end() );
2472
2473 // Build maps.
2474 myOverlapStateMap_ = ROL::makePtr<Tpetra::Map<>>
2475 (Teuchos::OrdinalTraits<GO>::invalid(), myGlobalIds1, GO(0), comm_);
2476 //std::cout << std::endl << myOverlapMap_->getNodeElementList()<<std::endl;
2477 /** One can also use the non-member function:
2478 myOverlapMap_ = Tpetra::createNonContigMap<int,int>(myGlobalIds_, comm_);
2479 to build the overlap map.
2480 **/
2481 myUniqueStateMap_ = Tpetra::createOneToOne(myOverlapStateMap_);
2482 myOverlapResidualMap_ = myOverlapStateMap_;
2483 myUniqueResidualMap_ = myUniqueStateMap_;
2484 myOverlapControlMap_ = ROL::makePtr<Tpetra::Map<>>
2485 (Teuchos::OrdinalTraits<GO>::invalid(), myGlobalIds2, GO(0), comm_);
2486 myUniqueControlMap_ = Tpetra::createOneToOne(myOverlapControlMap_);;
2487 //std::cout << std::endl << myUniqueMap_->getNodeElementList() << std::endl;
2488 // myCellMap_ = ROL::makePtr<Tpetra::Map<>>(
2489 // Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid(),
2490 // myCellIds_, 0, comm_);
2491
2492 /****************************************/
2493 /*** Assemble global graph structure. ***/
2494 /****************************************/
2495
2496 // Make a GO copy to interface with Tpetra; currently dof manager uses int directly
2497 Teuchos::ArrayRCP<const int> cellDofs1ArrayRCP = cellDofs1.getData();
2498 Teuchos::ArrayRCP<const int> cellDofs2ArrayRCP = cellDofs2.getData();
2499 Teuchos::ArrayRCP<GO> cellDofs1GO(cellDofs1ArrayRCP.size(), GO());
2500 Teuchos::ArrayRCP<GO> cellDofs2GO(cellDofs2ArrayRCP.size(), GO());
2501 std::copy(cellDofs1ArrayRCP.getRawPtr(), cellDofs1ArrayRCP.getRawPtr()+cellDofs1ArrayRCP.size(),
2502 cellDofs1GO.getRawPtr());
2503 std::copy(cellDofs2ArrayRCP.getRawPtr(), cellDofs2ArrayRCP.getRawPtr()+cellDofs2ArrayRCP.size(),
2504 cellDofs2GO.getRawPtr());
2505 Teuchos::ArrayRCP<const GO> cellDofs1GOArrayRCP = cellDofs1GO.getConst();
2506 Teuchos::ArrayRCP<const GO> cellDofs2GOArrayRCP = cellDofs2GO.getConst();
2507
2508 // Estimate the max number of entries per row
2509 // using a map (row indicies can be non-contiguous)
2510 GO maxEntriesPerRow1(0), maxEntriesPerRow2(0);
2511 {
2512 std::map<GO,GO> numEntriesCount1, numEntriesCount2;
2513 for (int i=0; i<numCells_; ++i) {
2514 for (int j=0; j<numLocalDofs1; ++j) {
2515 numEntriesCount1[GO(cellDofs1(myCellIds_[i],j))] += numLocalDofs1;
2516 }
2517 for (int j=0; j<numLocalDofs2; ++j) {
2518 numEntriesCount2[GO(cellDofs2(myCellIds_[i],j))] += numLocalDofs2;
2519 }
2520 }
2521 const auto rowIndexWithMaxEntries1
2522 = std::max_element(std::begin(numEntriesCount1), std::end(numEntriesCount1),
2523 [](const std::pair<GO,GO> &pa, const std::pair<GO,GO> &pb) {
2524 return pa.second < pb.second;
2525 });
2526 const auto rowIndexWithMaxEntries2
2527 = std::max_element(std::begin(numEntriesCount2), std::end(numEntriesCount2),
2528 [](const std::pair<GO,GO> &pa, const std::pair<GO,GO> &pb) {
2529 return pa.second < pb.second;
2530 });
2531 if (!numEntriesCount1.empty())
2532 maxEntriesPerRow1 = rowIndexWithMaxEntries1->second;
2533 if (!numEntriesCount2.empty())
2534 maxEntriesPerRow2 = rowIndexWithMaxEntries2->second;
2535 }
2536
2537 matJ1Graph_ = ROL::makePtr<Tpetra::CrsGraph<>>(myUniqueStateMap_, maxEntriesPerRow1);
2538 for (int i=0; i<numCells_; ++i) {
2539 for (int j=0; j<numLocalDofs1; ++j) {
2540 matJ1Graph_->insertGlobalIndices(GO(cellDofs1(myCellIds_[i],j)),
2541 cellDofs1GOArrayRCP(myCellIds_[i]*numLocalDofs1, numLocalDofs1));
2542 }
2543 }
2544 matJ1Graph_->fillComplete(myUniqueStateMap_,myUniqueStateMap_);
2545 matR1Graph_ = matJ1Graph_;
2546 matH11Graph_ = matJ1Graph_;
2547
2548 matJ2Graph_ = ROL::makePtr<Tpetra::CrsGraph<>>(myUniqueStateMap_, std::max(maxEntriesPerRow1,maxEntriesPerRow2));
2549 for (int i=0; i<numCells_; ++i) {
2550 for (int j=0; j<numLocalDofs1; ++j) {
2551 matJ2Graph_->insertGlobalIndices(GO(cellDofs1(myCellIds_[i],j)),
2552 cellDofs2GOArrayRCP(myCellIds_[i]*numLocalDofs2, numLocalDofs2));
2553 }
2554 }
2555 matJ2Graph_->fillComplete(myUniqueControlMap_,myUniqueStateMap_);
2556 matH21Graph_ = matJ2Graph_;
2557
2558 matH12Graph_ = ROL::makePtr<Tpetra::CrsGraph<>>(myUniqueControlMap_, maxEntriesPerRow1);
2559 for (int i=0; i<numCells_; ++i) {
2560 for (int j=0; j<numLocalDofs2; ++j) {
2561 matH12Graph_->insertGlobalIndices(GO(cellDofs2(myCellIds_[i],j)),
2562 cellDofs1GOArrayRCP(myCellIds_[i]*numLocalDofs1, numLocalDofs1));
2563 }
2564 }
2565 matH12Graph_->fillComplete(myUniqueStateMap_,myUniqueControlMap_);
2566
2567 matR2Graph_ = ROL::makePtr<Tpetra::CrsGraph<>>(myUniqueControlMap_, maxEntriesPerRow2);
2568 for (int i=0; i<numCells_; ++i) {
2569 for (int j=0; j<numLocalDofs2; ++j) {
2570 matR2Graph_->insertGlobalIndices(GO(cellDofs2(myCellIds_[i],j)),
2571 cellDofs2GOArrayRCP(myCellIds_[i]*numLocalDofs2, numLocalDofs2));
2572 }
2573 }
2574 matR2Graph_->fillComplete(myUniqueControlMap_,myUniqueControlMap_);
2575 matH22Graph_ = matR2Graph_;
2576
2577 if (verbose_ && myRank_==0) {
2578 outStream << "Initialized parallel structures." << std::endl;
2579 }
2580 }
2581
2582 template<class Real>
setCellNodes(std::ostream & outStream)2583 void Assembler<Real>::setCellNodes(std::ostream &outStream) {
2584 // Build volume cell nodes
2585 shards::CellTopology cellType = basisPtrs1_[0]->getBaseCellTopology();
2586 int spaceDim = cellType.getDimension();
2587 int numNodesPerCell = cellType.getNodeCount();
2588 volCellNodes_ = ROL::makePtr<Intrepid::FieldContainer<Real>>(numCells_, numNodesPerCell, spaceDim);
2589 Intrepid::FieldContainer<Real> &nodes = *meshMgr_->getNodes();
2590 Intrepid::FieldContainer<int> &ctn = *meshMgr_->getCellToNodeMap();
2591 for (int i=0; i<numCells_; ++i) {
2592 for (int j=0; j<numNodesPerCell; ++j) {
2593 for (int k=0; k<spaceDim; ++k) {
2594 (*volCellNodes_)(i, j, k) = nodes(ctn(myCellIds_[i],j), k);
2595 }
2596 }
2597 }
2598 // Build boundary cell nodes
2599 bdryCellIds_ = meshMgr_->getSideSets((verbose_ && myRank_==0), outStream);
2600 int numSideSets = bdryCellIds_->size();
2601 if (numSideSets > 0) {
2602 bdryCellNodes_.resize(numSideSets);
2603 bdryCellLocIds_.resize(numSideSets);
2604 for (int i=0; i<numSideSets; ++i) {
2605 int numLocSides = (*bdryCellIds_)[i].size();
2606 bdryCellNodes_[i].resize(numLocSides);
2607 bdryCellLocIds_[i].resize(numLocSides);
2608 for (int j=0; j<numLocSides; ++j) {
2609 if ((*bdryCellIds_)[i][j].size() > 0) {
2610 int numCellsSide = (*bdryCellIds_)[i][j].size();
2611 for (int k=0; k<numCellsSide; ++k) {
2612 int idx = mapGlobalToLocalCellId((*bdryCellIds_)[i][j][k]);
2613 if (idx > -1) {
2614 bdryCellLocIds_[i][j].push_back(idx);
2615 //if (myRank_==1) {std::cout << "\nrank " << myRank_ << " bcid " << i << " " << j << " " << k << " " << myCellIds_[idx] << " " << idx;}
2616 }
2617 }
2618 int myNumCellsSide = bdryCellLocIds_[i][j].size();
2619 if (myNumCellsSide > 0) {
2620 bdryCellNodes_[i][j] = ROL::makePtr<Intrepid::FieldContainer<Real>>(myNumCellsSide, numNodesPerCell, spaceDim);
2621 }
2622 for (int k=0; k<myNumCellsSide; ++k) {
2623 for (int l=0; l<numNodesPerCell; ++l) {
2624 for (int m=0; m<spaceDim; ++m) {
2625 (*bdryCellNodes_[i][j])(k, l, m) = nodes(ctn(myCellIds_[bdryCellLocIds_[i][j][k]],l), m);
2626 }
2627 }
2628 }
2629 }
2630 //if ((myRank_==1) && (myNumCellsSide > 0)) {std::cout << (*bdryCellNodes_[i][j]);}
2631 }
2632 }
2633 }
2634 bdryCellNodes_.resize(numSideSets);
2635 }
2636
2637 template<class Real>
mapGlobalToLocalCellId(const int & gid)2638 int Assembler<Real>::mapGlobalToLocalCellId(const int & gid) {
2639 auto it = std::find(myCellIds_.begin(),myCellIds_.end(),gid);
2640 if (it != myCellIds_.end()) {
2641 return it-myCellIds_.begin();
2642 }
2643 else {
2644 return -1;
2645 }
2646 /*
2647 int minId = cellOffsets_[myRank_];
2648 int maxId = cellOffsets_[myRank_]+numCells_-1;
2649 if ((gid >= minId) && (gid <= maxId)) {
2650 return (gid - cellOffsets_[myRank_]);
2651 }
2652 else {
2653 return -1;
2654 }
2655 */
2656 }
2657
2658 template<class Real>
getCoeffFromStateVector(ROL::Ptr<Intrepid::FieldContainer<Real>> & xcoeff,const ROL::Ptr<const Tpetra::MultiVector<>> & x) const2659 void Assembler<Real>::getCoeffFromStateVector(ROL::Ptr<Intrepid::FieldContainer<Real>> &xcoeff,
2660 const ROL::Ptr<const Tpetra::MultiVector<>> &x) const {
2661 if ( x != ROL::nullPtr ) {
2662 // Perform import onto myOverlapMap
2663 ROL::Ptr<Tpetra::MultiVector<>> xshared =
2664 ROL::makePtr<Tpetra::MultiVector<>>(myOverlapStateMap_, 1, true);
2665 Tpetra::Import<> importer(myUniqueStateMap_, myOverlapStateMap_);
2666 xshared->doImport(*x,importer,Tpetra::REPLACE);
2667 // Populate xcoeff
2668 Intrepid::FieldContainer<int> &cellDofs = *(dofMgr1_->getCellDofs());
2669 int lfs = dofMgr1_->getLocalFieldSize();
2670 xcoeff = ROL::makePtr<Intrepid::FieldContainer<Real>>(numCells_, lfs);
2671 Teuchos::ArrayRCP<const Real> xdata = xshared->get1dView();
2672 for (int i=0; i<numCells_; ++i) {
2673 for (int j=0; j<lfs; ++j) {
2674 (*xcoeff)(i,j) = xdata[xshared->getMap()->getLocalElement(cellDofs(myCellIds_[i],j))];
2675 }
2676 }
2677 dofMgr1_->transformToIntrepidPattern(xcoeff);
2678 }
2679 else {
2680 xcoeff = ROL::nullPtr;
2681 }
2682 }
2683
2684 template<class Real>
getCoeffFromControlVector(ROL::Ptr<Intrepid::FieldContainer<Real>> & xcoeff,const ROL::Ptr<const Tpetra::MultiVector<>> & x) const2685 void Assembler<Real>::getCoeffFromControlVector(ROL::Ptr<Intrepid::FieldContainer<Real>> &xcoeff,
2686 const ROL::Ptr<const Tpetra::MultiVector<>> &x) const {
2687 if ( x != ROL::nullPtr ) {
2688 // Perform import onto myOverlapMap
2689 ROL::Ptr<Tpetra::MultiVector<>> xshared =
2690 ROL::makePtr<Tpetra::MultiVector<>>(myOverlapControlMap_, 1, true);
2691 Tpetra::Import<> importer(myUniqueControlMap_, myOverlapControlMap_);
2692 xshared->doImport(*x,importer,Tpetra::REPLACE);
2693 // Populate xcoeff
2694 Intrepid::FieldContainer<int> &cellDofs = *(dofMgr2_->getCellDofs());
2695 int lfs = dofMgr2_->getLocalFieldSize();
2696 xcoeff = ROL::makePtr<Intrepid::FieldContainer<Real>>(numCells_, lfs);
2697 Teuchos::ArrayRCP<const Real> xdata = xshared->get1dView();
2698 for (int i=0; i<numCells_; ++i) {
2699 for (int j=0; j<lfs; ++j) {
2700 (*xcoeff)(i,j) = xdata[xshared->getMap()->getLocalElement(cellDofs(myCellIds_[i],j))];
2701 }
2702 }
2703 dofMgr2_->transformToIntrepidPattern(xcoeff);
2704 }
2705 else {
2706 xcoeff = ROL::nullPtr;
2707 }
2708 }
2709
2710 /***************************************************************************/
2711 /****** GENERIC ASSEMBLY ROUTINES ******************************************/
2712 /***************************************************************************/
2713 template<class Real>
assembleScalar(ROL::Ptr<Intrepid::FieldContainer<Real>> & val)2714 Real Assembler<Real>::assembleScalar(ROL::Ptr<Intrepid::FieldContainer<Real>> &val) {
2715 // Assembly
2716 if ( val != ROL::nullPtr ) {
2717 Real myval(0), gval(0);
2718 for (int i=0; i<numCells_; ++i) {
2719 myval += (*val)(i);
2720 }
2721 Teuchos::reduceAll<int,Real>(*comm_,Teuchos::REDUCE_SUM,1,&myval,&gval);
2722 return gval;
2723 }
2724 return static_cast<Real>(0);
2725 }
2726
2727 template<class Real>
assembleFieldVector(ROL::Ptr<Tpetra::MultiVector<>> & v,ROL::Ptr<Intrepid::FieldContainer<Real>> & val,ROL::Ptr<Tpetra::MultiVector<>> & vecOverlap,const ROL::Ptr<DofManager<Real>> & dofMgr)2728 void Assembler<Real>::assembleFieldVector(ROL::Ptr<Tpetra::MultiVector<>> &v,
2729 ROL::Ptr<Intrepid::FieldContainer<Real>> &val,
2730 ROL::Ptr<Tpetra::MultiVector<>> &vecOverlap,
2731 const ROL::Ptr<DofManager<Real>> &dofMgr) {
2732 // Set residual vectors to zero
2733 v->putScalar(static_cast<Real>(0));
2734 vecOverlap->putScalar(static_cast<Real>(0));
2735 // Get degrees of freedom
2736 Intrepid::FieldContainer<int> &cellDofs = *(dofMgr->getCellDofs());
2737 int numLocalDofs = cellDofs.dimension(1);
2738 // Transform values
2739 transformToFieldPattern(val,dofMgr);
2740 // assembly on the overlap map
2741 for (int i=0; i<numCells_; ++i) {
2742 for (int j=0; j<numLocalDofs; ++j) {
2743 vecOverlap->sumIntoGlobalValue(cellDofs(myCellIds_[i],j),0,(*val)(i,j));
2744 }
2745 }
2746 // change map
2747 Tpetra::Export<> exporter(vecOverlap->getMap(), v->getMap()); // redistribution
2748 v->doExport(*vecOverlap, exporter, Tpetra::ADD); // from the overlap map to the unique map
2749 }
2750
2751 template<class Real>
assembleParamVector(ROL::Ptr<std::vector<Real>> & v,std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & val)2752 void Assembler<Real>::assembleParamVector(ROL::Ptr<std::vector<Real>> &v,
2753 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> &val) {
2754 int size = v->size();
2755 v->assign(size,0);
2756 // for (int i = 0; i < size; ++i) {
2757 // dofMgr_->transformToFieldPattern(val[i]);
2758 // }
2759 // Assembly
2760 std::vector<Real> myVal(size,0);
2761 for (int j = 0; j < size; ++j) {
2762 if ( val[j] != ROL::nullPtr ) {
2763 for (int i=0; i<numCells_; ++i) {
2764 myVal[j] += (*val[j])(i);
2765 }
2766 }
2767 }
2768 Teuchos::reduceAll<int,Real>(*comm_,Teuchos::REDUCE_SUM,size,&myVal[0],&(*v)[0]);
2769 }
2770
2771 template<class Real>
assembleFieldMatrix(ROL::Ptr<Tpetra::CrsMatrix<>> & M,ROL::Ptr<Intrepid::FieldContainer<Real>> & val,const ROL::Ptr<DofManager<Real>> & dofMgr1,const ROL::Ptr<DofManager<Real>> & dofMgr2)2772 void Assembler<Real>::assembleFieldMatrix(ROL::Ptr<Tpetra::CrsMatrix<>> &M,
2773 ROL::Ptr<Intrepid::FieldContainer<Real>> &val,
2774 const ROL::Ptr<DofManager<Real>> &dofMgr1,
2775 const ROL::Ptr<DofManager<Real>> &dofMgr2) {
2776 // Transform data
2777 transformToFieldPattern(val,dofMgr1,dofMgr2);
2778 // Zero PDE Jacobian
2779 M->resumeFill(); M->setAllToScalar(static_cast<Real>(0));
2780 // Assemble PDE Jacobian
2781 Intrepid::FieldContainer<int> &cellDofs1 = *(dofMgr1->getCellDofs());
2782 Intrepid::FieldContainer<int> &cellDofs2 = *(dofMgr2->getCellDofs());
2783 int numLocalDofs1 = cellDofs1.dimension(1);
2784 int numLocalDofs2 = cellDofs2.dimension(1);
2785 int numLocalMatEntries = numLocalDofs1 * numLocalDofs2;
2786 Teuchos::ArrayRCP<const int> cellDofs2ArrayRCP = cellDofs2.getData();
2787 Teuchos::ArrayRCP<GO> cellDofs2GO(cellDofs2ArrayRCP.size(), GO());
2788 std::copy(cellDofs2ArrayRCP.getRawPtr(), cellDofs2ArrayRCP.getRawPtr()+cellDofs2ArrayRCP.size(),
2789 cellDofs2GO.getRawPtr());
2790 Teuchos::ArrayRCP<const GO> cellDofs2GOArrayRCP = cellDofs2GO.getConst();
2791 Teuchos::ArrayRCP<const Real> valArrayRCP = val->getData();
2792 for (int i=0; i<numCells_; ++i) {
2793 for (int j=0; j<numLocalDofs1; ++j) {
2794 M->sumIntoGlobalValues(GO(cellDofs1(myCellIds_[i],j)),
2795 cellDofs2GOArrayRCP(myCellIds_[i] * numLocalDofs2, numLocalDofs2),
2796 valArrayRCP(i*numLocalMatEntries+j*numLocalDofs2, numLocalDofs2));
2797 }
2798 }
2799 M->fillComplete();
2800 }
2801
2802 template<class Real>
assembleParamFieldMatrix(ROL::Ptr<Tpetra::MultiVector<>> & M,std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> & val,ROL::Ptr<Tpetra::MultiVector<>> & matOverlap,const ROL::Ptr<DofManager<Real>> & dofMgr)2803 void Assembler<Real>::assembleParamFieldMatrix(ROL::Ptr<Tpetra::MultiVector<>> &M,
2804 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> &val,
2805 ROL::Ptr<Tpetra::MultiVector<>> &matOverlap,
2806 const ROL::Ptr<DofManager<Real>> &dofMgr) {
2807 // Initialize res
2808 int size = M->getNumVectors();
2809 // Compute PDE local Jacobian wrt parametric controls
2810 for (int i = 0; i < size; ++i) {
2811 transformToFieldPattern(val[i],dofMgr);
2812 }
2813 // Assemble PDE Jacobian wrt parametric controls
2814 M->scale(static_cast<Real>(0));
2815 matOverlap->scale(static_cast<Real>(0));
2816 for (int k = 0; k < size; ++k) {
2817 Intrepid::FieldContainer<int> &cellDofs = *(dofMgr->getCellDofs());
2818 int numLocalDofs = cellDofs.dimension(1);
2819 // assembly on the overlap map
2820 for (int i=0; i<numCells_; ++i) {
2821 for (int j=0; j<numLocalDofs; ++j) {
2822 matOverlap->sumIntoGlobalValue(cellDofs(myCellIds_[i],j),
2823 k,(*val[k])[i*numLocalDofs+j]);
2824 }
2825 }
2826 // change map
2827 Tpetra::Export<> exporter(matOverlap->getMap(), M->getMap()); // redistribution
2828 M->doExport(*matOverlap, exporter, Tpetra::ADD); // from the overlap map to the unique map
2829 }
2830 }
2831
2832 template<class Real>
assembleParamMatrix(ROL::Ptr<std::vector<std::vector<Real>>> & M,std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> & val,const ROL::Ptr<DofManager<Real>> & dofMgr)2833 void Assembler<Real>::assembleParamMatrix(ROL::Ptr<std::vector<std::vector<Real>>> &M,
2834 std::vector<std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>>> &val,
2835 const ROL::Ptr<DofManager<Real>> &dofMgr) {
2836 // Initialize local matrix
2837 int size = M->size();
2838 std::vector<ROL::Ptr<Intrepid::FieldContainer<Real>>> tmp(size,ROL::nullPtr);
2839 // Compute local matrix
2840 for (int i = 0; i < size; ++i) {
2841 for (int j = 0; j < size; ++j) {
2842 transformToFieldPattern(val[i][j],dofMgr);
2843 }
2844 }
2845 // Assemble PDE Jacobian wrt parametric controls
2846 int cnt = 0, matSize = static_cast<int>(0.5*static_cast<Real>((size+1)*size));
2847 std::vector<Real> myMat(matSize,static_cast<Real>(0));
2848 std::vector<Real> globMat(matSize,static_cast<Real>(0));
2849 for (int k = 0; k < size; ++k) {
2850 for (int j = k; j < size; ++j) {
2851 for (int i=0; i<numCells_; ++i) {
2852 myMat[cnt] += (*(val[k][j]))(i);
2853 }
2854 cnt++;
2855 }
2856 }
2857 Teuchos::reduceAll<int,Real>(*comm_,Teuchos::REDUCE_SUM,matSize,&myMat[0],&globMat[0]);
2858 cnt = 0;
2859 for (int k = 0; k < size; ++k) {
2860 for (int j = k; j < size; ++j) {
2861 (*M)[k][j] += globMat[cnt];
2862 if ( j != k ) {
2863 (*M)[j][k] += globMat[cnt];
2864 }
2865 cnt++;
2866 }
2867 }
2868 }
2869
2870 template<class Real>
transformToFieldPattern(const ROL::Ptr<Intrepid::FieldContainer<Real>> & array,const ROL::Ptr<DofManager<Real>> & dofMgr1,const ROL::Ptr<DofManager<Real>> & dofMgr2) const2871 void Assembler<Real>::transformToFieldPattern(const ROL::Ptr<Intrepid::FieldContainer<Real>> &array,
2872 const ROL::Ptr<DofManager<Real>> &dofMgr1,
2873 const ROL::Ptr<DofManager<Real>> &dofMgr2) const {
2874 if ( array != ROL::nullPtr ) {
2875 int rank = array->rank();
2876 int nc = array->dimension(0);
2877 if ( rank == 2 ) {
2878 int nf = array->dimension(1);
2879 Intrepid::FieldContainer<Real> tmp(nc, nf);
2880 for (int c = 0; c < nc; ++c) {
2881 for (int f = 0; f < nf; ++f) {
2882 tmp(c, dofMgr1->mapToFieldPattern(f)) = (*array)(c, f);
2883 }
2884 }
2885 *array = tmp;
2886 }
2887 else if (rank == 3 ) {
2888 int nf1 = array->dimension(1);
2889 int nf2 = array->dimension(2);
2890 Intrepid::FieldContainer<Real> tmp(nc, nf1, nf2);
2891 for (int c = 0; c < nc; ++c) {
2892 for (int f1 = 0; f1 < nf1; ++f1) {
2893 for (int f2 = 0; f2 < nf2; ++f2) {
2894 tmp(c, dofMgr1->mapToFieldPattern(f1), dofMgr2->mapToFieldPattern(f2)) = (*array)(c, f1, f2);
2895 }
2896 }
2897 }
2898 *array = tmp;
2899 }
2900 else {
2901 TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument,
2902 ">>> PDE-OPT/TOOLS/assembler.hpp (transformToFieldPattern): Input array rank not 2 or 3!");
2903 }
2904 }
2905 }
2906
2907 #endif
2908