Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix refinement next to refined blocks #928

Merged
merged 10 commits into from
Sep 29, 2023
Merged

Conversation

bprather
Copy link
Collaborator

@bprather bprather commented Aug 22, 2023

PR Summary

Fixes #927

Not attached to the carry-around-the-list interface here, or the cheeky double-lambda.

Note that the issue this fixes is really two issues:

  1. There must be an MPI sync between ProlongateShared and ProlongateInternal. This is the primary error and easy to change.
  2. During such an MPI sync, one should not prioritize zones from the new block, which were generated by prolongation, over "naturally" finer zones in a previously-refined block.

Most of the code is aimed at dealing with (2), which requires determining and then syncing according to a special priority order, namely:

  1. any neighbor blocks at the new refinement level of this block
  2. this block
  3. any neighbor blocks at the parent refinement level

That is, freshly-refined blocks should own any boundaries with coarser blocks, but none of their boundaries with previously-refined blocks (and should still choose by Morton number among themselves).

Still working on getting this entirely correct, (2) and (3) are muddy in the code as posted.

PR Checklist

  • Code passes cpplint
  • New features are documented.
  • Adds a test for any bugs fixed. Adds tests for new features.
  • Code is formatted
  • Changes are summarized in CHANGELOG.md
  • CI has been triggered on Darwin for performance regression tests.
  • Docs build
  • (@lanl.gov employees) Update copyright on changed files

Ben Prather added 2 commits August 22, 2023 16:54
During re-meshing, track which meshblocks are newly created.
After prolongating shared boundaries, but before prolongating
internal boundaries, update elements on block faces to respect
the ownership model.

Still needs tweaks to the new-mesh priority!
@bprather
Copy link
Collaborator Author

@par-hermes format

Comment on lines 478 to 482

// Output variables in use in this run
if (Globals::my_rank == 0) {
std::cout << "#Variables in use:\n" << *(resolved_packages) << std::endl;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this included in another PR? Did that not get merged?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that one's still in queue. I pinged some people, probably it will still go in before this one and I can avoid having to correct my mistake here.

return 2 * a.level();
};

auto ownership_less_than = [ownership_level](const LogicalLocation &a,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still cheeky IMO

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As in, I should collapse it? This seemed pretty easy to understand, if a little over-engineered

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no no---it's fine. Cheeky is not a bad thing.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no no---it's fine. Cheeky is not a bad thing.

@Yurlungur
Copy link
Collaborator

Check boxes needed :)

Not for this PR, but we really need a regression test

@lroberts36
Copy link
Collaborator

Not for this PR, but we really need a regression test

Yeah, we need to write a vector wave equation example I think.

Copy link
Collaborator

@lroberts36 lroberts36 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good to me, but one potential bug and one potential performance enhancement below.

src/mesh/amr_loadbalance.cpp Outdated Show resolved Hide resolved
@@ -789,6 +789,7 @@ void Mesh::RedistributeAndRefineMeshBlocks(ParameterInput *pin, ApplicationInput
RegionSize block_size = GetBlockSize();

BlockList_t new_block_list(nbe - nbs + 1);
std::set<LogicalLocation> newly_refined;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we may want this to be a std::unordered_set for performance reasons.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I think, the list could potentially be long and we're checking membership.
What's a good hash function for the unordered_set? Just morton number?

Speaking of that, I think I populate this list incorrectly, since I only pull from nbs to nbe of the global block list in populating newly_refined, meaning I need to collate the lists from all ranks. So, also going to fix that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A hash for LogicalLocation is injected into the std:: namespace, so std::unordered_map<LogicalLocation> should just work.

Good catch. Yeah, I think you need the locations on all ranks.

@bprather
Copy link
Collaborator Author

bprather commented Sep 5, 2023

Okay, as updated the PR now gathers new refinements by comparing the global new & old lists of blocks (I think. The variable naming wasn't completely clear to me in an MPI context and there are no relevant comments). Testing with multiple MPI ranks now.

Also switched to unordered_map, which required a bit of reordering in the LogicalLocation header. The class definition for LogicalLocation contains one member function implementation which uses an unordered_set<LogicalLocation>, which relies on std::hash<LogicalLocation>, which relies on... the class definition of LogicalLocation. Solution:

  1. Declare class LogicalLocation
  2. Declare std::hash<LogicalLocation>
  3. Implement LogicalLocation
  4. Implement std::hash<LogicalLocation>

Pretty sure this is the simple way to solve it, but maybe I'm missing something.

Copy link
Collaborator

@lroberts36 lroberts36 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for switching over to std::unordered_set. I think your solution is the right one.

@bprather
Copy link
Collaborator Author

Would love to just merge this in the next few days if there aren't objections

@Yurlungur
Copy link
Collaborator

I'm enabling auto merge

@Yurlungur Yurlungur merged commit 79151f1 into develop Sep 29, 2023
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Parthenon does not respect ownership of shared prolongated elements
3 participants