/home/runner/work/kynema-sgf/kynema-sgf/src/utilities/sampling/SamplingContainer.H Source File

Kynema-SGF API: /home/runner/work/kynema-sgf/kynema-sgf/src/utilities/sampling/SamplingContainer.H Source File
Kynema-SGF API v0.1.0
CFD solver for wind plant simulations
Loading...
Searching...
No Matches
SamplingContainer.H
Go to the documentation of this file.
1#ifndef SAMPLINGCONTAINER_H
2#define SAMPLINGCONTAINER_H
3
4#include <memory>
5#include <cstdint>
6
7#include "AMReX_AmrParticles.H"
9#include "AMReX_REAL.H"
10
11using namespace amrex::literals;
12
13namespace kynema_sgf {
14
15class Field;
16
17namespace sampling {
18
19class SamplerBase;
20
21static constexpr int SNStructReal = 0;
22static constexpr int SNStructInt = 3;
23static constexpr int SNArrayReal = 0;
24static constexpr int SNArrayInt = 0;
25
29struct IIx
30{
31 enum Indices : std::uint8_t {
32 uid = 0,
35 };
36};
37
64 : public amrex::AmrParticleContainer<
65 SNStructReal,
66 SNStructInt,
67 SNArrayReal,
68 SNArrayInt>
69{
70public:
71 explicit SamplingContainer(amrex::AmrCore& mesh)
72 : amrex::AmrParticleContainer<
76 SNArrayInt>(&mesh)
77 , m_mesh(mesh)
78 {}
79
82 void setup_container(int num_real_components, int num_int_components = 0);
83
87 const amrex::Vector<std::unique_ptr<SamplerBase>>& /*samplers*/);
88
90 void set_interpolation_order(const int order)
91 {
92 AMREX_ALWAYS_ASSERT(order == 0 || order == 1);
94 }
95
97 template <typename FType>
98 void interpolate_fields(const amrex::Vector<FType>& fields, const int scomp)
99 {
100 BL_PROFILE("kynema-sgf::SamplingContainer::interpolate_fields");
101
102 const int nlevels = m_mesh.finestLevel() + 1;
103
104 for (int lev = 0; lev < nlevels; ++lev) {
105 for (ParIterType pti(*this, lev); pti.isValid(); ++pti) {
106 int scomp_curr = scomp;
107 for (const auto* fld : fields) {
108 const bool use_nearest = (m_interpolation_order == 0);
109 if (!use_nearest) {
110 AMREX_ALWAYS_ASSERT(
111 fld->num_grow() > amrex::IntVect{0});
112 }
113 const auto farr = (*fld)(lev).const_array(pti);
115 pti, farr, lev, fld->field_location(), fld->num_comp(),
116 scomp_curr, use_nearest);
117
118 scomp_curr += fld->num_comp();
119 }
120 }
121 }
122 }
123
126 const DerivedQtyMgr& derived_mgr, const FieldRepo& repo, int scomp);
127
129 void populate_buffer(std::vector<amrex::Real>& buf);
130
132
134
151 template <typename FType>
153 const int np,
154 const int ic,
155 SamplingContainer::ParticleVector& pvec,
156 SamplingContainer::RealVector& pavec,
157 const FType& farr,
158 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& problo,
159 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxi,
160 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dx,
161 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& offset)
162 {
163 BL_PROFILE("kynema-sgf::SamplingContainer::sample_nearest_impl");
164
165 auto* pstruct = pvec.data();
166 auto* parr = pavec.data();
167
168 amrex::ParallelFor(np, [=] AMREX_GPU_DEVICE(int ip) {
169 auto& p = pstruct[ip];
170 const amrex::Real x =
171 (p.pos(0) - problo[0] - offset[0] * dx[0]) * dxi[0];
172 const amrex::Real y =
173 (p.pos(1) - problo[1] - offset[1] * dx[1]) * dxi[1];
174 const amrex::Real z =
175 (p.pos(2) - problo[2] - offset[2] * dx[2]) * dxi[2];
176
177 // Round to the nearest data point index
178 const int i = static_cast<int>(std::round(x));
179 const int j = static_cast<int>(std::round(y));
180 const int k = static_cast<int>(std::round(z));
181
182 parr[ip] = farr(i, j, k, ic);
183 });
184 }
185
186 template <typename FType>
188 const int np,
189 const int ic,
190 SamplingContainer::ParticleVector& pvec,
191 SamplingContainer::RealVector& pavec,
192 const FType& farr,
193 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& problo,
194 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dxi,
195 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& dx,
196 const amrex::GpuArray<amrex::Real, AMREX_SPACEDIM>& offset)
197 {
198 BL_PROFILE("kynema-sgf::SamplingContainer::sample_impl");
199
200 auto* pstruct = pvec.data();
201 auto* parr = pavec.data();
202
203 amrex::ParallelFor(np, [=] AMREX_GPU_DEVICE(int ip) {
204 auto& p = pstruct[ip];
205 // Determine offsets within the containing cell
206 const amrex::Real x =
207 (p.pos(0) - problo[0] - offset[0] * dx[0]) * dxi[0];
208 const amrex::Real y =
209 (p.pos(1) - problo[1] - offset[1] * dx[1]) * dxi[1];
210 const amrex::Real z =
211 (p.pos(2) - problo[2] - offset[2] * dx[2]) * dxi[2];
212
213 // Index of the low corner
214 const int i = static_cast<int>(std::floor(x));
215 const int j = static_cast<int>(std::floor(y));
216 const int k = static_cast<int>(std::floor(z));
217
218 // Interpolation weights in each direction (linear basis)
219 const amrex::Real wx_hi = (x - i);
220 const amrex::Real wy_hi = (y - j);
221 const amrex::Real wz_hi = (z - k);
222
223 const amrex::Real wx_lo = 1.0_rt - wx_hi;
224 const amrex::Real wy_lo = 1.0_rt - wy_hi;
225 const amrex::Real wz_lo = 1.0_rt - wz_hi;
226
227 parr[ip] = (wx_lo * wy_lo * wz_lo * farr(i, j, k, ic)) +
228 (wx_lo * wy_lo * wz_hi * farr(i, j, k + 1, ic)) +
229 (wx_lo * wy_hi * wz_lo * farr(i, j + 1, k, ic)) +
230 (wx_lo * wy_hi * wz_hi * farr(i, j + 1, k + 1, ic)) +
231 (wx_hi * wy_lo * wz_lo * farr(i + 1, j, k, ic)) +
232 (wx_hi * wy_lo * wz_hi * farr(i + 1, j, k + 1, ic)) +
233 (wx_hi * wy_hi * wz_lo * farr(i + 1, j + 1, k, ic)) +
234 (wx_hi * wy_hi * wz_hi * farr(i + 1, j + 1, k + 1, ic));
235 });
236 }
237
238private:
240 template <typename FType>
242 const ParIterType& pti,
243 const FType& farr,
244 const int lev,
245 const FieldLoc floc,
246 const int ncomp,
247 const int scomp,
248 const bool use_nearest = false)
249 {
250 const auto& geom = m_mesh.Geom(lev);
251 const auto dx = geom.CellSizeArray();
252 const auto dxi = geom.InvCellSizeArray();
253 const auto plo = geom.ProbLoArray();
254 const int np = pti.numParticles();
255 auto& pvec = pti.GetArrayOfStructs()();
256 int fidx = scomp;
257
258 // Determine the stagger offset for this field location
259 amrex::GpuArray<amrex::Real, AMREX_SPACEDIM> offset{};
260 switch (floc) {
261 case FieldLoc::NODE:
262 offset = {0.0_rt, 0.0_rt, 0.0_rt};
263 break;
264 case FieldLoc::CELL:
265 offset = {0.5_rt, 0.5_rt, 0.5_rt};
266 break;
267 case FieldLoc::XFACE:
268 offset = {0.0_rt, 0.5_rt, 0.5_rt};
269 break;
270 case FieldLoc::YFACE:
271 offset = {0.5_rt, 0.0_rt, 0.5_rt};
272 break;
273 case FieldLoc::ZFACE:
274 offset = {0.5_rt, 0.5_rt, 0.0_rt};
275 break;
276 }
277
278 for (int ic = 0; ic < ncomp; ++ic) {
279 auto& parr = pti.GetStructOfArrays().GetRealData(fidx++);
280 if (use_nearest) {
282 np, ic, pvec, parr, farr, plo, dxi, dx, offset);
283 } else {
284 sample_field(np, ic, pvec, parr, farr, plo, dxi, dx, offset);
285 }
286 }
287 }
288
289 const amrex::AmrCore& m_mesh;
290
292
295};
296
297} // namespace sampling
298} // namespace kynema_sgf
299
300#endif /* SAMPLINGCONTAINER_H */
Definition DerivedQuantity.H:32
Definition Field.H:112
Definition FieldRepo.H:86
Definition SamplerBase.H:60
SamplingContainer(amrex::AmrCore &mesh)
Definition SamplingContainer.H:71
long num_sampling_particles() const
Definition SamplingContainer.H:131
const amrex::AmrCore & m_mesh
Definition SamplingContainer.H:289
void initialize_particles(const amrex::Vector< std::unique_ptr< SamplerBase > > &)
Definition SamplingContainer.cpp:36
void sample_field(const int np, const int ic, SamplingContainer::ParticleVector &pvec, SamplingContainer::RealVector &pavec, const FType &farr, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &problo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxi, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &offset)
Definition SamplingContainer.H:187
long m_total_particles
Definition SamplingContainer.H:291
void set_interpolation_order(const int order)
Interpolation order for sampling: 0 = nearest-neighbor, 1 = linear.
Definition SamplingContainer.H:90
void setup_container(int num_real_components, int num_int_components=0)
Definition SamplingContainer.cpp:13
void interpolate_fields(const amrex::Vector< FType > &fields, const int scomp)
Perform field interpolation to sampling locations.
Definition SamplingContainer.H:98
int m_interpolation_order
Interpolation order for sampling: 0 = nearest-neighbor, 1 = linear.
Definition SamplingContainer.H:294
void populate_buffer(std::vector< amrex::Real > &buf)
Populate the buffer with data for all the particles.
Definition SamplingContainer.cpp:168
void interpolate_derived_fields(const DerivedQtyMgr &derived_mgr, const FieldRepo &repo, int scomp)
Perform derived field interpolation to sampling locations.
Definition SamplingContainer.cpp:147
void sample_field_nearest(const int np, const int ic, SamplingContainer::ParticleVector &pvec, SamplingContainer::RealVector &pavec, const FType &farr, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &problo, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dxi, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &offset)
Definition SamplingContainer.H:152
long & num_sampling_particles()
Definition SamplingContainer.H:133
void interpolate(const ParIterType &pti, const FType &farr, const int lev, const FieldLoc floc, const int ncomp, const int scomp, const bool use_nearest=false)
Interpolate from an array4 onto particles.
Definition SamplingContainer.H:241
FieldLoc
Definition FieldDescTypes.H:29
@ NODE
Node-centered (e.g., for pressure)
Definition FieldDescTypes.H:31
@ ZFACE
Face-centered in z-direction.
Definition FieldDescTypes.H:34
@ XFACE
Face-centered in x-direction (e.g., face normal velocity)
Definition FieldDescTypes.H:32
@ CELL
Cell-centered (default)
Definition FieldDescTypes.H:30
@ YFACE
Face-centered in y-direction.
Definition FieldDescTypes.H:33
Definition console_io.cpp:30
Definition DTUSpinnerSampler.cpp:19
static constexpr int SNStructInt
Definition SamplingContainer.H:22
static constexpr int SNStructReal
Definition SamplingContainer.H:21
static constexpr int SNArrayInt
Definition SamplingContainer.H:24
static constexpr int SNArrayReal
Definition SamplingContainer.H:23
This test case is intended as an evaluation of the momentum advection scheme.
Definition BCInterface.cpp:10
Definition SamplingContainer.H:30
Indices
Definition SamplingContainer.H:31
@ nid
Index within the set for this particle.
Definition SamplingContainer.H:34
@ sid
Identifier of the set this particle belongs to.
Definition SamplingContainer.H:33
@ uid
Unique identifier for this particle.
Definition SamplingContainer.H:32