Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_GatherSolution_EpetraSG_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Panzer: A partial differential equation assembly
5 // engine for strongly coupled complex multiphysics systems
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39 // Eric C. Cyr (eccyr@sandia.gov)
40 // ***********************************************************************
41 // @HEADER
42 
43 #ifndef PANZER_GATHER_SOLUTION_EPETRA_SG_IMPL_HPP
44 #define PANZER_GATHER_SOLUTION_EPETRA_SG_IMPL_HPP
45 
46 #include "Panzer_config.hpp"
47 #ifdef HAVE_STOKHOS
48 
49 #include "Teuchos_Assert.hpp"
50 #include "Phalanx_DataLayout.hpp"
51 
53 #include "Panzer_BasisIRLayout.hpp"
55 
56 #include "Teuchos_FancyOStream.hpp"
57 
58 #include "Epetra_Vector.h"
59 #include "Epetra_Map.h"
60 
61 // **********************************************************************
62 // Specialization: SGResidual
63 // **********************************************************************
64 
65 template<typename TRAITS,typename LO,typename GO>
68  const Teuchos::RCP<const panzer::UniqueGlobalIndexer<LO,GO> > & indexer,
69  const Teuchos::ParameterList& p)
70  : globalIndexer_(indexer)
71  , useTimeDerivativeSolutionVector_(false)
72  , globalDataKey_("Solution Gather Container")
73 {
74  const std::vector<std::string>& names =
75  *(p.get< Teuchos::RCP< std::vector<std::string> > >("DOF Names"));
76 
77  indexerNames_ = p.get< Teuchos::RCP< std::vector<std::string> > >("Indexer Names");
78 
81 
82  gatherFields_.resize(names.size());
83  for (std::size_t fd = 0; fd < names.size(); ++fd) {
84  gatherFields_[fd] =
85  PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
86  this->addEvaluatedField(gatherFields_[fd]);
87  }
88 
89  if (p.isType<bool>("Use Time Derivative Solution Vector"))
90  useTimeDerivativeSolutionVector_ = p.get<bool>("Use Time Derivative Solution Vector");
91 
92  if (p.isType<std::string>("Global Data Key"))
93  globalDataKey_ = p.get<std::string>("Global Data Key");
94 
95  this->setName("Gather Solution");
96 }
97 
98 // **********************************************************************
99 template<typename TRAITS,typename LO,typename GO>
101 postRegistrationSetup(typename TRAITS::SetupData d,
103 {
104  // globalIndexer_ = d.globalIndexer_;
105  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_->size());
106 
107  fieldIds_.resize(gatherFields_.size());
108 
109  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
110  // get field ID from DOF manager
111  //std::string fieldName = gatherFields_[fd].fieldTag().name();
112  const std::string& fieldName = (*indexerNames_)[fd];
113  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
114 
115  // setup the field data object
116  this->utils.setFieldData(gatherFields_[fd],fm);
117  }
118 
119  indexerNames_ = Teuchos::null; // Don't need this anymore
120 }
121 
122 // **********************************************************************
123 template<typename TRAITS,typename LO,typename GO>
125 preEvaluate(typename TRAITS::PreEvalData d)
126 {
127  // extract linear object container
128  sgEpetraContainer_ = Teuchos::rcp_dynamic_cast<SGEpetraLinearObjContainer>(d.gedc.getDataObject(globalDataKey_),true);
129 }
130 
131 // **********************************************************************
132 template<typename TRAITS,typename LO,typename GO>
134 evaluateFields(typename TRAITS::EvalData workset)
135 {
136  std::vector<GO> GIDs;
137  std::vector<int> LIDs;
138 
139  // for convenience pull out some objects from workset
140  std::string blockId = this->wda(workset).block_id;
141  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
142 
143  Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = sgEpetraContainer_->getExpansion();
144 
145  Teuchos::RCP<Epetra_Vector> x_template; // this will be used to map from GIDs --> LIDs
146  if (useTimeDerivativeSolutionVector_)
147  x_template = (*sgEpetraContainer_->begin())->get_dxdt();
148  else
149  x_template = (*sgEpetraContainer_->begin())->get_x();
150 
151  // NOTE: A reordering of these loops will likely improve performance
152  // The "getGIDFieldOffsets may be expensive. However the
153  // "getElementGIDs" can be cheaper. However the lookup for LIDs
154  // may be more expensive!
155 
156  // gather operation for each cell in workset
157  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
158  std::size_t cellLocalId = localCellIds[worksetCellIndex];
159 
160  globalIndexer_->getElementGIDs(cellLocalId,GIDs,blockId);
161 
162  // caculate the local IDs for this element
163  LIDs.resize(GIDs.size());
164  for(std::size_t i=0;i<GIDs.size();i++)
165  LIDs[i] = x_template->Map().LID(GIDs[i]);
166 
167  // loop over the fields to be gathered
168  for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
169  int fieldNum = fieldIds_[fieldIndex];
170  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
171 
172  // loop over basis functions and fill the fields
173  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
174  int offset = elmtOffset[basis];
175  int lid = LIDs[offset];
176 
177  PHX::MDField<ScalarT,Cell,NODE> field = (gatherFields_[fieldIndex]);
178  // ScalarT & field = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
179  field(worksetCellIndex,basis).reset(expansion); // jamb in expansion here
180  field(worksetCellIndex,basis).copyForWrite();
181 
182  // loop over stochastic basis initialzing field gather values
183  int stochIndex = 0;
185  for(itr=sgEpetraContainer_->begin();itr!=sgEpetraContainer_->end();++itr,++stochIndex) {
186  // extract solution and time derivative vectors
188  if (useTimeDerivativeSolutionVector_)
189  x = (*itr)->get_dxdt();
190  else
191  x = (*itr)->get_x();
192 
193  field(worksetCellIndex,basis).fastAccessCoeff(stochIndex) = (*x)[lid];
194  }
195  }
196  }
197  }
198 }
199 
200 // **********************************************************************
201 // Specialization: SGJacobian
202 // **********************************************************************
203 
204 template<typename TRAITS,typename LO,typename GO>
207  const Teuchos::RCP<const panzer::UniqueGlobalIndexer<LO,GO> > & indexer,
208  const Teuchos::ParameterList& p)
209  : globalIndexer_(indexer)
210  , useTimeDerivativeSolutionVector_(false)
211  , globalDataKey_("Solution Gather Container")
212 {
213  const std::vector<std::string>& names =
214  *(p.get< Teuchos::RCP< std::vector<std::string> > >("DOF Names"));
215 
216  indexerNames_ = p.get< Teuchos::RCP< std::vector<std::string> > >("Indexer Names");
217 
219  p.get< Teuchos::RCP<panzer::PureBasis> >("Basis")->functional;
220 
221  gatherFields_.resize(names.size());
222  for (std::size_t fd = 0; fd < names.size(); ++fd) {
223  PHX::MDField<ScalarT,Cell,NODE> f(names[fd],dl);
224  gatherFields_[fd] = f;
225  this->addEvaluatedField(gatherFields_[fd]);
226  }
227 
228  if (p.isType<bool>("Use Time Derivative Solution Vector"))
229  useTimeDerivativeSolutionVector_ = p.get<bool>("Use Time Derivative Solution Vector");
230 
231  if (p.isType<std::string>("Global Data Key"))
232  globalDataKey_ = p.get<std::string>("Global Data Key");
233 
234 
235  this->setName("Gather Solution");
236 }
237 
238 // **********************************************************************
239 template<typename TRAITS,typename LO,typename GO>
241 postRegistrationSetup(typename TRAITS::SetupData d,
243 {
244  // globalIndexer_ = d.globalIndexer_;
245  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_->size());
246 
247  fieldIds_.resize(gatherFields_.size());
248 
249  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
250  // get field ID from DOF manager
251  //std::string fieldName = gatherFields_[fd].fieldTag().name();
252  const std::string& fieldName = (*indexerNames_)[fd];
253  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
254 
255  // setup the field data object
256  this->utils.setFieldData(gatherFields_[fd],fm);
257  }
258 
259  indexerNames_ = Teuchos::null; // Don't need this anymore
260 }
261 
262 // **********************************************************************
263 template<typename TRAITS,typename LO,typename GO>
265 preEvaluate(typename TRAITS::PreEvalData d)
266 {
267  // extract linear object container
268  sgEpetraContainer_ = Teuchos::rcp_dynamic_cast<SGEpetraLinearObjContainer>(d.gedc.getDataObject(globalDataKey_),true);
269 }
270 
271 // **********************************************************************
272 template<typename TRAITS,typename LO,typename GO>
274 evaluateFields(typename TRAITS::EvalData workset)
275 {
276  std::vector<GO> GIDs;
277  std::vector<int> LIDs;
278 
279  // for convenience pull out some objects from workset
280  std::string blockId = this->wda(workset).block_id;
281  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
282 
283  Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = sgEpetraContainer_->getExpansion();
284 
285  Teuchos::RCP<Epetra_Vector> x_template;
286  double seed_value = 0.0;
287  if (useTimeDerivativeSolutionVector_) {
288  x_template = (*sgEpetraContainer_->begin())->get_dxdt();
289  seed_value = workset.alpha;
290  }
291  else {
292  x_template = (*sgEpetraContainer_->begin())->get_x();
293  seed_value = workset.beta;
294  }
295 
296  // NOTE: A reordering of these loops will likely improve performance
297  // The "getGIDFieldOffsets may be expensive. However the
298  // "getElementGIDs" can be cheaper. However the lookup for LIDs
299  // may be more expensive!
300 
301  // gather operation for each cell in workset
302  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
303  std::size_t cellLocalId = localCellIds[worksetCellIndex];
304 
305  globalIndexer_->getElementGIDs(cellLocalId,GIDs,blockId);
306 
307  // caculate the local IDs for this element
308  LIDs.resize(GIDs.size());
309  for(std::size_t i=0;i<GIDs.size();i++)
310  LIDs[i] = x_template->Map().LID(GIDs[i]);
311 
312  // loop over the fields to be gathered
313  for(std::size_t fieldIndex=0;
314  fieldIndex<gatherFields_.size();fieldIndex++) {
315  int fieldNum = fieldIds_[fieldIndex];
316  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
317 
318  // loop over basis functions and fill the fields
319  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
320  int offset = elmtOffset[basis];
321  int lid = LIDs[offset];
322 
323  PHX::MDField<ScalarT,Cell,NODE> field = (gatherFields_[fieldIndex]);
324  // ScalarT & field = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
325 
326  field(worksetCellIndex,basis) = ScalarT(GIDs.size(), 0.0);
327 
328  // set the value and seed the FAD object
329  field(worksetCellIndex,basis).fastAccessDx(offset) = seed_value;
330  field(worksetCellIndex,basis).val().reset(expansion);
331  field(worksetCellIndex,basis).val().copyForWrite();
332 
333  // loop over stochastic basis initialzing field gather values
334  int stochIndex = 0;
336  for(itr=sgEpetraContainer_->begin();itr!=sgEpetraContainer_->end();++itr,++stochIndex) {
337  // extract solution and time derivative vectors
339  if (useTimeDerivativeSolutionVector_)
340  x = (*itr)->get_dxdt();
341  else
342  x = (*itr)->get_x();
343 
344  field(worksetCellIndex,basis).val().fastAccessCoeff(stochIndex) = (*x)[lid];
345  }
346  }
347  }
348  }
349 }
350 
351 // **********************************************************************
352 #endif // end HAVE_STOKHOS
353 
354 #endif
Gathers solution values from the Newton solution vector into the nodal fields of the field manager...
T & get(const std::string &name, T def_value)
PHX::MDField< ScalarT, Cell, IP > field
Teuchos::RCP< const panzer::PureBasis > basis
Interpolates basis DOF values to IP DOF values.
bool isType(const std::string &name) const
#define TEUCHOS_ASSERT(assertion_test)