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 a MeshData variant for refinement tagging #1182

Open
wants to merge 54 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
6814173
meshdata version of refinement tagging
acreyes Sep 26, 2024
6df75e7
got initialization and vector indices working
acreyes Sep 26, 2024
2fdc2ed
fix tensor indices
acreyes Sep 27, 2024
5cb25b4
added CheckRefinementMesh to fine-advection example
acreyes Sep 27, 2024
3ad74e1
cleaning up var names
acreyes Sep 28, 2024
16a1c58
cleanup
acreyes Sep 28, 2024
6e1b905
adding scatter view utilities
acreyes Sep 28, 2024
2b6545c
scatterview version of refinement
acreyes Sep 28, 2024
ccf72b0
burgers-benchmark uses Tag<MeshData>
acreyes Sep 29, 2024
d7d536f
add hierarchial par
acreyes Sep 29, 2024
fa37fb9
cleanup includes
acreyes Sep 29, 2024
401f412
missed one
acreyes Sep 29, 2024
638e077
Update CHANGELOG.md
acreyes Sep 29, 2024
b6e0e6b
remove default level tag
acreyes Sep 29, 2024
2b3f32a
default CheckRefineMesh to true
acreyes Sep 29, 2024
622882d
respect amr_criteria max_level
acreyes Sep 29, 2024
5b7863b
renaming delta_levels->amr_tags, mc->md
acreyes Sep 30, 2024
06e0ade
fix refinement/bc order
acreyes Sep 30, 2024
3cf589d
docs for CheckRefinementMesh
acreyes Sep 30, 2024
7ea604c
move amr_tags array to mesh
acreyes Oct 1, 2024
d2a92b0
Merge branch 'develop' into acreyes/meshdata-refinement
Yurlungur Oct 14, 2024
dd4a652
adding comments for ScatterMax view
acreyes Oct 2, 2024
fe95b47
it compiles at least
jonahm-LANL Sep 13, 2024
554a1d4
add easy machinery to register reflecting BCs
jonahm-LANL Sep 13, 2024
781d032
changelog
acreyes Nov 8, 2024
c1beb9e
swarm bcs differetn from mesh bcs
jonahm-LANL Sep 13, 2024
9e8b17f
use new input block
jonahm-LANL Sep 13, 2024
bcbc1c7
typo
jonahm-LANL Sep 27, 2024
b2a5e52
add error checking for swarm/mesh BC consistency
jonahm-LANL Sep 27, 2024
46517ab
typo
jonahm-LANL Sep 27, 2024
f9313d3
phdf diff
jonahm-LANL Sep 28, 2024
20abf5a
Register reflecting BCs for advection examples
jonahm-LANL Sep 28, 2024
1408bf0
typo
jonahm-LANL Sep 28, 2024
5b91a7a
silly backwards compatibility thing to make it so you don't have to s…
jonahm-LANL Sep 28, 2024
382a6a7
working
lroberts36 Oct 10, 2024
4ee02c5
changelog
lroberts36 Oct 10, 2024
862c2a9
Make everything work
lroberts36 Oct 10, 2024
bd50d24
format
lroberts36 Oct 10, 2024
09464c2
maybe fix doc issue?
lroberts36 Oct 10, 2024
df06a50
Address CUDA MPI/ICP issue with Kokkos <=4.4.1 (#1189)
pgrete Oct 15, 2024
511c77c
Jonah's fix for this CI issue
brryan Oct 31, 2024
328dc33
CHANGELOG
brryan Oct 31, 2024
5e657c0
Remove else from if constexpr when there are returns
adamdempsey90 Oct 31, 2024
dd928ab
Consolidate buffer packing functions with less atomics (#1199)
alexrlongne Nov 1, 2024
0cbbdac
[Trivial] Fix type used for array init (#1170)
pgrete Nov 4, 2024
01517f7
Leapfrog fix (#1206)
brryan Nov 8, 2024
3ddbb9f
removing meshblock amr_criteria
acreyes Nov 8, 2024
454324f
Merge remote-tracking branch 'upstream/develop' into acreyes/meshdata…
acreyes Nov 14, 2024
9cdf3aa
Merge remote-tracking branch 'upstream/develop' into acreyes/meshdata…
acreyes Nov 15, 2024
ed3e16f
use pack.UpperBound(b) to check allocation
acreyes Nov 15, 2024
cc01266
Merge branch 'develop' into acreyes/meshdata-refinement
pgrete Nov 25, 2024
5a2470b
Merge branch 'develop' into acreyes/meshdata-refinement
Yurlungur Nov 25, 2024
cc97120
remove meshblock first/second derivative from cpp
acreyes Nov 25, 2024
9338c54
linting
acreyes Nov 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Current develop

### Added (new features/APIs/variables/...)
- [[PR 1182]](https://github.com/parthenon-hpc-lab/parthenon/pull/1182) Add a MeshData variant for refinement tagging
- [[PR 1103]](https://github.com/parthenon-hpc-lab/parthenon/pull/1103) Add sparsity to vector wave equation test
- [[PR 1185]](https://github.com/parthenon-hpc-lab/parthenon/pull/1185/files) Bugfix to particle defragmentation
- [[PR 1184]](https://github.com/parthenon-hpc-lab/parthenon/pull/1184) Fix swarm block neighbor indexing in 1D, 2D
Expand Down
21 changes: 4 additions & 17 deletions benchmarks/burgers/burgers_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,27 +120,14 @@ TaskCollection BurgersDriver::MakeTaskCollection(BlockList_t &blocks, const int

auto fill_deriv = tl.AddTask(update, FillDerived<MeshData<Real>>, mc1.get());

auto set_bc = tl.AddTask(update, parthenon::ApplyBoundaryConditionsMD, mc1);

// estimate next time step
if (stage == integrator->nstages) {
auto new_dt = tl.AddTask(update, EstimateTimestep<MeshData<Real>>, mc1.get());
}
}

TaskRegion &async_region2 = tc.AddRegion(blocks.size());
assert(blocks.size() == async_region2.size());
for (int i = 0; i < blocks.size(); i++) {
auto &pmb = blocks[i];
auto &tl = async_region2[i];
auto &sc1 = pmb->meshblock_data.Get(stage_name[stage]);

// set physical boundaries
auto set_bc = tl.AddTask(none, parthenon::ApplyBoundaryConditions, sc1);

if (stage == integrator->nstages) {
// Update refinement
if (pmesh->adaptive) {
auto tag_refine = tl.AddTask(
set_bc, parthenon::Refinement::Tag<MeshBlockData<Real>>, sc1.get());
auto tag_refine =
tl.AddTask(set_bc, parthenon::Refinement::Tag<MeshData<Real>>, mc1.get());
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions doc/sphinx/src/interface/state.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ several useful features and functions.
``std::function`` member ``CheckRefinementBlock`` if set (defaults to
``nullptr`` and therefore a no-op) that allows an application to define
an application-specific refinement/de-refinement tagging function.
- ``void CheckRefinement(MeshData<Real>* md)`` delegates to the
``std::function`` member ``CheckRefinementMesh`` if set (defaults to
``nullptr`` and therefore a no-op) that allows an application to define
an application-specific refinement/de-refinement tagging function.
- ``void PreStepDiagnostics(SimTime const &simtime, MeshData<Real> *rc)``
deletgates to the ``std::function`` member ``PreStepDiagnosticsMesh`` if
set (defaults to ``nullptr`` an therefore a no-op) to print diagnostics
Expand Down
67 changes: 37 additions & 30 deletions example/fine_advection/advection_package.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,50 +118,57 @@ std::shared_ptr<StateDescriptor> Initialize(ParameterInput *pin) {
Metadata({Metadata::Cell, Metadata::Derived, Metadata::OneCopy}));
}

pkg->CheckRefinementBlock = CheckRefinement;
pkg->CheckRefinementMesh = CheckRefinementMesh;
pkg->EstimateTimestepMesh = EstimateTimestep;
pkg->FillDerivedMesh = FillDerived;
return pkg;
}

AmrTag CheckRefinement(MeshBlockData<Real> *rc) {
void CheckRefinementMesh(MeshData<Real> *md, parthenon::ParArray1D<AmrTag> &amr_tags) {
std::shared_ptr<StateDescriptor> pkg =
rc->GetMeshPointer()->packages.Get("advection_package");
md->GetMeshPointer()->packages.Get("advection_package");
auto do_regular_advection = pkg->Param<bool>("do_regular_advection");
if (do_regular_advection) {
// refine on advected, for example. could also be a derived quantity
static auto desc = parthenon::MakePackDescriptor<Conserved::phi>(rc);
auto pack = desc.GetPack(rc);

auto pmb = rc->GetBlockPointer();
IndexRange ib = pmb->cellbounds.GetBoundsI(IndexDomain::entire);
IndexRange jb = pmb->cellbounds.GetBoundsJ(IndexDomain::entire);
IndexRange kb = pmb->cellbounds.GetBoundsK(IndexDomain::entire);
static auto desc = parthenon::MakePackDescriptor<Conserved::phi>(md);
auto pack = desc.GetPack(md);

typename Kokkos::MinMax<Real>::value_type minmax;
parthenon::par_reduce(
parthenon::loop_pattern_mdrange_tag, PARTHENON_AUTO_LABEL, DevExecSpace(), 0,
pack.GetNBlocks() - 1, // Runs from [0, 0] since pack built from MeshBlockData
pack.GetLowerBoundHost(0), pack.GetUpperBoundHost(0), kb.s, kb.e, jb.s, jb.e,
ib.s, ib.e,
KOKKOS_LAMBDA(const int b, const int n, const int k, const int j, const int i,
typename Kokkos::MinMax<Real>::value_type &lminmax) {
lminmax.min_val = (pack(b, n, k, j, i) < lminmax.min_val ? pack(b, n, k, j, i)
: lminmax.min_val);
lminmax.max_val = (pack(b, n, k, j, i) > lminmax.max_val ? pack(b, n, k, j, i)
: lminmax.max_val);
},
Kokkos::MinMax<Real>(minmax));

auto pkg = pmb->packages.Get("advection_package");
const auto &refine_tol = pkg->Param<Real>("refine_tol");
const auto &derefine_tol = pkg->Param<Real>("derefine_tol");

if (minmax.max_val > refine_tol && minmax.min_val < derefine_tol)
return AmrTag::refine;
if (minmax.max_val < derefine_tol) return AmrTag::derefine;
auto ib = md->GetBoundsI(IndexDomain::entire);
auto jb = md->GetBoundsJ(IndexDomain::entire);
auto kb = md->GetBoundsK(IndexDomain::entire);
auto scatter_tags = amr_tags.ToScatterView<Kokkos::Experimental::ScatterMax>();
parthenon::par_for_outer(
PARTHENON_AUTO_LABEL, 0, 0, 0, pack.GetNBlocks() - 1, 0,
pack.GetMaxNumberOfVars() - 1, kb.s, kb.e,
KOKKOS_LAMBDA(parthenon::team_mbr_t team_member, const int b, const int n,
const int k) {
if (pack.GetIndex(b, Conserved::phi()) < 0) return;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there another way to check if a variable in a sparse pack is allocated, maybe using n similar to VariablePack::IsAllocated?

Copy link
Collaborator

@lroberts36 lroberts36 Nov 15, 2024

Choose a reason for hiding this comment

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

SparsePacks only pack variables that are allocated, so the standard way to check if a field is allocated is to compare

bool is_my_field_allocated = sparse_pack.GetSize(b, my_field_t()) > 0;

typename Kokkos::MinMax<Real>::value_type minmax;
par_reduce_inner(
parthenon::inner_loop_pattern_ttr_tag, team_member, jb.s, jb.e, ib.s, ib.e,
[&](const int j, const int i,
typename Kokkos::MinMax<Real>::value_type &lminmax) {
lminmax.min_val =
(pack(b, n, k, j, i) < lminmax.min_val ? pack(b, n, k, j, i)
: lminmax.min_val);
lminmax.max_val =
(pack(b, n, k, j, i) > lminmax.max_val ? pack(b, n, k, j, i)
: lminmax.max_val);
},
Kokkos::MinMax<Real>(minmax));

auto tags_access = scatter_tags.access();
auto flag = AmrTag::same;
if (minmax.max_val > refine_tol && minmax.min_val < derefine_tol)
flag = AmrTag::refine;
if (minmax.max_val < derefine_tol) flag = AmrTag::derefine;
tags_access(b).update(flag);
});
amr_tags.ContributeScatter(scatter_tags);
}
return AmrTag::same;
}

Real EstimateTimestep(MeshData<Real> *md) {
Expand Down
1 change: 1 addition & 0 deletions example/fine_advection/advection_package.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ VARIABLE(advection, divD);

std::shared_ptr<StateDescriptor> Initialize(ParameterInput *pin);
AmrTag CheckRefinement(MeshBlockData<Real> *rc);
void CheckRefinementMesh(MeshData<Real> *md, parthenon::ParArray1D<AmrTag> &amr_tags);
Real EstimateTimestep(MeshData<Real> *md);
TaskStatus FillDerived(MeshData<Real> *md);

Expand Down
55 changes: 34 additions & 21 deletions src/amr_criteria/amr_criteria.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,31 +78,44 @@ std::shared_ptr<AMRCriteria> AMRCriteria::MakeAMRCriteria(std::string &criteria,
block_name + ": " + criteria);
}

AMRBounds AMRCriteria::GetBounds(const MeshBlockData<Real> *rc) const {
auto ib = rc->GetBoundsI(IndexDomain::interior);
auto jb = rc->GetBoundsJ(IndexDomain::interior);
auto kb = rc->GetBoundsK(IndexDomain::interior);
return AMRBounds(ib, jb, kb);
}

AmrTag AMRFirstDerivative::operator()(const MeshBlockData<Real> *rc) const {
if (!rc->HasVariable(field) || !rc->IsAllocated(field)) {
return AmrTag::same;
void AMRFirstDerivative::operator()(MeshData<Real> *md,
ParArray1D<AmrTag> &amr_tags) const {
auto ib = md->GetBoundsI(IndexDomain::interior);
auto jb = md->GetBoundsJ(IndexDomain::interior);
auto kb = md->GetBoundsK(IndexDomain::interior);
auto bnds = AMRBounds(ib, jb, kb);
auto dims = md->GetMeshPointer()->resolved_packages->FieldMetadata(field).Shape();
int n5(0), n4(0);
if (dims.size() > 2) {
n5 = dims[1];
n4 = dims[2];
} else if (dims.size() > 1) {
n5 = dims[0];
n4 = dims[1];
}
auto bnds = GetBounds(rc);
auto q = Kokkos::subview(rc->Get(field).data, comp6, comp5, comp4, Kokkos::ALL(),
Kokkos::ALL(), Kokkos::ALL());
return Refinement::FirstDerivative(bnds, q, refine_criteria, derefine_criteria);
const int idx = comp4 + n4 * (comp5 + n5 * comp6);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm wondering if we don't have a simpler way to get a flat index (I imagine there must be more places with thus use case but I don't recall offhand).

Refinement::FirstDerivative(bnds, md, field, idx, amr_tags, refine_criteria,
derefine_criteria, max_level);
}

AmrTag AMRSecondDerivative::operator()(const MeshBlockData<Real> *rc) const {
if (!rc->HasVariable(field) || !rc->IsAllocated(field)) {
return AmrTag::same;
void AMRSecondDerivative::operator()(MeshData<Real> *md,
ParArray1D<AmrTag> &amr_tags) const {
auto ib = md->GetBoundsI(IndexDomain::interior);
auto jb = md->GetBoundsJ(IndexDomain::interior);
auto kb = md->GetBoundsK(IndexDomain::interior);
auto bnds = AMRBounds(ib, jb, kb);
auto dims = md->GetMeshPointer()->resolved_packages->FieldMetadata(field).Shape();
int n5(0), n4(0);
if (dims.size() > 2) {
n5 = dims[1];
n4 = dims[2];
} else if (dims.size() > 1) {
n5 = dims[0];
n4 = dims[1];
}
auto bnds = GetBounds(rc);
auto q = Kokkos::subview(rc->Get(field).data, comp6, comp5, comp4, Kokkos::ALL(),
Kokkos::ALL(), Kokkos::ALL());
return Refinement::SecondDerivative(bnds, q, refine_criteria, derefine_criteria);
const int idx = comp4 + n4 * (comp5 + n5 * comp6);
Refinement::SecondDerivative(bnds, md, field, idx, amr_tags, refine_criteria,
derefine_criteria, max_level);
}

} // namespace parthenon
8 changes: 4 additions & 4 deletions src/amr_criteria/amr_criteria.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "defs.hpp"
#include "mesh/domain.hpp"
#include "mesh/mesh.hpp"

namespace parthenon {

Expand All @@ -35,26 +36,25 @@ struct AMRBounds {
struct AMRCriteria {
AMRCriteria(ParameterInput *pin, std::string &block_name);
virtual ~AMRCriteria() {}
virtual AmrTag operator()(const MeshBlockData<Real> *rc) const = 0;
virtual void operator()(MeshData<Real> *md, ParArray1D<AmrTag> &delta_level) const = 0;
std::string field;
Real refine_criteria, derefine_criteria;
int max_level;
int comp6, comp5, comp4;
static std::shared_ptr<AMRCriteria>
MakeAMRCriteria(std::string &criteria, ParameterInput *pin, std::string &block_name);
AMRBounds GetBounds(const MeshBlockData<Real> *rc) const;
};

struct AMRFirstDerivative : public AMRCriteria {
AMRFirstDerivative(ParameterInput *pin, std::string &block_name)
: AMRCriteria(pin, block_name) {}
AmrTag operator()(const MeshBlockData<Real> *rc) const override;
void operator()(MeshData<Real> *md, ParArray1D<AmrTag> &delta_level) const override;
};

struct AMRSecondDerivative : public AMRCriteria {
AMRSecondDerivative(ParameterInput *pin, std::string &block_name)
: AMRCriteria(pin, block_name) {}
AmrTag operator()(const MeshBlockData<Real> *rc) const override;
void operator()(MeshData<Real> *md, ParArray1D<AmrTag> &delta_level) const override;
};

} // namespace parthenon
Expand Down
Loading