Skip to content

Commit 0a57ef5

Browse files
authored
Issue: new probe definitions in a restart sim affect part procId ownership (#481)
* Exploit "generateIds" and allow for the ability to mix and match new and old probe defintions in an arbitrary input order. The code now supports mix/matching by looking for the original part and assigning rank ownership based on the previous rule, not the now "candidate" rank suggestion. * remove probe file name tied to rank id. No need, in practice, and new design only knows if this probe is on or off the rank. Notes: a) not a bad design now. b) design of probeInfo->partName_[j] could benifit from a polymorphic design, however, no need for today:)
1 parent a396a87 commit 0a57ef5

File tree

2 files changed

+55
-36
lines changed

2 files changed

+55
-36
lines changed

include/DataProbePostProcessing.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class DataProbeInfo {
4949
std::vector<int> isLineOfSite_;
5050
std::vector<int> isRing_;
5151
std::vector<std::string> partName_;
52-
std::vector<int> processorId_;
52+
std::vector<int> probeOnThisRank_;
5353
std::vector<int> numPoints_;
5454
std::vector<int> numLinePoints_;
5555
std::vector<int> numTotalPoints_;

src/DataProbePostProcessing.C

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ DataProbePostProcessing::load(
111111
{
112112
// check for any data probes
113113
const YAML::Node y_dataProbe = y_node["data_probes"];
114-
if (y_dataProbe) {
114+
if ( y_dataProbe ) {
115115
NaluEnv::self().naluOutputP0() << "DataProbePostProcessing::load" << std::endl;
116116

117117
// extract the frequency of output
@@ -123,7 +123,7 @@ DataProbePostProcessing::load(
123123
get_if_present(y_dataProbe, "search_expansion_factor", searchExpansionFactor_, searchExpansionFactor_);
124124

125125
const YAML::Node y_specs = expect_sequence(y_dataProbe, "specifications", false);
126-
if (y_specs) {
126+
if ( y_specs ) {
127127

128128
// each specification can have multiple probes
129129
for (size_t ispec = 0; ispec < y_specs.size(); ++ispec) {
@@ -144,7 +144,7 @@ DataProbePostProcessing::load(
144144

145145
// extract the set of from target names; each spec is homogeneous in this respect
146146
const YAML::Node & fromTargets = y_spec["from_target_part"];
147-
if (fromTargets.Type() == YAML::NodeType::Scalar) {
147+
if ( fromTargets.Type() == YAML::NodeType::Scalar ) {
148148
probeSpec->fromTargetNames_.resize(1);
149149
probeSpec->fromTargetNames_[0] = fromTargets.as<std::string>() ;
150150
}
@@ -177,7 +177,7 @@ DataProbePostProcessing::load(
177177

178178
// resize is all; general
179179
probeInfo->partName_.resize(numProbes);
180-
probeInfo->processorId_.resize(numProbes);
180+
probeInfo->probeOnThisRank_.resize(numProbes,0);
181181
probeInfo->numPoints_.resize(numProbes);
182182
probeInfo->numLinePoints_.resize(numProbes);
183183
probeInfo->numTotalPoints_.resize(numProbes);
@@ -201,7 +201,7 @@ DataProbePostProcessing::load(
201201
int probeCounter = 0;
202202

203203
// points along a line-of-site
204-
if (y_loss) {
204+
if ( y_loss ) {
205205

206206
// loop over each line of site probe
207207
for (size_t ilos = 0; ilos < y_loss.size(); ++ilos, probeCounter++) {
@@ -210,9 +210,12 @@ DataProbePostProcessing::load(
210210

211211
// l-o-s is active..
212212
probeInfo->isLineOfSite_[probeCounter] = 1;
213-
213+
214214
// processor id; distribute los equally over the number of processors
215-
probeInfo->processorId_[probeCounter] = divProcProbe > 0 ? probeCounter % divProcProbe : 0;
215+
int candidateId = divProcProbe > 0 ? probeCounter % divProcProbe : 0;
216+
217+
if ( candidateId == NaluEnv::self().parallel_rank() )
218+
probeInfo->probeOnThisRank_[probeCounter] = 1;
216219

217220
// name; which is the part name of choice
218221
const YAML::Node nameNode = y_los["name"];
@@ -259,7 +262,10 @@ DataProbePostProcessing::load(
259262
probeInfo->isRing_[probeCounter] = 1;
260263

261264
// processor id; distribute rings equally over the number of processors
262-
probeInfo->processorId_[probeCounter] = divProcProbe > 0 ? probeCounter % divProcProbe : 0;
265+
int candidateId = divProcProbe > 0 ? probeCounter % divProcProbe : 0;
266+
267+
if ( candidateId == NaluEnv::self().parallel_rank() )
268+
probeInfo->probeOnThisRank_[probeCounter] = 1;
263269

264270
// name that will be the part of choice
265271
const YAML::Node nameNode = y_ring["name"];
@@ -330,7 +336,7 @@ DataProbePostProcessing::load(
330336

331337
// extract the output variables
332338
const YAML::Node y_outputs = expect_sequence(y_spec, "output_variables", false);
333-
if (y_outputs) {
339+
if ( y_outputs ) {
334340
for (size_t ioutput = 0; ioutput < y_outputs.size(); ++ioutput) {
335341
const YAML::Node y_output = y_outputs[ioutput];
336342

@@ -461,22 +467,35 @@ DataProbePostProcessing::initialize()
461467
// extract some things off of the probeInfo
462468
stk::mesh::Part *probePart = probeInfo->part_[j];
463469
const int numTotalPoints = probeInfo->numTotalPoints_[j];
464-
const int processorId = probeInfo->processorId_[j];
470+
const int probeOnThisRank = probeInfo->probeOnThisRank_[j];
465471
const bool generateNewIds = probeInfo->generateNewIds_[j];
466472

467-
// generate new ids; only if the part was
468-
std::vector<stk::mesh::EntityId> availableNodeIds(numTotalPoints);
469-
if ( generateNewIds > 0 )
473+
// Objective: fill the node vec. Two cases: either the part existed (with nodes) or not
474+
std::vector<stk::mesh::Entity> &nodeVec = probeInfo->nodeVector_[j];
475+
476+
// generate new ids is true only if the part was in existance at setup, e.g., a restart
477+
if ( generateNewIds > 0 ) {
478+
// no previous parts existed, generate new ids based on size of probe
479+
std::vector<stk::mesh::EntityId> availableNodeIds(numTotalPoints);
480+
// generate_new_ids must be called on all ranks
470481
bulkData.generate_new_ids(stk::topology::NODE_RANK, numTotalPoints, availableNodeIds);
471-
472-
// check to see if part has nodes on it already
473-
if ( processorId == NaluEnv::self().parallel_rank()) {
474482

475-
// set some data
483+
if ( probeOnThisRank ) {
484+
// calling declare_entity on this desired rank determines entity ownership
485+
NaluEnv::self().naluOutput() << "probeOnThisRank " << NaluEnv::self().parallel_rank()
486+
<< " for part: " << probeInfo->partName_[j] << std::endl;
487+
nodeVec.resize(numTotalPoints);
488+
for (int i = 0; i < numTotalPoints; ++i) {
489+
stk::mesh::Entity theNode = bulkData.declare_entity(stk::topology::NODE_RANK, availableNodeIds[i], *probePart);
490+
nodeVec[i] = theNode;
491+
}
492+
}
493+
}
494+
else {
495+
// previous part existed, make sure that the part has nodes on it already
476496
int checkNumTotalPoints = 0;
477497
bool nodesExist = false;
478-
std::vector<stk::mesh::Entity> &nodeVec = probeInfo->nodeVector_[j];
479-
498+
480499
stk::mesh::Selector s_local_nodes
481500
= metaData.locally_owned_part() &stk::mesh::Selector(*probePart);
482501

@@ -490,24 +509,26 @@ DataProbePostProcessing::initialize()
490509
nodesExist = true;
491510
}
492511
}
493-
494-
// check if nodes exists. If they do, did the number of points match?
512+
513+
// check if nodes exists.
495514
if ( nodesExist ) {
515+
516+
// subtlety here... if the nodes existed, then ensure that this rank owns the part
517+
probeInfo->probeOnThisRank_[j] = 1;
518+
519+
NaluEnv::self().naluOutput() << "probeOnThisRank " << NaluEnv::self().parallel_rank()
520+
<< " for part: " << probeInfo->partName_[j] << std::endl;
521+
522+
// sanity check: did the number of points match?
496523
if ( checkNumTotalPoints != numTotalPoints ) {
497524
std::cout << "Number of points specified within input file does not match nodes that exists: " << probePart->name() << std::endl;
498525
std::cout << "The old and new node count is as follows: " << numTotalPoints << " " << checkNumTotalPoints << std::endl;
499526
probeInfo->numTotalPoints_[j] = checkNumTotalPoints;
500527
}
501528
}
502529
else {
503-
// only declare entities on which these nodes parallel rank resides
504-
nodeVec.resize(numTotalPoints);
505-
506-
// declare the entity on this rank (rank is determined by calling declare_entity on this rank)
507-
for (int i = 0; i < numTotalPoints; ++i) {
508-
stk::mesh::Entity theNode = bulkData.declare_entity(stk::topology::NODE_RANK, availableNodeIds[i], *probePart);
509-
nodeVec[i] = theNode;
510-
}
530+
// reinforce that this probve is not on this rank
531+
probeInfo->probeOnThisRank_[j] = 0;
511532
}
512533
}
513534
}
@@ -757,12 +778,10 @@ DataProbePostProcessing::provide_output(
757778
for ( int inp = 0; inp < probeInfo->numProbes_; ++inp ) {
758779

759780
// open the file for this probe
760-
const int processorId = probeInfo->processorId_[inp];
761-
std::ostringstream ss;
762-
ss << processorId;
763-
const std::string fileName = probeInfo->partName_[inp] + "_" + ss.str() + ".dat";
764-
std::ofstream myfile;
765-
if ( processorId == NaluEnv::self().parallel_rank()) {
781+
if ( probeInfo->probeOnThisRank_[inp] ) {
782+
783+
const std::string fileName = probeInfo->partName_[inp] + ".dat";
784+
std::ofstream myfile;
766785

767786
// one banner per file
768787
const bool addBanner = std::ifstream(fileName.c_str()) ? false : true;

0 commit comments

Comments
 (0)