Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_GatherSolution_TpetraSG_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_TPETRA_SG_IMPL_HPP
44 #define PANZER_GATHER_SOLUTION_TPETRA_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 "Tpetra_Vector.hpp"
59 #include "Tpetra_Map.hpp"
60 
61 // **********************************************************************
62 // Specialization: SGResidual
63 // **********************************************************************
64 
65 template<typename TRAITS,typename LO,typename GO,typename NodeT>
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,typename NodeT>
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,typename NodeT>
125 preEvaluate(typename TRAITS::PreEvalData d)
126 {
128 
129  // extract linear object container
130  sgTpetraContainer_ = Teuchos::rcp_dynamic_cast<SGLOC>(d.gedc.getDataObject(globalDataKey_),true);
131 }
132 
133 // **********************************************************************
134 template<typename TRAITS,typename LO,typename GO,typename NodeT>
136 evaluateFields(typename TRAITS::EvalData workset)
137 {
138 /*
139  typedef TpetraLinearObjContainer<double,LO,GO,NodeT> LOC;
140  typedef SGTpetraLinearObjContainer<double,LO,GO,NodeT> SGLOC;
141 
142  std::vector<GO> GIDs;
143  std::vector<LO> LIDs;
144 
145  // for convenience pull out some objects from workset
146  std::string blockId = this->wda(workset).block_id;
147  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
148 
149  Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = sgTpetraContainer_->getExpansion();
150 
151  Teuchos::RCP<typename LOC::VectorType> x_template; // this will be used to map from GIDs --> LIDs
152  if (useTimeDerivativeSolutionVector_)
153  x_template = (*sgTpetraContainer_->begin())->get_dxdt();
154  else
155  x_template = (*sgTpetraContainer_->begin())->get_x();
156 
157  // NOTE: A reordering of these loops will likely improve performance
158  // The "getGIDFieldOffsets may be expensive. However the
159  // "getElementGIDs" can be cheaper. However the lookup for LIDs
160  // may be more expensive!
161 
162  // gather operation for each cell in workset
163  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
164  std::size_t cellLocalId = localCellIds[worksetCellIndex];
165 
166  globalIndexer_->getElementGIDs(cellLocalId,GIDs,blockId);
167 
168  // caculate the local IDs for this element
169  LIDs.resize(GIDs.size());
170  for(std::size_t i=0;i<GIDs.size();i++)
171  LIDs[i] = x_template->getMap()->getLocalElement(GIDs[i]);
172 
173  // loop over the fields to be gathered
174  for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
175  int fieldNum = fieldIds_[fieldIndex];
176  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
177 
178  // loop over basis functions and fill the fields
179  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
180  int offset = elmtOffset[basis];
181  LO lid = LIDs[offset];
182 
183  ScalarT & field = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
184  field.reset(expansion); // jamb in expansion here
185  field.copyForWrite();
186 
187  // loop over stochastic basis initialzing field gather values
188  int stochIndex = 0;
189  typename SGLOC::iterator itr;
190  for(itr=sgTpetraContainer_->begin();itr!=sgTpetraContainer_->end();++itr,++stochIndex) {
191  // extract solution and time derivative vectors
192  Teuchos::RCP<typename LOC::VectorType> x;
193  if (useTimeDerivativeSolutionVector_)
194  x = (*itr)->get_dxdt();
195  else
196  x = (*itr)->get_x();
197  Teuchos::ArrayRCP<const double> x_array = x->get1dView();
198 
199  field.fastAccessCoeff(stochIndex) = x_array[lid];
200  }
201  }
202  }
203  }
204 */
205 }
206 
207 // **********************************************************************
208 // Specialization: SGJacobian
209 // **********************************************************************
210 
211 template<typename TRAITS,typename LO,typename GO,typename NodeT>
214  const Teuchos::RCP<const panzer::UniqueGlobalIndexer<LO,GO> > & indexer,
215  const Teuchos::ParameterList& p)
216  : globalIndexer_(indexer)
217  , useTimeDerivativeSolutionVector_(false)
218  , globalDataKey_("Solution Gather Container")
219 {
220  const std::vector<std::string>& names =
221  *(p.get< Teuchos::RCP< std::vector<std::string> > >("DOF Names"));
222 
223  indexerNames_ = p.get< Teuchos::RCP< std::vector<std::string> > >("Indexer Names");
224 
226  p.get< Teuchos::RCP<panzer::PureBasis> >("Basis")->functional;
227 
228  gatherFields_.resize(names.size());
229  for (std::size_t fd = 0; fd < names.size(); ++fd) {
230  PHX::MDField<ScalarT,Cell,NODE> f(names[fd],dl);
231  gatherFields_[fd] = f;
232  this->addEvaluatedField(gatherFields_[fd]);
233  }
234 
235  if (p.isType<bool>("Use Time Derivative Solution Vector"))
236  useTimeDerivativeSolutionVector_ = p.get<bool>("Use Time Derivative Solution Vector");
237 
238  if (p.isType<std::string>("Global Data Key"))
239  globalDataKey_ = p.get<std::string>("Global Data Key");
240 
241  this->setName("Gather Solution");
242 }
243 
244 // **********************************************************************
245 template<typename TRAITS,typename LO,typename GO,typename NodeT>
247 postRegistrationSetup(typename TRAITS::SetupData d,
249 {
250  // globalIndexer_ = d.globalIndexer_;
251  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_->size());
252 
253  fieldIds_.resize(gatherFields_.size());
254 
255  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
256  // get field ID from DOF manager
257  //std::string fieldName = gatherFields_[fd].fieldTag().name();
258  const std::string& fieldName = (*indexerNames_)[fd];
259  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
260 
261  // setup the field data object
262  this->utils.setFieldData(gatherFields_[fd],fm);
263  }
264 
265  indexerNames_ = Teuchos::null; // Don't need this anymore
266 }
267 
268 // **********************************************************************
269 template<typename TRAITS,typename LO,typename GO,typename NodeT>
271 preEvaluate(typename TRAITS::PreEvalData d)
272 {
274 
275  // extract linear object container
276  sgTpetraContainer_ = Teuchos::rcp_dynamic_cast<SGLOC>(d.gedc.getDataObject(globalDataKey_),true);
277 }
278 
279 // **********************************************************************
280 template<typename TRAITS,typename LO,typename GO,typename NodeT>
282 evaluateFields(typename TRAITS::EvalData workset)
283 {
284 /*
285  typedef TpetraLinearObjContainer<double,LO,GO,NodeT> LOC;
286  typedef SGTpetraLinearObjContainer<double,LO,GO,NodeT> SGLOC;
287 
288  std::vector<GO> GIDs;
289  std::vector<LO> LIDs;
290 
291  // for convenience pull out some objects from workset
292  std::string blockId = this->wda(workset).block_id;
293  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
294 
295  Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = sgTpetraContainer_->getExpansion();
296 
297  Teuchos::RCP<typename LOC::VectorType> x_template; // this will be used to map from GIDs --> LIDs
298  double seed_value = 0.0;
299  if (useTimeDerivativeSolutionVector_) {
300  x_template = (*sgTpetraContainer_->begin())->get_dxdt();
301  seed_value = workset.alpha;
302  }
303  else {
304  x_template = (*sgTpetraContainer_->begin())->get_x();
305  seed_value = workset.beta;
306  }
307 
308  // NOTE: A reordering of these loops will likely improve performance
309  // The "getGIDFieldOffsets may be expensive. However the
310  // "getElementGIDs" can be cheaper. However the lookup for LIDs
311  // may be more expensive!
312 
313  // gather operation for each cell in workset
314  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
315  std::size_t cellLocalId = localCellIds[worksetCellIndex];
316 
317  globalIndexer_->getElementGIDs(cellLocalId,GIDs,blockId);
318 
319  // caculate the local IDs for this element
320  LIDs.resize(GIDs.size());
321  for(std::size_t i=0;i<GIDs.size();i++)
322  LIDs[i] = x_template->getMap()->getLocalElement(GIDs[i]);
323 
324  // loop over the fields to be gathered
325  for(std::size_t fieldIndex=0;
326  fieldIndex<gatherFields_.size();fieldIndex++) {
327  int fieldNum = fieldIds_[fieldIndex];
328  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
329 
330  // loop over basis functions and fill the fields
331  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
332  int offset = elmtOffset[basis];
333  LO lid = LIDs[offset];
334 
335  ScalarT & field = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
336 
337  field = ScalarT(GIDs.size(), 0.0);
338 
339  // set the value and seed the FAD object
340  field.fastAccessDx(offset) = seed_value;
341  field.val().reset(expansion);
342  field.val().copyForWrite();
343 
344  // loop over stochastic basis initialzing field gather values
345  int stochIndex = 0;
346  typename SGLOC::iterator itr;
347  for(itr=sgTpetraContainer_->begin();itr!=sgTpetraContainer_->end();++itr,++stochIndex) {
348  // extract solution and time derivative vectors
349  Teuchos::RCP<typename LOC::VectorType> x;
350  if (useTimeDerivativeSolutionVector_)
351  x = (*itr)->get_dxdt();
352  else
353  x = (*itr)->get_x();
354  Teuchos::ArrayRCP<const double> x_array = x->get1dView();
355 
356  field.val().fastAccessCoeff(stochIndex) = x_array[lid];
357  }
358  }
359  }
360  }
361 */
362 }
363 
364 // **********************************************************************
365 #endif // end HAVE_STOKHOS
366 
367 #endif
T & get(const std::string &name, T def_value)
Gathers solution values from the Newton solution vector into the nodal fields of the field manager...
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)