Skip to content

Commit c24b8b5

Browse files
committed
Update the stk poisson example.
A couple of fixes: 1. remove the duplication of ids in ownedPlusSharedGIDs. It was being filled with owned nodes and shared nodes. But shared nodes include shared-and-owned as well as shared-but-not-owned. So now it only contains owned and shared-but-not-owned. 2. The nnzPerRow array being given to FECrsGraph was the same length as the ownedMap, but is now the same length as the ownedPlusSharedMap. This allows the example to run correctly in parallel. Also streamlined some of the stk usage.
1 parent 69e0561 commit c24b8b5

File tree

1 file changed

+96
-142
lines changed

1 file changed

+96
-142
lines changed

packages/trilinoscouplings/examples/scaling/example_Poisson_stk.cpp

+96-142
Original file line numberDiff line numberDiff line change
@@ -120,23 +120,15 @@
120120
#include "stk_io/StkMeshIoBroker.hpp"
121121

122122
#include "stk_util/parallel/Parallel.hpp"
123+
#include "stk_mesh/base/Types.hpp"
123124
#include "stk_mesh/base/MetaData.hpp"
124-
#include "stk_mesh/base/CoordinateSystems.hpp"
125125
#include "stk_mesh/base/BulkData.hpp"
126-
#include "stk_mesh/base/Comm.hpp"
127-
#include "stk_mesh/base/Selector.hpp"
126+
#include "stk_mesh/base/ForEachEntity.hpp"
128127
#include "stk_mesh/base/GetEntities.hpp"
129-
#include "stk_mesh/base/GetBuckets.hpp"
130-
#include "stk_mesh/base/CreateAdjacentEntities.hpp"
131-
#include <stk_mesh/base/BulkData.hpp> // for BulkData
132-
#include <stk_mesh/base/CoordinateSystems.hpp> // for Cartesian3d, etc
133-
#include <stk_mesh/base/FEMHelpers.hpp> // for declare_element
134-
#include <stk_mesh/base/Field.hpp> // for Field
135-
#include <stk_mesh/base/MetaData.hpp> // for MetaData, entity_rank_names, etc
136-
#include "stk_mesh/base/Bucket.hpp" // for Bucket
137-
#include "stk_mesh/base/Entity.hpp" // for Entity
138-
#include "stk_mesh/base/FieldBase.hpp" // for field_data, etc
139-
#include "stk_mesh/base/Types.hpp" // for BucketVector, EntityId
128+
#include "stk_mesh/base/Selector.hpp"
129+
#include "stk_mesh/base/Bucket.hpp"
130+
#include "stk_mesh/base/Entity.hpp"
131+
#include "stk_mesh/base/Field.hpp"
140132

141133
#include "TrilinosCouplings_Statistics.hpp"
142134

@@ -297,6 +289,9 @@ void mesh_read_write(const std::string &type,
297289
MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
298290

299291
std::string absoluteFileName = working_directory + "/" + filename;
292+
if (myrank == 0) {
293+
std::cout<<"Reading mesh: "<<absoluteFileName<<std::endl;
294+
}
300295
size_t input_index = broker.add_mesh_database(absoluteFileName, type, stk::io::READ_MESH);
301296
broker.set_active_mesh(input_index);
302297
// creates metadata
@@ -429,7 +424,7 @@ int main(int argc, char *argv[]) {
429424
<< "| Kara Peterson ([email protected]). |\n" \
430425
<< "| |\n" \
431426
<< "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
432-
<< "| STK's website: http://trilinos.sandia.gov/packages/stk |\n" \
427+
<< "| STK's website: http://trilinos.github.io/stk.html |\n" \
433428
<< "| ML's website: http://trilinos.sandia.gov/packages/ml |\n" \
434429
<< "| Trilinos website: http://trilinos.sandia.gov |\n" \
435430
<< "| |\n" \
@@ -463,7 +458,7 @@ int main(int argc, char *argv[]) {
463458

464459
stk::io::StkMeshIoBroker broker(*MpiComm->getRawMpiComm());
465460
broker.property_add(Ioss::Property("MAXIMUM_NAME_LENGTH", 180));
466-
broker.property_add(Ioss::Property("DECOMPOSITION_METHOD", "rcb"));
461+
broker.property_add(Ioss::Property("DECOMPOSITION_METHOD", "HSFC"));
467462
broker.property_add(Ioss::Property("COMPOSE_RESULTS", false)); //Note! true results in an error in Seacas
468463

469464
std::string type = "exodusii";
@@ -482,39 +477,29 @@ int main(int argc, char *argv[]) {
482477

483478
// Count number of local nodes, record GIDs for Tpetra map.
484479
Teuchos::Array<GO> ownedGIDs, ownedPlusSharedGIDs;
485-
int numLocalNodes=0;
486-
stk::mesh::Selector locallyOwnedSelector = metaData.locally_owned_part(); //locally-owned
487-
const stk::mesh::BucketVector &localNodeBuckets = bulkData.get_buckets(NODE_RANK, locallyOwnedSelector);
488-
for (size_t bucketIndex = 0; bucketIndex < localNodeBuckets.size(); ++bucketIndex) {
489-
stk::mesh::Bucket &nodeBucket = *localNodeBuckets[bucketIndex];
490-
numLocalNodes += nodeBucket.size();
491-
for (size_t nodeIndex = 0; nodeIndex < nodeBucket.size(); ++nodeIndex) {
492-
stk::mesh::Entity node = nodeBucket[nodeIndex];
493-
ownedGIDs.push_back(bulkData.identifier(node)-1);
494-
ownedPlusSharedGIDs.push_back(bulkData.identifier(node)-1);
495-
}
496-
}
480+
stk::mesh::Selector locallyOwnedSelector = metaData.locally_owned_part();
481+
int numLocalNodes=stk::mesh::count_entities(bulkData, NODE_RANK, locallyOwnedSelector);
497482

498-
// Now record the shared nodal GIDs
483+
stk::mesh::for_each_entity_run(bulkData, NODE_RANK, locallyOwnedSelector,
484+
[&](const stk::mesh::BulkData& mesh, stk::mesh::Entity node)
485+
{
486+
ownedGIDs.push_back(mesh.identifier(node)-1);
487+
ownedPlusSharedGIDs.push_back(mesh.identifier(node)-1);
488+
});
489+
490+
// Now record the shared-but-not-owned nodal GIDs
499491
{
500492
stk::mesh::Selector globallySharedSelector = metaData.globally_shared_part();
501-
const stk::mesh::BucketVector &sharedNodeBuckets = bulkData.get_buckets(NODE_RANK, globallySharedSelector);
502-
for (size_t bucketIndex = 0; bucketIndex < sharedNodeBuckets.size(); ++bucketIndex) {
503-
stk::mesh::Bucket &nodeBucket = *sharedNodeBuckets[bucketIndex];
504-
for (size_t nodeIndex = 0; nodeIndex < nodeBucket.size(); ++nodeIndex) {
505-
stk::mesh::Entity node = nodeBucket[nodeIndex];
506-
ownedPlusSharedGIDs.push_back(bulkData.identifier(node)-1);
507-
}
508-
}
493+
globallySharedSelector &= !locallyOwnedSelector; //not owned
494+
stk::mesh::for_each_entity_run(bulkData, NODE_RANK, globallySharedSelector,
495+
[&](const stk::mesh::BulkData& mesh, stk::mesh::Entity node)
496+
{
497+
ownedPlusSharedGIDs.push_back(mesh.identifier(node)-1);
498+
});
509499
}
510500

511501
// Count # of local elements
512-
int numLocalElems=0;
513-
const stk::mesh::BucketVector &localElementBuckets = bulkData.get_buckets(ELEMENT_RANK, locallyOwnedSelector);
514-
for (size_t bucketIndex = 0; bucketIndex < localElementBuckets.size(); ++bucketIndex) {
515-
stk::mesh::Bucket &elemBucket = *localElementBuckets[bucketIndex];
516-
numLocalElems += elemBucket.size();
517-
}
502+
int numLocalElems=stk::mesh::count_entities(bulkData, ELEMENT_RANK, locallyOwnedSelector);
518503

519504
if (optPrintLocalStats) {
520505
for (int i=0; i<numRanks; ++i) {
@@ -543,53 +528,51 @@ int main(int argc, char *argv[]) {
543528

544529
RCP<Tpetra_Map> globalMapG = Teuchos::rcp(new Tpetra_Map( (Tpetra::global_size_t)numGlobalNodes,ownedGIDs(), (GO)0, Comm));
545530
RCP<Tpetra_Map> ownedPlusSharedMapG = Teuchos::rcp(new Tpetra_Map( (Tpetra::global_size_t)numGlobalNodes,ownedPlusSharedGIDs(), (GO)0, Comm));
546-
Kokkos::DualView<size_t*> nnzPerRowUpperBound("nnzbound",ownedGIDs.size());
531+
Kokkos::DualView<size_t*> nnzPerRowUpperBound("nnzbound",ownedPlusSharedGIDs.size());
547532
nnzPerRowUpperBound.template modify<typename Kokkos::DualView<size_t*>::host_mirror_space>();
548533
auto nnzPerRowUpperBound_h = nnzPerRowUpperBound.view_host();
549534

550535
// Count the local elements and get node index upper bound
551-
for (size_t bucketIndex = 0; bucketIndex < localElementBuckets.size(); ++bucketIndex) {
552-
stk::mesh::Bucket &elemBucket = *localElementBuckets[bucketIndex];
553-
for (size_t elemIndex = 0; elemIndex < elemBucket.size(); ++elemIndex) {
554-
stk::mesh::Entity elem = elemBucket[elemIndex];
555-
//TODO (Optimization) It's assumed all elements are the same type, so this is constant.
556-
//TODO Therefore there's no need to do this everytime.
557-
unsigned numNodes = bulkData.num_nodes(elem);
558-
stk::mesh::Entity const* nodes = bulkData.begin_nodes(elem);
536+
stk::mesh::for_each_entity_run(bulkData, ELEMENT_RANK, locallyOwnedSelector,
537+
[&](const stk::mesh::BulkData& mesh, stk::mesh::Entity elem)
538+
{
539+
stk::mesh::ConnectedEntities nodes = mesh.get_connected_entities(elem,NODE_RANK);
559540

560541
// NOTE: This will substantially overcount the NNZ needed. You should use hash table to be smarter
561-
for (unsigned inode = 0; inode < numNodes; ++inode) {
562-
GO GID = bulkData.identifier(nodes[inode])-1;
563-
LO LID = globalMapG->getLocalElement(GID);
542+
for (unsigned inode = 0; inode < nodes.size(); ++inode) {
543+
GO GID = mesh.identifier(nodes[inode])-1;
544+
LO LID = ownedPlusSharedMapG->getLocalElement(GID);
564545
if (LID != Teuchos::OrdinalTraits<LO>::invalid())
565-
nnzPerRowUpperBound_h[LID]+=numNodes;
546+
nnzPerRowUpperBound_h[LID]+=nodes.size();
566547
}
567-
}//end node loop
568-
}
548+
});
569549

570550
// Build the Graph
571551
RCP<Tpetra_FECrsGraph> StiffGraph = rcp(new Tpetra_FECrsGraph(globalMapG,ownedPlusSharedMapG,nnzPerRowUpperBound));
572552
Tpetra::beginAssembly(*StiffGraph);
573-
for (size_t bucketIndex = 0; bucketIndex < localElementBuckets.size(); ++bucketIndex) {
574-
stk::mesh::Bucket &elemBucket = *localElementBuckets[bucketIndex];
575-
for (size_t elemIndex = 0; elemIndex < elemBucket.size(); ++elemIndex) {
576-
stk::mesh::Entity elem = elemBucket[elemIndex];
577-
//TODO (Optimization) It's assumed all elements are the same type, so this is constant.
578-
//TODO Therefore there's no need to do this everytime.
579-
unsigned numNodes = bulkData.num_nodes(elem);
580-
stk::mesh::Entity const* nodes = bulkData.begin_nodes(elem);
581-
582-
Teuchos::Array<GO> global_ids(numNodes);
583-
for (unsigned inode = 0; inode < numNodes; ++inode) {
584-
GO GID = bulkData.identifier(nodes[inode])-1;
553+
stk::mesh::for_each_entity_run(bulkData, ELEMENT_RANK, locallyOwnedSelector,
554+
[&](const stk::mesh::BulkData& mesh, stk::mesh::Entity elem)
555+
{
556+
stk::mesh::ConnectedEntities nodes = mesh.get_connected_entities(elem,NODE_RANK);
557+
558+
Teuchos::Array<GO> global_ids(nodes.size());
559+
bool foundOwnedNode = false;
560+
for (unsigned inode = 0; inode < nodes.size(); ++inode) {
561+
if (mesh.bucket(nodes[inode]).owned()) {
562+
foundOwnedNode = true;
563+
}
564+
GO GID = mesh.identifier(nodes[inode])-1;
585565
global_ids[inode]=GID;
586566
}
587567

588-
for (unsigned inode = 0; inode < numNodes; ++inode) {
568+
if (!foundOwnedNode) {
569+
std::cout<<"Warning, element "<<mesh.identifier(elem)<<" on P"<<mesh.parallel_rank()<<" doesn't have any locally-owned nodes."<<std::endl;
570+
}
571+
572+
for (unsigned inode = 0; inode < nodes.size(); ++inode) {
589573
StiffGraph->insertGlobalIndices(global_ids[inode],global_ids());
590574
}
591-
}//end node loop
592-
}//end bucket
575+
});
593576

594577
Tpetra::endAssembly(*StiffGraph);
595578
tm = Teuchos::null;
@@ -599,49 +582,35 @@ int main(int argc, char *argv[]) {
599582
/**********************************************************************************/
600583
tm = rcp(new TimeMonitor(*TimeMonitor::getNewTimer("3) Compute Coordinates and Stats")));
601584

602-
typedef stk::mesh::Field<double> CoordFieldType;
603-
// get coordinates field
604-
CoordFieldType *coords = metaData.get_field<double>(NODE_RANK,"coordinates");
605-
606-
// get buckets containing entities of node rank
607-
stk::mesh::Selector nothingSelector;
608-
stk::mesh::Selector allSelector(!nothingSelector);
609-
stk::mesh::BucketVector const & nodeBuckets = bulkData.get_buckets( NODE_RANK,allSelector );
610585
std::vector<entity_type> bcNodes;
611586

612-
// loop over all mesh parts
613-
const stk::mesh::PartVector & all_parts = metaData.get_parts();
587+
stk::mesh::ExodusTranslator exodusTranslator(bulkData);
588+
stk::mesh::PartVector nodeSets = exodusTranslator.get_node_set_parts();
614589
ShardsCellTopology cellType;
615-
for (stk::mesh::PartVector::const_iterator i = all_parts.begin(); i != all_parts.end(); ++i) {
590+
for (const stk::mesh::Part* nodeSet : nodeSets) {
616591

617-
stk::mesh::Part & part = **i ;
618-
//printf("Loading mesh part %s isnode=%s\n",part.name().c_str(),part.primary_entity_rank() == NODE_RANK ? "YES" : "NO");
619-
// if part only contains nodes and isn't the ROOT_CELL_TOPOLOGY guy, then it is a node set
620-
if (part.primary_entity_rank() == NODE_RANK && part.name() != "{FEM_ROOT_CELL_TOPOLOGY_PART_NODE}") {
621-
stk::mesh::Selector partSelector(part);
622-
stk::mesh::Selector bcNodeSelector = partSelector & locallyOwnedSelector;
592+
stk::mesh::Selector bcNodeSelector = *nodeSet & locallyOwnedSelector;
623593

624594
if(bcNodes.size() == 0)
625-
stk::mesh::get_selected_entities(bcNodeSelector, nodeBuckets, bcNodes);
595+
stk::mesh::get_entities(bulkData, NODE_RANK, bcNodeSelector, bcNodes);
626596
else {
627597
std::vector<entity_type> myBcNodes;
628-
stk::mesh::get_selected_entities(bcNodeSelector, nodeBuckets, myBcNodes);
598+
stk::mesh::get_entities(bulkData, NODE_RANK, bcNodeSelector, myBcNodes);
629599
std::copy(myBcNodes.begin(),myBcNodes.end(),std::back_inserter(bcNodes));
630600
}
631601

632-
if(MyPID==0) printf("Adding nodeset %s\n",part.name().c_str());
602+
if(MyPID==0) printf("Adding nodeset %s\n",nodeSet->name().c_str());
603+
}
633604

634-
}
635-
else if(part.primary_entity_rank() == ELEMENT_RANK) {
605+
stk::mesh::PartVector elemBlocks = exodusTranslator.get_element_block_parts();
606+
for(const stk::mesh::Part* elemBlock : elemBlocks) {
636607
// Here the topology is defined from the mesh. Note that it is assumed
637608
// that all parts with elements (aka ELEMENT_RANK) have the same topology type
638-
auto myCell = stk::mesh::get_cell_topology(metaData.get_topology( part ));
609+
auto myCell = stk::mesh::get_cell_topology(metaData.get_topology( *elemBlock ));
639610
if(myCell.getCellTopologyData()) {
640-
cellType = myCell;
611+
cellType = myCell;
641612
}
642-
}
643-
644-
} // end loop over mesh parts
613+
}
645614

646615
int numNodesPerElem = cellType.getNodeCount();
647616
int numEdgesPerElem = cellType.getEdgeCount();
@@ -724,22 +693,22 @@ int main(int argc, char *argv[]) {
724693
/**********************************************************************************/
725694
/******************************** STASH COORDINATES *******************************/
726695
/**********************************************************************************/
696+
typedef stk::mesh::Field<double> CoordFieldType;
697+
// get coordinates field
698+
CoordFieldType *coords = metaData.get_field<double>(NODE_RANK,"coordinates");
699+
727700
// Put coordinates in multivector for output
728701
RCP<Tpetra_MultiVector> nCoord = rcp(new Tpetra_MultiVector(globalMapG,spaceDim));
729702
auto nCoord_h = nCoord->get2dViewNonConst();
730703
// Loop over elements
731704

732-
for (size_t bucketIndex = 0; bucketIndex < localElementBuckets.size(); ++bucketIndex) {
733-
stk::mesh::Bucket &elemBucket = *localElementBuckets[bucketIndex];
734-
for (size_t elemIndex = 0; elemIndex < elemBucket.size(); ++elemIndex) {
735-
stk::mesh::Entity elem = elemBucket[elemIndex];
736-
//TODO (Optimization) It's assumed all elements are the same type, so this is constant.
737-
//TODO Therefore there's no need to do this everytime.
738-
unsigned numNodes = bulkData.num_nodes(elem);
739-
stk::mesh::Entity const* nodes = bulkData.begin_nodes(elem);
740-
for (unsigned inode = 0; inode < numNodes; ++inode) {
741-
double *coord = stk::mesh::field_data(*coords, nodes[inode]);
742-
LO lid = globalMapG->getLocalElement((int)bulkData.identifier(nodes[inode]) -1);
705+
const stk::mesh::BucketVector &localElementBuckets = bulkData.get_buckets(ELEMENT_RANK, locallyOwnedSelector);
706+
for (const stk::mesh::Bucket* elemBucketPtr : localElementBuckets) {
707+
for (stk::mesh::Entity elem : *elemBucketPtr) {
708+
stk::mesh::ConnectedEntities nodes = bulkData.get_connected_entities(elem,NODE_RANK);
709+
for (unsigned inode = 0; inode < nodes.size(); ++inode) {
710+
double *coord = stk::mesh::field_data(*coords, nodes[inode]);
711+
LO lid = globalMapG->getLocalElement((int)bulkData.identifier(nodes[inode]) -1);
743712
if(lid != Teuchos::OrdinalTraits<LO>::invalid()) {
744713
nCoord_h[0][lid] = coord[0];
745714
nCoord_h[1][lid] = coord[1];
@@ -764,16 +733,11 @@ int main(int argc, char *argv[]) {
764733
std::map<std::pair<int,int>,int> local_edge_hash;
765734
std::vector<std::pair<int,int> > edge_vector;
766735

767-
for (size_t bucketIndex = 0; bucketIndex < localElementBuckets.size(); ++bucketIndex) {
768-
stk::mesh::Bucket &elemBucket = *localElementBuckets[bucketIndex];
769-
for (size_t elemIndex = 0; elemIndex < elemBucket.size(); ++elemIndex) {
770-
stk::mesh::Entity elem = elemBucket[elemIndex];
771-
//TODO (Optimization) It's assumed all elements are the same type, so this is constant.
772-
//TODO Therefore there's no need to do this everytime.
773-
unsigned numNodes = bulkData.num_nodes(elem);
774-
stk::mesh::Entity const* nodes = bulkData.begin_nodes(elem);
775-
for (unsigned inode = 0; inode < numNodes; ++inode) {
776-
double *coord = stk::mesh::field_data(*coords, nodes[inode]);
736+
for (const stk::mesh::Bucket* elemBucketPtr : localElementBuckets) {
737+
for (stk::mesh::Entity elem : *elemBucketPtr) {
738+
stk::mesh::ConnectedEntities nodes = bulkData.get_connected_entities(elem,NODE_RANK);
739+
for (unsigned inode = 0; inode < nodes.size(); ++inode) {
740+
const double *coord = stk::mesh::field_data(*coords, nodes[inode]);
777741
LO lid = globalMapG->getLocalElement((int)bulkData.identifier(nodes[inode]) -1);
778742
elemToNode(elem_ct,inode) = lid;
779743
if(lid != -1) {
@@ -873,15 +837,10 @@ int main(int argc, char *argv[]) {
873837

874838
// copy coordinates into cell workset
875839
int cellCounter = 0;
876-
for (size_t bucketIndex = 0; bucketIndex < localElementBuckets.size(); ++bucketIndex) {
877-
stk::mesh::Bucket &elemBucket = *localElementBuckets[bucketIndex];
878-
for (size_t elemIndex = 0; elemIndex < elemBucket.size(); ++elemIndex) {
879-
stk::mesh::Entity elem = elemBucket[elemIndex];
880-
//TODO (Optimization) It's assumed all elements are the same type, so this is constant.
881-
//TODO Therefore there's no need to do this everytime.
882-
unsigned numNodes = bulkData.num_nodes(elem);
883-
stk::mesh::Entity const* nodes = bulkData.begin_nodes(elem);
884-
for (unsigned inode = 0; inode < numNodes; ++inode) {
840+
for (const stk::mesh::Bucket* elemBucket : localElementBuckets) {
841+
for (stk::mesh::Entity elem : *elemBucket) {
842+
stk::mesh::ConnectedEntities nodes = bulkData.get_connected_entities(elem,NODE_RANK);
843+
for (unsigned inode = 0; inode < nodes.size(); ++inode) {
885844
double *coord = stk::mesh::field_data(*coords, nodes[inode]);
886845
cellWorkset(cellCounter, inode, 0) = coord[0];
887846
cellWorkset(cellCounter, inode, 1) = coord[1];
@@ -1001,16 +960,12 @@ int main(int argc, char *argv[]) {
1001960
//"WORKSET CELL" loop: local cell ordinal is relative to numLocalElems
1002961
//JJH runs from 0 to (#local cells - 1)
1003962
int worksetCellOrdinal = 0;
1004-
for (size_t bucketIndex = 0; bucketIndex < localElementBuckets.size(); ++bucketIndex) {
1005-
1006-
stk::mesh::Bucket &elemBucket = *localElementBuckets[bucketIndex];
1007-
for (size_t elemIndex = 0; elemIndex < elemBucket.size(); ++elemIndex) {
963+
for (const stk::mesh::Bucket* elemBucketPtr : localElementBuckets) {
964+
for (stk::mesh::Entity elem : *elemBucketPtr) {
1008965

1009966
// Compute cell ordinal relative to the current workset
1010967

1011-
// Get element entity from id of cell
1012-
entity_type elem = elemBucket[elemIndex];
1013-
entity_type const* worksetNodes = bulkData.begin_nodes(elem);
968+
stk::mesh::ConnectedEntities worksetNodes = bulkData.get_connected_entities(elem,NODE_RANK);
1014969

1015970
// "CELL EQUATION" loop for the workset cell: cellRow is relative to the cell DoF numbering
1016971
for (int cellRow = 0; cellRow < numFieldsG; cellRow++) {
@@ -1036,7 +991,7 @@ int main(int argc, char *argv[]) {
1036991
}// end workset cell loop
1037992

1038993

1039-
} //for (size_t bucketIndex = 0; ...
994+
} //for (localElementBuckets
1040995

1041996
}// end workset loop
1042997

@@ -1124,10 +1079,9 @@ int main(int argc, char *argv[]) {
11241079
double TotalErrorExactSol = 0.0;
11251080

11261081
// Get exact solution at nodes
1127-
for (size_t bucketIndex = 0; bucketIndex < localNodeBuckets.size(); ++bucketIndex) {
1128-
stk::mesh::Bucket &nodeBucket = *localNodeBuckets[bucketIndex];
1129-
for (size_t nodeIndex = 0; nodeIndex < nodeBucket.size(); ++nodeIndex) {
1130-
stk::mesh::Entity node = nodeBucket[nodeIndex];
1082+
const stk::mesh::BucketVector &localNodeBuckets = bulkData.get_buckets(NODE_RANK, locallyOwnedSelector);
1083+
for (const stk::mesh::Bucket* bucketPtr : localNodeBuckets) {
1084+
for (stk::mesh::Entity node : *bucketPtr) {
11311085
double * coord = stk::mesh::field_data(*coords, node);
11321086
// look up exact value of function on boundary
11331087
double x = coord[0];

0 commit comments

Comments
 (0)