| 186 | template <class PC, class F> |
| 187 | requires (IsParticleContainer<PC>::value) |
| 188 | void |
| 189 | ParticleToMesh (PC const& pc, const Vector<MultiFab*>& mf, |
| 190 | int lev_min, int lev_max, F&& f, |
| 191 | bool zero_out_input=true, bool vol_weight=true) |
| 192 | { |
| 193 | BL_PROFILE("amrex::ParticleToMesh"); |
| 194 | |
| 195 | if (lev_max == -1) { lev_max = pc.finestLevel(); } |
| 196 | while (!pc.GetParGDB()->LevelDefined(lev_max)) { lev_max--; } |
| 197 | |
| 198 | if (lev_max == 0) |
| 199 | { |
| 200 | ParticleToMesh(pc, *mf[0], 0, std::forward<F>(f), zero_out_input); |
| 201 | if (vol_weight) { |
| 202 | const Real* dx = pc.Geom(0).CellSize(); |
| 203 | const Real vol = AMREX_D_TERM(dx[0], *dx[1], *dx[2]); |
| 204 | mf[0]->mult(Real(1.0)/vol, 0, mf[0]->nComp(), mf[0]->nGrow()); |
| 205 | } |
| 206 | return; |
| 207 | } |
| 208 | |
| 209 | int ngrow = amrex::max(AMREX_D_DECL(mf[0]->nGrow(0), |
| 210 | mf[0]->nGrow(1), |
| 211 | mf[0]->nGrow(2)), 2); |
| 212 | |
| 213 | if (zero_out_input) |
| 214 | { |
| 215 | for (int lev = lev_min; lev <= lev_max; ++lev) |
| 216 | { |
| 217 | mf[lev]->setVal(Real(0.0)); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | Vector<MultiFab> mf_part(lev_max+1); |
| 222 | Vector<MultiFab> mf_tmp( lev_max+1); |
| 223 | for (int lev = lev_min; lev <= lev_max; ++lev) |
| 224 | { |
| 225 | mf_part[lev].define(pc.ParticleBoxArray(lev), |
| 226 | pc.ParticleDistributionMap(lev), |
| 227 | mf[lev]->nComp(), ngrow); |
| 228 | mf_tmp[lev].define( pc.ParticleBoxArray(lev), |
| 229 | pc.ParticleDistributionMap(lev), |
| 230 | mf[lev]->nComp(), 0); |
| 231 | mf_part[lev].setVal(0.0); |
| 232 | mf_tmp[lev].setVal( 0.0); |
| 233 | } |
| 234 | |
| 235 | // configure this to do a no-op at the physical boundaries. |
| 236 | int lo_bc[] = {BCType::int_dir, BCType::int_dir, BCType::int_dir}; |
| 237 | int hi_bc[] = {BCType::int_dir, BCType::int_dir, BCType::int_dir}; |
| 238 | Vector<BCRec> bcs(mf_part[lev_min].nComp(), BCRec(lo_bc, hi_bc)); |
| 239 | PCInterp mapper; |
| 240 | |
| 241 | for (int lev = lev_min; lev <= lev_max; ++lev) |
| 242 | { |
| 243 | ParticleToMesh(pc, mf_part[lev], lev, f, true); // always zero out input on temp level |
| 244 | if (vol_weight) { |
| 245 | const Real* dx = pc.Geom(lev).CellSize(); |
no test coverage detected