REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_PC_Utils.cpp
Go to the documentation of this file.
1#ifdef REMORA_USE_PARTICLES
2
3#include <AMReX_ParticleInterpolators.H>
4#include <REMORA_Constants.H>
5#include <REMORA_PC.H>
6
7using namespace amrex;
8
9/**
10 * @param a_mf Multifab to calculate over
11 * @param a_lev level to calculate on
12 * @param a_comp component to calculate
13 */
14void REMORAPC::massDensity ( MultiFab& a_mf,
15 const int& a_lev,
16 const int& a_comp ) const
17{
18 BL_PROFILE("REMORAPC::massDensity()");
19
22
23 const auto& geom = Geom(a_lev);
24 const auto plo = geom.ProbLoArray();
25 const auto dxi = geom.InvCellSizeArray();
26
27 const Real inv_cell_volume = dxi[0]*dxi[1]*dxi[2];
28 a_mf.setVal(zero);
29
30 ParticleToMesh( *this, a_mf, a_lev,
31 [=] AMREX_GPU_DEVICE ( const REMORAPC::ParticleTileType::ConstParticleTileDataType& ptd,
32 int i, Array4<Real> const& rho)
33 {
34 auto p = ptd.m_aos[i];
35 ParticleInterpolator::Linear interp(p, plo, dxi);
36 interp.ParticleToMesh ( p, rho, 0, a_comp, 1,
37 [=] AMREX_GPU_DEVICE ( const REMORAPC::ParticleType&, int)
38 {
39 auto mass = ptd.m_rdata[REMORAParticlesRealIdxSoA::mass][i];
40 return static_cast<Real>(mass*inv_cell_volume);
41 });
42 });
43
44 return;
45}
46
47/**
48 * Write the particles to a plotfile with x and y in physical coordinates. The particles move
49 * in the uniform coordinates of the AMReX geometry; for output, x and y are replaced by the
50 * physical coordinates of the cell corners (psi points) interpolated bilinearly to each
51 * particle. These are the corner positions the plotfile's nodal displacement gives a viewer,
52 * so each particle is drawn inside the cell that holds it. z is already the physical height.
53 * Only a copy of the particles is converted, so writing a plotfile does not change the run.
54 *
55 * @param a_fname plotfile directory
56 * @param a_name particle species name
57 * @param a_xy per level, physical x and y of the psi points (REMORA::plot_node_coords)
58 */
59void REMORAPC::WritePlotFile ( const std::string& a_fname, const std::string& a_name,
60 const Vector<MultiFab>& a_xy ) const
61{
62 BL_PROFILE("REMORAPC::WritePlotFile()");
63
64 auto pc = make_alike();
65 pc.copyParticles(*this, true);
66
67 using PCType = decltype(pc);
68 for (int lev = 0; lev <= pc.finestLevel(); ++lev)
69 {
70 const Geometry& geom = m_gdb->Geom(lev);
71 const auto plo = geom.ProbLoArray();
72 const auto dxi = geom.InvCellSizeArray();
73
74#ifdef AMREX_USE_OMP
75#pragma omp parallel if (Gpu::notInLaunchRegion())
76#endif
77 for (typename PCType::ParIterType pti(pc, lev); pti.isValid(); ++pti)
78 {
79 auto& aos = pti.GetArrayOfStructs();
80 const int np = aos.numParticles();
81 auto* p_pbox = aos().data();
82 const auto xy = a_xy[lev].const_array(pti.index());
83 const Box& vbx = pti.validbox();
84 const int ilo = vbx.smallEnd(0);
85 const int ihi = vbx.bigEnd(0);
86 const int jlo = vbx.smallEnd(1);
87 const int jhi = vbx.bigEnd(1);
88
90 {
91 auto& p = p_pbox[n];
92 if (p.id() <= 0) { return; }
93
94 // Nodal index coordinates, kept in ParticleReal: rounding them to a
95 // single-precision Real first can carry a particle at the high edge of its grid
96 // into the next cell. The cell is clamped to the particle's grid, so both corner
97 // nodes are always inside the grid's nodal box (a_xy has no ghost cells).
98 const ParticleReal lx = (p.pos(0)-plo[0])*dxi[0];
99 const ParticleReal ly = (p.pos(1)-plo[1])*dxi[1];
100 const int i = amrex::max(ilo, amrex::min(static_cast<int>(amrex::Math::floor(lx)), ihi));
101 const int j = amrex::max(jlo, amrex::min(static_cast<int>(amrex::Math::floor(ly)), jhi));
102 const auto sx = static_cast<Real>(lx - static_cast<ParticleReal>(i));
103 const auto sy = static_cast<Real>(ly - static_cast<ParticleReal>(j));
104
105 for (int d = 0; d < 2; ++d) {
106 p.pos(d) = static_cast<ParticleReal>(
107 xy(i ,j ,0,d) * (one-sx) * (one-sy) + xy(i+1,j ,0,d) * sx * (one-sy) +
108 xy(i ,j+1,0,d) * (one-sx) * sy + xy(i+1,j+1,0,d) * sx * sy);
109 }
110 });
111 }
112 }
113
114 pc.Checkpoint(a_fname, a_name, true, varNames());
115}
116
117#endif
constexpr amrex::Real one
constexpr amrex::Real zero
mf_h setVal(geomdata.ProbHi(2))
virtual void massDensity(amrex::MultiFab &a_mf, const int &a_lev, const int &a_comp=0) const
void WritePlotFile(const std::string &a_fname, const std::string &a_name, const amrex::Vector< amrex::MultiFab > &a_xy) const
virtual amrex::Vector< std::string > varNames() const
Definition REMORA_PC.H:156