11#ifndef PANZER_BLOCKED_DOF_MANAGER_IMPL_HPP
12#define PANZER_BLOCKED_DOF_MANAGER_IMPL_HPP
20#include "Teuchos_DefaultMpiComm.hpp"
31 : fieldsRegistered_(false), maxSubFieldNum_(-1), requireOrientations_(false), useDOFManagerFEI_(true), useTieBreak_(false)
35 : fieldsRegistered_(false), maxSubFieldNum_(-1), requireOrientations_(false), useDOFManagerFEI_(true), useTieBreak_(false)
45 std::map<std::string,int>::const_iterator itr =
fieldStrToNum_.find(str);
50 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
51 "BlockedDOFManager::getFieldNum No field with the name \"" + str +
"\" has been added");
60 std::map<int,std::string>::const_iterator itr =
fieldNumToStr_.find(number);
64 std::stringstream ss; ss << number;
66 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
67 "BlockedDOFManager::getFieldString No field with number \"" + ss.str() +
"\" has been added");
77 std::map<std::string,std::set<std::string> >::const_iterator fieldsItr =
blockIdToFieldStrings_.find(block);
79 "BlockedDOFManager::fieldInBlock could not find the element block \""+block+
"\"");
82 const std::set<std::string> & fields = fieldsItr->second;
83 std::set<std::string>::const_iterator itr = fields.find(
field);
84 return itr!=fields.end();
94 return fieldsItr->second;
97 static std::vector<int> empty;
115 std::vector<panzer::GlobalOrdinal> fieldBlockOwned;
119 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getElementGIDs() not supported for BlockedDOFManager!")
139 std::vector<panzer::GlobalOrdinal> fieldBlockOwned;
143 for(std::size_t i=0;i<fieldBlockOwned.size();i++)
144 gids.push_back(std::make_pair(fbm,fieldBlockOwned[i]));
158 gidsOrientation.resize(0);
162 std::vector<double> blkOrientation;
166 for(std::size_t i=0;i<blkOrientation.size();i++)
167 gidsOrientation.push_back(blkOrientation[i]);
173 typedef std::map<std::string,std::map<int,std::vector<int> > > FieldOffsetsMap;
177 std::map<int,std::vector<int> > & fieldToVectorMap = blockItr->second;
178 std::map<int,std::vector<int> >::const_iterator itr = fieldToVectorMap.find(fieldNum);
181 if(itr!=fieldToVectorMap.end())
185 std::vector<std::string> elementBlocks;
187 TEUCHOS_TEST_FOR_EXCEPTION(std::find(elementBlocks.begin(),elementBlocks.end(),blockId)==elementBlocks.end(),std::logic_error,
188 "BlockedDOFManager::getGIDFieldOffsets: Block ID \""+blockId+
"\" does not exist");
195 std::map<int,std::vector<int> > & fieldToVectorMap = blockItr->second;
205 const std::vector<int> & subGIDOffsets
206 = dofManager->getGIDFieldOffsets(blockId,dofManager->getFieldNum(
getFieldString(fieldNum)));
210 std::vector<int> & finalFieldOffsets = fieldToVectorMap[fieldNum];
211 finalFieldOffsets.resize(subGIDOffsets.size());
212 for(std::size_t i=0;i<finalFieldOffsets.size();i++)
213 finalFieldOffsets[i] = gidOffset+subGIDOffsets[i];
215 return finalFieldOffsets;
218bool BlockedDOFManager::LessThan
219::operator()(
const Teuchos::Tuple<int,3> & a,
const Teuchos::Tuple<int,3> & b)
const
221 if(a[0] < b[0])
return true;
222 if(a[0] > b[0])
return false;
225 if(a[1] < b[1])
return true;
226 if(a[1] > b[1])
return false;
229 if(a[2] < b[2])
return true;
230 if(a[2] > b[2])
return false;
236const std::pair<std::vector<int>,std::vector<int> > &
242 typename TupleToVectorPairMap::const_iterator itr =
243 fieldToTupleMap.find(Teuchos::tuple(fieldNum,subcellDim,subcellId));
246 if(itr!=fieldToTupleMap.end())
250 std::vector<std::string> elementBlocks;
252 TEUCHOS_TEST_FOR_EXCEPTION(std::find(elementBlocks.begin(),elementBlocks.end(),blockId)==elementBlocks.end(),std::logic_error,
253 "BlockedDOFManager::getGIDFieldOffsets: Block ID \""+blockId+
"\" does not exist");
270 const std::pair<std::vector<int>,std::vector<int> > & subGIDOffsets_closure
271 = dofManager->getGIDFieldOffsets_closure(blockId,dofManager->getFieldNum(
getFieldString(fieldNum)),subcellDim,subcellId);
275 std::pair<std::vector<int>,std::vector<int> > & finalFieldOffsets = fieldToTupleMap[Teuchos::tuple(fieldNum,subcellDim,subcellId)];
276 finalFieldOffsets.first.resize(subGIDOffsets_closure.first.size());
277 finalFieldOffsets.second = subGIDOffsets_closure.second;
278 for(std::size_t i=0;i<finalFieldOffsets.first.size();i++)
279 finalFieldOffsets.first[i] = gidOffset+subGIDOffsets_closure.first[i];
281 return finalFieldOffsets;
291 using std::make_pair;
296 vector<panzer::GlobalOrdinal> fieldBlockOwned;
298 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getOwnedIndices() not supported for BlockedDOFManager!")
311 using std::make_pair;
316 vector<panzer::GlobalOrdinal> fieldBlockGhosted;
318 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getGhostedIndices() not supported for BlockedDOFManager!")
331 using std::make_pair;
336 vector<panzer::GlobalOrdinal> fieldBlockOwnedAndGhosted;
338 fieldBlockOwnedAndGhosted);
339 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getOwnedAndGhostedIndices() not supported for BlockedDOFManager!")
360 std::vector<int> fieldBlockOwned;
364 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getElementGIDsAsInt() not supported for BlockedDOFManager!")
373 using std::make_pair;
378 vector<int> fieldBlockOwned;
380 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getOwnedIndicesAsInt() not supported for BlockedDOFManager!")
389 using std::make_pair;
394 vector<int> fieldBlockGhosted;
396 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getGhostedIndicesAsInt() not supported for BlockedDOFManager!")
405 using std::make_pair;
410 vector<int> fieldBlockOwnedAndGhosted;
412 fieldBlockOwnedAndGhosted);
413 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"getOwnedAndGhostedIndicesAsInt() not supported for BlockedDOFManager!")
466 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"ownedIndices() not supported for BlockedDOFManager!")
472 std::vector<std::vector<bool>::const_iterator> blockItrs;
477 blockItrs.push_back(blockIsOwned[fbm].begin());
482 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"ownedIndices() not supported for BlockedDOFManager!")
542 Teuchos::RCP<ConnManager> connMngr =
connMngr_;
552 const Teuchos::RCP<const FieldPattern> & pattern)
554 std::vector<std::string> elementBlockIds;
555 connMngr_->getElementBlockIds(elementBlockIds);
558 for(std::size_t i=0;i<elementBlockIds.size();i++)
559 addField(elementBlockIds[i],str,pattern);
563 const Teuchos::RCP<const FieldPattern> & pattern)
566 "BlockedDOFManager::addField: addField cannot be called after registerFields or"
567 "buildGlobalUnknowns has been called");
587 std::set<std::string> fields;
588 for(std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator
590 std::string fieldName = fieldItr->first.second;
591 fields.insert(fieldName);
596 std::set<std::string>::const_iterator itr;
597 for(itr=fields.begin();itr!=fields.end();itr++) {
598 std::vector<std::string> block;
599 block.push_back(*itr);
608 std::stringstream ss;
610 ss <<
"BlockedDOFManager::registerFields - Field order is invalid!\n";
612 ss <<
" fields = [ ";
613 for(std::set<std::string>::const_iterator itr=fields.begin();
614 itr!=fields.end();++itr)
615 ss <<
"\"" << *itr <<
"\" ";
618 ss <<
" fieldOrder = [ ";
619 for(std::vector<std::vector<std::string> >::const_iterator bitr=
fieldOrder_.begin();
622 for(std::vector<std::string>::const_iterator itr=bitr->begin();
623 itr!=bitr->end();++itr) {
624 ss <<
"\"" << *itr <<
"\" ";
630 TEUCHOS_TEST_FOR_EXCEPTION(!validOrder,std::logic_error,ss.str());
636 for(std::size_t fldBlk=0;fldBlk<
fieldOrder_.size();fldBlk++) {
655 std::map<std::string,int> tempStrToNum;
657 Teuchos::RCP<const panzer::GlobalIndexer> dofManager =
659 const std::vector<std::string> & activeFields =
fieldOrder_[fldBlk];
662 for(std::size_t f=0;f<activeFields.size();f++) {
663 fieldNum = dofManager->getFieldNum(activeFields[f]);
664 tempStrToNum[activeFields[f]] = fieldNum;
674 const std::vector<std::string> & activeFields =
fieldOrder_[fldBlk];
676 for(std::size_t f=0;f<activeFields.size();f++) {
678 int fieldNum = tempStrToNum[activeFields[f]]+numOffset;
697 const std::set<std::string> & fields = itr->second;
700 for(std::set<std::string>::const_iterator fldItr=fields.begin();
701 fldItr!=fields.end();++fldItr) {
710Teuchos::RCP<GlobalIndexer>
715 dofManager->setConnManager(connManager,mpiComm);
722 using Teuchos::rcp_dynamic_cast;
726 RCP<DOFManager> dofManager = rcp_dynamic_cast<DOFManager>(indexer);
728 if(dofManager!=Teuchos::null) {
729 dofManager->setOrientationsRequired(required);
735 TEUCHOS_ASSERT(
false);
739buildGlobalUnknowns(
const Teuchos::RCP<GlobalIndexer> & indexer,
const Teuchos::RCP<const FieldPattern> & geomPattern)
const
742 using Teuchos::rcp_dynamic_cast;
746 RCP<DOFManager> dofManager = rcp_dynamic_cast<DOFManager>(indexer);
748 if(dofManager!=Teuchos::null) {
749 dofManager->buildGlobalUnknowns(geomPattern);
755 TEUCHOS_ASSERT(
false);
759 std::ostream & os)
const
762 using Teuchos::rcp_dynamic_cast;
766 RCP<DOFManager> dofManager = rcp_dynamic_cast<DOFManager>(indexer);
768 if(dofManager!=Teuchos::null) {
769 dofManager->printFieldInformation(os);
775 TEUCHOS_ASSERT(
false);
779 const std::string & elementBlock)
const
782 using Teuchos::rcp_dynamic_cast;
784 TEUCHOS_ASSERT(indexer!=Teuchos::null);
786 return indexer->getElementBlockGIDCount(elementBlock);
790 const std::size_t & elementBlock)
const
793 using Teuchos::rcp_dynamic_cast;
795 TEUCHOS_ASSERT(indexer!=Teuchos::null);
797 return indexer->getElementBlockGIDCount(elementBlock);
822 using Teuchos::ptrFromRef;
823 using Teuchos::ptr_dynamic_cast;
825 Ptr<GlobalIndexer> ugi_ptr = ptrFromRef(fieldBlockManager);
829 Ptr<DOFManager> dofManager_ptr = ptr_dynamic_cast<DOFManager>(ugi_ptr);
831 if(dofManager_ptr!=Teuchos::null) {
838 TEUCHOS_ASSERT(
false);
845 std::vector<std::size_t> correctnessCheck(activeFields.size(),0);
846 std::vector<std::string> elementBlocks;
850 for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
851 std::string elementBlock = elementBlocks[eb];
854 for(std::size_t f=0;f<activeFields.size();f++) {
855 std::string fieldName = activeFields[f];
856 Teuchos::RCP<const FieldPattern> fp = this->
getFieldPattern(elementBlock,fieldName);
858 if(fp!=Teuchos::null) {
859 fieldBlockManager.
addField(elementBlock,fieldName,fp);
860 correctnessCheck[f] = 1;
866 std::size_t correctFlag = std::accumulate(correctnessCheck.begin(),correctnessCheck.end(),0);
867 TEUCHOS_TEST_FOR_EXCEPTION(correctFlag!=activeFields.size(),std::logic_error,
868 "BlockedDOFManager::addFieldsToFieldBlockManager detected inconsistincies in the active fields.");
893 std::set<std::string> fields;
894 std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator itr;
896 fields.insert(itr->first.second);
898 return fields.size();
909 using Teuchos::rcp_dynamic_cast;
911 RCP<const FieldPattern> refGeomPattern;
920 TEUCHOS_ASSERT(fieldBlockManagers.size()>0);
923 RCP<const DOFManager> refDofManager = rcp_dynamic_cast<const DOFManager>(fieldBlockManagers[0]);
925 TEUCHOS_TEST_FOR_EXCEPTION(refDofManager==Teuchos::null,std::runtime_error,
926 "panzer::BlockedDOFManager::buildGlobalUnknowns: UGI at index " << 0 <<
927 " is not of DOFManager type!");
929 RCP<const ConnManager> connManager = refDofManager->getConnManager();
930 TEUCHOS_TEST_FOR_EXCEPTION(refConnManager!=connManager,std::runtime_error,
931 "panzer::BlockedDOFManager::buildGlobalUnknowns: connection manager for UGI " << 0 <<
932 " does not match the reference connection manager");
934 refGeomPattern = refDofManager->getGeometricFieldPattern();
936 for(std::size_t i=1;i<fieldBlockManagers.size();i++) {
937 RCP<const DOFManager> dofManager = rcp_dynamic_cast<const DOFManager>(fieldBlockManagers[i]);
939 TEUCHOS_TEST_FOR_EXCEPTION(refDofManager==Teuchos::null,std::runtime_error,
940 "panzer::BlockedDOFManager::buildGlobalUnknowns: UGI at index " << i <<
941 " is not of DOFManager type!");
943 RCP<const FieldPattern> geomPattern = dofManager->getGeometricFieldPattern();
944 RCP<const ConnManager> testConnManager = dofManager->getConnManager();
946 TEUCHOS_TEST_FOR_EXCEPTION(!refGeomPattern->equals(*geomPattern),std::runtime_error,
947 "panzer::BlockedDOFManager::buildGlobalUnknowns: geometric pattern for UGI " << i <<
948 " does not match the reference pattern (from UGI 0)");
949 TEUCHOS_TEST_FOR_EXCEPTION(refConnManager!=testConnManager,std::runtime_error,
950 "panzer::BlockedDOFManager::buildGlobalUnknowns: connection manager for UGI " << i <<
951 " does not match the reference connection manager (from UGI 0)");
958 std::vector<std::string> eblocks;
961 for(std::size_t i=0;i<fieldBlockManagers.size();i++) {
962 RCP<const DOFManager> dofManager
963 = rcp_dynamic_cast<const DOFManager>(fieldBlockManagers[i]);
965 for(std::size_t e=0;e<eblocks.size();e++) {
966 const std::vector<int> & fieldIds = dofManager->getBlockFieldNumbers(eblocks[e]);
969 for(std::size_t f=0;f<fieldIds.size();f++) {
971 std::string fieldName = dofManager->getFieldString(fieldIds[f]);
972 Teuchos::RCP<const panzer::FieldPattern> fieldPattern
973 = dofManager->getFieldPattern(eblocks[e],fieldName);
976 this->
addField(eblocks[e],fieldName,fieldPattern);
993 std::vector<std::string> elementBlocks;
995 for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
1027 std::vector<std::string> elementBlocks;
1029 for(std::size_t eb=0;eb<elementBlocks.size();eb++) {
1051 std::vector<std::pair<FieldType,RCP<const FieldPattern>>> patVector;
1052 std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::iterator f2p_itr;
1054 patVector.push_back(std::make_pair(
FieldType::CG,f2p_itr->second));
1061 aggFieldPattern->buildPattern(patVector);
1064 connMngr_->buildConnectivity(*aggFieldPattern);
1072 os <<
"BlockedDOFManager Field Information: " << std::endl;
1077 os <<
"*************************************************\n";
1078 os <<
"Field Block Index = " << fbm << std::endl;
1082 os <<
" Field String to Field Id (blocked/sub):\n";
1083 for(std::size_t i=0;i<
fieldOrder_[fbm].size();i++) {
1086 os <<
" \"" << fieldString <<
"\" is field ID " << fieldNum
1094 os <<
"Fields not yet registered! Unknowns not built (call registerFields or buildGlobalUnknowns)" << std::endl;
1098Teuchos::RCP<const FieldPattern>
1101 std::map<std::pair<std::string,std::string>,Teuchos::RCP<const FieldPattern> >::const_iterator itr;
1105 return Teuchos::null;
1119 const std::set<std::string> & fields)
const
1121 std::set<std::string> orderedFields;
1122 std::size_t numberInOrder = 0;
1124 for(std::size_t b=0;b<fieldOrder_ut.size();b++) {
1125 numberInOrder += fieldOrder_ut[b].size();
1126 orderedFields.insert(fieldOrder_ut[b].begin(),
1127 fieldOrder_ut[b].end());
1130 bool correctCount = (numberInOrder==fields.size());
1131 bool sameFields = (orderedFields==fields);
1133 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.