Skip to content

Commit 4720d13

Browse files
authored
Merge pull request #1314 from parthenon-hpc-lab/lroberts36/add-user-boundary-override
Allow for user overridable boundary conditions
2 parents bf202e9 + d73e763 commit 4720d13

File tree

4 files changed

+107
-45
lines changed

4 files changed

+107
-45
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Current develop
44

55
### Added (new features/APIs/variables/...)
6+
- [[PR 1314]](https://github.com/parthenon-hpc-lab/parthenon/pull/1314) Add option of user specified BCs in AddBoundaryExchangeTasks
67
- [[PR 1244]](https://github.com/parthenon-hpc-lab/parthenon/pull/1244) Add TaskCollection timeout capability
78
- [[PR 1311]](https://github.com/parthenon-hpc-lab/parthenon/pull/1311) Magnitude refinement criteria, per-package PostInitialize function hooks, mergescv and prettyparams utilities
89
- [[PR 1142]](https://github.com/parthenon-hpc-lab/parthenon/pull/1142) Unify par_dispatch, par_for_outer & par_for_inner overloads

doc/sphinx/src/boundary_conditions.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,17 @@ for a more complete example):
145145
pkg->UserBoundaryFunctions[BF::inner_x2].push_back(GetMyBC<X2DIR, BCSide::Inner>());
146146
...
147147
}
148+
149+
User override of boundary conditions in `AddBoundaryExchangeTasks`.
150+
-------------------------------------------------------------------
151+
152+
Sometimes it is desirable to apply different boundary conditions when communicating
153+
on different containers (e.g. when one container represents the value of a variable
154+
and another container represents a Newton-Raphson correction to that variable). To
155+
easily allow this, `AddBoundaryExchangeTasks` can take a final argument with type
156+
`std::function<TaskStatus(std::shared_ptr<MeshData<Real>> &, bool)>` or with type
157+
`std::function<TaskID(TaskID, TaskList *, std::shared_ptr<MeshData<Real>>, bool)>`.
158+
When this argument is specified, all other boundary conditions will be ignored and
159+
the passed functions will be used as boundary conditions instead. The final boolean
160+
arguments of the functions specify if the boundary condition needs to be applied on
161+
the coarse buffer.

src/bvals/comms/boundary_communication.cpp

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ template TaskStatus
168168
SendBoundBufs<BoundaryType::gmg_prolongate_send>(std::shared_ptr<MeshData<Real>> &);
169169
template TaskStatus
170170
SendBoundBufs<BoundaryType::flxcor_send>(std::shared_ptr<MeshData<Real>> &);
171+
template TaskStatus
172+
SendBoundBufs<BoundaryType::gmg_same>(std::shared_ptr<MeshData<Real>> &);
171173

172174
template <BoundaryType bound_type>
173175
TaskStatus StartReceiveBoundBufs(std::shared_ptr<MeshData<Real>> &md) {
@@ -196,6 +198,8 @@ template TaskStatus StartReceiveBoundBufs<BoundaryType::gmg_prolongate_recv>(
196198
std::shared_ptr<MeshData<Real>> &);
197199
template TaskStatus
198200
StartReceiveBoundBufs<BoundaryType::flxcor_recv>(std::shared_ptr<MeshData<Real>> &);
201+
template TaskStatus
202+
StartReceiveBoundBufs<BoundaryType::gmg_same>(std::shared_ptr<MeshData<Real>> &);
199203

200204
template <BoundaryType bound_type>
201205
TaskStatus ReceiveBoundBufs(std::shared_ptr<MeshData<Real>> &md) {
@@ -246,6 +250,8 @@ template TaskStatus
246250
ReceiveBoundBufs<BoundaryType::gmg_prolongate_recv>(std::shared_ptr<MeshData<Real>> &);
247251
template TaskStatus
248252
ReceiveBoundBufs<BoundaryType::flxcor_recv>(std::shared_ptr<MeshData<Real>> &);
253+
template TaskStatus
254+
ReceiveBoundBufs<BoundaryType::gmg_same>(std::shared_ptr<MeshData<Real>> &);
249255

250256
template <BoundaryType bound_type>
251257
TaskStatus SetBounds(std::shared_ptr<MeshData<Real>> &md) {
@@ -356,6 +362,7 @@ template TaskStatus
356362
SetBounds<BoundaryType::gmg_prolongate_recv>(std::shared_ptr<MeshData<Real>> &);
357363
template TaskStatus
358364
SetBounds<BoundaryType::flxcor_recv>(std::shared_ptr<MeshData<Real>> &);
365+
template TaskStatus SetBounds<BoundaryType::gmg_same>(std::shared_ptr<MeshData<Real>> &);
359366

360367
template <BoundaryType bound_type>
361368
TaskStatus ProlongateBounds(std::shared_ptr<MeshData<Real>> &md) {
@@ -400,56 +407,55 @@ template TaskStatus
400407
ProlongateBounds<BoundaryType::nonlocal>(std::shared_ptr<MeshData<Real>> &);
401408
template TaskStatus
402409
ProlongateBounds<BoundaryType::gmg_prolongate_recv>(std::shared_ptr<MeshData<Real>> &);
410+
template TaskStatus
411+
ProlongateBounds<BoundaryType::gmg_same>(std::shared_ptr<MeshData<Real>> &);
403412

404-
// Adds all relevant boundary communication to a single task list
405-
template <BoundaryType bounds>
406-
TaskID AddBoundaryExchangeTasks(TaskID dependency, TaskList &tl,
407-
std::shared_ptr<MeshData<Real>> &md, bool multilevel) {
408-
// TODO(LFR): Splitting up the boundary tasks while doing prolongation can cause some
409-
// possible issues for sparse fields. In particular, the order in which
410-
// fields are allocated and then set could potentially result in different
411-
// results if the default sparse value is non-zero.
412-
// const auto any = BoundaryType::any;
413-
static_assert(bounds == BoundaryType::any || bounds == BoundaryType::gmg_same);
414-
// const auto local = BoundaryType::local;
415-
// const auto nonlocal = BoundaryType::nonlocal;
416-
417-
// auto send = tl.AddTask(dependency, SendBoundBufs<nonlocal>, md);
418-
// auto send_local = tl.AddTask(dependency, SendBoundBufs<local>, md);
419-
420-
// auto recv_local = tl.AddTask(dependency, ReceiveBoundBufs<local>, md);
421-
// auto set_local = tl.AddTask(recv_local, SetBounds<local>, md);
422-
423-
// auto recv = tl.AddTask(dependency, ReceiveBoundBufs<nonlocal>, md);
424-
// auto set = tl.AddTask(recv, SetBounds<nonlocal>, md);
413+
template <BoundaryType bound_type>
414+
TaskStatus ProlongateInternalBounds(std::shared_ptr<MeshData<Real>> &md) {
415+
PARTHENON_INSTRUMENT
425416

426-
// auto cbound = tl.AddTask(set, ApplyCoarseBoundaryConditions, md);
417+
Mesh *pmesh = md->GetMeshPointer();
418+
auto &cache = md->GetBvarsCache().GetSubCache(bound_type, false);
427419

428-
// auto pro_local = tl.AddTask(cbound | set_local | set, ProlongateBounds<local>, md);
429-
// auto pro = tl.AddTask(cbound | set_local | set, ProlongateBounds<nonlocal>, md);
420+
auto [rebuild, nbound] = CheckReceiveBufferCacheForRebuild<bound_type, false>(md);
430421

431-
// auto out = (pro_local | pro);
422+
if (rebuild) {
423+
if constexpr (bound_type == BoundaryType::gmg_prolongate_recv) {
424+
RebuildBufferCache<bound_type, false>(md, nbound, BndInfo::GetSetBndInfo,
425+
ProResInfo::GetInteriorProlongate);
426+
} else if constexpr (bound_type == BoundaryType::gmg_restrict_recv) {
427+
RebuildBufferCache<bound_type, false>(md, nbound, BndInfo::GetSetBndInfo,
428+
ProResInfo::GetNull);
429+
} else {
430+
RebuildBufferCache<bound_type, false>(md, nbound, BndInfo::GetSetBndInfo,
431+
ProResInfo::GetSet);
432+
}
433+
}
432434

433-
auto send = tl.AddTask(dependency, TF(SendBoundBufs<bounds>), md);
434-
auto recv = tl.AddTask(dependency, TF(ReceiveBoundBufs<bounds>), md);
435-
auto set = tl.AddTask(recv, TF(SetBounds<bounds>), md);
435+
if (nbound > 0 && pmesh->multilevel && md->NumBlocks() > 0) {
436+
auto pmb = md->GetBlockData(0)->GetBlockPointer();
437+
StateDescriptor *resolved_packages = pmb->resolved_packages.get();
436438

437-
auto pro = set;
438-
if (md->GetMeshPointer()->multilevel) {
439-
auto cbound = tl.AddTask(set, TF(ApplyBoundaryConditionsOnCoarseOrFineMD), md, true);
440-
pro = tl.AddTask(cbound, TF(ProlongateBounds<bounds>), md);
439+
// Prolongate from coarse buffer
440+
refinement::ProlongateInternal(resolved_packages, cache.prores_cache, pmb->cellbounds,
441+
pmb->c_cellbounds);
441442
}
442-
auto fbound = tl.AddTask(pro, TF(ApplyBoundaryConditionsOnCoarseOrFineMD), md, false);
443-
444-
return fbound;
443+
return TaskStatus::complete;
445444
}
446-
template TaskID
447-
AddBoundaryExchangeTasks<BoundaryType::any>(TaskID, TaskList &,
448-
std::shared_ptr<MeshData<Real>> &, bool);
445+
template TaskStatus
446+
ProlongateInternalBounds<BoundaryType::any>(std::shared_ptr<MeshData<Real>> &);
447+
template TaskStatus
448+
ProlongateInternalBounds<BoundaryType::local>(std::shared_ptr<MeshData<Real>> &);
449+
template TaskStatus
450+
ProlongateInternalBounds<BoundaryType::nonlocal>(std::shared_ptr<MeshData<Real>> &);
451+
template TaskStatus ProlongateInternalBounds<BoundaryType::gmg_prolongate_recv>(
452+
std::shared_ptr<MeshData<Real>> &);
453+
template TaskStatus
454+
ProlongateInternalBounds<BoundaryType::gmg_same>(std::shared_ptr<MeshData<Real>> &);
449455

450-
template TaskID
451-
AddBoundaryExchangeTasks<BoundaryType::gmg_same>(TaskID, TaskList &,
452-
std::shared_ptr<MeshData<Real>> &, bool);
456+
bool IsMeshMultilevel(std::shared_ptr<MeshData<Real>> &md) {
457+
return md->GetMeshPointer()->multilevel;
458+
}
453459

454460
TaskID AddFluxCorrectionTasks(TaskID dependency, TaskList &tl,
455461
std::shared_ptr<MeshData<Real>> &md, bool multilevel) {

src/bvals/comms/bvals_in_one.hpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <vector>
2424

2525
#include "basic_types.hpp"
26+
#include "bvals/boundary_conditions.hpp"
2627
#include "bvals/neighbor_block.hpp"
2728
#include "coordinates/coordinates.hpp"
2829

@@ -62,6 +63,8 @@ inline TaskStatus SetBoundaries(std::shared_ptr<MeshData<Real>> &md) {
6263

6364
template <BoundaryType bound_type>
6465
TaskStatus ProlongateBounds(std::shared_ptr<MeshData<Real>> &md);
66+
template <BoundaryType bound_type>
67+
TaskStatus ProlongateInternalBounds(std::shared_ptr<MeshData<Real>> &md);
6568
inline TaskStatus ProlongateBoundaries(std::shared_ptr<MeshData<Real>> &md) {
6669
return ProlongateBounds<BoundaryType::any>(md);
6770
}
@@ -79,14 +82,52 @@ static TaskStatus SetFluxCorrections(std::shared_ptr<MeshData<Real>> &md) {
7982
return SetBounds<BoundaryType::flxcor_recv>(md);
8083
}
8184

85+
// Adds all relevant flux correction tasks to a single task list
86+
TaskID AddFluxCorrectionTasks(TaskID dependency, TaskList &tl,
87+
std::shared_ptr<MeshData<Real>> &md, bool multilevel);
88+
89+
using BValOnMDFunc_t = std::function<TaskStatus(std::shared_ptr<MeshData<Real>> &, bool)>;
90+
using BValOnMDTasks_t =
91+
std::function<TaskID(TaskID, TaskList *, std::shared_ptr<MeshData<Real>>, bool)>;
92+
bool IsMeshMultilevel(std::shared_ptr<MeshData<Real>> &md);
93+
8294
// Adds all relevant boundary communication to a single task list
8395
template <BoundaryType bounds = BoundaryType::any>
8496
TaskID AddBoundaryExchangeTasks(TaskID dependency, TaskList &tl,
85-
std::shared_ptr<MeshData<Real>> &md, bool multilevel);
97+
std::shared_ptr<MeshData<Real>> &md, bool multilevel,
98+
BValOnMDTasks_t ApplyBCs) {
99+
static_assert(bounds == BoundaryType::any || bounds == BoundaryType::gmg_same);
86100

87-
// Adds all relevant flux correction tasks to a single task list
88-
TaskID AddFluxCorrectionTasks(TaskID dependency, TaskList &tl,
89-
std::shared_ptr<MeshData<Real>> &md, bool multilevel);
101+
auto send = tl.AddTask(dependency, TF(SendBoundBufs<bounds>), md);
102+
auto recv = tl.AddTask(dependency, TF(ReceiveBoundBufs<bounds>), md);
103+
auto set = tl.AddTask(recv, TF(SetBounds<bounds>), md);
104+
105+
auto pro = set;
106+
if (IsMeshMultilevel(md)) {
107+
auto cbound = ApplyBCs(set, &tl, md, true);
108+
pro = tl.AddTask(cbound, TF(ProlongateBounds<bounds>), md);
109+
}
110+
auto fbound = ApplyBCs(pro, &tl, md, false);
111+
if (IsMeshMultilevel(md)) {
112+
// Need to prolongate internal bounds after setting physical boundary
113+
// conditions, since the internal prolongation uses the values of the
114+
// normal buffer on shared elements (rather than values in the coarse)
115+
// buffer for prolongation.
116+
fbound = tl.AddTask(fbound, TF(ProlongateInternalBounds<bounds>), md);
117+
}
118+
return fbound;
119+
}
120+
121+
template <BoundaryType bounds = BoundaryType::any>
122+
TaskID AddBoundaryExchangeTasks(
123+
TaskID dependency, TaskList &tl, std::shared_ptr<MeshData<Real>> &md, bool multilevel,
124+
BValOnMDFunc_t ApplyBCs = ApplyBoundaryConditionsOnCoarseOrFineMD) {
125+
return AddBoundaryExchangeTasks<bounds>(
126+
dependency, tl, md, multilevel,
127+
[&](TaskID id, TaskList *tl, std::shared_ptr<MeshData<Real>> md, bool coarse) {
128+
return tl->AddTask(id, TF(ApplyBCs), md, coarse);
129+
});
130+
}
90131

91132
// These tasks should not be called in down stream code
92133
TaskStatus BuildBoundaryBuffers(std::shared_ptr<MeshData<Real>> &md);

0 commit comments

Comments
 (0)