43#ifndef PANZER_DOF_MANAGER2_IMPL_HPP
44#define PANZER_DOF_MANAGER2_IMPL_HPP
51#include "PanzerDofMgr_config.hpp"
59#include "Teuchos_GlobalMPISession.hpp"
62#include "Teuchos_RCP.hpp"
63#include "Teuchos_Array.hpp"
64#include "Teuchos_ArrayView.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>
85template <
typename LocalOrdinal,
typename GlobalOrdinal>
86class HashTieBreak :
public Tpetra::Details::TieBreak<LocalOrdinal,GlobalOrdinal> {
90 HashTieBreak(
const unsigned int seed = (2654435761U))
93 virtual std::size_t selectedIndex(GlobalOrdinal GID,
94 const std::vector<std::pair<int,LocalOrdinal> > & pid_and_lid)
const
97 int intkey = (int) ((GID & 0x000000007fffffffLL) +
98 ((GID & 0x7fffffff80000000LL) >> 31));
99 return std::size_t((seed_ ^ intkey) % pid_and_lid.size());
107template <
typename LocalOrdinal,
typename GlobalOrdinal>
108class GreedyTieBreak :
public Tpetra::Details::TieBreak<LocalOrdinal,GlobalOrdinal> {
113 virtual bool mayHaveSideEffects()
const {
117 virtual std::size_t selectedIndex(GlobalOrdinal ,
118 const std::vector<std::pair<int,LocalOrdinal> > & pid_and_lid)
const
121 const std::size_t numLids = pid_and_lid.size();
123 int minpid = pid_and_lid[0].first;
124 std::size_t minidx = 0;
125 for (idx = 0; idx < numLids; ++idx) {
126 if (pid_and_lid[idx].first < minpid) {
127 minpid = pid_and_lid[idx].first;
143using Teuchos::ArrayRCP;
145using Teuchos::ArrayView;
149 : numFields_(0),buildConnectivityRun_(false),requireOrientations_(false), useTieBreak_(false), useNeighbors_(false)
154 : numFields_(0),buildConnectivityRun_(false),requireOrientations_(false), useTieBreak_(false), useNeighbors_(false)
163 "DOFManager::setConnManager: setConnManager cannot be called after "
164 "buildGlobalUnknowns has been called");
183 "DOFManager::addField: addField cannot be called after "
184 "buildGlobalUnknowns has been called");
203int DOFManager::addField(
const std::string & blockID,
const std::string & str,
const Teuchos::RCP<const FieldPattern> & pattern,
207 "DOFManager::addField: addField cannot be called after "
208 "buildGlobalUnknowns has been called");
209 TEUCHOS_TEST_FOR_EXCEPTION((
connMngr_==Teuchos::null),std::logic_error,
210 "DOFManager::addField: you must add a ConnManager before"
211 "you can associate a FP with a given block.")
221 TEUCHOS_TEST_FOR_EXCEPTION(!found,std::logic_error,
"DOFManager::addField: Invalid block name.");
226 std::map<std::string,int>::const_iterator fpIter =
fieldNameToAID_.find(str);
252 std::map<std::string,int>::const_iterator fitr =
fieldNameToAID_.find(name);
254 return Teuchos::null;
259 return Teuchos::null;
265 std::map<std::string,int>::const_iterator fitr =
fieldNameToAID_.find(fieldName);
267 return Teuchos::null;
280 return Teuchos::null;
289 return Teuchos::null;
309 for (
size_t i(0); i <
owned_.size(); ++i)
311 for (
size_t i(0); i <
ghosted_.size(); ++i)
318 const auto & element_ids =
elementGIDs_[localElementID];
319 gids.resize(element_ids.size());
320 for (std::size_t i=0; i < gids.size(); ++i)
321 gids[i] = element_ids[i];
327 indices.resize(
owned_.size());
328 for (std::size_t i=0; i <
owned_.size(); ++i)
336 for (std::size_t i=0; i <
ghosted_.size(); ++i)
344 for (std::size_t i=0; i <
owned_.size(); ++i)
346 for (std::size_t i=0; i <
ghosted_.size(); ++i)
375const std::vector<int> &
378 TEUCHOS_TEST_FOR_EXCEPTION(!
buildConnectivityRun_,std::logic_error,
"DOFManager::getGIDFieldOffsets: cannot be called before "
379 "buildGlobalUnknowns has been called");
380 std::map<std::string,int>::const_iterator bitr =
blockNameToID_.find(blockID);
382 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid block name");
383 int bid=bitr->second;
384 if(
fa_fps_[bid]!=Teuchos::null)
385 return fa_fps_[bid]->localOffsets(fieldNum);
387 static const std::vector<int> empty;
392const PHX::View<const int*>
395 TEUCHOS_TEST_FOR_EXCEPTION(!
buildConnectivityRun_,std::logic_error,
"DOFManager::getGIDFieldOffsets: cannot be called before "
396 "buildGlobalUnknowns has been called");
397 std::map<std::string,int>::const_iterator bitr =
blockNameToID_.find(blockID);
399 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid block name");
402 int bid=bitr->second;
403 if(
fa_fps_[bid]!=Teuchos::null)
404 return fa_fps_[bid]->localOffsetsKokkos(fieldNum);
406 static const PHX::View<int*> empty(
"panzer::DOFManager::getGIDFieldOffsetsKokkos() empty",0);
411const PHX::ViewOfViews3<1,PHX::View<const int*>>
414 TEUCHOS_TEST_FOR_EXCEPTION(!
buildConnectivityRun_,std::logic_error,
"DOFManager::getGIDFieldOffsets: cannot be called before "
415 "buildGlobalUnknowns has been called");
416 std::map<std::string,int>::const_iterator bitr =
blockNameToID_.find(blockID);
418 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid block name");
421 PHX::ViewOfViews3<1,PHX::View<const int*>> vov(
"panzer::getGIDFieldOffsetsKokkos vector version",fieldNums.size());
422 vov.disableSafetyCheck();
424 int bid=bitr->second;
426 for (
size_t i=0; i < fieldNums.size(); ++i) {
427 if(
fa_fps_[bid]!=Teuchos::null) {
428 vov.addView(
fa_fps_[bid]->localOffsetsKokkos(fieldNums[i]),i);
431 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"panzer::DOFManager::getGIDFieldOffsets() - no field pattern exists in block "
432 << blockID <<
"for field number " << fieldNums[i] <<
" exists!");
437 vov.syncHostToDevice();
460 std::vector<std::pair<FieldType,Teuchos::RCP<const FieldPattern>>> tmp;
466 connMngr_->buildConnectivity(*aggFieldPattern);
477 typedef Tpetra::Map<panzer::LocalOrdinal, panzer::GlobalOrdinal, Node> Map;
479 typedef Tpetra::Import<panzer::LocalOrdinal,panzer::GlobalOrdinal,Node> Import;
482 typedef Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,Node> MultiVector;
484 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns",
buildGlobalUnknowns);
486 Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
487 out.setOutputToRootOnly(-1);
488 out.setShowProcRank(
true);
491 "DOFManager::buildGlobalUnknowns: buildGlobalUnknowns cannot be called again "
492 "after buildGlobalUnknowns has been called");
497 std::size_t sz = geomPattern->getSubcellIndices(0,0).size();
499 TEUCHOS_TEST_FOR_EXCEPTION(sz==0,std::logic_error,
500 "DOFManager::buildGlobalUnknowns requires a geometric pattern including "
501 "the nodes when orientations are needed!");
516 RCP<const Map> overlap_map = tagged_overlap_mv->getMap();
518 RCP<MultiVector> overlap_mv = Tpetra::createMultiVector<panzer::GlobalOrdinal>(overlap_map,(
size_t)
numFields_);
522 RCP<MultiVector> non_overlap_mv = non_overlap_pair.first;
523 RCP<MultiVector> tagged_non_overlap_mv = non_overlap_pair.second;
524 RCP<const Map> non_overlap_map = non_overlap_mv->getMap();
539 RCP<const Map> overlap_map_neighbor =
543 Import imp_neighbor(non_overlap_map,overlap_map_neighbor);
545 Teuchos::RCP<MultiVector> overlap_mv_neighbor =
546 Tpetra::createMultiVector<panzer::GlobalOrdinal>(overlap_map_neighbor, (
size_t)
numFields_);
549 overlap_mv_neighbor->doImport(*non_overlap_mv, imp_neighbor,
553 *overlap_map_neighbor, *overlap_mv_neighbor);
562 panzer::GlobalOrdinal offset = 0xFFFFFFFFLL;
565 const std::vector<panzer::LocalOrdinal> & myElements =
connMngr_->getElementBlock(
blockOrder_[b]);
566 for (std::size_t l = 0; l < myElements.size(); ++l) {
567 std::vector<panzer::GlobalOrdinal> & localGIDs =
elementGIDs_[myElements[l]];
568 for(std::size_t c=0;c<localGIDs.size();c++)
569 localGIDs[c] += offset;
573 Teuchos::ArrayRCP<panzer::GlobalOrdinal> nvals = non_overlap_mv->get1dViewNonConst();
574 for (
int j = 0; j < nvals.size(); ++j)
581 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns::build_owned_vector",build_owned_vector);
583 typedef std::unordered_set<panzer::GlobalOrdinal> HashTable;
584 HashTable isOwned, remainingOwned;
587 auto nvals = non_overlap_mv->getLocalViewHost(Tpetra::Access::ReadOnly);
588 auto tagged_vals = tagged_non_overlap_mv->getLocalViewHost(Tpetra::Access::ReadOnly);
589 TEUCHOS_ASSERT(nvals.size()==tagged_vals.size());
590 for (
size_t i = 0; i < nvals.extent(1); ++i) {
591 for (
size_t j = 0; j < nvals.extent(0); ++j) {
592 if (nvals(j,i) != -1) {
593 for(panzer::GlobalOrdinal offset=0;offset<tagged_vals(j,i);++offset)
594 isOwned.insert(nvals(j,i)+offset);
598 TEUCHOS_ASSERT(tagged_vals(j,i)==0);
602 remainingOwned = isOwned;
610 const std::vector<panzer::LocalOrdinal> & myElements =
connMngr_->getElementBlock(
blockOrder_[b]);
612 for (
size_t l = 0; l < myElements.size(); ++l) {
613 const std::vector<panzer::GlobalOrdinal> & localOrdering =
elementGIDs_[myElements[l]];
616 for(std::size_t i=0;i<localOrdering.size();i++) {
618 if(isOwned.find(localOrdering[i])==isOwned.end())
622 std::pair<typename HashTable::iterator,bool> insertResult = hashTable.insert(localOrdering[i]);
623 if(insertResult.second) {
624 owned_.push_back(localOrdering[i]);
625 remainingOwned.erase(localOrdering[i]);
634 for(
typename HashTable::const_iterator itr=remainingOwned.begin();itr!=remainingOwned.end();itr++)
637 if(
owned_.size()!=isOwned.size()) {
638 out <<
"I'm about to hang because of unknown numbering failure ... sorry! (line = " << __LINE__ <<
")" << std::endl;
639 TEUCHOS_TEST_FOR_EXCEPTION(
owned_.size()!=isOwned.size(),std::logic_error,
640 "DOFManager::buildGlobalUnkonwns: Failure because not all owned unknowns have been accounted for.");
651 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns::build_ghosted_array",BGA);
654 typedef std::unordered_set<panzer::GlobalOrdinal> HashTable;
656 for (std::size_t i = 0; i <
owned_.size(); i++)
657 hashTable.insert(
owned_[i]);
662 std::vector<ElementBlockAccess> blockAccessVec;
666 for (std::size_t a = 0; a < blockAccessVec.size(); ++a)
672 if (
fa_fps_[b] == Teuchos::null)
674 const std::vector<panzer::LocalOrdinal>& myElements =
676 for (
size_t l = 0; l < myElements.size(); ++l)
678 const std::vector<panzer::GlobalOrdinal>& localOrdering =
elementGIDs_[myElements[l]];
681 for (std::size_t i = 0; i < localOrdering.size(); ++i)
683 std::pair<typename HashTable::iterator, bool> insertResult =
684 hashTable.insert(localOrdering[i]);
688 if(insertResult.second)
689 ghosted_.push_back(localOrdering[i]);
700 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns::build_orientation",BO);
706 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns::build_local_ids_from_owned_and_ghosted",BLOFOG);
710 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns::build_local_ids",BLI);
716std::pair<Teuchos::RCP<Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType> >,
717 Teuchos::RCP<Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType> > >
719 Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType> & overlap_mv)
const
723 typedef Tpetra::Map<panzer::LocalOrdinal, panzer::GlobalOrdinal, Node> Map;
725 typedef Tpetra::Export<panzer::LocalOrdinal,panzer::GlobalOrdinal,Node> Export;
726 typedef Tpetra::Import<panzer::LocalOrdinal,panzer::GlobalOrdinal,Node> Import;
729 typedef Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,Node> MultiVector;
731 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns_GUN",BGU_GUN);
734 RCP<const Map> overlap_map = tagged_overlap_mv.getMap();
741 RCP<const Map> non_overlap_map;
743 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns_GUN::line_04 createOneToOne",GUN04);
745 GreedyTieBreak<panzer::LocalOrdinal,panzer::GlobalOrdinal> greedy_tie_break;
746 non_overlap_map = Tpetra::createOneToOne<panzer::LocalOrdinal,panzer::GlobalOrdinal,Node>(overlap_map, greedy_tie_break);
751 HashTieBreak<panzer::LocalOrdinal,panzer::GlobalOrdinal> tie_break;
752 non_overlap_map = Tpetra::createOneToOne<panzer::LocalOrdinal,panzer::GlobalOrdinal,Node>(overlap_map,tie_break);
760 Teuchos::RCP<MultiVector> tagged_non_overlap_mv;
762 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns_GUN::line_05 alloc_unique_mv",GUN05);
764 tagged_non_overlap_mv = Tpetra::createMultiVector<panzer::GlobalOrdinal>(non_overlap_map,(
size_t)
numFields_);
773 RCP<MultiVector> non_overlap_mv;
775 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns_GUN::line_06 export",GUN06);
777 exp = rcp(
new Export(overlap_map,non_overlap_map));
781 tagged_non_overlap_mv->doExport(tagged_overlap_mv,*exp,Tpetra::ABSMAX);
785 non_overlap_mv = rcp(
new MultiVector(*tagged_non_overlap_mv,Teuchos::Copy));
793 panzer::GlobalOrdinal localsum=0;
795 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns_GUN::line_07-09 local_count",GUN07_09);
796 auto values = non_overlap_mv->getLocalViewDevice(Tpetra::Access::ReadOnly);
797 auto mv_size = values.extent(0);
806 panzer::GlobalOrdinal myOffset = -1;
808 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns_GUN::line_10 prefix_sum",GUN_10);
811 panzer::GlobalOrdinal scanResult = 0;
812 Teuchos::scan<int, panzer::GlobalOrdinal> (*
getComm(), Teuchos::REDUCE_SUM,
static_cast<panzer::GlobalOrdinal
> (localsum), Teuchos::outArg (scanResult));
813 myOffset = scanResult - localsum;
826 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns_GUN::line_13-21 gid_assignment",GUN13_21);
828 auto editnonoverlap = non_overlap_mv->getLocalViewHost(Tpetra::Access::ReadWrite);
829 for(
size_t i=0; i<non_overlap_mv->getLocalLength(); ++i){
831 if(editnonoverlap(i,j)!=0){
833 int ndof = Teuchos::as<int>(editnonoverlap(i,j));
834 editnonoverlap(i,j)=myOffset+which_id;
838 editnonoverlap(i,j)=-1;
854 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildGlobalUnknowns_GUN::line_23 final_import",GUN23);
857 overlap_mv.doImport(*non_overlap_mv,*exp,Tpetra::REPLACE);
863 return std::make_pair(non_overlap_mv,tagged_non_overlap_mv);
867Teuchos::RCP<Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType> >
872 typedef Tpetra::Map<panzer::LocalOrdinal, panzer::GlobalOrdinal, Node> Map;
873 typedef Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,Node> MultiVector;
875 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildTaggedMultiVector",BTMV);
881 std::vector<std::tuple< int, panzer::FieldType, RCP<const panzer::FieldPattern> > > faConstruct;
896 if(faConstruct.size()>0) {
904 fa_fps_.push_back(Teuchos::null);
914 Teuchos::RCP<MultiVector> overlap_mv;
916 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildTaggedMultiVector::allocate_tagged_multivector",ATMV);
918 overlap_mv = Tpetra::createMultiVector<panzer::GlobalOrdinal>(overlapmap,(
size_t)
numFields_);
919 overlap_mv->putScalar(0);
927 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::DOFManager::buildTaggedMultiVector::fill_tagged_multivector",FTMV);
930 std::vector<int> working(overlap_mv->getNumVectors());
931 auto edittwoview_host = overlap_mv->getLocalViewHost(Tpetra::Access::ReadWrite);
937 const std::vector<panzer::LocalOrdinal> &
numFields=
fa_fps_[b]->numFieldsPerId();
938 const std::vector<panzer::LocalOrdinal> & fieldIds=
fa_fps_[b]->fieldIds();
939 const std::vector<panzer::LocalOrdinal> & myElements =
connMngr_->getElementBlock(
blockOrder_[b]);
940 for (
size_t l = 0; l < myElements.size(); ++l) {
941 auto connSize =
connMngr_->getConnectivitySize(myElements[l]);
942 const auto * elmtConn =
connMngr_->getConnectivity(myElements[l]);
944 for (
int c = 0; c < connSize; ++c) {
945 size_t lid = overlapmap->getLocalElement(elmtConn[c]);
947 for(std::size_t i=0;i<working.size();i++)
950 int whichField = fieldIds[offset];
953 working[whichField]++;
956 for(std::size_t i=0;i<working.size();i++) {
957 auto current = edittwoview_host(lid,i);
958 edittwoview_host(lid,i) = (current > working[i]) ? current : working[i];
1007 std::stringstream ss;
1009 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid field name. DOF information is:\n"+ss.str());
1011 std::map<std::string,int>::const_iterator bitr =
blockNameToID_.find(block);
1013 std::stringstream ss;
1015 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid block name. DOF information is:\n"+ss.str());
1017 int fid=fitr->second;
1018 int bid=bitr->second;
1034 TEUCHOS_TEST_FOR_EXCEPTION(!
buildConnectivityRun_,std::logic_error,
"DOFManager::getBlockFieldNumbers: BuildConnectivity must be run first.");
1036 std::map<std::string,int>::const_iterator bitr =
blockNameToID_.find(blockId);
1038 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid block name");
1039 int bid=bitr->second;
1042 if(
fa_fps_[bid]!=Teuchos::null)
1043 return fa_fps_[bid]->fieldIds();
1046 static std::vector<int> empty;
1051const std::pair<std::vector<int>,std::vector<int> > &
1054 TEUCHOS_TEST_FOR_EXCEPTION(!
buildConnectivityRun_,std::logic_error,
"DOFManager::getGIDFieldOffsets_closure: BuildConnectivity must be run first.");
1055 std::map<std::string,int>::const_iterator bitr =
blockNameToID_.find(blockId);
1057 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::getGIDFieldOffsets_closure: invalid block name.");
1060 if(
fa_fps_[bitr->second]!=Teuchos::null)
1061 return fa_fps_[bitr->second]->localOffsets_closure(fieldNum, subcellDim, subcellId);
1063 static std::pair<std::vector<int>,std::vector<int> > empty;
1071 if(indices.size()!=isOwned.size())
1072 isOwned.resize(indices.size(),
false);
1073 typename std::vector<panzer::GlobalOrdinal>::const_iterator endOf =
owned_.end();
1074 for (std::size_t i = 0; i < indices.size(); ++i) {
1075 isOwned[i] = ( std::find(
owned_.begin(),
owned_.end(), indices[i])!=endOf );
1083 "DOFManager::setFieldOrder: setFieldOrder cannot be called after "
1084 "buildGlobalUnknowns has been called");
1093 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::setFieldOrder: Invalid Field Ordering!");
1106 for (
size_t j = 0; j < proposed_fieldOrder.size(); ++j) {
1121 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"DOFManager::getFieldString: invalid number");
1135 std::vector<std::string> elementBlockIds;
1136 connMngr_->getElementBlockIds(elementBlockIds);
1139 std::size_t myElementCount = 0;
1140 for(std::vector<std::string>::const_iterator blockItr=elementBlockIds.begin(); blockItr!=elementBlockIds.end();++blockItr)
1141 myElementCount +=
connMngr_->getElementBlock(*blockItr).size();
1147 for(std::vector<std::string>::const_iterator blockItr=elementBlockIds.begin();
1148 blockItr!=elementBlockIds.end();++blockItr) {
1149 const std::string & blockName = *blockItr;
1152 std::map<std::string,int>::const_iterator fap =
blockNameToID_.find(blockName);
1154 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::buildUnknownsOrientation: invalid block name");
1157 int bid=fap->second;
1159 if(
fa_fps_[bid]==Teuchos::null)
1166 std::vector<std::pair<int,int> > topEdgeIndices;
1170 std::vector<std::vector<int> > topFaceIndices;
1171 if(
ga_fp_->getDimension()==3)
1175 const std::vector<panzer::LocalOrdinal> & elmts =
connMngr_->getElementBlock(blockName);
1176 for(std::size_t e=0;e<elmts.size();e++) {
1178 std::vector<signed char> & eOrientation =
orientation_[elmts[e]];
1183 eOrientation.resize(fieldPattern.
numberIds());
1184 for(std::size_t s=0;s<eOrientation.size();s++)
1185 eOrientation[s] = 1;
1188 auto connSz =
connMngr_->getConnectivitySize(elmts[e]);
1189 const panzer::GlobalOrdinal * connPtr =
connMngr_->getConnectivity(elmts[e]);
1190 const std::vector<panzer::GlobalOrdinal> connectivity(connPtr,connPtr+connSz);
1195 if(
ga_fp_->getDimension()==3)
1204 TEUCHOS_TEST_FOR_EXCEPTION(
orientation_.size()==0,std::logic_error,
1205 "DOFManager::getElementOrientations: Orientations were not constructed!");
1207 const std::vector<signed char> & local_o =
orientation_[localElmtId];
1208 gidsOrientation.resize(local_o.size());
1209 for(std::size_t i=0;i<local_o.size();i++) {
1210 gidsOrientation[i] = double(local_o[i]);
1216 Teuchos::RCP<ConnManager> connMngr =
connMngr_;
1234 std::map<std::string,int>::const_iterator bitr =
blockNameToID_.find(blockId);
1236 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFManager::fieldInBlock: invalid block name");
1237 return bitr->second;
1243 os <<
"DOFManager Field Information: " << std::endl;
1249 os <<
" Element Block = " <<
blockOrder_[i] << std::endl;
1253 for(std::size_t f=0;f<fieldIds.size();f++)
1254 os <<
" \"" <<
getFieldString(fieldIds[f]) <<
"\" is field ID " << fieldIds[f] << std::endl;
1259Teuchos::RCP<const Tpetra::Map<panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType> >
1262 PANZER_FUNC_TIME_MONITOR(
"panzer::DOFManager::builderOverlapMapFromElements");
1269 std::set<panzer::GlobalOrdinal> overlapset;
1272 for (
size_t e = 0; e < myElements.size(); ++e) {
1273 auto connSize =
connMngr_->getConnectivitySize(myElements[e]);
1274 const panzer::GlobalOrdinal * elmtConn =
connMngr_->getConnectivity(myElements[e]);
1275 for (
int k = 0; k < connSize; ++k) {
1276 overlapset.insert(elmtConn[k]);
1281 Array<panzer::GlobalOrdinal> overlapVector;
1282 for (
typename std::set<panzer::GlobalOrdinal>::const_iterator itr = overlapset.begin(); itr!=overlapset.end(); ++itr) {
1283 overlapVector.push_back(*itr);
1288 return Tpetra::createNonContigMapWithNode<panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType>(overlapVector,
getComm());
1294 std::vector<std::vector< panzer::GlobalOrdinal > > & elementGIDs,
1295 const Tpetra::Map<panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType> & overlapmap,
1296 const Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType> & const_overlap_mv)
const
1298 using Teuchos::ArrayRCP;
1301 auto overlap_mv =
const_cast<Tpetra::MultiVector<panzer::GlobalOrdinal,panzer::LocalOrdinal,panzer::GlobalOrdinal,panzer::TpetraNodeType>&
>(const_overlap_mv);
1302 const auto twoview_host = overlap_mv.getLocalViewHost(Tpetra::Access::ReadOnly);
1309 if(
fa_fps_[b]==Teuchos::null) {
1311 for (
size_t l = 0; l < myElements.size(); ++l) {
1312 panzer::LocalOrdinal thisID=myElements[l];
1313 if(elementGIDs.size()<=(size_t)thisID)
1314 elementGIDs.resize(thisID+1);
1320 const std::vector<int> & fieldIds=
fa_fps_[b]->fieldIds();
1323 for (
size_t l = 0; l < myElements.size(); ++l) {
1324 auto connSize =
connMngr_->getConnectivitySize(myElements[l]);
1325 const panzer::GlobalOrdinal * elmtConn =
connMngr_->getConnectivity(myElements[l]);
1326 std::vector<panzer::GlobalOrdinal> localOrdering;
1328 for (
int c = 0; c < connSize; ++c) {
1329 size_t lid = overlapmap.getLocalElement(elmtConn[c]);
1331 for (
int n = 0; n <
numFields[c]; ++n) {
1332 int whichField = fieldIds[offset];
1336 localOrdering.push_back(twoview_host(lid,whichField)+dofsPerField[whichField]);
1338 dofsPerField[whichField]++;
1341 panzer::LocalOrdinal thisID=myElements[l];
1342 if(elementGIDs.size()<=(
size_t)thisID){
1343 elementGIDs.resize(thisID+1);
1345 elementGIDs[thisID]=localOrdering;
1352 std::vector<std::vector<panzer::LocalOrdinal> > elementLIDs(
elementGIDs_.size());
1354 std::vector<panzer::GlobalOrdinal> ownedAndGhosted;
1358 std::unordered_map<panzer::GlobalOrdinal,panzer::LocalOrdinal> hashMap;
1359 for(std::size_t i = 0; i < ownedAndGhosted.size(); ++i)
1360 hashMap[ownedAndGhosted[i]] = i;
1362 for (std::size_t i = 0; i <
elementGIDs_.size(); ++i) {
1363 const std::vector<panzer::GlobalOrdinal>& gids =
elementGIDs_[i];
1364 std::vector<panzer::LocalOrdinal>&
lids = elementLIDs[i];
1365 lids.resize(gids.size());
1366 for (std::size_t g = 0; g < gids.size(); ++g)
1367 lids[g] = hashMap[gids[g]];
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.
Kokkos::View< const LO **, Kokkos::LayoutRight, PHX::Device > lids
const std::vector< panzer::LocalOrdinal > & getElementBlock(const std::string &eBlock) const
void ownedIndices(const std::vector< panzer::GlobalOrdinal > &indices, std::vector< bool > &isOwned) const
std::vector< int > elementBlockGIDCount_
bool validFieldOrder(const std::vector< std::string > &proposed_fieldOrder)
Teuchos::RCP< Teuchos::Comm< int > > getComm() const
const PHX::View< const int * > getGIDFieldOffsetsKokkos(const std::string &blockID, int fieldNum) const
int getNumGhosted() const
Get the number of indices ghosted for this processor.
std::vector< std::string > blockOrder_
std::vector< panzer::GlobalOrdinal > ghosted_
std::vector< FieldType > fieldTypes_
std::map< std::string, int > blockNameToID_
std::vector< int > fieldAIDOrder_
void getOwnedIndicesAsInt(std::vector< int > &indices) const
Get the set of indices owned by this processor.
void getGhostedIndices(std::vector< panzer::GlobalOrdinal > &indices) const
Get the set of indices ghosted for this processor.
void getFieldOrder(std::vector< std::string > &fieldOrder) const
bool getOrientationsRequired() const
void setConnManager(const Teuchos::RCP< ConnManager > &connMngr, MPI_Comm mpiComm)
Adds a Connection Manager that will be associated with this DOFManager.
std::vector< panzer::GlobalOrdinal > owned_
void fillGIDsFromOverlappedMV(const ElementBlockAccess &access, std::vector< std::vector< panzer::GlobalOrdinal > > &elementGIDs, const Tpetra::Map< panzer::LocalOrdinal, panzer::GlobalOrdinal, panzer::TpetraNodeType > &overlapmap, const Tpetra::MultiVector< panzer::GlobalOrdinal, panzer::LocalOrdinal, panzer::GlobalOrdinal, panzer::TpetraNodeType > &overlap_mv) const
void getElementOrientation(panzer::LocalOrdinal localElmtId, std::vector< double > &gidsOrientation) const
Get a vector containg the orientation of the GIDs relative to the neighbors.
Teuchos::RCP< const panzer::FieldPattern > ga_fp_
void buildLocalIdsFromOwnedAndGhostedElements()
Teuchos::RCP< ConnManager > connMngr_
void getOwnedAndGhostedIndicesAsInt(std::vector< int > &indices) const
Get the set of owned and ghosted indices for this processor.
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...
std::pair< Teuchos::RCP< Tpetra::MultiVector< panzer::GlobalOrdinal, panzer::LocalOrdinal, panzer::GlobalOrdinal, panzer::TpetraNodeType > >, Teuchos::RCP< Tpetra::MultiVector< panzer::GlobalOrdinal, panzer::LocalOrdinal, panzer::GlobalOrdinal, panzer::TpetraNodeType > > > buildGlobalUnknowns_GUN(const Tpetra::MultiVector< panzer::GlobalOrdinal, panzer::LocalOrdinal, panzer::GlobalOrdinal, panzer::TpetraNodeType > &tagged_overlap_mv, Tpetra::MultiVector< panzer::GlobalOrdinal, panzer::LocalOrdinal, panzer::GlobalOrdinal, panzer::TpetraNodeType > &overlap_mv) const
std::vector< std::vector< int > > blockToAssociatedFP_
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 setFieldOrder(const std::vector< std::string > &fieldOrder)
Teuchos::RCP< Tpetra::MultiVector< panzer::GlobalOrdinal, panzer::LocalOrdinal, panzer::GlobalOrdinal, panzer::TpetraNodeType > > buildTaggedMultiVector(const ElementBlockAccess &access)
void buildUnknownsOrientation()
std::vector< std::vector< panzer::GlobalOrdinal > > elementGIDs_
std::vector< std::vector< signed char > > orientation_
Teuchos::RCP< ConnManager > resetIndices()
Reset the indices for this DOF manager.
bool requireOrientations_
std::size_t blockIdToIndex(const std::string &blockId) const
void getElementGIDsAsInt(panzer::LocalOrdinal localElementID, std::vector< int > &gids, const std::string &blockIdHint="") const
Get the global IDs for a particular element. This function overwrites the gids variable.
void buildGlobalUnknowns()
builds the global unknowns array
Teuchos::RCP< Teuchos::Comm< int > > communicator_
std::vector< Teuchos::RCP< panzer::FieldAggPattern > > fa_fps_
void getOwnedIndices(std::vector< panzer::GlobalOrdinal > &indices) const
Get the set of indices owned by this processor.
int getNumOwnedAndGhosted() const
Get the number of owned and ghosted indices for this processor.
void getElementGIDs(panzer::LocalOrdinal localElementID, std::vector< panzer::GlobalOrdinal > &gids, const std::string &blockIdHint="") const
get associated GIDs for a given local element
std::map< std::string, int > fieldNameToAID_
std::vector< std::string > fieldStringOrder_
void printFieldInformation(std::ostream &os) const
bool buildConnectivityRun_
void getGhostedIndicesAsInt(std::vector< int > &indices) const
Get the set of indices ghosted for this processor.
int getFieldNum(const std::string &string) const
Get the number used for access to this field.
int getNumOwned() const
Get the number of indices owned by this processor.
const std::string & getFieldString(int num) const
Reverse lookup of the field string from a field number.
std::vector< Teuchos::RCP< const FieldPattern > > fieldPatterns_
bool fieldInBlock(const std::string &field, const std::string &block) const
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.
int getNumFields() const
gets the number of fields
void getOwnedAndGhostedIndices(std::vector< panzer::GlobalOrdinal > &indices) const
Get the set of owned and ghosted indices for this processor.
Teuchos::RCP< const Tpetra::Map< panzer::LocalOrdinal, panzer::GlobalOrdinal, panzer::TpetraNodeType > > buildOverlapMapFromElements(const ElementBlockAccess &access) const
const std::vector< int > & getBlockFieldNumbers(const std::string &blockId) const
const std::vector< int > & getGIDFieldOffsets(const std::string &blockID, int fieldNum) const
virtual int numberIds() const
void setLocalIds(const std::vector< std::vector< panzer::LocalOrdinal > > &localIDs)
void computeCellEdgeOrientations(const std::vector< std::pair< int, int > > &topEdgeIndices, const std::vector< panzer::GlobalOrdinal > &topology, const FieldPattern &fieldPattern, std::vector< signed char > &orientation)
void computePatternEdgeIndices(const FieldPattern &pattern, std::vector< std::pair< int, int > > &edgeIndices)
void computeCellFaceOrientations(const std::vector< std::vector< int > > &topFaceIndices, const std::vector< panzer::GlobalOrdinal > &topology, const FieldPattern &fieldPattern, std::vector< signed char > &orientation)
void computePatternFaceIndices(const FieldPattern &pattern, std::vector< std::vector< int > > &faceIndices)
Kokkos::Compat::KokkosDeviceWrapperNode< PHX::Device > TpetraNodeType
FieldType
The type of discretization to use for a field pattern.
Sums all entries of a Rank 2 Kokkos View.