43 #ifndef PANZER_DOF_MANAGER_FEI_IMPL_HPP
44 #define PANZER_DOF_MANAGER_FEI_IMPL_HPP
46 #include "PanzerDofMgr_config.hpp"
48 #ifdef PANZER_HAVE_FEI
51 #include "fei_Factory_Trilinos.hpp"
69 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
70 DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::DOFManagerFEI()
71 : numFields_(0), fieldsRegistered_(false), requireOrientations_(false)
74 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
75 DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::DOFManagerFEI(
const Teuchos::RCP<ConnManager<LocalOrdinalT,GlobalOrdinalT> > & connMngr,MPI_Comm mpiComm)
76 : numFields_(0), fieldsRegistered_(false), requireOrientations_(false)
78 setConnManager(connMngr,mpiComm);
92 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
93 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::setConnManager(
const Teuchos::RCP<ConnManager<LocalOrdinalT,GlobalOrdinalT> > & connMngr,MPI_Comm mpiComm)
96 communicator_ =
Teuchos::rcp(
new Teuchos::MpiComm<int>(Teuchos::opaqueWrapper(mpiComm)));
101 connMngr_ = connMngr;
104 feiFactory_ =
Teuchos::rcp(
new Factory_Trilinos(*communicator_->getRawMpiComm()));
107 vectorSpace_ = feiFactory_->createVectorSpace(*communicator_->getRawMpiComm(),
"problem_vs");
108 matrixGraph_ = feiFactory_->createMatrixGraph(vectorSpace_,vectorSpace_,
"problem_mg");
111 vectorSpace_->defineIDTypes(1,&nodeType_);
113 vectorSpace_->defineIDTypes(1,&edgeType_);
124 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
129 connMngr_ = Teuchos::null;
133 feiFactory_ = Teuchos::null;
134 vectorSpace_.
reset();
135 matrixGraph_.reset();
137 ownedGIDHashTable_.clear();
142 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
143 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::addField(
const std::string & str,
146 std::vector<std::string> elementBlockIds;
147 connMngr_->getElementBlockIds(elementBlockIds);
150 for(std::size_t i=0;i<elementBlockIds.size();i++)
151 addField(elementBlockIds[i],str,pattern);
154 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
155 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::addField(
const std::string & blockId,
const std::string & str,
159 "DOFManagerFEI::addField: addField cannot be called after registerFields or"
160 "buildGlobalUnknowns has been called");
162 fieldStringToPattern_[std::make_pair(blockId,str)] = pattern;
165 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
166 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::registerFields()
173 std::set<std::string> fields;
175 fieldItr=fieldStringToPattern_.begin(); fieldItr!=fieldStringToPattern_.end();++fieldItr) {
176 std::string fieldName = fieldItr->first.second;
177 fields.insert(fieldName);
181 if(fieldOrder_.size()==0) {
182 std::set<std::string>::const_iterator itr;
183 for(itr=fields.begin();itr!=fields.end();itr++)
184 fieldOrder_.push_back(*itr);
188 bool validOrder = validFieldOrder(fieldOrder_,fields);
191 std::stringstream ss;
193 ss <<
"DOFManagerFEI::registerFields - Field order is invalid!\n";
195 ss <<
" fields = [ ";
196 for(std::set<std::string>::const_iterator itr=fields.begin();
197 itr!=fields.end();++itr)
198 ss <<
"\"" << *itr <<
"\" ";
201 ss <<
" fieldOrder = [ ";
202 for(std::vector<std::string>::const_iterator itr=fieldOrder_.begin();
203 itr!=fieldOrder_.end();++itr)
204 ss <<
"\"" << *itr <<
"\" ";
212 for(std::size_t fo_index=0;fo_index<fieldOrder_.size();fo_index++) {
213 std::string fieldName = fieldOrder_[fo_index];
216 int fieldNum = fo_index;
218 vectorSpace_->defineFields(1,&fieldNum,&size);
220 fieldStrToInt_[fieldName] = fieldNum;
221 intToFieldStr_[fieldNum] = fieldName;
223 numFields_ = fieldOrder_.size();
227 std::vector<std::string> elementBlockIds;
228 getElementBlockIds(elementBlockIds);
229 for(std::size_t ebi=0;ebi<elementBlockIds.size();ebi++)
230 blockToField_.insert(std::make_pair(elementBlockIds[ebi],std::set<int>()));
234 fieldItr=fieldStringToPattern_.begin(); fieldItr!=fieldStringToPattern_.end();++fieldItr) {
236 std::string blockId = fieldItr->first.first;
237 std::string fieldName = fieldItr->first.second;
239 std::map<std::string,int>::const_iterator itr = fieldStrToInt_.find(fieldName);
240 if(itr!=fieldStrToInt_.end()) {
242 blockToField_[blockId].insert(itr->second);
243 fieldIntToPattern_[std::make_pair(blockId,itr->second)] = fieldItr->second;
252 "DOFManagerFEI::registerFields - Impossible case discoverved!");
256 fieldsRegistered_ =
true;
259 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
260 int DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::getFieldNum(
const std::string & str)
const
262 std::map<std::string,int>::const_iterator itr = fieldStrToInt_.find(str);
265 if(itr==fieldStrToInt_.end()) {
268 "DOFManagerFEI::getFieldNum No field with the name \"" + str +
"\" has been added");
275 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
276 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::setFieldOrder(
const std::vector<std::string> & fieldOrder)
278 fieldOrder_ = fieldOrder;
283 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
284 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::getFieldOrder(std::vector<std::string> & fieldOrder)
const
286 fieldOrder = fieldOrder_;
289 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
290 int DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::getNumFields()
const
292 return vectorSpace_->getNumFields();
299 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
304 if(getOrientationsRequired()) {
308 "DOFManagerFEI::buildGlobalUnknowns requires a geometric pattern including "
309 "the nodes when orientations are needed!");
312 if(!fieldsRegistered_)
315 std::vector<std::string> fieldOrder;
316 getFieldOrder(fieldOrder);
319 geomPattern_ = geomPattern;
322 std::vector<std::string> elementBlockIds;
323 connMngr->getElementBlockIds(elementBlockIds);
326 patternNum_.resize(connMngr->numElementBlocks());
327 std::vector<std::string>::const_iterator blockItr;
328 for(blockItr=elementBlockIds.begin();blockItr!=elementBlockIds.end();++blockItr) {
329 std::string blockId = *blockItr;
330 std::size_t blockIndex = blockIdToIndex(blockId);
333 bool patternBuilt = buildPattern(fieldOrder,blockId);
339 const std::vector<int> & numFieldsPerID = fieldAggPattern_[blockId]->numFieldsPerId();
340 std::vector<int> activeIds;
341 for(std::size_t i=0;i<numFieldsPerID.size();i++)
342 if(numFieldsPerID[i]>0)
343 activeIds.push_back(i);
344 std::vector<int> reduceConn(activeIds.size());
347 const std::vector<LocalOrdinal> & elements = connMngr->getElementBlock(blockId);
350 matrixGraph_->initConnectivityBlock(blockIndex,elements.size(),patternNum_[blockIndex]);
351 for(std::size_t e=0;e<elements.size();e++) {
352 const GlobalOrdinal * conn = connMngr->getConnectivity(elements[e]);
353 for(std::size_t i=0;i<activeIds.size();i++)
354 reduceConn[i] = conn[activeIds[i]];
356 matrixGraph_->initConnectivity(blockIndex,elements[e],&reduceConn[0]);
363 matrixGraph_->initComplete();
366 std::vector<GlobalOrdinal> ownedIndices;
367 getOwnedIndices(ownedIndices);
368 ownedGIDHashTable_.insert(ownedIndices.begin(),ownedIndices.end());
371 if(getOrientationsRequired())
372 buildUnknownsOrientation();
375 this->buildLocalIds();
382 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
383 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::buildGlobalUnknowns()
385 if(!fieldsRegistered_)
389 std::vector<RCP<const FieldPattern> > patVector;
390 RCP<GeometricAggFieldPattern> aggFieldPattern =
Teuchos::rcp(
new GeometricAggFieldPattern);;
392 for(f2p_itr=fieldIntToPattern_.begin();f2p_itr!=fieldIntToPattern_.end();f2p_itr++)
393 patVector.push_back(f2p_itr->second);
399 if(getOrientationsRequired())
400 patVector.push_back(
Teuchos::rcp(
new NodalFieldPattern(patVector[0]->getCellTopology())));
403 aggFieldPattern->buildPattern(patVector);
406 connMngr_->buildConnectivity(*aggFieldPattern);
409 buildGlobalUnknowns(aggFieldPattern);
412 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
413 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::buildUnknownsOrientation()
415 orientation_.clear();
417 std::vector<std::string> elementBlockIds;
418 connMngr_->getElementBlockIds(elementBlockIds);
421 std::size_t myElementCount = 0;
422 for(std::vector<std::string>::const_iterator blockItr=elementBlockIds.begin();
423 blockItr!=elementBlockIds.end();++blockItr)
424 myElementCount += connMngr_->getElementBlock(*blockItr).size();
427 orientation_.resize(myElementCount);
430 for(std::vector<std::string>::const_iterator blockItr=elementBlockIds.begin();
431 blockItr!=elementBlockIds.end();++blockItr) {
432 const std::string & blockName = *blockItr;
435 std::map<std::string,Teuchos::RCP<FieldAggPattern> >::const_iterator fap = fieldAggPattern_.find(blockName);
436 if(fap==fieldAggPattern_.end() || fap->second==Teuchos::null)
440 const FieldPattern & fieldPattern = *fap->second;
442 std::vector<std::pair<int,int> > topEdgeIndices;
445 std::vector<std::vector<int> > topFaceIndices;
446 if(geomPattern_->getDimension()==3)
449 std::size_t numGIDs = getElementBlockGIDCount(blockName);
450 const std::vector<LocalOrdinal> & elmts = getElementBlock(blockName);
451 for(std::size_t e=0;e<elmts.size();e++) {
453 std::vector<char> & eOrientation = orientation_[elmts[e]];
454 eOrientation.resize(numGIDs);
455 for(std::size_t s=0;s<eOrientation.size();s++)
459 LocalOrdinalT connSz = connMngr_->getConnectivitySize(elmts[e]);
460 const GlobalOrdinalT * connPtr = connMngr_->getConnectivity(elmts[e]);
461 const std::vector<GlobalOrdinalT> connectivity(connPtr,connPtr+connSz);
466 if(geomPattern_->getDimension()==3)
472 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
473 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::getOrderedBlock(
const std::vector<std::string> & fieldOrder,
474 const std::string & blockId,
475 std::vector<int> & orderedBlock)
const
477 const std::set<int> & fieldSet = this->getFields(blockId);
478 orderedBlock.clear();
480 std::vector<std::string>::const_iterator itr;
481 for(itr=fieldOrder.begin();itr!=fieldOrder.end();++itr) {
482 int fieldNum = this->getFieldNum(*itr);
485 if(fieldSet.find(fieldNum)!=fieldSet.end())
486 orderedBlock.push_back(fieldNum);
491 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
492 bool DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::buildPattern(
const std::vector<std::string> & fieldOrder,
493 const std::string & blockId)
499 std::vector<std::pair<int,Teuchos::RCP<const FieldPattern> > > blockPatterns;
500 std::vector<int> orderedBlock;
501 getOrderedBlock(fieldOrder,blockId,orderedBlock);
504 std::vector<int>::const_iterator itr;
505 for(itr=orderedBlock.begin();itr!=orderedBlock.end();++itr) {
507 blockPatterns.push_back(std::make_pair(*itr,fp));
510 std::size_t blockIndex = blockIdToIndex(blockId);
511 if(blockPatterns.size()<=0) {
512 patternNum_[blockIndex] = -1;
518 fieldAggPattern_[blockId] =
rcp(
new FieldAggPattern(blockPatterns,geomPattern_));
521 const std::vector<int> & fields = fieldAggPattern_[blockId]->fieldIds();
522 const std::vector<int> & numFieldsPerID = fieldAggPattern_[blockId]->numFieldsPerId();
524 std::vector<int> reduceNumFieldsPerID;
525 for(std::size_t i=0;i<numFieldsPerID.size();i++)
526 if(numFieldsPerID[i]>0)
527 reduceNumFieldsPerID.push_back(numFieldsPerID[i]);
529 int idsPerElement = reduceNumFieldsPerID.size();
531 patternNum_[blockIndex]
532 = matrixGraph_->definePattern(idsPerElement,nodeType_,&reduceNumFieldsPerID[0],&fields[0]);
543 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
544 inline void getGIDsFromMatrixGraph(
int blockIndex,
int dof,LocalOrdinalT localElmtId,
545 fei::MatrixGraph & mg,std::vector<GlobalOrdinalT> & gids)
547 std::vector<int> indices(dof);
551 mg.getConnectivityIndices(blockIndex,localElmtId,dof,&indices[0],localSize);
555 for(std::size_t i=0;i<indices.size();i++)
556 gids[i] = (GlobalOrdinalT) indices[i];
559 template <
typename LocalOrdinalT>
560 inline void getGIDsFromMatrixGraph(
int blockIndex,
int dof,LocalOrdinalT localElmtId,
561 fei::MatrixGraph & mg,std::vector<int> & gids)
566 mg.getConnectivityIndices(blockIndex,localElmtId,dof,&gids[0],localSize);
571 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
572 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::getElementGIDs(LocalOrdinalT localElmtId,std::vector<GlobalOrdinalT> & gids,
const std::string & blockIdHint)
const
577 blockId = blockIdHint;
579 blockId = connMngr_->getBlockId(localElmtId);
582 std::size_t blockIndex = blockIdToIndex(blockId);
583 int dof = getElementBlockGIDCount(blockIndex);
589 getGIDsFromMatrixGraph(blockIndex,dof,localElmtId,*matrixGraph_,gids);
597 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
598 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::
599 getElementOrientation(LocalOrdinalT localElmtId,std::vector<double> & gidsOrientation)
const
604 "DOFManagerFEI::getElementOrientations: Orientations were not constructed!");
606 const std::vector<char> & local_o = orientation_[localElmtId];
607 gidsOrientation.resize(local_o.size());
608 for(std::size_t i=0;i<local_o.size();i++) {
609 gidsOrientation[i] = double(local_o[i]);
613 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
614 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::printFieldInformation(std::ostream & os)
const
616 os <<
"DOFManagerFEI Field Information: " << std::endl;
618 if(fieldsRegistered_) {
619 std::map<std::string,Teuchos::RCP<FieldAggPattern> >::const_iterator iter;
620 for(iter=fieldAggPattern_.begin();iter!=fieldAggPattern_.end();++iter) {
621 os <<
"Element Block = " << iter->first << std::endl;
622 iter->second->print(os);
625 std::set<int>::const_iterator itr_fieldIds = blockToField_.find(iter->first)->second.begin();
626 std::set<int>::const_iterator end_fieldIds = blockToField_.find(iter->first)->second.end();
627 os <<
" Field String to Field Id:\n";
628 for( ;itr_fieldIds!=end_fieldIds;++itr_fieldIds)
629 os <<
" \"" << getFieldString(*itr_fieldIds) <<
"\" is field ID " << *itr_fieldIds << std::endl;
634 os <<
"Fields not yet registered! Unknowns not built (call buildGlobalUnknowns)" << std::endl;
638 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
642 itr = fieldIntToPattern_.find(std::make_pair(blockId,fieldNum));
644 if(itr==fieldIntToPattern_.end()) {
646 return Teuchos::null;
652 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
654 getFieldPattern(
const std::string & blockId,
const std::string & fieldName)
const
659 fieldNum = getFieldNum(fieldName);
661 catch(
const std::logic_error & le) {
662 return Teuchos::null;
665 return getFieldPattern(blockId,fieldNum);
668 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
669 std::size_t DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::blockIdToIndex(
const std::string & blockId)
const
672 if(blockIdToIndex_==Teuchos::null) {
674 std::vector<std::string> elementBlockIds;
675 connMngr_->getElementBlockIds(elementBlockIds);
678 blockIdToIndex_ =
Teuchos::rcp(
new std::map<std::string,std::size_t>);
679 for(std::size_t i=0;i<elementBlockIds.size();i++)
680 (*blockIdToIndex_)[elementBlockIds[i]] = i;
683 return (*blockIdToIndex_)[blockId];
686 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
687 const std::map<std::string,std::size_t> & DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::blockIdToIndexMap()
const
690 if(blockIdToIndex_==Teuchos::null) {
692 std::vector<std::string> elementBlockIds;
693 connMngr_->getElementBlockIds(elementBlockIds);
696 blockIdToIndex_ =
Teuchos::rcp(
new std::map<std::string,std::size_t>);
697 for(std::size_t i=0;i<elementBlockIds.size();i++)
698 (*blockIdToIndex_)[elementBlockIds[i]] = i;
701 return *blockIdToIndex_;
704 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
705 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::ownedIndices(
const std::vector<GlobalOrdinalT> & indices,std::vector<bool> & isOwned)
const
708 if(indices.size()!=isOwned.size())
709 isOwned.resize(indices.size(),
false);
712 typename std::unordered_set<GlobalOrdinal>::const_iterator endItr = ownedGIDHashTable_.end();
713 for(std::size_t i=0;i<indices.size();i++)
714 isOwned[i] = (ownedGIDHashTable_.find(indices[i])!=endItr);
719 template <
typename OrdinalType>
720 static void getOwnedIndices_T(
const fei::SharedPtr<fei::VectorSpace> & vs,std::vector<OrdinalType> & indices)
723 numIndices = vs->getNumIndices_Owned();
724 indices.resize(numIndices);
725 std::vector<int> int_Indices;
728 int_Indices.resize(numIndices);
731 vs->getIndices_Owned(numIndices,&int_Indices[0],ni);
733 for(std::size_t i=0;i<int_Indices.size();i++)
734 indices[i] = (OrdinalType) int_Indices[i];
737 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
738 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::getOwnedIndices(std::vector<GlobalOrdinalT> & indices)
const
740 getOwnedIndices_T<GlobalOrdinalT>(vectorSpace_,indices);
751 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
752 bool DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::validFieldOrder(
const std::vector<std::string> & fieldOrder_ut,
const std::set<std::string> & fields)
const
754 if(fields.size()!=fieldOrder_ut.size())
757 std::set<std::string> fieldOrderSet;
760 std::vector<std::string>::const_iterator itr;
761 for(itr=fieldOrder_ut.begin();itr!=fieldOrder_ut.end();++itr)
762 fieldOrderSet.insert(*itr);
764 if(fieldOrderSet.size()!=fieldOrder_ut.size())
768 std::set<std::string>::const_iterator itr_ut = fieldOrderSet.begin();
769 std::set<std::string>::const_iterator itr_src = fields.begin();
770 while(itr_ut!=fieldOrderSet.end()) {
771 if(*itr_ut!=*itr_src)
785 template <
typename OrdinalType>
786 static void getOwnedAndSharedIndices_T(
const fei::SharedPtr<fei::VectorSpace> & vs,std::vector<OrdinalType> & indices)
788 std::vector<int> int_Indices;
791 vs->getIndices_SharedAndOwned(int_Indices);
793 indices.resize(int_Indices.size());
794 for(std::size_t i=0;i<int_Indices.size();i++)
795 indices[i] = (OrdinalType) int_Indices[i];
798 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
799 void DOFManagerFEI<LocalOrdinalT,GlobalOrdinalT>::getOwnedAndSharedIndices(std::vector<GlobalOrdinalT> & indices)
const
801 getOwnedAndSharedIndices_T<GlobalOrdinalT>(vectorSpace_,indices);
RCP< const T > getConst() const
void computeCellFaceOrientations(const std::vector< std::pair< int, int > > &topEdgeIndices, const std::vector< GlobalOrdinalT > &topology, const FieldPattern &fieldPattern, std::vector< char > &orientation)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void computeCellEdgeOrientations(const std::vector< std::pair< int, int > > &topEdgeIndices, const std::vector< GlobalOrdinalT > &topology, const FieldPattern &fieldPattern, std::vector< char > &orientation)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
PHX::MDField< const ScalarT > dof
void computePatternFaceIndices(const FieldPattern &pattern, std::vector< std::vector< int > > &faceIndices)
virtual const std::vector< int > & getSubcellIndices(int dim, int cellIndex) const =0
void computePatternEdgeIndices(const FieldPattern &pattern, std::vector< std::pair< int, int > > &edgeIndices)