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

Add hook for UserWorkBeforeLoop #971

Merged
merged 6 commits into from
Nov 7, 2023
Merged

Conversation

Yurlungur
Copy link
Collaborator

@Yurlungur Yurlungur commented Nov 6, 2023

PR Summary

What it says on the can... This kind of workflow has come up a number of times for us in downstream applications, so I decided to finally stick it into parthenon. The basic need here is that you want to modify some variables after the mesh has been generated and problem generator has been called, for example, because you want to compute some global reduction variable, you want to normalize some field, you want to apply atmospheres, etc.

Now this can be done within a problem generator in some cases, for example with mesh-level problem generators. But it may be desired to do this work for every problem (for example). I add a hook in ApplicationInputs and in StateDescriptor. As usual, you assign a function pointer, and then it gets called by EvolutionDriver.

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

Copy link
Collaborator

@brryan brryan left a comment

Choose a reason for hiding this comment

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

This is a nice addition, will clean up some downstream code :)

Maybe just check formatting though.

example/advection/advection_package.cpp Outdated Show resolved Hide resolved
example/advection/advection_package.hpp Outdated Show resolved Hide resolved
@Yurlungur
Copy link
Collaborator Author

Maybe just check formatting though.

Thanks for the catches. Fixed. :)

doc/sphinx/src/interface/state.rst Show resolved Hide resolved
@@ -94,6 +94,7 @@ class Mesh {

// data
bool modified;
const bool is_restart;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I wanted people to be able to easily do different things upon restart vs first initialization, but without having to register two separate, maybe almost identical functions. There might be a better way than storing restart state in the mesh pointer, but it also seemed natural as something inherited from Athena++.

Copy link
Collaborator

Choose a reason for hiding this comment

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

What we've typically been doing is to check for tm.cycle != 0, which should also be possible in the new callbacks given that the SimTime object is passed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point---is_restart feels cleaner/less ambiguous to me, but I'm fine to remove this and tell people to use tm.cycle if preferred.

Comment on lines +409 to +411
void UserWorkBeforeLoop(Mesh *pmesh, ParameterInput *pin, SimTime &tm) const {
if (UserWorkBeforeLoopMesh != nullptr) return UserWorkBeforeLoopMesh(pmesh, pin, tm);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This copies the design of the other function hooks in state descriptor, but we could cut out the middle and just check for nullptr in the function pointer itself.

Comment on lines 78 to 86
// Before loop do work
// App input version
if (app_input->UserWorkBeforeLoop != nullptr) {
app_input->UserWorkBeforeLoop(pmesh, pinput, tm);
}
// packages version
for (auto &[name, pkg] : pmesh->packages.AllPackages()) {
pkg->UserWorkBeforeLoop(pmesh, pinput, tm);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Many of the older function hooks store the function pointers in the mesh. I think this is a holdover from Athena++ and in parthenon, it's more natural to just query the app input or the state descriptor directly.

@Yurlungur
Copy link
Collaborator Author

Does anyone from the AthenaPK team want to take a look at this before I merge it? Changes are pretty minor and just value-add, so maybe not necessary. @BenWibking @pgrete @forrestglines .

@Yurlungur Yurlungur self-assigned this Nov 6, 2023
Copy link
Collaborator

@pgrete pgrete left a comment

Choose a reason for hiding this comment

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

LGTM

We already used something similar in AthenaPK, but realized it as time or cycle based conditional within the PreStep callback.

src/driver/driver.cpp Show resolved Hide resolved
@@ -94,6 +94,7 @@ class Mesh {

// data
bool modified;
const bool is_restart;
Copy link
Collaborator

Choose a reason for hiding this comment

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

What we've typically been doing is to check for tm.cycle != 0, which should also be possible in the new callbacks given that the SimTime object is passed.

@Yurlungur Yurlungur merged commit 0279e1d into develop Nov 7, 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.

5 participants