Panzer  Version of the Day
Panzer_BlockedDOFManager_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_BLOCKED_DOF_MANAGER_IMPL_HPP
44 #define PANZER_BLOCKED_DOF_MANAGER_IMPL_HPP
45 
46 #include <map>
47 
50 
52 
53 using Teuchos::RCP;
54 
55 namespace panzer {
56 
57 // ************************************************************
58 // class BlockedDOFManager
59 // ************************************************************
60 
61 template <typename LocalOrdinalT,typename GlobalOrdinalT>
63  : fieldsRegistered_(false), maxSubFieldNum_(-1), requireOrientations_(false), useDOFManagerFEI_(true), useTieBreak_(false)
64 { }
65 
66 template <typename LocalOrdinalT,typename GlobalOrdinalT>
68  : fieldsRegistered_(false), maxSubFieldNum_(-1), requireOrientations_(false), useDOFManagerFEI_(true), useTieBreak_(false)
69 {
70  setConnManager(connMngr,mpiComm);
71 }
72 
75 
76 template <typename LocalOrdinalT,typename GlobalOrdinalT>
78 {
79  std::map<std::string,int>::const_iterator itr = fieldStrToNum_.find(str);
80 
81  // return based on what was found
82  if(itr==fieldStrToNum_.end()) {
83  // incorrect field name
84  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
85  "BlockedDOFManager::getFieldNum No field with the name \"" + str + "\" has been added");
86  }
87  else {
88  return itr->second;
89  }
90 }
91 
92 template <typename LocalOrdinalT,typename GlobalOrdinalT>
94 {
95  std::map<int,std::string>::const_iterator itr = fieldNumToStr_.find(number);
96 
97  // return based on what was found
98  if(itr==fieldNumToStr_.end()) {
99  std::stringstream ss; ss << number; // itoa() in c-language
100  // incorrect field name
101  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
102  "BlockedDOFManager::getFieldString No field with number \"" + ss.str() + "\" has been added");
103  }
104  else {
105  return itr->second;
106  }
107 }
108 
109 template <typename LocalOrdinalT,typename GlobalOrdinalT>
110 bool BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::fieldInBlock(const std::string & field,const std::string & block) const
111 {
112  // try to find element block
113  std::map<std::string,std::set<std::string> >::const_iterator fieldsItr = blockIdToFieldStrings_.find(block);
114  TEUCHOS_TEST_FOR_EXCEPTION(fieldsItr==blockIdToFieldStrings_.end(),std::logic_error,
115  "BlockedDOFManager::fieldInBlock could not find the element block \""+block+"\"");
116 
117  // find field in element block
118  const std::set<std::string> & fields = fieldsItr->second;
119  std::set<std::string>::const_iterator itr = fields.find(field);
120  return itr!=fields.end();
121 }
122 
125 template <typename LocalOrdinalT,typename GlobalOrdinalT>
126 const std::vector<int> & BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::getBlockFieldNumbers(const std::string & block) const
127 {
128  // try to find element block
129  std::map<std::string,std::vector<int> >::const_iterator fieldsItr = blockIdToFieldNumbers_.find(block);
130  if(fieldsItr!=blockIdToFieldNumbers_.end())
131  return fieldsItr->second;
132 
133  // nothing to return
134  static std::vector<int> empty;
135  return empty;
136 }
137 
138 template <typename LocalOrdinalT,typename GlobalOrdinalT>
139 void BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::getElementGIDs(LocalOrdinalT localElmtId,std::vector<GlobalOrdinal> & gids,const std::string & blockIdHint) const
140 {
141  // WARNING: there is an assumed ordering being used here it
142  // corresponds directly to the blockGIDOffset_ map and (as
143  // a result) the getBlockGIDOffset function. However for
144  // the sake of speed this conversion is implicit.
145  //
146  // Any changes to the order should be reflected in the
147  // blockGIDOffset_ map.
148 
149  gids.resize(0);
150 
151  // loop over field block manager and grab indices
152  for(std::size_t fbm=0;fbm<fieldBlockManagers_.size();fbm++) {
153  std::vector<GlobalOrdinalT> fieldBlockOwned;
154 
155  fieldBlockManagers_[fbm]->getElementGIDs(localElmtId,fieldBlockOwned,blockIdHint);
156 
157  for(std::size_t i=0;i<fieldBlockOwned.size();i++)
158  gids.push_back(std::make_pair(fbm,fieldBlockOwned[i]));
159  }
160 }
161 
162 template <typename LocalOrdinalT,typename GlobalOrdinalT>
163 void BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::getElementOrientation(LocalOrdinalT localElmtId,std::vector<double> & gidsOrientation) const
164 {
165  // WARNING: there is an assumed ordering being used here it
166  // corresponds directly to the blockGIDOffset_ map and (as
167  // a result) the getBlockGIDOffset function. However for
168  // the sake of speed this conversion is implicit.
169  //
170  // Any changes to the order should be reflected in the
171  // blockGIDOffset_ map.
172 
173  gidsOrientation.resize(0);
174 
175  // loop over field block manager and grab indices
176  for(std::size_t fbm=0;fbm<fieldBlockManagers_.size();fbm++) {
177  std::vector<double> blkOrientation;
178 
179  fieldBlockManagers_[fbm]->getElementOrientation(localElmtId,blkOrientation);
180 
181  for(std::size_t i=0;i<blkOrientation.size();i++)
182  gidsOrientation.push_back(blkOrientation[i]);
183  }
184 }
185 
186 template <typename LocalOrdinalT,typename GlobalOrdinalT>
187 const std::vector<int> & BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::getGIDFieldOffsets(const std::string & blockId,int fieldNum) const
188 {
189  typedef std::map<std::string,std::map<int,std::vector<int> > > FieldOffsetsMap;
190 
191  FieldOffsetsMap::iterator blockItr = gidFieldOffsets_.find(blockId);
192  if(blockItr!=gidFieldOffsets_.end()) {
193  std::map<int,std::vector<int> > & fieldToVectorMap = blockItr->second;
194  std::map<int,std::vector<int> >::const_iterator itr = fieldToVectorMap.find(fieldNum);
195 
196  // we have found the vector, return the precomputed one
197  if(itr!=fieldToVectorMap.end())
198  return itr->second;
199  }
200  else {
201  std::vector<std::string> elementBlocks;
202  getElementBlockIds(elementBlocks);
203  TEUCHOS_TEST_FOR_EXCEPTION(std::find(elementBlocks.begin(),elementBlocks.end(),blockId)==elementBlocks.end(),std::logic_error,
204  "BlockedDOFManager::getGIDFieldOffsets: Block ID \""+blockId+"\" does not exist");
205 
206  gidFieldOffsets_[blockId] = std::map<int,std::vector<int> >();
207  blockItr = gidFieldOffsets_.find(blockId);
208  }
209 
210  // grab relevant map from iterator
211  std::map<int,std::vector<int> > & fieldToVectorMap = blockItr->second;
212 
213  // we have not found the vector, now we need to build one
215 
216  // first grab all pieces that are needed for extracting GIDs from sub system
217  int fieldBlock = getFieldBlock(fieldNum);
218  Teuchos::RCP<const UniqueGlobalIndexer<LocalOrdinalT,GlobalOrdinalT> > dofManager = fieldBlockManagers_[fieldBlock];
219 
220  // grab offsets for sub dof manager. Notice you must convert to field number used by sub manager!
221  const std::vector<int> & subGIDOffsets
222  = dofManager->getGIDFieldOffsets(blockId,dofManager->getFieldNum(getFieldString(fieldNum)));
223 
224  // increment offsets to correspond with blocked system
225  int gidOffset = getBlockGIDOffset(blockId,fieldBlock);
226  std::vector<int> & finalFieldOffsets = fieldToVectorMap[fieldNum];
227  finalFieldOffsets.resize(subGIDOffsets.size());
228  for(std::size_t i=0;i<finalFieldOffsets.size();i++)
229  finalFieldOffsets[i] = gidOffset+subGIDOffsets[i];
230 
231  return finalFieldOffsets;
232 }
233 
234 template <typename LocalOrdinalT,typename GlobalOrdinalT>
237 {
238  if(a[0] < b[0]) return true;
239  if(a[0] > b[0]) return false;
240 
241  // a[0]==b[0]
242  if(a[1] < b[1]) return true;
243  if(a[1] > b[1]) return false;
244 
245  // a[1]==b[1] && a[0]==b[0]
246  if(a[2] < b[2]) return true;
247  if(a[2] > b[2]) return false;
248 
249  // a[2]==b[2] && a[1]==b[1] && a[0]==b[0]
250  return false; // these are equal to, but not less than!
251 }
252 
253 template <typename LocalOrdinalT,typename GlobalOrdinalT>
254 const std::pair<std::vector<int>,std::vector<int> > &
255 BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::getGIDFieldOffsets_closure(const std::string & blockId,int fieldNum,int subcellDim,int subcellId) const
256 {
257  typename std::map<std::string,TupleToVectorPairMap>::iterator blockItr = gidFieldOffsets_closure_.find(blockId);
258  if(blockItr!=gidFieldOffsets_closure_.end()) {
259  TupleToVectorPairMap & fieldToTupleMap = blockItr->second;
260  typename TupleToVectorPairMap::const_iterator itr =
261  fieldToTupleMap.find(Teuchos::tuple(fieldNum,subcellDim,subcellId));
262 
263  // we have found the vector, return the precomputed one
264  if(itr!=fieldToTupleMap.end())
265  return itr->second;
266  }
267  else {
268  std::vector<std::string> elementBlocks;
269  getElementBlockIds(elementBlocks);
270  TEUCHOS_TEST_FOR_EXCEPTION(std::find(elementBlocks.begin(),elementBlocks.end(),blockId)==elementBlocks.end(),std::logic_error,
271  "BlockedDOFManager::getGIDFieldOffsets: Block ID \""+blockId+"\" does not exist");
272 
273  gidFieldOffsets_closure_[blockId] = TupleToVectorPairMap();
274  blockItr = gidFieldOffsets_closure_.find(blockId);
275  }
276 
277  // grab relevant map from iterator
278  TupleToVectorPairMap & fieldToTupleMap = blockItr->second;
279 
280  // we have not found the vector, now we need to build one
282 
283  // first grab all pieces that are needed for extracting GIDs from sub system
284  int fieldBlock = getFieldBlock(fieldNum);
285  Teuchos::RCP<const UniqueGlobalIndexer<LocalOrdinalT,GlobalOrdinalT> > dofManager = fieldBlockManagers_[fieldBlock];
286 
287  // grab offsets for sub dof manager. Notice you must convert to field number used by sub manager!
288  const std::pair<std::vector<int>,std::vector<int> > & subGIDOffsets_closure
289  = dofManager->getGIDFieldOffsets_closure(blockId,dofManager->getFieldNum(getFieldString(fieldNum)),subcellDim,subcellId);
290 
291  // increment offsets to correspond with blocked system
292  int gidOffset = getBlockGIDOffset(blockId,fieldBlock);
293  std::pair<std::vector<int>,std::vector<int> > & finalFieldOffsets = fieldToTupleMap[Teuchos::tuple(fieldNum,subcellDim,subcellId)];
294  finalFieldOffsets.first.resize(subGIDOffsets_closure.first.size());
295  finalFieldOffsets.second = subGIDOffsets_closure.second;
296  for(std::size_t i=0;i<finalFieldOffsets.first.size();i++)
297  finalFieldOffsets.first[i] = gidOffset+subGIDOffsets_closure.first[i];
298 
299  return finalFieldOffsets;
300 }
301 
302 template <typename LocalOrdinalT,typename GlobalOrdinalT>
303 void BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::getOwnedIndices(std::vector<GlobalOrdinal> & indices) const
304 {
305  // loop over field block manager and grab indices
306  for(std::size_t fbm=0;fbm<fieldBlockManagers_.size();fbm++) {
307  std::vector<GlobalOrdinalT> fieldBlockOwned;
308 
309  fieldBlockManagers_[fbm]->getOwnedIndices(fieldBlockOwned);
310 
311  for(std::size_t i=0;i<fieldBlockOwned.size();i++)
312  indices.push_back(std::make_pair(fbm,fieldBlockOwned[i]));
313  }
314 }
315 
316 template <typename LocalOrdinalT,typename GlobalOrdinalT>
318 {
319  // loop over field block manager and grab indices
320  for(std::size_t fbm=0;fbm<fieldBlockManagers_.size();fbm++) {
321  std::vector<GlobalOrdinalT> fieldBlockOwned;
322 
323  fieldBlockManagers_[fbm]->getOwnedAndGhostedIndices(fieldBlockOwned);
324 
325  for(std::size_t i=0;i<fieldBlockOwned.size();i++)
326  indices.push_back(std::make_pair(fbm,fieldBlockOwned[i]));
327  }
328 }
329 
330 template <typename LocalOrdinalT,typename GlobalOrdinalT>
331 void BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::ownedIndices(const std::vector<GlobalOrdinal> & indices,std::vector<bool> & isOwned) const
332 {
333  isOwned.resize(0);
334 
335  std::vector<std::vector<GlobalOrdinalT> > blockIndices(fieldBlockManagers_.size());
336  for(std::size_t i=0;i<indices.size();i++)
337  blockIndices[indices[i].first].push_back(indices[i].second);
338 
339  // build bool vector stating if each sub block is owned
340  std::vector<std::vector<bool> > blockIsOwned(fieldBlockManagers_.size());
341  std::vector<std::vector<bool>::const_iterator> blockItrs;
342  for(std::size_t fbm=0;fbm<fieldBlockManagers_.size();fbm++) {
343  fieldBlockManagers_[fbm]->ownedIndices(blockIndices[fbm],blockIsOwned[fbm]);
344 
345  // setup iterators to boolean vectors
346  blockItrs.push_back(blockIsOwned[fbm].begin());
347  }
348 
349  // loop over indices, consider their block and look it up
350  // in iterator vector
351  for(std::size_t i=0;i<indices.size();i++) {
352  int block = indices[i].first;
353 
354  // set owned status from iterator of block
355  bool owned = *blockItrs[block];
356  isOwned.push_back(owned);
357 
358  // increment block iterator
359  blockItrs[block]++;
360  }
361 
362  // quick error sanity check
363  TEUCHOS_ASSERT(isOwned.size()==indices.size());
364  for(std::size_t fbm=0;fbm<fieldBlockManagers_.size();fbm++) {
365  TEUCHOS_TEST_FOR_EXCEPTION(blockItrs[fbm]!=blockIsOwned[fbm].end(),std::logic_error,
366  "BlockedDOFManager::ownedIndices: Did not consume all sub block boolean entries as expected.");
367  }
368 
369 }
370 
371 
374 
375 
387 template <typename LocalOrdinalT,typename GlobalOrdinalT>
389 {
390  communicator_ = Teuchos::rcp(new Teuchos::MpiComm<int>(Teuchos::opaqueWrapper(mpiComm)));
391 
392  // this kills any old connection manager as well as the old FEI objects
393  resetIndices();
394 
395  connMngr_ = connMngr;
396 
397  mpiComm_ = *communicator_->getRawMpiComm();
398 }
399 
408 template <typename LocalOrdinalT,typename GlobalOrdinalT>
410 {
412 
413  connMngr_ = Teuchos::null;
414  ownedGIDHashTable_.clear();
415  blockGIDOffset_.clear();
416 
417 #ifdef PANZER_HAVE_FEI
418  for(std::size_t fbm=0;fbm<fieldBlockManagers_.size();fbm++) {
420  = Teuchos::rcp_dynamic_cast<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> >(fieldBlockManagers_[fbm]);
421  if(dofMngr!=Teuchos::null)
422  dofMngr->resetIndices();
423  }
424 #endif
425 
426  return connMngr;
427 }
428 
429 template <typename LocalOrdinalT,typename GlobalOrdinalT>
431  const Teuchos::RCP<const FieldPattern> & pattern)
432 {
433  std::vector<std::string> elementBlockIds;
434  connMngr_->getElementBlockIds(elementBlockIds);
435 
436  // loop over blocks adding field pattern to each
437  for(std::size_t i=0;i<elementBlockIds.size();i++)
438  addField(elementBlockIds[i],str,pattern);
439 }
440 
441 template <typename LocalOrdinalT,typename GlobalOrdinalT>
442 void BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::addField(const std::string & blockId,const std::string & str,
443  const Teuchos::RCP<const FieldPattern> & pattern)
444 {
445  TEUCHOS_TEST_FOR_EXCEPTION(fieldsRegistered(),std::logic_error,
446  "BlockedDOFManager::addField: addField cannot be called after registerFields or"
447  "buildGlobalUnknowns has been called");
448 
449  fieldStringToPattern_[std::make_pair(blockId,str)] = pattern;
450  blockIdToFieldStrings_[blockId].insert(str);
451 }
452 
453 template <typename LocalOrdinalT,typename GlobalOrdinalT>
455 {
456  if(buildSubUGIs)
457  fieldBlockManagers_.clear();
458  fieldStrToNum_.clear();
459  fieldNumToStr_.clear();
460  fieldNumToFieldBlk_.clear();
461  maxSubFieldNum_ = -1;
462 
463  fieldsRegistered_ = false;
464 
465  // test validity of the field order, build default if none is provided
466  {
467  // build a unique set of fields, so we can compare validate the ordered list
468  std::set<std::string> fields;
469  for(std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator
470  fieldItr=fieldStringToPattern_.begin(); fieldItr!=fieldStringToPattern_.end();++fieldItr) {
471  std::string fieldName = fieldItr->first.second;
472  fields.insert(fieldName);
473  }
474 
475  // construct default field order if neccessary
476  if(fieldOrder_.size()==0) {
477  std::set<std::string>::const_iterator itr;
478  for(itr=fields.begin();itr!=fields.end();itr++) {
479  std::vector<std::string> block;
480  block.push_back(*itr);
481  fieldOrder_.push_back(block);
482  }
483  }
484 
485  // check validity of field order: no repeats, and everything is accounted for
486  bool validOrder = validFieldOrder(fieldOrder_,fields);
487  if(!validOrder) {
488  // for outputing
489  std::stringstream ss;
490 
491  ss << "BlockedDOFManager::registerFields - Field order is invalid!\n";
492 
493  ss << " fields = [ ";
494  for(std::set<std::string>::const_iterator itr=fields.begin();
495  itr!=fields.end();++itr)
496  ss << "\"" << *itr << "\" ";
497  ss << " ]\n";
498 
499  ss << " fieldOrder = [ ";
500  for(std::vector<std::vector<std::string> >::const_iterator bitr=fieldOrder_.begin();
501  bitr!=fieldOrder_.end();++bitr) {
502  ss << "[ ";
503  for(std::vector<std::string>::const_iterator itr=bitr->begin();
504  itr!=bitr->end();++itr) {
505  ss << "\"" << *itr << "\" ";
506  }
507  ss << " ], ";
508  }
509  ss << " ]\n";
510 
511  TEUCHOS_TEST_FOR_EXCEPTION(!validOrder,std::logic_error,ss.str());
512  }
513  }
514 
515  // build sub DOFManagers for each field block
516  if(buildSubUGIs) {
517  for(std::size_t fldBlk=0;fldBlk<fieldOrder_.size();fldBlk++) {
518  Teuchos::RCP<panzer::UniqueGlobalIndexer<LocalOrdinalT,GlobalOrdinalT> > dofManager = buildNewIndexer(getConnManager(),mpiComm_);
519 
520  // add in these fields to the new manager
521  this->addFieldsToFieldBlockManager(fieldOrder_[fldBlk],*dofManager);
522 
523  fieldBlockManagers_.push_back(dofManager);
524  }
525  }
526 
528  // build field numbers: two stage algorithm
529 
530  // 1st Stage: Extract field numbers used by each sub DOFManager.
531  // determine largest of these
532  //
533  // - note at this point since "validFieldOrder" has
534  // been called we are gurranteed to not have repeated fields
535  maxSubFieldNum_ = -1;
536  std::map<std::string,int> tempStrToNum;
537  for(std::size_t fldBlk=0;fldBlk<fieldBlockManagers_.size();fldBlk++) {
539  fieldBlockManagers_[fldBlk];
540  const std::vector<std::string> & activeFields = fieldOrder_[fldBlk];
541 
542  int fieldNum = 0;
543  for(std::size_t f=0;f<activeFields.size();f++) {
544  fieldNum = dofManager->getFieldNum(activeFields[f]);
545  tempStrToNum[activeFields[f]] = fieldNum;
546 
547  maxSubFieldNum_ = (fieldNum>maxSubFieldNum_) ? fieldNum : maxSubFieldNum_;
548  }
549  }
550 
551  // 2nd Stage: Using field block index, field number and largest field number
552  // build a up fieldStrToNum_ map and fieldNumToFieldBlk_
553  int numOffset = 0;
554  for(std::size_t fldBlk=0;fldBlk<fieldBlockManagers_.size();fldBlk++) {
555  const std::vector<std::string> & activeFields = fieldOrder_[fldBlk];
556 
557  for(std::size_t f=0;f<activeFields.size();f++) {
558  // compute offset field number
559  int fieldNum = tempStrToNum[activeFields[f]]+numOffset;
560 
561  // build up map data
562  fieldStrToNum_[activeFields[f]] = fieldNum;
563  fieldNumToStr_[fieldNum] = activeFields[f];
564  fieldNumToFieldBlk_[fieldNum] = fldBlk;
565  }
566 
567  // increament field number offset based on largest sub field number
568  numOffset += (maxSubFieldNum_+1);
569  }
570 
571  // end build field numbers
573 
574  // build block to field numbers: this requires field numbers have been built
575  // and that "getFieldNum" behaves correctly
576  for(std::map<std::string,std::set<std::string> >::const_iterator itr=blockIdToFieldStrings_.begin();
577  itr!=blockIdToFieldStrings_.end();++itr) {
578  const std::set<std::string> & fields = itr->second;
579 
580  std::vector<int> & fieldNums = blockIdToFieldNumbers_[itr->first];
581  for(std::set<std::string>::const_iterator fldItr=fields.begin();
582  fldItr!=fields.end();++fldItr) {
583  fieldNums.push_back(getFieldNum(*fldItr));
584  }
585  }
586 
587  // everything completed, mark as fields registered
588  fieldsRegistered_ = true;
589 }
590 
591 template <typename LocalOrdinalT,typename GlobalOrdinalT>
594 buildNewIndexer(const Teuchos::RCP<ConnManager<LocalOrdinalT,GlobalOrdinalT> > & connManager,MPI_Comm mpiComm) const
595 {
596 #ifdef PANZER_HAVE_FEI
597  if(getUseDOFManagerFEI()) {
598  Teuchos::RCP<panzer::DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> > dofManager = Teuchos::rcp(new panzer::DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>);
599  dofManager->setConnManager(connManager,mpiComm);
600 
601  return dofManager;
602  }
603  else
604  {
606  dofManager->enableTieBreak(useTieBreak_);
607  dofManager->setConnManager(connManager,mpiComm);
608 
609  return dofManager;
610  }
611 #else
613  dofManager->enableTieBreak(useTieBreak_);
614  dofManager->setConnManager(connManager,mpiComm);
615 
616  return dofManager;
617 #endif
618 
619 }
620 
621 template <typename LocalOrdinalT,typename GlobalOrdinalT>
624 {
625  using Teuchos::RCP;
626  using Teuchos::rcp_dynamic_cast;
627 
628  // standard version
629  {
631 
632  if(dofManager!=Teuchos::null) {
633  dofManager->setOrientationsRequired(required);
634  return;
635  }
636  }
637 
638 #ifdef PANZER_HAVE_FEI
639  // now the FEI version
640  {
641  RCP<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> > dofManager = rcp_dynamic_cast<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> >(indexer);
642 
643  if(dofManager!=Teuchos::null) {
644  dofManager->setOrientationsRequired(required);
645  return;
646  }
647  }
648 #endif
649 
650  // you should never get here!
651  TEUCHOS_ASSERT(false);
652 }
653 
654 template <typename LocalOrdinalT,typename GlobalOrdinalT>
657 {
658  using Teuchos::RCP;
659  using Teuchos::rcp_dynamic_cast;
660 
661  // standard version
662  {
664 
665  if(dofManager!=Teuchos::null) {
666  dofManager->buildGlobalUnknowns(geomPattern);
667  return;
668  }
669  }
670 
671 #ifdef PANZER_HAVE_FEI
672  // now the FEI version
673  {
674  RCP<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> > dofManager = rcp_dynamic_cast<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> >(indexer);
675 
676  if(dofManager!=Teuchos::null) {
677  dofManager->buildGlobalUnknowns(geomPattern);
678  return;
679  }
680  }
681 #endif
682 
683  // you should never get here!
684  TEUCHOS_ASSERT(false);
685 }
686 
687 template <typename LocalOrdinalT,typename GlobalOrdinalT>
690 {
691  using Teuchos::RCP;
692  using Teuchos::rcp_dynamic_cast;
693 
694  // standard version
695  {
697 
698  if(dofManager!=Teuchos::null) {
699  dofManager->printFieldInformation(os);
700  return;
701  }
702  }
703 
704 #ifdef PANZER_HAVE_FEI
705  // now the FEI version
706  {
707  RCP<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> > dofManager = rcp_dynamic_cast<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> >(indexer);
708 
709  if(dofManager!=Teuchos::null) {
710  dofManager->printFieldInformation(os);
711  return;
712  }
713  }
714 #endif
715 
716  // you should never get here!
717  TEUCHOS_ASSERT(false);
718 }
719 
720 template <typename LocalOrdinalT,typename GlobalOrdinalT>
722 getElementBlockGIDCount(const Teuchos::RCP<UniqueGlobalIndexer<LocalOrdinalT,GlobalOrdinalT> > & indexer,const std::string & elementBlock) const
723 {
724  using Teuchos::RCP;
725  using Teuchos::rcp_dynamic_cast;
726 
727  TEUCHOS_ASSERT(indexer!=Teuchos::null);
728 
729  return indexer->getElementBlockGIDCount(elementBlock);
730 }
731 
732 template <typename LocalOrdinalT,typename GlobalOrdinalT>
734 getElementBlockGIDCount(const Teuchos::RCP<UniqueGlobalIndexer<LocalOrdinalT,GlobalOrdinalT> > & indexer,const std::size_t & elementBlock) const
735 {
736  using Teuchos::RCP;
737  using Teuchos::rcp_dynamic_cast;
738 
739  TEUCHOS_ASSERT(indexer!=Teuchos::null);
740 
741  return indexer->getElementBlockGIDCount(elementBlock);
742 }
743 
744 template <typename LocalOrdinalT,typename GlobalOrdinalT>
746 getElementBlockGIDCount(const std::string & elementBlock) const
747 {
748  int gidCount = 0;
749  for(std::size_t i=0;i<fieldBlockManagers_.size();i++)
750  gidCount += fieldBlockManagers_[i]->getElementBlockGIDCount(elementBlock);
751 
752  return gidCount;
753 }
754 
755 template <typename LocalOrdinalT,typename GlobalOrdinalT>
757 getElementBlockGIDCount(const std::size_t & elementBlock) const
758 {
759  int gidCount = 0;
760  for(std::size_t i=0;i<fieldBlockManagers_.size();i++)
761  gidCount += fieldBlockManagers_[i]->getElementBlockGIDCount(elementBlock);
762 
763  return gidCount;
764 }
765 
766 template <typename LocalOrdinalT,typename GlobalOrdinalT>
768 addFieldsToFieldBlockManager(const std::vector<std::string> & activeFields,
769  UniqueGlobalIndexer<LocalOrdinalT,GlobalOrdinalT> & fieldBlockManager) const
770 {
771  using Teuchos::Ptr;
772  using Teuchos::ptrFromRef;
773  using Teuchos::ptr_dynamic_cast;
774 
775  Ptr<UniqueGlobalIndexer<LocalOrdinalT,GlobalOrdinalT> > ugi_ptr = ptrFromRef(fieldBlockManager);
776 
777  // standard version
778  {
779  Ptr<DOFManager<LocalOrdinalT,GlobalOrdinalT> > dofManager_ptr = ptr_dynamic_cast<DOFManager<LocalOrdinalT,GlobalOrdinalT> >(ugi_ptr);
780 
781  if(dofManager_ptr!=Teuchos::null) {
782  addFieldsToFieldBlockManager(activeFields,*dofManager_ptr);
783  return;
784  }
785  }
786 
787 #ifdef PANZER_HAVE_FEI
788  // now the FEI version
789  {
790  Ptr<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> > dofManager_ptr = ptr_dynamic_cast<DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> >(ugi_ptr);
791 
792  if(dofManager_ptr!=Teuchos::null) {
793  addFieldsToFieldBlockManager(activeFields,*dofManager_ptr);
794  return;
795  }
796  }
797 #endif
798 
799  // you should never get here!
800  TEUCHOS_ASSERT(false);
801 }
802 
803 #ifdef PANZER_HAVE_FEI
804 template <typename LocalOrdinalT,typename GlobalOrdinalT>
806 addFieldsToFieldBlockManager(const std::vector<std::string> & activeFields,
807  DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT> & fieldBlockManager) const
808 {
809  std::vector<std::size_t> correctnessCheck(activeFields.size(),0);
810  std::vector<std::string> elementBlocks;
811  this->getElementBlockIds(elementBlocks);
812 
813  // loop over element blocks adding each field in this element block and this field block
814  for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
815  std::string elementBlock = elementBlocks[eb];
816 
817  // loop over active fields extracting those that are associated with this element block
818  for(std::size_t f=0;f<activeFields.size();f++) {
819  std::string fieldName = activeFields[f];
820  Teuchos::RCP<const FieldPattern> fp = this->getFieldPattern(elementBlock,fieldName);
821 
822  if(fp!=Teuchos::null) {
823  fieldBlockManager.addField(elementBlock,fieldName,fp);
824  correctnessCheck[f] = 1; // all active fields should be placed in DOFManager
825  }
826  }
827  }
828 
829  // verify correctness check
830  std::size_t correctFlag = std::accumulate(correctnessCheck.begin(),correctnessCheck.end(),0);
831  TEUCHOS_TEST_FOR_EXCEPTION(correctFlag!=activeFields.size(),std::logic_error,
832  "BlockedDOFManager::addFieldsToFieldBlockManager detected inconsistincies in the active fields.");
833 
834  // set field order
835  fieldBlockManager.setFieldOrder(activeFields);
836 
837  // register added fields
838  fieldBlockManager.registerFields();
839 }
840 #endif
841 
842 template <typename LocalOrdinalT,typename GlobalOrdinalT>
844 addFieldsToFieldBlockManager(const std::vector<std::string> & activeFields,
845  DOFManager<LocalOrdinalT,GlobalOrdinalT> & fieldBlockManager) const
846 {
847  std::vector<std::size_t> correctnessCheck(activeFields.size(),0);
848  std::vector<std::string> elementBlocks;
849  this->getElementBlockIds(elementBlocks);
850 
851  // loop over element blocks adding each field in this element block and this field block
852  for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
853  std::string elementBlock = elementBlocks[eb];
854 
855  // loop over active fields extracting those that are associated with this element block
856  for(std::size_t f=0;f<activeFields.size();f++) {
857  std::string fieldName = activeFields[f];
858  Teuchos::RCP<const FieldPattern> fp = this->getFieldPattern(elementBlock,fieldName);
859 
860  if(fp!=Teuchos::null) {
861  fieldBlockManager.addField(elementBlock,fieldName,fp);
862  correctnessCheck[f] = 1; // all active fields should be placed in DOFManager
863  }
864  }
865  }
866 
867  // verify correctness check
868  std::size_t correctFlag = std::accumulate(correctnessCheck.begin(),correctnessCheck.end(),0);
869  TEUCHOS_TEST_FOR_EXCEPTION(correctFlag!=activeFields.size(),std::logic_error,
870  "BlockedDOFManager::addFieldsToFieldBlockManager detected inconsistincies in the active fields.");
871 
872  // set field order
873  fieldBlockManager.setFieldOrder(activeFields);
874 }
875 
876 template <typename LocalOrdinalT,typename GlobalOrdinalT>
877 void BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::setFieldOrder(const std::vector<std::vector<std::string> > & fieldOrder)
878 {
879  fieldOrder_ = fieldOrder;
880 }
881 
884 template <typename LocalOrdinalT,typename GlobalOrdinalT>
885 void BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::getFieldOrder(std::vector<std::vector<std::string> > & fieldOrder) const
886 {
887  fieldOrder = fieldOrder_;
888 }
889 
890 template <typename LocalOrdinalT,typename GlobalOrdinalT>
892 {
893  if(fieldsRegistered())
894  return fieldStrToNum_.size();
895 
896  // more work needs to be done if the fields have not yet been registered
897  // pull it from the (block id x field name) ==> pattern map
898  std::set<std::string> fields;
899  std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator itr;
900  for(itr=fieldStringToPattern_.begin();itr!=fieldStringToPattern_.end();++itr)
901  fields.insert(itr->first.second);
902 
903  return fields.size();
904 }
905 
906 // build the global unknown numberings
907 // 1. this builds the pattens
908 // 2. initializes the connectivity
909 // 3. calls initComplete
910 template <typename LocalOrdinalT,typename GlobalOrdinalT>
913 {
914  using Teuchos::RCP;
915  using Teuchos::rcp_dynamic_cast;
916 
917  RCP<const FieldPattern> refGeomPattern;
918  RCP<ConnManager<LocalOrdinalT,GlobalOrdinalT> > refConnManager = getConnManager();
919 
920  // verify the pre-conditions:
921  // 1. all the UGIs are of type DOFManager
922  // 2. the geometric patterns are all the same
923  // 3. the connection managers are all the same
925  {
926  TEUCHOS_ASSERT(fieldBlockManagers.size()>0); // the minimum requirement!
927 
928  // get reference values from the initial DOFManager
930  = rcp_dynamic_cast<const DOFManager<LocalOrdinalT,GlobalOrdinalT> >(fieldBlockManagers[0]);
931 
932  TEUCHOS_TEST_FOR_EXCEPTION(refDofManager==Teuchos::null,std::runtime_error,
933  "panzer::BlockedDOFManager::buildGlobalUnknowns: UGI at index " << 0 <<
934  " is not of DOFManager type!");
935 
936  RCP<const ConnManager<LocalOrdinalT,GlobalOrdinalT> > connManager = refDofManager->getConnManager();
937  TEUCHOS_TEST_FOR_EXCEPTION(refConnManager!=connManager,std::runtime_error,
938  "panzer::BlockedDOFManager::buildGlobalUnknowns: connection manager for UGI " << 0 <<
939  " does not match the reference connection manager");
940 
941  refGeomPattern = refDofManager->getGeometricFieldPattern();
942 
943  for(std::size_t i=1;i<fieldBlockManagers.size();i++) {
945  = rcp_dynamic_cast<const DOFManager<LocalOrdinalT,GlobalOrdinalT> >(fieldBlockManagers[i]);
946 
947  TEUCHOS_TEST_FOR_EXCEPTION(refDofManager==Teuchos::null,std::runtime_error,
948  "panzer::BlockedDOFManager::buildGlobalUnknowns: UGI at index " << i <<
949  " is not of DOFManager type!");
950 
951  RCP<const FieldPattern> geomPattern = dofManager->getGeometricFieldPattern();
952  RCP<const ConnManager<LocalOrdinalT,GlobalOrdinalT> > connManager = dofManager->getConnManager();
953 
954  TEUCHOS_TEST_FOR_EXCEPTION(!refGeomPattern->equals(*geomPattern),std::runtime_error,
955  "panzer::BlockedDOFManager::buildGlobalUnknowns: geometric pattern for UGI " << i <<
956  " does not match the reference pattern (from UGI 0)");
957  TEUCHOS_TEST_FOR_EXCEPTION(refConnManager!=connManager,std::runtime_error,
958  "panzer::BlockedDOFManager::buildGlobalUnknowns: connection manager for UGI " << i <<
959  " does not match the reference connection manager (from UGI 0)");
960  }
961  }
962 
963  // add all the fields to the blocked dof manager
965  {
966  std::vector<std::string> eblocks;
967  this->getElementBlockIds(eblocks);
968 
969  for(std::size_t i=0;i<fieldBlockManagers.size();i++) {
971  = rcp_dynamic_cast<const DOFManager<LocalOrdinalT,GlobalOrdinalT> >(fieldBlockManagers[i]);
972 
973  for(std::size_t e=0;e<eblocks.size();e++) {
974  const std::vector<int> & fieldIds = dofManager->getBlockFieldNumbers(eblocks[e]);
975 
976  // insert the fields into the block dof manager
977  for(std::size_t f=0;f<fieldIds.size();f++) {
978  // get the field name and pattern
979  std::string fieldName = dofManager->getFieldString(fieldIds[f]);
981  = dofManager->getFieldPattern(eblocks[e],fieldName);
982 
983  // add in the field
984  this->addField(eblocks[e],fieldName,fieldPattern);
985  }
986  }
987  }
988  }
989 
990  // save and set some of the data
991  fieldBlockManagers_ = fieldBlockManagers;
992 
993  registerFields(false);
994 
995  geomPattern_ = refGeomPattern;
996 
997  // build field block offsets: this helps fast construction
998  // of GID offset vectors. GIDs are ordering by field block.
1000  {
1001  std::vector<std::string> elementBlocks;
1002  getElementBlockIds(elementBlocks);
1003  for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
1004  int offset = 0;
1005  for(std::size_t fb=0;fb<fieldBlockManagers_.size();fb++) {
1006  int cnt = getElementBlockGIDCount(fieldBlockManagers_[fb],elementBlocks[eb]);
1007  blockGIDOffset_[std::make_pair(elementBlocks[eb],fb)] = offset;
1008  offset += cnt;
1009  }
1010  }
1011  }
1012 }
1013 
1014 // build the global unknown numberings
1015 // 1. this builds the pattens
1016 // 2. initializes the connectivity
1017 // 3. calls initComplete
1018 template <typename LocalOrdinalT,typename GlobalOrdinalT>
1020 {
1021  if(!fieldsRegistered()) {
1022  registerFields(true);
1023  }
1024 
1025  // save the geometry pattern
1026  geomPattern_ = geomPattern;
1027 
1028  // build global unknowns for each field block
1029  for(std::size_t fb=0;fb<fieldBlockManagers_.size();fb++) {
1030  setOrientationsRequired(fieldBlockManagers_[fb],getOrientationsRequired());
1031  buildGlobalUnknowns(fieldBlockManagers_[fb],geomPattern_);
1032  }
1033 
1034  // build field block offsets: this helps fast construction
1035  // of GID offset vectors. GIDs are ordering by field block.
1036  std::vector<std::string> elementBlocks;
1037  getElementBlockIds(elementBlocks);
1038  for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
1039  int offset = 0;
1040  for(std::size_t fb=0;fb<fieldBlockManagers_.size();fb++) {
1041  // int cnt = fieldBlockManagers_[fb]->getElementBlockGIDCount(elementBlocks[eb]);
1042  int cnt = getElementBlockGIDCount(fieldBlockManagers_[fb],elementBlocks[eb]);
1043  blockGIDOffset_[std::make_pair(elementBlocks[eb],fb)] = offset;
1044  offset += cnt;
1045  }
1046  }
1047 }
1048 
1049 // build the global unknown numberings
1050 // 1. this builds the pattens
1051 // 2. initializes the connectivity
1052 // 3. calls initComplete
1053 template <typename LocalOrdinalT,typename GlobalOrdinalT>
1055 {
1056  if(!fieldsRegistered())
1057  registerFields(true);
1058 
1059  // build the pattern for the ID layout on the mesh
1060  std::vector<RCP<const FieldPattern> > patVector;
1061  std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::iterator f2p_itr;
1062  for(f2p_itr=fieldStringToPattern_.begin();f2p_itr!=fieldStringToPattern_.end();f2p_itr++)
1063  patVector.push_back(f2p_itr->second);
1064 
1065  // if orientations are required, add the nodal field pattern to make it possible to compute them
1066  if(requireOrientations_)
1067  patVector.push_back(Teuchos::rcp(new NodalFieldPattern(patVector[0]->getCellTopology())));
1068 
1070  aggFieldPattern->buildPattern(patVector);
1071 
1072  // setup connectivity mesh
1073  connMngr_->buildConnectivity(*aggFieldPattern);
1074 
1075  // using new geometric pattern, build global unknowns
1076  buildGlobalUnknowns(aggFieldPattern);
1077 }
1078 
1079 template <typename LocalOrdinalT,typename GlobalOrdinalT>
1081 {
1082  os << "BlockedDOFManager Field Information: " << std::endl;
1083 
1084  if(fieldsRegistered()) {
1085  // Print field block DOF managers
1086  for(std::size_t fbm=0;fbm<fieldBlockManagers_.size();fbm++) {
1087  os << "*************************************************\n";
1088  os << "Field Block Index = " << fbm << std::endl;
1089  printFieldInformation(fieldBlockManagers_[fbm],os);
1090 
1091  // print out mapping between sub field IDs and blocked field IDs
1092  os << " Field String to Field Id (blocked/sub):\n";
1093  for(std::size_t i=0;i<fieldOrder_[fbm].size();i++) {
1094  std::string fieldString = fieldOrder_[fbm][i];
1095  int fieldNum = getFieldNum(fieldString);
1096  os << " \"" << fieldString << "\" is field ID " << fieldNum
1097  << "/" << fieldBlockManagers_[fbm]->getFieldNum(fieldString) << std::endl;
1098  }
1099  os << std::endl;
1100  }
1101  }
1102  else {
1103  // fields are not registered
1104  os << "Fields not yet registered! Unknowns not built (call registerFields or buildGlobalUnknowns)" << std::endl;
1105  }
1106 }
1107 
1108 template <typename LocalOrdinalT,typename GlobalOrdinalT>
1110 BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::getFieldPattern(const std::string & blockId, const std::string & fieldName) const
1111 {
1112  std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator itr;
1113  itr = fieldStringToPattern_.find(std::make_pair(blockId,fieldName));
1114 
1115  if(itr==fieldStringToPattern_.end()) // not found
1116  return Teuchos::null;
1117  else // found
1118  return itr->second;
1119 }
1120 
1129 template <typename LocalOrdinalT,typename GlobalOrdinalT>
1130 bool BlockedDOFManager<LocalOrdinalT,GlobalOrdinalT>::validFieldOrder(const std::vector<std::vector<std::string> > & fieldOrder_ut,
1131  const std::set<std::string> & fields) const
1132 {
1133  std::set<std::string> orderedFields;
1134  std::size_t numberInOrder = 0;
1135 
1136  for(std::size_t b=0;b<fieldOrder_ut.size();b++) {
1137  numberInOrder += fieldOrder_ut[b].size();
1138  orderedFields.insert(fieldOrder_ut[b].begin(),
1139  fieldOrder_ut[b].end());
1140  }
1141 
1142  bool correctCount = (numberInOrder==fields.size());
1143  bool sameFields = (orderedFields==fields);
1144 
1145  return correctCount && sameFields;
1146 }
1147 
1148 template <typename LocalOrdinalT,typename GlobalOrdinalT>
1150 {
1151  if(fieldOrder_.size()==0)
1152  return 1; // only one field block
1153  return fieldOrder_.size();
1154 }
1155 
1157 
1158 }
1159 
1160 #endif
int getFieldBlock(const std::string &fieldName, const std::vector< Teuchos::RCP< UniqueGlobalIndexer< LocalOrdinalT, GlobalOrdinalT > > > &ugis)
Teuchos::RCP< const FieldPattern > getFieldPattern(const std::string &blockId, const std::string &fieldName) const
Find a field pattern stored for a particular block and field number. This will retrive the pattern ad...
virtual bool equals(const FieldPattern &fp) const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual const std::pair< std::vector< int >, std::vector< int > > & getGIDFieldOffsets_closure(const std::string &blockId, int fieldNum, int subcellDim, int subcellId) const
Use the field pattern so that you can find a particular field in the GIDs array. This version lets yo...
void setConnManager(const Teuchos::RCP< ConnManager< LocalOrdinalT, GlobalOrdinalT > > &connMngr, MPI_Comm mpiComm)
Set the connection manager and MPI_Comm objects.
Teuchos::RCP< UniqueGlobalIndexer< LocalOrdinalT, GlobalOrdinalT > > buildNewIndexer(const Teuchos::RCP< ConnManager< LocalOrdinalT, GlobalOrdinalT > > &connManager, MPI_Comm mpiComm) const
void printFieldInformation(std::ostream &os) const
virtual void getOwnedIndices(std::vector< GlobalOrdinal > &indices) const
virtual const std::vector< int > & getBlockFieldNumbers(const std::string &block) const
void addField(const std::string &str, const Teuchos::RCP< const FieldPattern > &pattern)
Add a field to the DOF manager.
PHX::MDField< ScalarT > vector
int getNumFields() const
How many fields are handled by this manager.
void addFieldsToFieldBlockManager(const std::vector< std::string > &activeFields, UniqueGlobalIndexer< LocalOrdinalT, GlobalOrdinalT > &fieldBlockManager) const
Teuchos::RCP< ConnManager< LocalOrdinalT, GlobalOrdinalT > > resetIndices()
Reset the indicies for this DOF manager.
virtual void getOwnedAndGhostedIndices(std::vector< GlobalOrdinal > &indices) const
virtual int getElementBlockGIDCount(const std::string &blockId) const
How any GIDs are associate with a particular element block.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void setFieldOrder(const std::vector< std::string > &fieldOrder)
virtual void getElementOrientation(LocalOrdinalT localElmtId, std::vector< double > &gidsOrientation) const
Get a vector containg the orientation of the GIDs relative to the neighbors.
int addField(const std::string &str, const Teuchos::RCP< const FieldPattern > &pattern)
Add a field to the DOF manager.
bool operator()(const Teuchos::Tuple< int, 3 > &a, const Teuchos::Tuple< int, 3 > &b) const
PHX::MDField< const ScalarT, Cell, IP > field
const std::string & getFieldString(int num) const
Get the string name associated with a field number.
virtual const std::vector< int > & getGIDFieldOffsets(const std::string &blockId, int fieldNum) const
Use the field pattern so that you can find a particular field in the GIDs array.
virtual void buildPattern(const std::vector< Teuchos::RCP< const FieldPattern > > &patterns)
int getFieldNum(const std::string &str) const
Get the number used for access to this field.
void setFieldOrder(const std::vector< std::vector< std::string > > &fieldOrder)
bool validFieldOrder(const std::vector< std::vector< std::string > > &fieldOrder_ut, const std::set< std::string > &fields) const
virtual bool fieldInBlock(const std::string &field, const std::string &block) const
void getFieldOrder(std::vector< std::vector< std::string > > &fieldOrder) const
#define TEUCHOS_ASSERT(assertion_test)
std::map< Teuchos::Tuple< int, 3 >, std::pair< std::vector< int >, std::vector< int > >, LessThan > TupleToVectorPairMap
virtual void ownedIndices(const std::vector< GlobalOrdinal > &indices, std::vector< bool > &isOwned) const
void getElementGIDs(LocalOrdinalT localElmtId, std::vector< GlobalOrdinal > &gids, const std::string &blockIdHint="") const
Get the global IDs for a particular element. This function overwrites the gids variable.