Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_ScatterDirichletResidual_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_SCATTER_DIRICHLET_RESIDUAL_TPETRA_SG_IMPL_HPP
44 #define PANZER_SCATTER_DIRICHLET_RESIDUAL_TPETRA_SG_IMPL_HPP
45 
46 #include "Panzer_config.hpp"
47 #ifdef HAVE_STOKHOS
48 
50 #include "Phalanx_DataLayout_MDALayout.hpp"
51 
53 
54 // **********************************************************************
55 // Specialization: SGResidual
56 // **********************************************************************
57 
58 template<typename TRAITS,typename LO,typename GO,typename NodeT>
61  const Teuchos::ParameterList& p)
62  : globalIndexer_(indexer)
63  , globalDataKey_("Residual Scatter Container")
64 {
65  std::string scatterName = p.get<std::string>("Scatter Name");
66  scatterHolder_ =
67  Teuchos::rcp(new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(new PHX::MDALayout<Dummy>(0))));
68 
69  // get names to be evaluated
70  const std::vector<std::string>& names =
71  *(p.get< Teuchos::RCP< std::vector<std::string> > >("Dependent Names"));
72 
73  // grab map from evaluated names to field names
74  fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >("Dependent Map");
75 
77  p.get< Teuchos::RCP<panzer::PureBasis> >("Basis")->functional;
78 
79  side_subcell_dim_ = p.get<int>("Side Subcell Dimension");
80  local_side_id_ = p.get<int>("Local Side ID");
81 
82 
83  // build the vector of fields that this is dependent on
84  scatterFields_.resize(names.size());
85  for (std::size_t eq = 0; eq < names.size(); ++eq) {
86  scatterFields_[eq] = PHX::MDField<ScalarT,Cell,NODE>(names[eq],dl);
87 
88  // tell the field manager that we depend on this field
89  this->addDependentField(scatterFields_[eq]);
90  }
91 
92  // this is what this evaluator provides
93  this->addEvaluatedField(*scatterHolder_);
94 
95  if (p.isType<std::string>("Global Data Key"))
96  globalDataKey_ = p.get<std::string>("Global Data Key");
97 
98  this->setName(scatterName+" Scatter Residual (SGResidual)");
99 }
100 
101 // **********************************************************************
102 template<typename TRAITS,typename LO,typename GO,typename NodeT>
104 postRegistrationSetup(typename TRAITS::SetupData d,
106 {
107  fieldIds_.resize(scatterFields_.size());
108 
109  // load required field numbers for fast use
110  for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
111  // get field ID from DOF manager
112  std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
113  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
114 
115  // fill field data object
116  this->utils.setFieldData(scatterFields_[fd],fm);
117  }
118 
119  // get the number of nodes (Should be renamed basis)
120  num_nodes = scatterFields_[0].dimension(1);
121 }
122 
123 // **********************************************************************
124 template<typename TRAITS,typename LO,typename GO,typename NodeT>
126 preEvaluate(typename TRAITS::PreEvalData d)
127 {
128 /*
129  // extract dirichlet counter from container
130  sgTpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.getDataObject("Dirichlet Counter"),true);
131 
132  dirichletCounter_ = sgTpetraContainer_->get_f();
133  TEUCHOS_ASSERT(!Teuchos::is_null(dirichletCounter_));
134 */
135  TEUCHOS_ASSERT(false);
136 }
137 
138 // **********************************************************************
139 template<typename TRAITS,typename LO,typename GO,typename NodeT>
141 evaluateFields(typename TRAITS::EvalData workset)
142 {
143 /*
144  typedef SGTpetraLinearObjContainer<double,LO,GO,NodeT> SGLOC;
145 
146  std::vector<GO> GIDs;
147  std::vector<LO> LIDs;
148 
149  // for convenience pull out some objects from workset
150  std::string blockId = this->wda(workset).block_id;
151  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
152 
153  Teuchos::RCP<typename LOC::VectorType> r_template = (*sgTpetraContainer_->begin())->get_f();
154  Teuchos::RCP<const typename LOC::MapType> map = r_template->getMap();
155 
156  Teuchos::ArrayRCP<double> dc_array = dirichletCounter_->get1dViewNonConst();
157 
158  // NOTE: A reordering of these loops will likely improve performance
159  // The "getGIDFieldOffsets may be expensive. However the
160  // "getElementGIDs" can be cheaper. However the lookup for LIDs
161  // may be more expensive!
162 
163  // scatter operation for each cell in workset
164  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
165  std::size_t cellLocalId = localCellIds[worksetCellIndex];
166 
167  globalIndexer_->getElementGIDs(cellLocalId,GIDs);
168 
169  // caculate the local IDs for this element
170  LIDs.resize(GIDs.size());
171  for(std::size_t i=0;i<GIDs.size();i++)
172  LIDs[i] = map->getLocalElement(GIDs[i]);
173 
174  std::vector<bool> is_owned(GIDs.size(), false);
175  globalIndexer_->ownedIndices(GIDs,is_owned);
176 
177  // loop over each field to be scattered
178  for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
179  int fieldNum = fieldIds_[fieldIndex];
180 
181  // this call "should" get the right ordering according to the Intrepid basis
182  const std::pair<std::vector<int>,std::vector<int> > & indicePair
183  = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
184  const std::vector<int> & elmtOffset = indicePair.first;
185  const std::vector<int> & basisIdMap = indicePair.second;
186 
187  // loop over basis functions
188  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
189  int offset = elmtOffset[basis];
190  LO lid = LIDs[offset];
191  if(lid<0) // not on this processor!
192  continue;
193 
194  int basisId = basisIdMap[basis];
195  const ScalarT field = (scatterFields_[fieldIndex])(worksetCellIndex,basisId);
196 
197  // loop over stochastic basis scatter field values to residual vectors
198  int stochIndex = 0;
199  typename SGLOC::iterator itr;
200  for(itr=sgTpetraContainer_->begin();itr!=sgTpetraContainer_->end();++itr,++stochIndex) {
201  Teuchos::RCP<typename LOC::VectorType> f = (*itr)->get_f();
202  f->replaceLocalValue(lid,field.coeff(stochIndex));
203  }
204 
205  // dirichlet condition application
206  dc_array[lid] = 1.0;
207  }
208  }
209  }
210 */
211  TEUCHOS_ASSERT(false);
212 }
213 
214 // **********************************************************************
215 // Specialization: SGJacobian
216 // **********************************************************************
217 
218 template<typename TRAITS,typename LO,typename GO,typename NodeT>
221  const Teuchos::ParameterList& p)
222  : globalIndexer_(indexer)
223 {
224  std::string scatterName = p.get<std::string>("Scatter Name");
225  scatterHolder_ =
226  Teuchos::rcp(new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(new PHX::MDALayout<Dummy>(0))));
227 
228  // get names to be evaluated
229  const std::vector<std::string>& names =
230  *(p.get< Teuchos::RCP< std::vector<std::string> > >("Dependent Names"));
231 
232  // grab map from evaluated names to field names
233  fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >("Dependent Map");
234 
236  p.get< Teuchos::RCP<panzer::PureBasis> >("Basis")->functional;
237 
238  side_subcell_dim_ = p.get<int>("Side Subcell Dimension");
239  local_side_id_ = p.get<int>("Local Side ID");
240 
241  // build the vector of fields that this is dependent on
242  scatterFields_.resize(names.size());
243  for (std::size_t eq = 0; eq < names.size(); ++eq) {
244  scatterFields_[eq] = PHX::MDField<ScalarT,Cell,NODE>(names[eq],dl);
245 
246  // tell the field manager that we depend on this field
247  this->addDependentField(scatterFields_[eq]);
248  }
249 
250  // this is what this evaluator provides
251  this->addEvaluatedField(*scatterHolder_);
252 
253  this->setName(scatterName+" Scatter Residual (SGJacobian)");
254 }
255 
256 // **********************************************************************
257 template<typename TRAITS,typename LO,typename GO,typename NodeT>
259 postRegistrationSetup(typename TRAITS::SetupData d,
261 {
262  fieldIds_.resize(scatterFields_.size());
263  // load required field numbers for fast use
264  for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
265  // get field ID from DOF manager
266  std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
267  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
268 
269  // fill field data object
270  this->utils.setFieldData(scatterFields_[fd],fm);
271  }
272 
273  // get the number of nodes (Should be renamed basis)
274  num_nodes = scatterFields_[0].dimension(1);
275  num_eq = scatterFields_.size();
276 }
277 
278 // **********************************************************************
279 template<typename TRAITS,typename LO,typename GO,typename NodeT>
281 preEvaluate(typename TRAITS::PreEvalData d)
282 {
283 /*
284  // extract dirichlet counter from container
285  sgTpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.getDataObject("Dirichlet Counter"),true);
286 
287  dirichletCounter_ = sgTpetraContainer_->get_f();
288  TEUCHOS_ASSERT(!Teuchos::is_null(dirichletCounter_));
289 */
290  TEUCHOS_ASSERT(false);
291 }
292 
293 // **********************************************************************
294 template<typename TRAITS,typename LO,typename GO,typename NodeT>
296 evaluateFields(typename TRAITS::EvalData workset)
297 {
298 /*
299  typedef SGTpetraLinearObjContainer<double,LO,GO,NodeT> SGLOC;
300 
301  std::vector<GO> GIDs;
302  std::vector<LO> LIDs;
303 
304  // for convenience pull out some objects from workset
305  std::string blockId = this->wda(workset).block_id;
306  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
307 
308  Teuchos::RCP<typename LOC::CrsMatrixType> Jac_template = (*sgTpetraContainer_->begin())->get_A();
309  Teuchos::RCP<const typename LOC::MapType> map = Jac_template->getRowMap();
310 
311  Teuchos::ArrayRCP<double> dc_array = dirichletCounter_->get1dViewNonConst();
312 
313  // NOTE: A reordering of these loops will likely improve performance
314  // The "getGIDFieldOffsets may be expensive. However the
315  // "getElementGIDs" can be cheaper. However the lookup for LIDs
316  // may be more expensive!
317 
318  // scatter operation for each cell in workset
319  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
320  std::size_t cellLocalId = localCellIds[worksetCellIndex];
321 
322  globalIndexer_->getElementGIDs(cellLocalId,GIDs);
323 
324  // caculate the local IDs for this element
325  LIDs.resize(GIDs.size());
326  for(std::size_t i=0;i<GIDs.size();i++)
327  LIDs[i] = map->getLocalElement(GIDs[i]);
328 
329  std::vector<bool> is_owned(GIDs.size(), false);
330  globalIndexer_->ownedIndices(GIDs,is_owned);
331 
332  // loop over each field to be scattered
333  for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
334  int fieldNum = fieldIds_[fieldIndex];
335 
336  // this call "should" get the right ordering according to the Intrepid basis
337  const std::pair<std::vector<int>,std::vector<int> > & indicePair
338  = globalIndexer_->getGIDFieldOffsets_closure(blockId,fieldNum, side_subcell_dim_, local_side_id_);
339  const std::vector<int> & elmtOffset = indicePair.first;
340  const std::vector<int> & basisIdMap = indicePair.second;
341 
342  // loop over basis functions
343  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
344  int offset = elmtOffset[basis];
345  LO lid = LIDs[offset];
346  GO gid = GIDs[offset];
347  int basisId = basisIdMap[basis];
348  if(lid<0) // not on this processor
349  continue;
350 
351  const ScalarT scatterField = (scatterFields_[fieldIndex])(worksetCellIndex,basisId);
352 
353  // loop over stochastic basis scatter field values to residual vectors
354  int stochIndex = 0;
355  typename SGLOC::iterator itr;
356  for(itr=sgTpetraContainer_->begin();itr!=sgTpetraContainer_->end();++itr,++stochIndex) {
357  Teuchos::RCP<typename LOC::VectorType> r = (*itr)->get_f();
358  Teuchos::RCP<typename LOC::CrsMatrixType> Jac = (*itr)->get_A();
359  Teuchos::ArrayRCP<double> r_array = r->get1dViewNonConst();
360 
361  // zero out matrix row
362  {
363  std::size_t sz = Jac->getNumEntriesInLocalRow(lid);
364  std::size_t numEntries = 0;
365  Teuchos::Array<LO> rowIndices(sz);
366  Teuchos::Array<double> rowValues(sz);
367 
368  Jac->getLocalRowCopy(lid,rowIndices,rowValues,numEntries);
369 
370  for(std::size_t i=0;i<numEntries;i++)
371  rowValues[i] = 0.0;
372 
373  Jac->replaceLocalValues(lid,rowIndices,rowValues);
374  }
375 
376  r_array[lid] = scatterField.val().coeff(stochIndex);
377 
378  // loop over the sensitivity indices: all DOFs on a cell
379  std::vector<double> jacRow(scatterField.size(),0.0);
380 
381  for(int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
382  jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex).coeff(stochIndex);
383 
384  Jac->replaceGlobalValues(gid, GIDs, jacRow);
385  }
386 
387  // dirichlet condition application
388  dc_array[lid] = 1.0;
389  }
390  }
391  }
392 
393 */
394 
395  TEUCHOS_ASSERT(false); // lets face it this doesn't work
396 }
397 
398 // **********************************************************************
399 #endif
400 
401 #endif
std::vector< PHX::MDField< const ScalarT, panzer::Cell, panzer::Point > > scatterFields_
T & get(const std::string &name, T def_value)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Pushes residual values into the residual vector for a Newton-based solve.
bool isType(const std::string &name) const
#define TEUCHOS_ASSERT(assertion_test)