43#ifndef PANZER_BLOCKED_DOF_MANAGER_IMPL_HPP
44#define PANZER_BLOCKED_DOF_MANAGER_IMPL_HPP
52#include "Teuchos_DefaultMpiComm.hpp"
63 : fieldsRegistered_(false), maxSubFieldNum_(-1), requireOrientations_(false), useDOFManagerFEI_(true), useTieBreak_(false)
67 : fieldsRegistered_(false), maxSubFieldNum_(-1), requireOrientations_(false), useDOFManagerFEI_(true), useTieBreak_(false)
77 std::map<std::string,int>::const_iterator itr =
fieldStrToNum_.find(str);
82 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
83 "BlockedDOFManager::getFieldNum No field with the name \"" + str +
"\" has been added");
92 std::map<int,std::string>::const_iterator itr =
fieldNumToStr_.find(number);
96 std::stringstream ss; ss << number;
98 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
99 "BlockedDOFManager::getFieldString No field with number \"" + ss.str() +
"\" has been added");
109 std::map<std::string,std::set<std::string> >::const_iterator fieldsItr =
blockIdToFieldStrings_.find(block);
111 "BlockedDOFManager::fieldInBlock could not find the element block \""+block+
"\"");
114 const std::set<std::string> & fields = fieldsItr->second;
115 std::set<std::string>::const_iterator itr = fields.find(
field);
116 return itr!=fields.end();
126 return fieldsItr->second;
129 static std::vector<int> empty;
147 std::vector<panzer::GlobalOrdinal> fieldBlockOwned;
151 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getElementGIDs() not supported for BlockedDOFManager!")
171 std::vector<panzer::GlobalOrdinal> fieldBlockOwned;
175 for(std::size_t i=0;i<fieldBlockOwned.size();i++)
176 gids.push_back(std::make_pair(fbm,fieldBlockOwned[i]));
190 gidsOrientation.resize(0);
194 std::vector<double> blkOrientation;
198 for(std::size_t i=0;i<blkOrientation.size();i++)
199 gidsOrientation.push_back(blkOrientation[i]);
205 typedef std::map<std::string,std::map<int,std::vector<int> > > FieldOffsetsMap;
209 std::map<int,std::vector<int> > & fieldToVectorMap = blockItr->second;
210 std::map<int,std::vector<int> >::const_iterator itr = fieldToVectorMap.find(fieldNum);
213 if(itr!=fieldToVectorMap.end())
217 std::vector<std::string> elementBlocks;
219 TEUCHOS_TEST_FOR_EXCEPTION(std::find(elementBlocks.begin(),elementBlocks.end(),blockId)==elementBlocks.end(),std::logic_error,
220 "BlockedDOFManager::getGIDFieldOffsets: Block ID \""+blockId+
"\" does not exist");
227 std::map<int,std::vector<int> > & fieldToVectorMap = blockItr->second;
237 const std::vector<int> & subGIDOffsets
238 = dofManager->getGIDFieldOffsets(blockId,dofManager->getFieldNum(
getFieldString(fieldNum)));
242 std::vector<int> & finalFieldOffsets = fieldToVectorMap[fieldNum];
243 finalFieldOffsets.resize(subGIDOffsets.size());
244 for(std::size_t i=0;i<finalFieldOffsets.size();i++)
245 finalFieldOffsets[i] = gidOffset+subGIDOffsets[i];
247 return finalFieldOffsets;
250bool BlockedDOFManager::LessThan
251::operator()(
const Teuchos::Tuple<int,3> & a,
const Teuchos::Tuple<int,3> & b)
const
253 if(a[0] < b[0])
return true;
254 if(a[0] > b[0])
return false;
257 if(a[1] < b[1])
return true;
258 if(a[1] > b[1])
return false;
261 if(a[2] < b[2])
return true;
262 if(a[2] > b[2])
return false;
268const std::pair<std::vector<int>,std::vector<int> > &
274 typename TupleToVectorPairMap::const_iterator itr =
275 fieldToTupleMap.find(Teuchos::tuple(fieldNum,subcellDim,subcellId));
278 if(itr!=fieldToTupleMap.end())
282 std::vector<std::string> elementBlocks;
284 TEUCHOS_TEST_FOR_EXCEPTION(std::find(elementBlocks.begin(),elementBlocks.end(),blockId)==elementBlocks.end(),std::logic_error,
285 "BlockedDOFManager::getGIDFieldOffsets: Block ID \""+blockId+
"\" does not exist");
302 const std::pair<std::vector<int>,std::vector<int> > & subGIDOffsets_closure
303 = dofManager->getGIDFieldOffsets_closure(blockId,dofManager->getFieldNum(
getFieldString(fieldNum)),subcellDim,subcellId);
307 std::pair<std::vector<int>,std::vector<int> > & finalFieldOffsets = fieldToTupleMap[Teuchos::tuple(fieldNum,subcellDim,subcellId)];
308 finalFieldOffsets.first.resize(subGIDOffsets_closure.first.size());
309 finalFieldOffsets.second = subGIDOffsets_closure.second;
310 for(std::size_t i=0;i<finalFieldOffsets.first.size();i++)
311 finalFieldOffsets.first[i] = gidOffset+subGIDOffsets_closure.first[i];
313 return finalFieldOffsets;
323 using std::make_pair;
328 vector<panzer::GlobalOrdinal> fieldBlockOwned;
330 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getOwnedIndices() not supported for BlockedDOFManager!")
343 using std::make_pair;
348 vector<panzer::GlobalOrdinal> fieldBlockGhosted;
350 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getGhostedIndices() not supported for BlockedDOFManager!")
363 using std::make_pair;
368 vector<panzer::GlobalOrdinal> fieldBlockOwnedAndGhosted;
370 fieldBlockOwnedAndGhosted);
371 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getOwnedAndGhostedIndices() not supported for BlockedDOFManager!")
392 std::vector<int> fieldBlockOwned;
396 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getElementGIDsAsInt() not supported for BlockedDOFManager!")
405 using std::make_pair;
410 vector<int> fieldBlockOwned;
412 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getOwnedIndicesAsInt() not supported for BlockedDOFManager!")
421 using std::make_pair;
426 vector<int> fieldBlockGhosted;
428 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getGhostedIndicesAsInt() not supported for BlockedDOFManager!")
437 using std::make_pair;
442 vector<int> fieldBlockOwnedAndGhosted;
444 fieldBlockOwnedAndGhosted);
445 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getOwnedAndGhostedIndicesAsInt() not supported for BlockedDOFManager!")
498 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"ownedIndices() not supported for BlockedDOFManager!")
504 std::vector<std::vector<bool>::const_iterator> blockItrs;
509 blockItrs.push_back(blockIsOwned[fbm].begin());
514 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"ownedIndices() not supported for BlockedDOFManager!")
574 Teuchos::RCP<ConnManager> connMngr =
connMngr_;
584 const Teuchos::RCP<const FieldPattern> & pattern)
586 std::vector<std::string> elementBlockIds;
587 connMngr_->getElementBlockIds(elementBlockIds);
590 for(std::size_t i=0;i<elementBlockIds.size();i++)
591 addField(elementBlockIds[i],str,pattern);
595 const Teuchos::RCP<const FieldPattern> & pattern)
598 "BlockedDOFManager::addField: addField cannot be called after registerFields or"
599 "buildGlobalUnknowns has been called");
619 std::set<std::string> fields;
620 for(std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator
622 std::string fieldName = fieldItr->first.second;
623 fields.insert(fieldName);
628 std::set<std::string>::const_iterator itr;
629 for(itr=fields.begin();itr!=fields.end();itr++) {
630 std::vector<std::string> block;
631 block.push_back(*itr);
640 std::stringstream ss;
642 ss <<
"BlockedDOFManager::registerFields - Field order is invalid!\n";
644 ss <<
" fields = [ ";
645 for(std::set<std::string>::const_iterator itr=fields.begin();
646 itr!=fields.end();++itr)
647 ss <<
"\"" << *itr <<
"\" ";
650 ss <<
" fieldOrder = [ ";
651 for(std::vector<std::vector<std::string> >::const_iterator bitr=
fieldOrder_.begin();
654 for(std::vector<std::string>::const_iterator itr=bitr->begin();
655 itr!=bitr->end();++itr) {
656 ss <<
"\"" << *itr <<
"\" ";
662 TEUCHOS_TEST_FOR_EXCEPTION(!validOrder,std::logic_error,ss.str());
668 for(std::size_t fldBlk=0;fldBlk<
fieldOrder_.size();fldBlk++) {
687 std::map<std::string,int> tempStrToNum;
689 Teuchos::RCP<const panzer::GlobalIndexer> dofManager =
691 const std::vector<std::string> & activeFields =
fieldOrder_[fldBlk];
694 for(std::size_t f=0;f<activeFields.size();f++) {
695 fieldNum = dofManager->getFieldNum(activeFields[f]);
696 tempStrToNum[activeFields[f]] = fieldNum;
706 const std::vector<std::string> & activeFields =
fieldOrder_[fldBlk];
708 for(std::size_t f=0;f<activeFields.size();f++) {
710 int fieldNum = tempStrToNum[activeFields[f]]+numOffset;
729 const std::set<std::string> & fields = itr->second;
732 for(std::set<std::string>::const_iterator fldItr=fields.begin();
733 fldItr!=fields.end();++fldItr) {
742Teuchos::RCP<GlobalIndexer>
747 dofManager->setConnManager(connManager,mpiComm);
754 using Teuchos::rcp_dynamic_cast;
758 RCP<DOFManager> dofManager = rcp_dynamic_cast<DOFManager>(indexer);
760 if(dofManager!=Teuchos::null) {
761 dofManager->setOrientationsRequired(required);
767 TEUCHOS_ASSERT(
false);
771buildGlobalUnknowns(
const Teuchos::RCP<GlobalIndexer> & indexer,
const Teuchos::RCP<const FieldPattern> & geomPattern)
const
774 using Teuchos::rcp_dynamic_cast;
778 RCP<DOFManager> dofManager = rcp_dynamic_cast<DOFManager>(indexer);
780 if(dofManager!=Teuchos::null) {
781 dofManager->buildGlobalUnknowns(geomPattern);
787 TEUCHOS_ASSERT(
false);
791 std::ostream & os)
const
794 using Teuchos::rcp_dynamic_cast;
798 RCP<DOFManager> dofManager = rcp_dynamic_cast<DOFManager>(indexer);
800 if(dofManager!=Teuchos::null) {
801 dofManager->printFieldInformation(os);
807 TEUCHOS_ASSERT(
false);
811 const std::string & elementBlock)
const
814 using Teuchos::rcp_dynamic_cast;
816 TEUCHOS_ASSERT(indexer!=Teuchos::null);
818 return indexer->getElementBlockGIDCount(elementBlock);
822 const std::size_t & elementBlock)
const
825 using Teuchos::rcp_dynamic_cast;
827 TEUCHOS_ASSERT(indexer!=Teuchos::null);
829 return indexer->getElementBlockGIDCount(elementBlock);
854 using Teuchos::ptrFromRef;
855 using Teuchos::ptr_dynamic_cast;
857 Ptr<GlobalIndexer> ugi_ptr = ptrFromRef(fieldBlockManager);
861 Ptr<DOFManager> dofManager_ptr = ptr_dynamic_cast<DOFManager>(ugi_ptr);
863 if(dofManager_ptr!=Teuchos::null) {
870 TEUCHOS_ASSERT(
false);
877 std::vector<std::size_t> correctnessCheck(activeFields.size(),0);
878 std::vector<std::string> elementBlocks;
882 for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
883 std::string elementBlock = elementBlocks[eb];
886 for(std::size_t f=0;f<activeFields.size();f++) {
887 std::string fieldName = activeFields[f];
888 Teuchos::RCP<const FieldPattern> fp = this->
getFieldPattern(elementBlock,fieldName);
890 if(fp!=Teuchos::null) {
891 fieldBlockManager.
addField(elementBlock,fieldName,fp);
892 correctnessCheck[f] = 1;
898 std::size_t correctFlag = std::accumulate(correctnessCheck.begin(),correctnessCheck.end(),0);
899 TEUCHOS_TEST_FOR_EXCEPTION(correctFlag!=activeFields.size(),std::logic_error,
900 "BlockedDOFManager::addFieldsToFieldBlockManager detected inconsistincies in the active fields.");
925 std::set<std::string> fields;
926 std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator itr;
928 fields.insert(itr->first.second);
930 return fields.size();
941 using Teuchos::rcp_dynamic_cast;
943 RCP<const FieldPattern> refGeomPattern;
952 TEUCHOS_ASSERT(fieldBlockManagers.size()>0);
955 RCP<const DOFManager> refDofManager = rcp_dynamic_cast<const DOFManager>(fieldBlockManagers[0]);
957 TEUCHOS_TEST_FOR_EXCEPTION(refDofManager==Teuchos::null,std::runtime_error,
958 "panzer::BlockedDOFManager::buildGlobalUnknowns: UGI at index " << 0 <<
959 " is not of DOFManager type!");
961 RCP<const ConnManager> connManager = refDofManager->getConnManager();
962 TEUCHOS_TEST_FOR_EXCEPTION(refConnManager!=connManager,std::runtime_error,
963 "panzer::BlockedDOFManager::buildGlobalUnknowns: connection manager for UGI " << 0 <<
964 " does not match the reference connection manager");
966 refGeomPattern = refDofManager->getGeometricFieldPattern();
968 for(std::size_t i=1;i<fieldBlockManagers.size();i++) {
969 RCP<const DOFManager> dofManager = rcp_dynamic_cast<const DOFManager>(fieldBlockManagers[i]);
971 TEUCHOS_TEST_FOR_EXCEPTION(refDofManager==Teuchos::null,std::runtime_error,
972 "panzer::BlockedDOFManager::buildGlobalUnknowns: UGI at index " << i <<
973 " is not of DOFManager type!");
975 RCP<const FieldPattern> geomPattern = dofManager->getGeometricFieldPattern();
976 RCP<const ConnManager> testConnManager = dofManager->getConnManager();
978 TEUCHOS_TEST_FOR_EXCEPTION(!refGeomPattern->equals(*geomPattern),std::runtime_error,
979 "panzer::BlockedDOFManager::buildGlobalUnknowns: geometric pattern for UGI " << i <<
980 " does not match the reference pattern (from UGI 0)");
981 TEUCHOS_TEST_FOR_EXCEPTION(refConnManager!=testConnManager,std::runtime_error,
982 "panzer::BlockedDOFManager::buildGlobalUnknowns: connection manager for UGI " << i <<
983 " does not match the reference connection manager (from UGI 0)");
990 std::vector<std::string> eblocks;
993 for(std::size_t i=0;i<fieldBlockManagers.size();i++) {
994 RCP<const DOFManager> dofManager
995 = rcp_dynamic_cast<const DOFManager>(fieldBlockManagers[i]);
997 for(std::size_t e=0;e<eblocks.size();e++) {
998 const std::vector<int> & fieldIds = dofManager->getBlockFieldNumbers(eblocks[e]);
1001 for(std::size_t f=0;f<fieldIds.size();f++) {
1003 std::string fieldName = dofManager->getFieldString(fieldIds[f]);
1004 Teuchos::RCP<const panzer::FieldPattern> fieldPattern
1005 = dofManager->getFieldPattern(eblocks[e],fieldName);
1008 this->
addField(eblocks[e],fieldName,fieldPattern);
1025 std::vector<std::string> elementBlocks;
1027 for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
1059 std::vector<std::string> elementBlocks;
1061 for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
1083 std::vector<std::pair<FieldType,RCP<const FieldPattern>>> patVector;
1084 std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::iterator f2p_itr;
1086 patVector.push_back(std::make_pair(
FieldType::CG,f2p_itr->second));
1093 aggFieldPattern->buildPattern(patVector);
1096 connMngr_->buildConnectivity(*aggFieldPattern);
1104 os <<
"BlockedDOFManager Field Information: " << std::endl;
1109 os <<
"*************************************************\n";
1110 os <<
"Field Block Index = " << fbm << std::endl;
1114 os <<
" Field String to Field Id (blocked/sub):\n";
1115 for(std::size_t i=0;i<
fieldOrder_[fbm].size();i++) {
1118 os <<
" \"" << fieldString <<
"\" is field ID " << fieldNum
1126 os <<
"Fields not yet registered! Unknowns not built (call registerFields or buildGlobalUnknowns)" << std::endl;
1130Teuchos::RCP<const FieldPattern>
1133 std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator itr;
1137 return Teuchos::null;
1151 const std::set<std::string> & fields)
const
1153 std::set<std::string> orderedFields;
1154 std::size_t numberInOrder = 0;
1156 for(std::size_t b=0;b<fieldOrder_ut.size();b++) {
1157 numberInOrder += fieldOrder_ut[b].size();
1158 orderedFields.insert(fieldOrder_ut[b].begin(),
1159 fieldOrder_ut[b].end());
1162 bool correctCount = (numberInOrder==fields.size());
1163 bool sameFields = (orderedFields==fields);
1165 return correctCount && sameFields;
PHX::MDField< ScalarT, panzer::Cell, panzer::IP > result
A field that will be used to build up the result of the integral we're performing.
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we'll contribute, or in which we'll store, the result of computing this integral.
void setFieldOrder(const std::vector< std::vector< std::string > > &fieldOrder)
virtual void getGhostedIndicesAsInt(std::vector< int > &indices) const
Get the set of indices ghosted for this processor.
Teuchos::RCP< ConnManager > connMngr_
int getFieldBlock(int fieldNum) const
void addFieldsToFieldBlockManager(const std::vector< std::string > &activeFields, GlobalIndexer &fieldBlockManager) const
virtual int getNumGhosted() const
Get the number of indices ghosted for this processor.
bool validFieldOrder(const std::vector< std::vector< std::string > > &fieldOrder_ut, const std::set< std::string > &fields) const
virtual void getOwnedIndicesAsInt(std::vector< int > &indices) const
Get the set of indices owned by this processor.
virtual void getGhostedIndices(std::vector< GlobalOrdinal > &indices) const
Get the set of indices ghosted for this processor.
void registerFields(bool buildSubUGIs)
virtual const std::vector< int > & getBlockFieldNumbers(const std::string &block) const
Teuchos::RCP< Teuchos::MpiComm< int > > communicator_
std::map< std::string, TupleToVectorPairMap > gidFieldOffsets_closure_
std::map< int, std::string > fieldNumToStr_
field number ==> field string
void getElementGIDsAsInt(panzer::LocalOrdinal localElmtId, std::vector< int > &gids, const std::string &blockIdHint="") const
Get the global IDs for a particular element. This function overwrites the gids variable.
int getNumFieldBlocks() const
std::map< std::pair< std::string, int >, int > blockGIDOffset_
(element block,field block) ==> gid offset
void getElementGIDsPair(panzer::LocalOrdinal localElmtId, std::vector< std::pair< int, GlobalOrdinal > > &gids, const std::string &blockIdHint="") const
Get the global IDs for a particular element. This function overwrites the gids variable.
virtual int getNumOwnedAndGhosted() const
Get the number of owned and ghosted indices for this processor.
virtual void buildGlobalUnknowns()
int getBlockGIDOffset(const std::string &elementBlock, int fieldBlock) const
void getElementGIDs(panzer::LocalOrdinal localElmtId, std::vector< GlobalOrdinal > &gids, const std::string &blockIdHint="") const
Get the global IDs for a particular element. This function overwrites the gids variable.
virtual void getElementOrientation(panzer::LocalOrdinal localElmtId, std::vector< double > &gidsOrientation) const
Get a vector containg the orientation of the GIDs relative to the neighbors.
virtual bool fieldInBlock(const std::string &field, const std::string &block) const
void addField(const std::string &str, const Teuchos::RCP< const FieldPattern > &pattern)
Add a field to the DOF manager.
void setConnManager(const Teuchos::RCP< ConnManager > &connMngr, MPI_Comm mpiComm)
Set the connection manager and MPI_Comm objects.
bool requireOrientations_
int getNumFields() const
How many fields are handled by this manager.
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.
std::vector< std::vector< std::string > > fieldOrder_
virtual void getOwnedAndGhostedIndicesAsInt(std::vector< int > &indices) const
Get the set of owned and ghosted indices for this processor.
std::map< std::pair< std::string, std::string >, Teuchos::RCP< const FieldPattern > > fieldStringToPattern_
(block ID x field string) ==> pattern
const std::string & getFieldString(int num) const
Get the string name associated with a field number.
Teuchos::RCP< const FieldPattern > geomPattern_
virtual void getElementBlockIds(std::vector< std::string > &elementBlockIds) const
virtual void getOwnedAndGhostedIndices(std::vector< GlobalOrdinal > &indices) const
Get the set of owned and ghosted indices for this processor.
virtual void getOwnedIndices(std::vector< GlobalOrdinal > &indices) const
Get the set of indices owned by this processor.
std::map< Teuchos::Tuple< int, 3 >, std::pair< std::vector< int >, std::vector< int > >, LessThan > TupleToVectorPairMap
void setOrientationsRequired(bool ro)
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...
int getFieldNum(const std::string &str) const
Get the number used for access to this field.
Teuchos::RCP< ConnManager > resetIndices()
Reset the indicies for this DOF manager.
bool getOrientationsRequired() const
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 int getNumOwned() const
Get the number of indices owned by this processor.
std::vector< Teuchos::RCP< GlobalIndexer > > fieldBlockManagers_
Teuchos::RCP< GlobalIndexer > buildNewIndexer(const Teuchos::RCP< ConnManager > &connManager, MPI_Comm mpiComm) const
void getFieldOrder(std::vector< std::vector< std::string > > &fieldOrder) const
virtual void ownedIndices(const std::vector< GlobalOrdinal > &indices, std::vector< bool > &isOwned) const
std::map< int, int > fieldNumToFieldBlk_
field number ==> field block
std::map< std::string, int > fieldStrToNum_
field string ==> field number
Teuchos::RCP< const ConnManager > getConnManager() const
bool fieldsRegistered() const
std::map< std::string, std::map< int, std::vector< int > > > gidFieldOffsets_
std::map< std::string, std::set< std::string > > blockIdToFieldStrings_
block ID ==> field strings
std::map< std::string, std::vector< int > > blockIdToFieldNumbers_
block ID ==> field numbers
virtual int getElementBlockGIDCount(const std::string &blockId) const
How any GIDs are associate with a particular element block.
void printFieldInformation(std::ostream &os) const
void setFieldOrder(const std::vector< std::string > &fieldOrder)
int addField(const std::string &str, const Teuchos::RCP< const FieldPattern > &pattern, const panzer::FieldType &type=panzer::FieldType::CG)
Add a field to the DOF manager.