Skip to content

Commit

Permalink
fix openPMD plotfile output (#804)
Browse files Browse the repository at this point in the history
### Description
Fixes a segmentation fault during openPMD plotfile output when
face-centered variables are enabled.

There was an implicit assumption in
`AMRSimulation<problem_t>::AverageFCToCC()` that the number of
face-centered ghost zones was the same as the number of cell-centered
ghost zones. This PR allows the number of ghosts to differ.

I manually tested that this works inside the CUDA dev container by
compiling Quokka with `-DQUOKKA_OPENPMD=ON`, running the HydroBlast3D
problem, and then examining the output files with
[openPMD-viewer](https://github.com/openPMD/openPMD-viewer).

### Related issues
Fixes #742.

### Checklist
_Before this pull request can be reviewed, all of these tasks should be
completed. Denote completed tasks with an `x` inside the square brackets
`[ ]` in the Markdown source below:_
- [x] I have added a description (see above).
- [x] I have added a link to any related issues (if applicable; see
above).
- [x] I have read the [Contributing
Guide](https://github.com/quokka-astro/quokka/blob/development/CONTRIBUTING.md).
- [ ] I have added tests for any new physics that this PR adds to the
code.
- [x] *(For quokka-astro org members)* I have manually triggered the GPU
tests with the magic comment `/azp run`.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
BenWibking and pre-commit-ci[bot] authored Dec 9, 2024
1 parent e8a181b commit 214de9d
Showing 1 changed file with 14 additions and 13 deletions.
27 changes: 14 additions & 13 deletions src/simulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,7 @@ template <typename problem_t> class AMRSimulation : public amrex::AmrCore
void computeTimestep();
auto computeTimestepAtLevel(int lev) -> amrex::Real;

void AverageFCToCC(amrex::MultiFab &mf_cc, const amrex::MultiFab &mf_fc, int idim, int dstcomp_start, int srccomp_start, int srccomp_total,
int nGrow) const;
void AverageFCToCC(amrex::MultiFab &mf_cc, const amrex::MultiFab &mf_fc, int idim, int dstcomp_start, int srccomp_start, int srccomp_total) const;

virtual void computeMaxSignalLocal(int level) = 0;
virtual auto computeExtraPhysicsTimestep(int lev) -> amrex::Real = 0;
Expand Down Expand Up @@ -586,11 +585,9 @@ template <typename problem_t> void AMRSimulation<problem_t>::PerformanceHints()
}

#ifdef QUOKKA_USE_OPENPMD
// warning about face-centered variables and OpenPMD outputs
if constexpr (Physics_Indices<problem_t>::nvarTotal_fc > 0) {
amrex::Print() << "\n[Warning] [I/O] Plotfiles will ONLY contain cell-centered averages of face-centered variables!"
<< " Support for outputting face-centered variables for openPMD is not yet implemented.\n";
}
// warning about particles and OpenPMD outputs
amrex::Print() << "\n[Warning] [I/O] OpenPMD outputs currently do NOT include particles!"
<< " Support for outputting particles for openPMD is not yet implemented.\n";
#endif
}

Expand Down Expand Up @@ -2089,7 +2086,7 @@ template <typename problem_t> auto AMRSimulation<problem_t>::CustomPlotFileName(

template <typename problem_t>
void AMRSimulation<problem_t>::AverageFCToCC(amrex::MultiFab &mf_cc, const amrex::MultiFab &mf_fc, int idim, int dstcomp_start, int srccomp_start,
int srccomp_total, int nGrow) const
int srccomp_total) const
{
int di = 0;
int dj = 0;
Expand All @@ -2104,7 +2101,10 @@ void AMRSimulation<problem_t>::AverageFCToCC(amrex::MultiFab &mf_cc, const amrex
// iterate over the domain
auto const &state_cc = mf_cc.arrays();
auto const &state_fc = mf_fc.const_arrays();
amrex::ParallelFor(mf_cc, amrex::IntVect(AMREX_D_DECL(nGrow, nGrow, nGrow)), [=] AMREX_GPU_DEVICE(int boxidx, int i, int j, int k) {
int const ng_cc = mf_cc.nGrow();
int const ng_fc = mf_fc.nGrow();
AMREX_ALWAYS_ASSERT(ng_cc <= ng_fc); // if this is false, we can't fill the ghost cells!
amrex::ParallelFor(mf_cc, amrex::IntVect(AMREX_D_DECL(ng_cc, ng_cc, ng_cc)), [=] AMREX_GPU_DEVICE(int boxidx, int i, int j, int k) {
for (int icomp = 0; icomp < srccomp_total; ++icomp) {
state_cc[boxidx](i, j, k, dstcomp_start + icomp) =
0.5 * (state_fc[boxidx](i, j, k, srccomp_start + icomp) + state_fc[boxidx](i + di, j + dj, k + dk, srccomp_start + icomp));
Expand Down Expand Up @@ -2153,7 +2153,7 @@ template <typename problem_t> auto AMRSimulation<problem_t>::PlotFileMFAtLevel(c
// compute cell-center averaged face-centred data
if constexpr (Physics_Indices<problem_t>::nvarTotal_fc > 0) {
for (int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
AverageFCToCC(plotMF, state_new_fc_[lev][idim], idim, comp, 0, ncomp_per_dim_fc, nghost_fc);
AverageFCToCC(plotMF, state_new_fc_[lev][idim], idim, comp, 0, ncomp_per_dim_fc);
comp += ncomp_per_dim_fc;
}
}
Expand Down Expand Up @@ -2240,7 +2240,7 @@ template <typename problem_t> void AMRSimulation<problem_t>::doDiagnostics()
if (computeVars) {
for (int lev{0}; lev <= finestLevel(); ++lev) {
diagMFVec[lev] = std::make_unique<amrex::MultiFab>(grids[lev], dmap[lev], m_diagVars.size(), 1);
amrex::MultiFab const mf = PlotFileMFAtLevel(lev, nghost_cc_);
amrex::MultiFab const mf = PlotFileMFAtLevel(lev, std::min(nghost_cc_, nghost_fc_));
auto const varnames = GetPlotfileVarNames();

for (int v{0}; v < m_diagVars.size(); ++v) {
Expand Down Expand Up @@ -2301,7 +2301,8 @@ template <typename problem_t> void AMRSimulation<problem_t>::RenderAscent()
BL_PROFILE("AMRSimulation::RenderAscent()");

// combine multifabs
amrex::Vector<amrex::MultiFab> mf = PlotFileMF(nghost_cc_);
const int included_ghosts = std::min(nghost_cc_, nghost_fc_);
amrex::Vector<amrex::MultiFab> mf = PlotFileMF(included_ghosts);
amrex::Vector<const amrex::MultiFab *> mf_ptr = amrex::GetVecOfConstPtrs(mf);
amrex::Vector<std::string> varnames;
varnames.insert(varnames.end(), componentNames_cc_.begin(), componentNames_cc_.end());
Expand Down Expand Up @@ -2364,7 +2365,7 @@ template <typename problem_t> void AMRSimulation<problem_t>::WritePlotFile()
#ifdef QUOKKA_USE_OPENPMD
int included_ghosts = 0;
#else
int included_ghosts = nghost_cc_;
int included_ghosts = std::min(nghost_cc_, nghost_fc_);
#endif
amrex::Vector<amrex::MultiFab> mf = PlotFileMF(included_ghosts);
amrex::Vector<const amrex::MultiFab *> mf_ptr = amrex::GetVecOfConstPtrs(mf);
Expand Down

0 comments on commit 214de9d

Please # to comment.