34 assert(sc &&
"Invalid Pointer to Spatial Cell !");
36 const size_t total_blocks = blockContainer->
size();
40 Realf* data = blockContainer->getData();
41 assert(max_v_lims &&
"Invalid Pointre to max_v_limits");
42 assert(min_v_lims &&
"Invalid Pointre to min_v_limits");
43 assert(data &&
"Invalid Pointre block container data");
44 auto vcoords = std::vector<std::array<Real, 3>>(blockContainer->size() *
WID3, {
Real(0),
Real(0),
Real(0)});
45 auto vspace = std::vector<Realf>(blockContainer->size() *
WID3,
Realf(0));
48 std::array<Real, 6> vlims{std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(),
49 std::numeric_limits<Real>::max(), std::numeric_limits<Real>::lowest(),
50 std::numeric_limits<Real>::lowest(), std::numeric_limits<Real>::lowest()};
53 for (std::size_t n = 0; n < total_blocks; ++n) {
56 for (uint
k = 0;
k <
WID; ++
k) {
57 for (uint
j = 0;
j <
WID; ++
j) {
58 for (uint
i = 0;
i <
WID; ++
i) {
62 vlims[0] = std::min(vlims[0], vx);
63 vlims[1] = std::min(vlims[1], vy);
64 vlims[2] = std::min(vlims[2], vz);
65 vlims[3] = std::max(vlims[3], vx);
66 vlims[4] = std::max(vlims[4], vy);
67 vlims[5] = std::max(vlims[5], vz);
69 vcoords[cnt] = {vx, vy, vz};
70 vspace[cnt] = vdf_val;
76 return UnorderedVDF{.vdf_vals = vspace, .vdf_coords = vcoords, .v_limits = vlims};
110 assert(sc &&
"Invalid Pointer to Spatial Cell !");
112 const size_t total_blocks = blockContainer->
size();
114 Realf* data = blockContainer->getData();
116 for (std::size_t n = 0; n < total_blocks; ++n) {
119 for (uint
k = 0;
k <
WID; ++
k) {
120 for (uint
j = 0;
j <
WID; ++
j) {
121 for (uint
i = 0;
i <
WID; ++
i) {
125 const std::size_t nx = std::ceil((vdf.v_limits[3] - vdf.v_limits[0]) / dvx);
126 const std::size_t ny = std::ceil((vdf.v_limits[4] - vdf.v_limits[1]) / dvy);
127 const std::size_t nz = std::ceil((vdf.v_limits[5] - vdf.v_limits[2]) /
dvz);
131 const size_t bbox_i = std::min(
static_cast<size_t>(std::floor((vx - vdf.v_limits[0]) / dvx)), nx - 1);
132 const size_t bbox_j = std::min(
static_cast<size_t>(std::floor((vy - vdf.v_limits[1]) / dvy)), ny - 1);
133 const size_t bbox_k = std::min(
static_cast<size_t>(std::floor((vz - vdf.v_limits[2]) /
dvz)), nz - 1);
134 const size_t index = bbox_i * (ny * nz) + bbox_j * nz + bbox_k;
150 assert(sc &&
"Invalid Pointer to Spatial Cell !");
152 throw std::runtime_error(
"Zoom is not supported yet!");
155 const size_t total_blocks = blockContainer->
size();
159 std::array<Real, 6> vlims{std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(),
160 std::numeric_limits<Real>::max(), std::numeric_limits<Real>::lowest(),
161 std::numeric_limits<Real>::lowest(), std::numeric_limits<Real>::lowest()};
168 for (std::size_t n = 0; n < total_blocks; ++n) {
170 for (uint
k = 0;
k <
WID; ++
k) {
171 for (uint
j = 0;
j <
WID; ++
j) {
172 for (uint
i = 0;
i <
WID; ++
i) {
176 vlims[0] = std::min(vlims[0], vx);
177 vlims[1] = std::min(vlims[1], vy);
178 vlims[2] = std::min(vlims[2], vz);
179 vlims[3] = std::max(vlims[3], vx);
180 vlims[4] = std::max(vlims[4], vy);
181 vlims[5] = std::max(vlims[5], vz);
187 assert(
isPow2(
static_cast<size_t>(std::abs(zoom))));
188 float ratio = (zoom > 0) ?
static_cast<float>(std::abs(zoom)) : 1.0 /
static_cast<float>(std::abs(zoom));
191 const Real target_dvx = dvx * ratio;
192 const Real target_dvy = dvy * ratio;
193 const Real target_dvz =
dvz * ratio;
194 std::size_t nx = std::ceil((vlims[3] - vlims[0]) / target_dvx);
195 std::size_t ny = std::ceil((vlims[4] - vlims[1]) / target_dvy);
196 std::size_t nz = std::ceil((vlims[5] - vlims[2]) / target_dvz);
199 std::unordered_set<vmesh::GlobalID> ignore_list;
200 for (std::size_t
k = 0;
k < nz; ++
k) {
201 for (std::size_t
j = 0;
j < ny; ++
j) {
202 for (std::size_t
i = 0;
i < nx; ++
i) {
203 const Real vx = vlims[0] + (
i + 0.5) * dvx;
204 const Real vy = vlims[1] + (
j + 0.5) * dvy;
205 const Real vz = vlims[2] + (
k + 0.5) *
dvz;
206 const std::array<Real,3>coords={vx,vy,vz};
208 ignore_list.insert(gid);
213 Realf* data = blockContainer->getData();
214 std::vector<Realf> vspace(nx * ny * nz,
Realf(0));
215 for (std::size_t n = 0; n < total_blocks; ++n) {
219 (void)ignore_list.erase(gid);
220 for (uint
k = 0;
k <
WID; ++
k) {
221 for (uint
j = 0;
j <
WID; ++
j) {
222 for (uint
i = 0;
i <
WID; ++
i) {
226 const size_t bbox_i = std::min(
static_cast<size_t>(std::floor((vx - vlims[0]) / target_dvx)), nx - 1);
227 const size_t bbox_j = std::min(
static_cast<size_t>(std::floor((vy - vlims[1]) / target_dvy)), ny - 1);
228 const size_t bbox_k = std::min(
static_cast<size_t>(std::floor((vz - vlims[2]) / target_dvz)), nz - 1);
232 const size_t index = bbox_i * (ny * nz) + bbox_j * nz + bbox_k;
236 int max_off = 1 / ratio;
237 for (
int off_z = 0; off_z <= max_off; off_z++) {
238 for (
int off_y = 0; off_y <= max_off; off_y++) {
239 for (
int off_x = 0; off_x <= max_off; off_x++) {
240 const size_t index = (bbox_i + off_x) * (ny * nz) + (bbox_j + off_y) * nz + (bbox_k + off_z);
241 if (
index < vspace.size()) {
253 std::vector<vmesh::GlobalID >ignored;
254 ignored.reserve(ignore_list.size());
255 for (
auto it = ignore_list.begin(); it != ignore_list.end(); ) {
256 ignored.push_back(std::move(ignore_list.extract(it++).value()));
259 return ASTERIX::OrderedVDF{.blocks_to_ignore=ignored,.sparse_vdf_bytes=total_blocks*
WID*
WID*
WID*
sizeof(
Realf),.vdf_vals = vspace, .v_limits = vlims, .shape = {nx, ny, nz}};
263 dccrg::Dccrg<spatial_cell::SpatialCell, dccrg::Cartesian_Geometry>& mpiGrid,
264 const std::vector<std::array<Real, 3>>& vcoords,
265 const std::vector<Realf>& vspace_union,
266 const std::unordered_map<vmesh::LocalID, std::size_t>& map_exists_id) {
267 const std::size_t nrows = vcoords.size();
268 const std::size_t ncols = cids.size();
270 auto index_2d = [nrows, ncols](std::size_t row, std::size_t col) -> std::size_t {
return row * ncols + col; };
272 for (std::size_t cc = 0; cc < cids.size(); ++cc) {
273 const auto& cid = cids[cc];
276 const size_t total_blocks = blockContainer->
size();
277 Realf* data = blockContainer->getData();
279 for (std::size_t n = 0; n < total_blocks; ++n) {
282 const auto it = map_exists_id.find(gid);
283 const bool exists = it != map_exists_id.end();
285 std::cerr<<
"This should not happen!"<<std::endl;
288 assert(exists &&
"Someone has a buuuug!");
289 const auto index = it->second;
292 for (uint
k = 0;
k <
WID; ++
k) {
293 for (uint
j = 0;
j <
WID; ++
j) {
294 for (uint
i = 0;
i <
WID; ++
i) {
295 const std::size_t
index = it->second;
336 Real PTensor[3] = {};
342 Real norm_par =
sqrt(BX * BX + BY * BY + BZ * BZ);
343 b_par[0] = BX / norm_par;
344 b_par[1] = BY / norm_par;
345 b_par[2] = BZ / norm_par;
348 Real BV0 =
sqrt(b_par[0] * V0[0] + b_par[1] * V0[1] + b_par[2] * V0[2]);
349 b_perp1[0] = V0[0] - BV0 * b_par[0];
350 b_perp1[1] = V0[1] - BV0 * b_par[1];
351 b_perp1[2] = V0[2] - BV0 * b_par[2];
352 Real norm_perp1 =
sqrt(b_perp1[0] * b_perp1[0] + b_perp1[1] * b_perp1[1] + b_perp1[2] * b_perp1[2]);
353 if (!(norm_perp1 > 0.0)) {
355 b_perp1[0] = +b_par[1] + b_par[2];
356 b_perp1[1] = +b_par[2] - b_par[0];
357 b_perp1[2] = -b_par[0] - b_par[1];
358 norm_perp1 =
sqrt(b_perp1[0] * b_perp1[0] + b_perp1[1] * b_perp1[1] + b_perp1[2] * b_perp1[2]);
360 b_perp1[0] /= norm_perp1;
361 b_perp1[1] /= norm_perp1;
362 b_perp1[2] /= norm_perp1;
365 b_perp2[0] = b_par[1] * b_perp1[2] - b_par[2] * b_perp1[1];
366 b_perp2[1] = b_par[2] * b_perp1[0] - b_par[0] * b_perp1[2];
367 b_perp2[2] = b_par[0] * b_perp1[1] - b_par[1] * b_perp1[0];
368 Real norm_perp2 =
sqrt(b_perp2[0] * b_perp2[0] + b_perp2[1] * b_perp2[1] + b_perp2[2] * b_perp2[2]);
369 b_perp2[0] /= norm_perp2;
370 b_perp2[1] /= norm_perp2;
371 b_perp2[2] /= norm_perp2;
377 Real thread_nvxvx_sum = 0.0;
378 Real thread_nvyvy_sum = 0.0;
379 Real thread_nvzvz_sum = 0.0;
386 for (uint
k = 0;
k <
WID; ++
k)
387 for (uint
j = 0;
j <
WID; ++
j)
388 for (uint
i = 0;
i <
WID; ++
i) {
399 const Real V_par = (
VX - V0[0]) * b_par[0] + (
VY - V0[1]) * b_par[1] + (
VZ - V0[2]) * b_par[2];
401 (
VX - V0[0]) * b_perp1[0] + (
VY - V0[1]) * b_perp1[1] + (
VZ - V0[2]) * b_perp1[2];
403 (
VX - V0[0]) * b_perp2[0] + (
VY - V0[1]) * b_perp2[1] + (
VZ - V0[2]) * b_perp2[2];
419 PTensor[0] += thread_nvxvx_sum;
420 PTensor[1] += thread_nvyvy_sum;
421 PTensor[2] += thread_nvzvz_sum;
432 Real thread_epsilon_sum = 0.0;
439 for (uint
k = 0;
k <
WID; ++
k)
440 for (uint
j = 0;
j <
WID; ++
j)
441 for (uint
i = 0;
i <
WID; ++
i) {
452 const Real V_par = (
VX - V0[0]) * b_par[0] + (
VY - V0[1]) * b_par[1] + (
VZ - V0[2]) * b_par[2];
454 (
VX - V0[0]) * b_perp1[0] + (
VY - V0[1]) * b_perp1[1] + (
VZ - V0[2]) * b_perp1[2];
456 (
VX - V0[0]) * b_perp2[0] + (
VY - V0[1]) * b_perp2[1] + (
VZ - V0[2]) * b_perp2[2];
458 const Real bimaxwellian =
459 rho /
sqrt(M_PI * M_PI * M_PI * V_par_th_sq * V_par_th_sq * V_par_th_sq) * (T_par / T_perp) *
460 exp(-(V_par * V_par) / V_par_th_sq -
461 (V_perp1 * V_perp1 + V_perp2 * V_perp2) / (V_par_th_sq * T_perp / T_par));
463 thread_epsilon_sum +=
472 { epsilon += thread_epsilon_sum; }
474 epsilon *=
HALF / rho;
ObjectWrapper & getObjectWrapper()
auto overwrite_cellids_vdfs(const std::span< const CellID > cids, uint popID, dccrg::Dccrg< spatial_cell::SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::vector< std::array< Real, 3 > > &vcoords, const std::vector< Realf > &vspace_union, const std::unordered_map< vmesh::LocalID, std::size_t > &map_exists_id) -> void