43 #ifndef PANZER_DOF_MANAGER2_IMPL_HPP 44 #define PANZER_DOF_MANAGER2_IMPL_HPP 50 #include "PanzerDofMgr_config.hpp" 63 #include "Teuchos_ArrayView.hpp" 65 #include "Tpetra_DefaultPlatform.hpp" 66 #include "Tpetra_Map.hpp" 67 #include "Tpetra_Export.hpp" 68 #include "Tpetra_Vector.hpp" 69 #include "Tpetra_MultiVector.hpp" 71 #include <unordered_set> 73 #define PANZER_DOFMGR_FUNC_TIME_MONITOR(a) \ 74 PANZER_FUNC_TIME_MONITOR(a) 76 #ifdef PHX_KOKKOS_DEVICE_TYPE_CUDA 77 #define PANZER_DOFMGR_REQUIRE_CUDA 91 template <
typename LocalOrdinal,
typename GlobalOrdinal>
92 class HashTieBreak :
public Tpetra::Details::TieBreak<LocalOrdinal,GlobalOrdinal> {
96 HashTieBreak(
const unsigned int seed = (2654435761U))
99 virtual std::size_t selectedIndex(GlobalOrdinal GID,
100 const std::vector<std::pair<int,LocalOrdinal> > & pid_and_lid)
const 103 int intkey = (int) ((GID & 0x000000007fffffffLL) +
104 ((GID & 0x7fffffff80000000LL) >> 31));
105 return std::size_t((
seed_ ^ intkey) % pid_and_lid.size());
117 template <
typename LO,
typename GO>
119 : numFields_(0),buildConnectivityRun_(false),requireOrientations_(false), useTieBreak_(false), useNeighbors_(false)
122 template <
typename LO,
typename GO>
124 : numFields_(0),buildConnectivityRun_(false),requireOrientations_(false), useTieBreak_(false), useNeighbors_(false)
129 template <
typename LO,
typename GO>
133 "DOFManager::setConnManager: setConnManager cannot be called after " 134 "buildGlobalUnknowns has been called");
135 connMngr_ = connMngr;
137 connMngr_->getElementBlockIds(blockOrder_);
138 for (
size_t i = 0; i < blockOrder_.size(); ++i) {
139 blockNameToID_.insert(std::map<std::string,int>::value_type(blockOrder_[i],i));
142 blockToAssociatedFP_.resize(blockOrder_.size());
143 communicator_ =
Teuchos::rcp(
new Teuchos::MpiComm<int>(Teuchos::opaqueWrapper(mpiComm)));
149 template <
typename LO,
typename GO>
153 "DOFManager::addField: addField cannot be called after " 154 "buildGlobalUnknowns has been called");
156 fieldPatterns_.push_back(pattern);
157 fieldNameToAID_.insert(std::map<std::string,int>::value_type(str, numFields_));
160 fieldStringOrder_.push_back(str);
161 fieldAIDOrder_.push_back(numFields_);
163 for(std::size_t i=0;i<blockOrder_.size();i++) {
164 blockToAssociatedFP_[i].push_back(numFields_);
171 template <
typename LO,
typename GO>
175 "DOFManager::addField: addField cannot be called after " 176 "buildGlobalUnknowns has been called");
178 "DOFManager::addField: you must add a ConnManager before" 179 "you can associate a FP with a given block.")
182 while(!found && blocknum<blockOrder_.size()){
183 if(blockOrder_[blocknum]==blockID){
194 std::map<std::string,int>::const_iterator fpIter = fieldNameToAID_.find(str);
195 if(fpIter!=fieldNameToAID_.end())
199 fieldPatterns_.push_back(pattern);
200 fieldNameToAID_.insert(std::map<std::string,int>::value_type(str, numFields_));
202 fieldStringOrder_.push_back(str);
203 fieldAIDOrder_.push_back(numFields_);
206 blockToAssociatedFP_[blocknum].push_back(numFields_);
211 blockToAssociatedFP_[blocknum].push_back(fpIter->second);
219 template <
typename LO,
typename GO>
222 std::map<std::string,int>::const_iterator fitr = fieldNameToAID_.find(name);
223 if(fitr==fieldNameToAID_.end())
224 return Teuchos::null;
226 if(fitr->second<
int(fieldPatterns_.size()))
227 return fieldPatterns_[fitr->second];
229 return Teuchos::null;
233 template <
typename LO,
typename GO>
236 std::map<std::string,int>::const_iterator fitr = fieldNameToAID_.find(fieldName);
237 if(fitr==fieldNameToAID_.end())
238 return Teuchos::null;
242 while(!found && blocknum<blockOrder_.size()){
243 if(blockOrder_[blocknum]==blockId){
251 return Teuchos::null;
253 std::vector<int>::const_iterator itr = std::find(blockToAssociatedFP_[blocknum].begin(),
254 blockToAssociatedFP_[blocknum].end(),fitr->second);
255 if(itr!=blockToAssociatedFP_[blocknum].end()) {
256 if(fitr->second<
int(fieldPatterns_.size()))
257 return fieldPatterns_[fitr->second];
260 return Teuchos::null;
263 template <
typename LO,
typename GO>
269 template <
typename LO,
typename GO>
273 indices.resize(owned_.size() + ghosted_.size());
274 for (
size_t i = 0; i < owned_.size(); ++i)
275 indices[i] = owned_[i];
276 for (
size_t i = 0; i < ghosted_.size(); ++i)
277 indices[owned_.size() + i] = ghosted_[i];
281 template <
typename LO,
typename GO>
287 template <
typename LO,
typename GO>
290 TEUCHOS_TEST_FOR_EXCEPTION(!buildConnectivityRun_,std::logic_error,
"DOFManager::getGIDFieldOffsets: cannot be called before " 291 "buildGlobalUnknowns has been called");
292 std::map<std::string,int>::const_iterator bitr = blockNameToID_.find(blockID);
293 if(bitr==blockNameToID_.end())
295 int bid=bitr->second;
296 if(fa_fps_[bid]!=Teuchos::null)
297 return fa_fps_[bid]->localOffsets(fieldNum);
299 static const std::vector<int> empty;
303 template <
typename LO,
typename GO>
306 gids = elementGIDs_[localElementID];
309 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
315 if(requireOrientations_){
321 connMngr_->buildConnectivity(*aggFieldPattern);
324 buildGlobalUnknowns(aggFieldPattern);
328 template <
typename LO,
typename GO>
333 typedef Tpetra::Map<LO, GO, Node> Map;
335 typedef Tpetra::Import<LO,GO,Node> Import;
338 typedef Tpetra::MultiVector<GO,LO,GO,Node> MultiVector;
347 "DOFManager::buildGlobalUnknowns: buildGlobalUnknowns cannot be called again " 348 "after buildGlobalUnknowns has been called");
352 if(getOrientationsRequired()) {
356 "DOFManager::buildGlobalUnknowns requires a geometric pattern including " 357 "the nodes when orientations are needed!");
363 ga_fp_ = geomPattern;
374 RCP<MultiVector> overlap_mv = Tpetra::createMultiVector<GO>(overlap_map,(size_t)numFields_);
377 auto non_overlap_pair = buildGlobalUnknowns_GUN(*tagged_overlap_mv,*overlap_mv);
388 fillGIDsFromOverlappedMV(ownedAccess,elementGIDs_,*overlap_map,*overlap_mv);
396 buildOverlapMapFromElements(neighborAccess);
399 Import imp_neighbor(non_overlap_map,overlap_map_neighbor);
402 Tpetra::createMultiVector<GO>(overlap_map_neighbor, (size_t)numFields_);
405 overlap_mv_neighbor->doImport(*non_overlap_mv, imp_neighbor,
408 fillGIDsFromOverlappedMV(neighborAccess, elementGIDs_,
409 *overlap_map_neighbor, *overlap_mv_neighbor);
418 panzer::Ordinal64
offset = 0xFFFFFFFFLL;
420 for (
size_t b = 0; b < blockOrder_.size(); ++b) {
421 const std::vector<LO> & myElements = connMngr_->getElementBlock(blockOrder_[b]);
422 for (std::size_t l = 0; l < myElements.size(); ++l) {
423 std::vector<GO> & localGIDs = elementGIDs_[myElements[l]];
424 for(std::size_t c=0;c<localGIDs.size();c++)
430 for (
int j = 0; j < nvals.
size(); ++j)
439 typedef std::unordered_set<GO> HashTable;
440 HashTable isOwned, remainingOwned;
446 for (
int j = 0; j < nvals.
size(); ++j) {
447 if (nvals[j] != -1) {
449 isOwned.insert(nvals[j]+
offset);
456 remainingOwned = isOwned;
459 for (
size_t b = 0; b < blockOrder_.size(); ++b) {
461 if(fa_fps_[b]==Teuchos::null)
464 const std::vector<LO> & myElements = connMngr_->getElementBlock(blockOrder_[b]);
466 for (
size_t l = 0; l < myElements.size(); ++l) {
467 const std::vector<GO> & localOrdering = elementGIDs_[myElements[l]];
470 for(std::size_t i=0;i<localOrdering.size();i++) {
472 if(isOwned.find(localOrdering[i])==isOwned.end())
476 std::pair<typename HashTable::iterator,bool> insertResult = hashTable.insert(localOrdering[i]);
477 if(insertResult.second) {
478 owned_.push_back(localOrdering[i]);
479 remainingOwned.erase(localOrdering[i]);
488 for(
typename HashTable::const_iterator itr=remainingOwned.begin();itr!=remainingOwned.end();itr++)
489 owned_.push_back(*itr);
491 if(owned_.size()!=isOwned.size()) {
492 out <<
"I'm about to hang because of unknown numbering failure ... sorry! (line = " << __LINE__ <<
")" << std::endl;
494 "DOFManager::buildGlobalUnkonwns: Failure because not all owned unknowns have been accounted for.");
506 "buildGlobalUnknowns::build_ghosted_array");
509 typedef std::unordered_set<GO> HashTable;
511 for (std::size_t i = 0; i < owned_.size(); i++)
512 hashTable.insert(owned_[i]);
517 std::vector<ElementBlockAccess> blockAccessVec;
521 for (std::size_t a = 0; a < blockAccessVec.size(); ++a)
525 for (
size_t b = 0; b < blockOrder_.size(); ++b)
527 if (fa_fps_[b] == Teuchos::null)
529 const std::vector<LO>& myElements =
531 for (
size_t l = 0; l < myElements.size(); ++l)
533 const std::vector<GO>& localOrdering = elementGIDs_[myElements[l]];
536 for (std::size_t i = 0; i < localOrdering.size(); ++i)
538 std::pair<typename HashTable::iterator, bool> insertResult =
539 hashTable.insert(localOrdering[i]);
543 if(insertResult.second)
544 ghosted_.push_back(localOrdering[i]);
551 buildConnectivityRun_ =
true;
554 if(requireOrientations_) {
556 buildUnknownsOrientation();
562 this->buildLocalIdsFromOwnedAndGhostedElements();
566 this->buildLocalIds();
570 template <
typename LO,
typename GO>
571 std::pair<Teuchos::RCP<Tpetra::MultiVector<GO,LO,GO,panzer::TpetraNodeType> >,
574 Tpetra::MultiVector<GO,LO,GO,panzer::TpetraNodeType> & overlap_mv)
const 578 typedef Tpetra::Map<LO, GO, Node> Map;
580 typedef Tpetra::Export<LO,GO,Node> Export;
581 typedef Tpetra::Import<LO,GO,Node> Import;
584 typedef Tpetra::MultiVector<GO,LO,GO,Node> MultiVector;
600 non_overlap_map = Tpetra::createOneToOne<LO,GO,Node>(overlap_map);
605 HashTieBreak<LO,GO> tie_break;
606 non_overlap_map = Tpetra::createOneToOne<LO,GO,Node>(overlap_map,tie_break);
618 tagged_non_overlap_mv = Tpetra::createMultiVector<GO>(non_overlap_map,(size_t)numFields_);
631 exp =
rcp(
new Export(overlap_map,non_overlap_map));
633 #ifdef PANZER_DOFMGR_REQUIRE_CUDA 637 imp =
rcp(
new Import(non_overlap_map,overlap_map));
642 tagged_non_overlap_mv->doExport(tagged_overlap_mv,*exp,Tpetra::ABSMAX);
646 non_overlap_mv =
rcp(
new MultiVector(*tagged_non_overlap_mv,
Teuchos::Copy));
659 typedef typename Tpetra::MultiVector<GO,Node> MV;
660 typedef typename MV::dual_view_type::t_dev KV;
661 typedef typename MV::dual_view_type::t_dev::memory_space DMS;
662 KV
values = non_overlap_mv->template getLocalView<DMS>();
663 auto mv_size =
values.dimension_0();
678 Teuchos::scan<int, GO> (*getComm(), Teuchos::REDUCE_SUM,
static_cast<size_t> (localsum), Teuchos::outArg (scanResult));
679 myOffset = scanResult - localsum;
697 for(
size_t i=0; i<non_overlap_mv->getLocalLength(); ++i){
698 for(
int j=0; j<numFields_; ++j){
699 if(editnonoverlap[j][i]!=0){
701 int ndof = Teuchos::as<int>(editnonoverlap[j][i]);
702 editnonoverlap[j][i]=myOffset+which_id;
706 editnonoverlap[j][i]=-1;
724 #ifdef PANZER_DOFMGR_REQUIRE_CUDA 725 overlap_mv.doImport(*non_overlap_mv,*imp,Tpetra::REPLACE);
728 overlap_mv.doImport(*non_overlap_mv,*exp,Tpetra::REPLACE);
735 return std::make_pair(non_overlap_mv,tagged_non_overlap_mv);
738 template <
typename LO,
typename GO>
744 typedef Tpetra::Map<LO, GO, Node> Map;
745 typedef Tpetra::MultiVector<GO,LO,GO,Node> MultiVector;
752 for (
size_t b = 0; b < blockOrder_.size(); ++b) {
753 std::vector<std::pair< int, RCP<const panzer::FieldPattern> > > faConstruct;
757 for (
size_t i = 0; i < fieldAIDOrder_.size(); ++i) {
758 int looking = fieldAIDOrder_[i];
761 std::vector<int>::const_iterator reu = std::find(blockToAssociatedFP_[b].begin(), blockToAssociatedFP_[b].end(), looking);
762 if(!(reu==blockToAssociatedFP_[b].end())){
763 faConstruct.push_back(std::make_pair(i, fieldPatterns_[fieldAIDOrder_[i]]));
768 if(faConstruct.size()>0) {
772 int gidsInBlock = fa_fps_[fa_fps_.size()-1]->numberIds();
773 elementBlockGIDCount_.push_back(gidsInBlock);
776 fa_fps_.push_back(Teuchos::null);
777 elementBlockGIDCount_.push_back(0);
781 RCP<const Map> overlapmap = buildOverlapMapFromElements(ownedAccess);
790 overlap_mv = Tpetra::createMultiVector<GO>(overlapmap,(size_t)numFields_);
791 overlap_mv->putScalar(0);
802 std::vector<int> working(overlap_mv->getNumVectors());
804 for (
size_t b = 0; b < blockOrder_.size(); ++b) {
806 if(fa_fps_[b]==Teuchos::null)
809 const std::vector<LO> &
numFields= fa_fps_[b]->numFieldsPerId();
810 const std::vector<LO> & fieldIds= fa_fps_[b]->fieldIds();
811 const std::vector<LO> & myElements = connMngr_->getElementBlock(blockOrder_[b]);
812 for (
size_t l = 0; l < myElements.size(); ++l) {
813 LO connSize = connMngr_->getConnectivitySize(myElements[l]);
814 const GO * elmtConn = connMngr_->getConnectivity(myElements[l]);
816 for (
int c = 0; c < connSize; ++c) {
817 size_t lid = overlapmap->getLocalElement(elmtConn[c]);
819 for(std::size_t i=0;i<working.size();i++)
822 int whichField = fieldIds[
offset];
825 working[whichField]++;
828 for(std::size_t i=0;i<working.size();i++) {
829 auto current = edittwoview[i][lid];
830 edittwoview[i][lid] = (current > working[i]) ? current : working[i];
848 template <
typename LO,
typename GO>
853 while(!found && (
size_t)ind<fieldStringOrder_.size()){
854 if(fieldStringOrder_[ind]==
string)
867 template <
typename LO,
typename GO>
870 fieldOrder.resize(fieldStringOrder_.size());
871 for (
size_t i = 0; i < fieldStringOrder_.size(); ++i)
872 fieldOrder[i]=fieldStringOrder_[i];
875 template <
typename LO,
typename GO>
878 std::map<std::string,int>::const_iterator fitr = fieldNameToAID_.find(
field);
879 if(fitr==fieldNameToAID_.end()) {
880 std::stringstream ss;
881 printFieldInformation(ss);
882 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid field name. DOF information is:\n"+ss.str());
884 std::map<std::string,int>::const_iterator bitr = blockNameToID_.find(block);
885 if(bitr==blockNameToID_.end()) {
886 std::stringstream ss;
887 printFieldInformation(ss);
888 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid block name. DOF information is:\n"+ss.str());
890 int fid=fitr->second;
891 int bid=bitr->second;
894 for (
size_t i = 0; i < blockToAssociatedFP_[bid].size(); ++i) {
895 if(blockToAssociatedFP_[bid][i]==fid){
904 template <
typename LO,
typename GO>
907 TEUCHOS_TEST_FOR_EXCEPTION(!buildConnectivityRun_,std::logic_error,
"DOFManager::getBlockFieldNumbers: BuildConnectivity must be run first.");
909 std::map<std::string,int>::const_iterator bitr = blockNameToID_.find(blockId);
910 if(bitr==blockNameToID_.end())
912 int bid=bitr->second;
915 if(fa_fps_[bid]!=Teuchos::null)
916 return fa_fps_[bid]->fieldIds();
919 static std::vector<int> empty;
923 template <
typename LO,
typename GO>
924 const std::pair<std::vector<int>,std::vector<int> > &
927 TEUCHOS_TEST_FOR_EXCEPTION(!buildConnectivityRun_,std::logic_error,
"DOFManager::getGIDFieldOffsets_closure: BuildConnectivity must be run first.");
928 std::map<std::string,int>::const_iterator bitr = blockNameToID_.find(blockId);
929 if(bitr==blockNameToID_.end())
933 if(fa_fps_[bitr->second]!=Teuchos::null)
934 return fa_fps_[bitr->second]->localOffsets_closure(fieldNum, subcellDim, subcellId);
936 static std::pair<std::vector<int>,std::vector<int> > empty;
940 template <
typename LO,
typename GO>
944 if(indices.size()!=isOwned.size())
945 isOwned.resize(indices.size(),
false);
946 typename std::vector<GO>::const_iterator endOf = owned_.end();
947 for (std::size_t i = 0; i < indices.size(); ++i) {
948 isOwned[i] = ( std::find(owned_.begin(), owned_.end(), indices[i])!=endOf );
952 template <
typename LO,
typename GO>
956 "DOFManager::setFieldOrder: setFieldOrder cannot be called after " 957 "buildGlobalUnknowns has been called");
958 if(validFieldOrder(fieldOrder)){
959 fieldStringOrder_=fieldOrder;
961 for (
size_t i = 0; i < fieldStringOrder_.size(); ++i) {
962 fieldAIDOrder_[i]=fieldNameToAID_[fieldStringOrder_[i]];
971 template <
typename LO,
typename GO>
974 if(fieldStringOrder_.size()!=proposed_fieldOrder.size())
978 for (
size_t i = 0; i < fieldStringOrder_.size(); ++i) {
980 for (
size_t j = 0; j < proposed_fieldOrder.size(); ++j) {
981 if(fieldStringOrder_[i]==proposed_fieldOrder[j])
990 template <
typename LO,
typename GO>
994 if(num>=(
int)fieldStringOrder_.size())
996 return fieldStringOrder_[num];
1004 template <
typename LO,
typename GO>
1007 orientation_.clear();
1009 std::vector<std::string> elementBlockIds;
1010 connMngr_->getElementBlockIds(elementBlockIds);
1013 std::size_t myElementCount = 0;
1014 for(std::vector<std::string>::const_iterator blockItr=elementBlockIds.begin(); blockItr!=elementBlockIds.end();++blockItr)
1015 myElementCount += connMngr_->getElementBlock(*blockItr).size();
1018 orientation_.resize(myElementCount);
1021 for(std::vector<std::string>::const_iterator blockItr=elementBlockIds.begin();
1022 blockItr!=elementBlockIds.end();++blockItr) {
1023 const std::string & blockName = *blockItr;
1026 std::map<std::string,int>::const_iterator fap = blockNameToID_.find(blockName);
1027 if(fap==blockNameToID_.end()) {
1031 int bid=fap->second;
1033 if(fa_fps_[bid]==Teuchos::null)
1040 std::vector<std::pair<int,int> > topEdgeIndices;
1044 std::vector<std::vector<int> > topFaceIndices;
1045 if(ga_fp_->getDimension()==3)
1049 const std::vector<LO> & elmts = connMngr_->getElementBlock(blockName);
1050 for(std::size_t e=0;e<elmts.size();e++) {
1052 std::vector<char> & eOrientation = orientation_[elmts[e]];
1057 eOrientation.resize(fieldPattern.
numberIds());
1058 for(std::size_t s=0;s<eOrientation.size();s++)
1059 eOrientation[s] = 1;
1062 LO connSz = connMngr_->getConnectivitySize(elmts[e]);
1063 const GO * connPtr = connMngr_->getConnectivity(elmts[e]);
1064 const std::vector<GO> connectivity(connPtr,connPtr+connSz);
1069 if(ga_fp_->getDimension()==3)
1075 template <
typename LO,
typename GO>
1079 "DOFManager::getElementOrientations: Orientations were not constructed!");
1081 const std::vector<char> & local_o = orientation_[localElmtId];
1082 gidsOrientation.resize(local_o.size());
1083 for(std::size_t i=0;i<local_o.size();i++) {
1084 gidsOrientation[i] = double(local_o[i]);
1088 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
1093 connMngr_ = Teuchos::null;
1096 orientation_.clear();
1098 elementGIDs_.clear();
1101 elementBlockGIDCount_.clear();
1106 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
1109 std::map<std::string,int>::const_iterator bitr = blockNameToID_.find(blockId);
1110 if(bitr==blockNameToID_.end())
1112 return bitr->second;
1115 template <
typename LocalOrdinalT,
typename GlobalOrdinalT>
1118 os <<
"DOFManager Field Information: " << std::endl;
1123 for(std::size_t i=0;i<blockOrder_.size();i++) {
1124 os <<
" Element Block = " << blockOrder_[i] << std::endl;
1127 const std::vector<int> & fieldIds = blockToAssociatedFP_[i];
1128 for(std::size_t f=0;f<fieldIds.size();f++)
1129 os <<
" \"" << getFieldString(fieldIds[f]) <<
"\" is field ID " << fieldIds[f] << std::endl;
1133 template <
typename LO,
typename GO>
1145 std::set<GO> overlapset;
1146 for (
size_t i = 0; i < blockOrder_.size(); ++i) {
1147 const std::vector<LO> & myElements = access.
getElementBlock(blockOrder_[i]);
1148 for (
size_t e = 0; e < myElements.size(); ++e) {
1149 LO connSize = connMngr_->getConnectivitySize(myElements[e]);
1150 const GO * elmtConn = connMngr_->getConnectivity(myElements[e]);
1151 for (
int k = 0; k < connSize; ++k) {
1152 overlapset.insert(elmtConn[k]);
1158 for (
typename std::set<GO>::const_iterator itr = overlapset.begin(); itr!=overlapset.end(); ++itr) {
1164 return Tpetra::createNonContigMap<LO,GO>(overlapVector,getComm());
1167 template <
typename LO,
typename GO>
1171 const Tpetra::Map<LO,GO,panzer::TpetraNodeType> & overlapmap,
1172 const Tpetra::MultiVector<GO,LO,GO,panzer::TpetraNodeType> & overlap_mv)
const 1181 for (
size_t b = 0; b < blockOrder_.size(); ++b) {
1182 const std::vector<LO> & myElements = access.
getElementBlock(blockOrder_[b]);
1184 if(fa_fps_[b]==Teuchos::null) {
1186 for (
size_t l = 0; l < myElements.size(); ++l) {
1187 LO thisID=myElements[l];
1188 if(elementGIDs.size()<=(size_t)thisID)
1189 elementGIDs.resize(thisID+1);
1194 const std::vector<int> &
numFields= fa_fps_[b]->numFieldsPerId();
1195 const std::vector<int> & fieldIds= fa_fps_[b]->fieldIds();
1198 for (
size_t l = 0; l < myElements.size(); ++l) {
1199 LO connSize = connMngr_->getConnectivitySize(myElements[l]);
1200 const GO * elmtConn = connMngr_->getConnectivity(myElements[l]);
1201 std::vector<GO> localOrdering;
1203 for (
int c = 0; c < connSize; ++c) {
1204 size_t lid = overlapmap.getLocalElement(elmtConn[c]);
1205 std::vector<int> dofsPerField(numFields_,0);
1206 for (
int n = 0; n <
numFields[c]; ++n) {
1207 int whichField = fieldIds[
offset];
1211 localOrdering.push_back(twoview[whichField][lid]+dofsPerField[whichField]);
1213 dofsPerField[whichField]++;
1216 LO thisID=myElements[l];
1217 if(elementGIDs.size()<=(size_t)thisID){
1218 elementGIDs.resize(thisID+1);
1220 elementGIDs[thisID]=localOrdering;
1225 template <
typename LO,
typename GO>
1228 std::vector<std::vector<LO> > elementLIDs(elementGIDs_.size());
1230 std::vector<GO> ownedAndGhosted;
1231 this->getOwnedAndGhostedIndices(ownedAndGhosted);
1234 std::unordered_map<GO,LO> hashMap;
1235 for(std::size_t i = 0; i < ownedAndGhosted.size(); ++i)
1236 hashMap[ownedAndGhosted[i]] = i;
1238 for (std::size_t i = 0; i < elementGIDs_.size(); ++i) {
1239 const std::vector<GO>& gids = elementGIDs_[i];
1240 std::vector<LO>&
lids = elementLIDs[i];
1241 lids.resize(gids.size());
1242 for (std::size_t g = 0; g < gids.size(); ++g)
1243 lids[g] = hashMap[gids[g]];
1246 this->setLocalIds(elementLIDs);
void buildLocalIdsFromOwnedAndGhostedElements()
const std::vector< int > & getBlockFieldNumbers(const std::string &blockId) const
void computeCellFaceOrientations(const std::vector< std::pair< int, int > > &topEdgeIndices, const std::vector< GlobalOrdinalT > &topology, const FieldPattern &fieldPattern, std::vector< char > &orientation)
Sums all entries of a Rank 2 Kokkos View.
int getFieldNum(const std::string &string) const
Get the number used for access to this field.
void getElementGIDs(LO localElementID, std::vector< GO > &gids, const std::string &blockIdHint="") const
get associated GIDs for a given local element
const std::string & getFieldString(int num) const
Reverse lookup of the field string from a field number.
void fillGIDsFromOverlappedMV(const ElementBlockAccess &access, std::vector< std::vector< GO > > &elementGIDs, const Tpetra::Map< LO, GO, panzer::TpetraNodeType > &overlapmap, const Tpetra::MultiVector< GO, LO, GO, panzer::TpetraNodeType > &overlap_mv) const
basic_FancyOStream & setShowProcRank(const bool showProcRank)
#define PANZER_DOFMGR_FUNC_TIME_MONITOR(a)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void setConnManager(const Teuchos::RCP< ConnManager< LO, GO > > &connMngr, MPI_Comm mpiComm)
Adds a Connection Manager that will be associated with this DOFManager.
const std::vector< int > & getGIDFieldOffsets(const std::string &blockID, int fieldNum) const
Teuchos::RCP< const Tpetra::Map< LO, GO, panzer::TpetraNodeType > > buildOverlapMapFromElements(const ElementBlockAccess &access) const
PHX::MDField< ScalarT > vector
const std::vector< LO > & getElementBlock(const std::string &eBlock) const
Teuchos::RCP< ConnManager< LocalOrdinalT, GlobalOrdinalT > > resetIndices()
Reset the indices for this DOF manager.
Kokkos::View< const LO **, PHX::Device > lids
virtual int numberIds() const
void computeCellEdgeOrientations(const std::vector< std::pair< int, int > > &topEdgeIndices, const std::vector< GlobalOrdinalT > &topology, const FieldPattern &fieldPattern, std::vector< char > &orientation)
std::size_t blockIdToIndex(const std::string &blockId) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< const FieldPattern > getFieldPattern(const std::string &name) const
Find a field pattern stored for a particular block and field number. This will retrive the pattern ad...
void setFieldOrder(const std::vector< std::string > &fieldOrder)
void getOwnedAndGhostedIndices(std::vector< GlobalOrdinalT > &indices) const
std::vector< ScalarT > values
Kokkos::Compat::KokkosDeviceWrapperNode< PHX::Device > TpetraNodeType
int addField(const std::string &str, const Teuchos::RCP< const FieldPattern > &pattern)
Add a field to the DOF manager.
void buildUnknownsOrientation()
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
void buildGlobalUnknowns()
builds the global unknowns array
PHX::MDField< const ScalarT, Cell, IP > field
void computePatternFaceIndices(const FieldPattern &pattern, std::vector< std::vector< int > > &faceIndices)
bool validFieldOrder(const std::vector< std::string > &proposed_fieldOrder)
void getFieldOrder(std::vector< std::string > &fieldOrder) const
void getOwnedIndices(std::vector< GlobalOrdinalT > &indices) const
std::pair< Teuchos::RCP< Tpetra::MultiVector< GO, LO, GO, panzer::TpetraNodeType > >, Teuchos::RCP< Tpetra::MultiVector< GO, LO, GO, panzer::TpetraNodeType > > > buildGlobalUnknowns_GUN(const Tpetra::MultiVector< GO, LO, GO, panzer::TpetraNodeType > &tagged_overlap_mv, Tpetra::MultiVector< GO, LO, GO, panzer::TpetraNodeType > &overlap_mv) const
Teuchos::RCP< Tpetra::MultiVector< GO, LO, GO, panzer::TpetraNodeType > > buildTaggedMultiVector(const ElementBlockAccess &access)
void push_back(const value_type &x)
void printFieldInformation(std::ostream &os) const
void getElementOrientation(LocalOrdinalT localElmtId, std::vector< double > &gidsOrientation) const
Get a vector containg the orientation of the GIDs relative to the neighbors.
int getNumFields() const
gets the number of fields
bool fieldInBlock(const std::string &field, const std::string &block) const
virtual const std::vector< int > & getSubcellIndices(int dim, int cellIndex) const =0
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...
#define TEUCHOS_ASSERT(assertion_test)
void computePatternEdgeIndices(const FieldPattern &pattern, std::vector< std::pair< int, int > > &edgeIndices)
void ownedIndices(const std::vector< GlobalOrdinalT > &indices, std::vector< bool > &isOwned) const