Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
spatial_cell_cpu.hpp
Go to the documentation of this file.
1/*
2 * This file is part of Vlasiator.
3 * Copyright 2010-2024 Finnish Meteorological Institute and University of Helsinki
4 *
5 * For details of usage, see the COPYING file and read the "Rules of the Road"
6 * at http://www.physics.helsinki.fi/vlasiator/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
26
27#ifndef VLASIATOR_SPATIAL_CELL_CPU_HPP
28#define VLASIATOR_SPATIAL_CELL_CPU_HPP
29
30#include <algorithm>
31#include <cmath>
32#include <fstream>
33#include <iostream>
34#include <mpi.h>
35#include <limits>
36#include <stdint.h>
37#include <vector>
38#include <array>
39#include <unordered_map>
40#include <set>
41#include <map>
42#include <phiprof.hpp>
43#include <tuple>
44
45#include "../memoryallocation.h"
46#include "../common.h"
47#include "../parameters.h"
48#include "../definitions.h"
49
50#include "velocity_mesh_cpu.h"
52
53#ifdef DEBUG_VLASIATOR
54 #ifndef DEBUG_SPATIAL_CELL
55 #define DEBUG_SPATIAL_CELL
56 #endif
57#endif
58
59namespace spatial_cell {
60
66 struct Population {
68 Real V[3];
73 Real P[6];
79
87 std::vector<char> compressed_state_buffer;
88 float mlp_error = {std::numeric_limits<float>::max()};
89 uint32_t mlp_epochs = {0};
90
96
97 // Constructor, destructor
101 // Set values to zero in case of zero-block populations
103 for (uint i=0; i<2; ++i) {
104 max_dt[i] = 0;
105 }
106 for (uint i=0; i<3; ++i) {
107 V[i] = V_R[i] = V_V[i] = 0;
108 }
109 for (uint i=0; i<6; i++) {
110 P[i] = P_R[i] = P_V[i] = 0;
111 }
112 }
114 delete vmesh;
115 delete blockContainer;
116 }
117 Population(const Population& other) {
118 vmesh = new vmesh::VelocityMesh(*(other.vmesh));
120
121 RHO = other.RHO;
122 RHO_R = other.RHO_R;
123 RHO_V = other.RHO_V;
127 N_blocks = other.N_blocks;
128 for (uint i=0; i<2; ++i) {
129 max_dt[i] = other.max_dt[i];
130 }
131 for (uint i=0; i<3; ++i) {
132 V[i] = other.V[i];
133 V_R[i] = other.V_R[i];
134 V_V[i] = other.V_V[i];
135 }
136 for (uint i=0; i<6; i++) {
137 P[i] = other.P[i];
138 P_R[i] = other.P_R[i];
139 P_V[i] = other.P_V[i];
140 }
141 }
142 const Population& operator=(const Population& other) {
143 delete vmesh;
144 delete blockContainer;
145 vmesh = new vmesh::VelocityMesh(*(other.vmesh));
147
148 RHO = other.RHO;
149 RHO_R = other.RHO_R;
150 RHO_V = other.RHO_V;
154 N_blocks = other.N_blocks;
155 for (uint i=0; i<2; ++i) {
156 max_dt[i] = other.max_dt[i];
157 }
158 for (uint i=0; i<3; ++i) {
159 V[i] = other.V[i];
160 V_R[i] = other.V_R[i];
161 V_V[i] = other.V_V[i];
162 }
163 for (uint i=0; i<6; i++) {
164 P[i] = other.P[i];
165 P_R[i] = other.P_R[i];
166 P_V[i] = other.P_V[i];
167 }
168 return *this;
169 }
170 void ResizeClear(const uint newSize) {
171 // Resizes the vmesh localToGlobalMap, clears the vmesh GlobalToLocalMap,
172 // and resizes the velocity block container.
173 // Contents of the localToGlobalMap or the VBC are not edited.
174 vmesh->setNewSize(newSize);
175 vmesh->clearMap(newSize);
176 blockContainer->setNewSize(newSize);
177 }
178 void Scale(creal factor) {
179 RHO *= factor;
180 RHO_R *= factor;
181 RHO_V *= factor;
182 for (uint i=0; i<3; ++i) {
183 P[i] *= factor;
184 P_R[i] *= factor;
185 P_V[i] *= factor;
186 }
187 // Now loop over whole velocity space and scale the values
188 for (vmesh::LocalID blockLID=0; blockLID < vmesh->size(); ++blockLID) {
189 // Pointer to target block data
190 Realf* toData = blockContainer->getData(blockLID);
191 // Scale data
192 for (uint i=0; i<WID3; ++i) {
193 toData[i] = toData[i] * factor;
194 }
195 }
196 }
197 void Increment(const Population& other, creal factor) {
198 // Note: moments will be invalidated.
199 // Loop over the whole velocity space, and add scaled values.
200 for (vmesh::LocalID incBlockLID=0; incBlockLID<(other.vmesh)->size(); ++incBlockLID) {
201 const Realf* fromData = (other.blockContainer)->getData(incBlockLID);
202
203 // Global ID of the block containing incoming data
204 vmesh::GlobalID incBlockGID = (other.vmesh)->getGlobalID(incBlockLID);
205
206 // Get local ID of the target block. If the block doesn't exist, create it.
207 vmesh::GlobalID toBlockLID = vmesh->getLocalID(incBlockGID);
208 if (toBlockLID == vmesh->invalidLocalID()) {
209 bool success = vmesh->push_back(incBlockGID);
210 toBlockLID = blockContainer->push_back_and_zero();
211 Real* parameters = blockContainer->getParameters(toBlockLID);
212 vmesh->getBlockInfo(incBlockGID, parameters+BlockParams::VXCRD);
213 }
214
215 // Pointer to target block data
216 Realf* toData = blockContainer->getData(toBlockLID);
217 // Add scaled values from source cells
218 for (uint i=0; i<WID3; ++i) {
219 toData[i] += fromData[i] * factor;
220 }
221 } // for-loop over velocity blocks
222 }
223 };
224
225 typedef std::array<unsigned int, 3> velocity_cell_indices_t;
229
230 typedef std::array<vmesh::LocalID,3> velocity_block_indices_t;
234
236 public:
237 SpatialCell();
238 ~SpatialCell();
239 SpatialCell(const SpatialCell& other);
240 const SpatialCell& operator=(const SpatialCell& other);
241
242 // Following functions return velocity grid metadata //
243 template<int PAD> void fetch_data(const vmesh::GlobalID& blockGID,const vmesh::VelocityMesh* vmesh,
244 const Realf* src,Realf* array);
245 template<int PAD> void fetch_acc_data(const vmesh::GlobalID& blockGID,const int& dim,
247 const Realf* src,Realf* array,Real cellSizeFractions[2]);
248
249 vmesh::GlobalID find_velocity_block(vmesh::GlobalID cellIndices[3],const uint popID);
250 Realf* get_data(const uint popID);
251 const Realf* get_data(const uint popID) const;
252 Realf* get_data(const vmesh::LocalID& blockLID,const uint popID);
253 const Realf* get_data(const vmesh::LocalID& blockLID,const uint popID) const;
254 Real* get_block_parameters(const uint popID);
255 const Real* get_block_parameters(const uint popID) const;
256 Real* get_block_parameters(const vmesh::LocalID& blockLID,const uint popID);
257 const Real* get_block_parameters(const vmesh::LocalID& blockLID,const uint popID) const;
258
260 const Real* get_cell_parameters() const;
261
262 vmesh::LocalID get_number_of_velocity_blocks(const uint popID) const;
264 int get_number_of_populations() const;
265 void debug_population_check(const uint popID) const;
266 void debug_population_check(const uint popID, const vmesh::LocalID blockLID) const;
267
268 Population & get_population(const uint popID);
269 const Population & get_population(const uint popID) const;
270 void set_population(const Population& pop, cuint popID);
271 void scale_population(creal factor, cuint popID);
272 void increment_population(const Population& pop, creal factor, cuint popID);
273
274 std::vector<Population>& get_populations();
275 const std::vector<Population>& get_populations() const;
276
277 const Real& get_max_r_dt(const uint popID) const;
278 const Real& get_max_v_dt(const uint popID) const;
279
280 const vmesh::LocalID* get_velocity_grid_length(const uint popID);
281 const Real* get_velocity_grid_block_size(const uint popID);
282 const Real* get_velocity_grid_cell_size(const uint popID);
283 void get_velocity_block_coordinates(const uint popID,const vmesh::GlobalID& globalID,Real* coords);
285 vmesh::GlobalID get_velocity_block(const uint popID,vmesh::GlobalID blockIndices[3]) const;
286 vmesh::GlobalID get_velocity_block(const uint popID,const velocity_block_indices_t indices) const;
287 vmesh::GlobalID get_velocity_block(const uint popID,const Real* coords) const;
288 vmesh::GlobalID get_velocity_block(const uint popID,const Real vx,const Real vy,const Real vz) const;
290 const int& i_cell,const int& j_cell,const int& k_cell);
292 std::vector<vmesh::LocalID>& childrenLIDs,
293 const uint popID);
295 vmesh::GlobalID get_velocity_block_global_id(const vmesh::LocalID& blockLID,const uint popID) const;
296 vmesh::LocalID get_velocity_block_local_id(const vmesh::GlobalID& blockGID,const uint popID) const;
297 void get_velocity_block_size(const uint popID,const vmesh::GlobalID block,Real size[3]);
298 Real get_velocity_block_vx_min(const uint popID,const vmesh::GlobalID block) const;
299 Real get_velocity_block_vx_max(const uint popID,const vmesh::GlobalID block) const;
300 Real get_velocity_block_vy_min(const uint popID,const vmesh::GlobalID block) const;
301 Real get_velocity_block_vy_max(const uint popID,const vmesh::GlobalID block) const;
302 Real get_velocity_block_vz_min(const uint popID,const vmesh::GlobalID block) const;
303 Real get_velocity_block_vz_max(const uint popID,const vmesh::GlobalID block) const;
304
305 static unsigned int invalid_block_index();
308
309 size_t count(const vmesh::GlobalID& block,const uint popID) const;
310
311 void add_values(const vmesh::GlobalID& targetGID,
312 std::unordered_map<vmesh::GlobalID,Realf[(WID+2)*(WID+2)*(WID+2)]>& sourceData,
313 const uint popID);
314
315 void printMeshSizes();
316 static bool setCommunicatedSpecies(const uint popID);
317
318 // Following functions adjust velocity blocks stored on the cell //
319 bool add_velocity_block(const vmesh::GlobalID& block,const uint popID);
320 void adjustSingleCellVelocityBlocks(const uint popID, bool doDeleteEmpty=false);
321 void adjust_velocity_blocks(const std::vector<SpatialCell*>& spatial_neighbors,
322 const uint popID,
323 bool doDeleteEmptyBlocks=true);
324 // Templated function for storing a v-space read from a file or generated elsewhere
325 template <typename fileReal> void add_velocity_blocks(const uint popID,const std::vector<vmesh::GlobalID>& blocks,fileReal* avgBuffer);
326
327 void update_velocity_block_content_lists(const uint popID);
328 bool checkMesh(const uint popID);
329 void clear(const uint popID, bool shrink=false);
330 void setNewSizeClear(const uint popID, const vmesh::LocalID& newSize);
331 void setNewSizeClear(const uint popID);
332
333 uint64_t get_cell_memory_capacity();
334 uint64_t get_cell_memory_size();
335 void merge_values(const uint popID);
336 void prepare_to_receive_blocks(const uint popID);
337 bool shrink_to_fit();
338 size_t size(const uint popID) const;
339 void remove_velocity_block(const vmesh::GlobalID& block,const uint popID);
340 vmesh::VelocityMesh* get_velocity_mesh(const size_t& popID);
342 const vmesh::VelocityBlockContainer* get_velocity_blocks(const size_t& popID) const;
343
344 void set_max_r_dt(const uint popID,const Real& value);
345 void set_max_v_dt(const uint popID,const Real& value);
346
347 // Following functions are related to MPI //
348 std::tuple<void*, int, MPI_Datatype> get_mpi_datatype(const CellID cellID,const int sender_rank,const int receiver_rank,
349 const bool receiving,const int neighborhood);
350 static uint64_t get_mpi_transfer_type(void);
351 static void set_mpi_transfer_type(const uint64_t type,bool atSysBoundaries=false);
352 static void set_mpi_transfer_direction(const int dimension);
353 void set_mpi_transfer_enabled(bool transferEnabled);
354 void updateSparseMinValue(const uint popID);
355 Real getVelocityBlockMinValue(const uint popID) const;
356
357 // Member variables //
358 std::array<Real, vderivatives::N_V_DERIVATIVES> derivativesV;
359 std::array<Real, bvolderivatives::N_BVOL_DERIVATIVES> derivativesBVOL;
361 std::array<Real, CellParams::N_SPATIAL_CELL_PARAMS> parameters;
362 std::array<Realf, WID3> null_block_data;
363
364 uint64_t ioLocalCellId;
366 std::array<Realf*,MAX_NEIGHBORS_PER_DIM> neighbor_block_data;
368 std::array<vmesh::LocalID,MAX_NEIGHBORS_PER_DIM> neighbor_number_of_blocks;
369 std::map<int,std::set<int>> face_neighbor_ranks;
375 std::vector<vmesh::GlobalID> *velocity_block_with_content_list;
378 std::vector<vmesh::GlobalID> *velocity_block_with_no_content_list;
381 static uint64_t mpi_transfer_type;
383
384 //SpatialCell& operator=(const SpatialCell& other);
385 private:
386 //SpatialCell& operator=(const SpatialCell&);
387
388 bool compute_block_has_content(const vmesh::GlobalID& block,const uint popID) const;
389
390 static int activePopID;
393
394 std::vector<spatial_cell::Population> populations;
395 };
396
397 inline void SpatialCell::debug_population_check(const uint popID) const {
398 #ifdef DEBUG_SPATIAL_CELL
399 if (popID >= populations.size()) {
400 std::cerr << "ERROR, popID " << popID << " exceeds populations.size() " << populations.size() << " in ";
401 std::cerr << __FILE__ << ":" << __LINE__ << std::endl;
402 exit(1);
403 }
404 #endif
405 }
406 inline void SpatialCell::debug_population_check(const uint popID, const vmesh::LocalID blockLID) const {
408 #ifdef DEBUG_SPATIAL_CELL
409 if (blockLID >= populations[popID].blockContainer->size()) {
410 std::cerr << "ERROR, block LID out of bounds, blockContainer->size() " << populations[popID].blockContainer->size() << " in ";
411 std::cerr << __FILE__ << ":" << __LINE__ << std::endl;
412 exit(1);
413 }
414 #endif
415 }
416
417 inline vmesh::GlobalID SpatialCell::find_velocity_block(vmesh::GlobalID cellIndices[3],const uint popID) {
419 return populations[popID].vmesh->findBlock(cellIndices);
420 }
421
422 inline Realf* SpatialCell::get_data(const uint popID) {
424 return populations[popID].blockContainer->getData();
425 }
426
427 inline const Realf* SpatialCell::get_data(const uint popID) const {
429 return populations[popID].blockContainer->getData();
430 }
431
432 inline Realf* SpatialCell::get_data(const vmesh::LocalID& blockLID,const uint popID) {
433 debug_population_check(popID,blockLID);
434 if (blockLID == vmesh::VelocityMesh::invalidLocalID()) {
435 return null_block_data.data();
436 }
437 return populations[popID].blockContainer->getData(blockLID);
438 }
439
440 inline const Realf* SpatialCell::get_data(const vmesh::LocalID& blockLID,const uint popID) const {
441 debug_population_check(popID,blockLID);
442 if (blockLID == vmesh::VelocityMesh::invalidLocalID()) {
443 return null_block_data.data();
444 }
445 return populations[popID].blockContainer->getData(blockLID);
446 }
447
448 inline Real* SpatialCell::get_block_parameters(const uint popID) {
450 return populations[popID].blockContainer->getParameters();
451 }
452
453 inline const Real* SpatialCell::get_block_parameters(const uint popID) const {
455 return populations[popID].blockContainer->getParameters();
456 }
457
458 inline Real* SpatialCell::get_block_parameters(const vmesh::LocalID& blockLID,const uint popID) {
459 debug_population_check(popID,blockLID);
460 return populations[popID].blockContainer->getParameters(blockLID);
461 }
462
463 inline const Real* SpatialCell::get_block_parameters(const vmesh::LocalID& blockLID,const uint popID) const {
464 debug_population_check(popID,blockLID);
465 return populations[popID].blockContainer->getParameters(blockLID);
466 }
467
469 return parameters.data();
470 }
471
473 return parameters.data();
474 }
475
478 return populations[popID].blockContainer->size();
479 }
480
485 vmesh::LocalID N_blocks = 0;
486 for (size_t p=0; p<populations.size(); ++p)
487 N_blocks += populations[p].blockContainer->size();
488 return N_blocks;
489 }
490
492 return populations.size();
493 }
494
495 inline Population & SpatialCell::get_population(const uint popID) {
496 return populations[popID];
497 }
498
499 inline const Population & SpatialCell::get_population(const uint popID) const {
500 return populations[popID];
501 }
502
503 inline void SpatialCell::set_population(const Population& pop, cuint popID) {
504 this->populations[popID] = pop;
505 }
506 inline void SpatialCell::scale_population(creal factor, cuint popID) {
507 (this->populations[popID]).Scale(factor);
508 }
509 inline void SpatialCell::increment_population(const Population& pop, creal factor, cuint popID) {
510 (this->populations[popID]).Increment(pop, factor);
511 }
512 inline std::vector<Population>& SpatialCell::get_populations() {
513 return populations;
514 }
515 inline const std::vector<Population>& SpatialCell::get_populations() const {
516 return populations;
517 }
518
520 return populations[popID].vmesh->getGridLength();
521 }
522
523 inline const Real* SpatialCell::get_velocity_grid_block_size(const uint popID) {
524 return populations[popID].vmesh->getBlockSize();
525 }
526
527 inline const Real* SpatialCell::get_velocity_grid_cell_size(const uint popID) {
528 return populations[popID].vmesh->getCellSize();
529 }
530
531 inline void SpatialCell::get_velocity_block_coordinates(const uint popID,const vmesh::GlobalID& globalID,Real* coords) {
532 populations[popID].vmesh->getBlockCoordinates(globalID,coords);
533 }
534
540 populations[popID].vmesh->getIndices(block,indices[0],indices[1],indices[2]);
541 return indices;
542 }
543
547 inline vmesh::GlobalID SpatialCell::get_velocity_block(const uint popID,const velocity_block_indices_t indices) const {
548 return populations[popID].vmesh->getGlobalID(indices[0],indices[1],indices[2]);
549 }
550
551 inline vmesh::GlobalID SpatialCell::get_velocity_block(const uint popID,vmesh::GlobalID blockIndices[3]) const {
552 return populations[popID].vmesh->getGlobalID(blockIndices[0],blockIndices[1],blockIndices[2]);
553 }
554
559 inline vmesh::GlobalID SpatialCell::get_velocity_block(const uint popID,const Real vx,const Real vy,const Real vz) const {
560 Real coords[3] = {vx,vy,vz};
561 return populations[popID].vmesh->getGlobalID(coords);
562 }
563
564 inline vmesh::GlobalID SpatialCell::get_velocity_block(const uint popID,const Real* coords) const {
565 return populations[popID].vmesh->getGlobalID(coords);
566 }
567
568 inline vmesh::GlobalID SpatialCell::get_velocity_block_global_id(const vmesh::LocalID& blockLID,const uint popID) const {
570 return populations[popID].vmesh->getGlobalID(blockLID);
571 }
572
573 inline vmesh::LocalID SpatialCell::get_velocity_block_local_id(const vmesh::GlobalID& blockGID,const uint popID) const {
575 return populations[popID].vmesh->getLocalID(blockGID);
576 }
577
578 inline void SpatialCell::get_velocity_block_size(const uint popID,const vmesh::GlobalID block,Real blockSize[3]) {
579 populations[popID].vmesh->getBlockSize(block,blockSize);
580 }
581
585 inline Real SpatialCell::get_velocity_block_vx_min(const uint popID,const vmesh::GlobalID block) const {
586 Real coords[3];
587 populations[popID].vmesh->getBlockCoordinates(block,coords);
588 return coords[0];
589 }
590
594 inline Real SpatialCell::get_velocity_block_vx_max(const uint popID,const vmesh::GlobalID block) const {
595 Real coords[3];
596 populations[popID].vmesh->getBlockCoordinates(block,coords);
597
598 Real size[3];
599 populations[popID].vmesh->getBlockSize(block,size);
600 return coords[0]+size[0];
601 }
602
606 inline Real SpatialCell::get_velocity_block_vy_min(const uint popID,const vmesh::GlobalID block) const {
607 Real coords[3];
608 populations[popID].vmesh->getBlockCoordinates(block,coords);
609 return coords[1];
610 }
611
615 inline Real SpatialCell::get_velocity_block_vy_max(const uint popID,const vmesh::GlobalID block) const {
616 Real coords[3];
617 populations[popID].vmesh->getBlockCoordinates(block,coords);
618
619 Real size[3];
620 populations[popID].vmesh->getBlockSize(block,size);
621 return coords[1]+size[1];
622 }
623
627 inline Real SpatialCell::get_velocity_block_vz_min(const uint popID,const vmesh::GlobalID block) const {
628 Real coords[3];
629 populations[popID].vmesh->getBlockCoordinates(block,coords);
630 return coords[2];
631 }
632
636 inline Real SpatialCell::get_velocity_block_vz_max(const uint popID,const vmesh::GlobalID block) const {
637 Real coords[3];
638 populations[popID].vmesh->getBlockCoordinates(block,coords);
639
640 Real size[3];
641 populations[popID].vmesh->getBlockSize(block,size);
642 return coords[2]+size[2];
643 }
644
648
652
656
660 inline size_t SpatialCell::count(const vmesh::GlobalID& block,const uint popID) const {
662 return populations[popID].vmesh->count(block);
663 }
664
668 inline size_t SpatialCell::size(const uint popID) const {
670 return populations[popID].vmesh->size();
671 }
672
675 return populations[popID].vmesh;
676 }
677
680 return populations[popID].blockContainer;
681 }
682 inline const vmesh::VelocityBlockContainer* SpatialCell::get_velocity_blocks(const size_t& popID) const {
684 return populations[popID].blockContainer;
685 }
686
687 inline bool SpatialCell::checkMesh(const uint popID) {
689 return populations[popID].vmesh->check();
690 }
691
695 inline void SpatialCell::clear(const uint popID, bool shrink) {
697 populations[popID].vmesh->clear(shrink);
698 populations[popID].blockContainer->clear(shrink);
699 }
700
706 inline void SpatialCell::setNewSizeClear(const uint popID, const vmesh::LocalID& newSize) {
707 populations[popID].ResizeClear(newSize);
708 }
709 inline void SpatialCell::setNewSizeClear(const uint popID) {
710 populations[popID].ResizeClear(populations[popID].N_blocks);
711 }
712
718 uint64_t size = 0;
719 size += 2 * WID3 * sizeof(Realf);
724
725 for (size_t p=0; p<populations.size(); ++p) {
726 size += populations[p].vmesh->sizeInBytes();
727 size += populations[p].blockContainer->sizeInBytes();
728 }
729
730 return size;
731 }
732
738 uint64_t capacity = 0;
739
740 capacity += 2 * WID3 * sizeof(Realf);
741 capacity += velocity_block_with_content_list->capacity() * sizeof(vmesh::GlobalID);
742 capacity += velocity_block_with_no_content_list->capacity() * sizeof(vmesh::GlobalID);
743 capacity += CellParams::N_SPATIAL_CELL_PARAMS * sizeof(Real);
744 capacity += bvolderivatives::N_BVOL_DERIVATIVES * sizeof(Real);
745
746 for (size_t p=0; p<populations.size(); ++p) {
747 capacity += populations[p].vmesh->capacityInBytes();
748 capacity += populations[p].blockContainer->capacityInBytes();
749 }
750
751 return capacity;
752 }
753
760 inline bool SpatialCell::add_velocity_block(const vmesh::GlobalID& block,const uint popID) {
762 // Block insert will fail, if the block already exists, or if
763 // there are too many blocks in the spatial cell
764 bool success = true;
765 if (populations[popID].vmesh->push_back(block) == false) {
766 return false;
767 }
768
769 const vmesh::LocalID VBC_LID = populations[popID].blockContainer->push_back_and_zero();
770
771 // Set block parameters:
772 Real* parameters = get_block_parameters(VBC_LID,popID);
773 populations[popID].vmesh->getBlockInfo(block, parameters);
774
775 // The following call 'should' be the fastest, but is actually
776 // much slower that the parameter setting above
777 //vmesh::VelocityMesh::getBlockInfo(block,get_block_parameters( blockContainer->push_back() ));
778 return success;
779 }
780
785 template <typename fileReal> void SpatialCell::add_velocity_blocks(const uint popID,const std::vector<vmesh::GlobalID>& blocks,fileReal* avgBuffer) {
787 // Return if no blocks to add
788 const uint nBlocks = blocks.size();
789 if (nBlocks==0) {
790 return;
791 }
792 populations[popID].vmesh->setNewCapacity(nBlocks);
793 populations[popID].blockContainer->setNewCapacity(nBlocks);
794
795 // Add blocks to mesh
796 const uint8_t adds = populations[popID].vmesh->push_back(blocks);
797 if (adds == 0) {
798 std::cerr << "Failed to add blocks" << std::endl;
799 return;
800 }
801
802 // Add blocks to block container
803 vmesh::LocalID startLID = populations[popID].blockContainer->push_back(nBlocks);
804 Real* parameters = populations[popID].blockContainer->getParameters(startLID);
805
806 #ifdef DEBUG_SPATIAL_CELL
807 if (populations[popID].vmesh->size() != populations[popID].blockContainer->size()) {
808 std::cerr << "size mismatch in " << __FILE__ << ' ' << __LINE__ << std::endl; exit(1);
809 }
810 #endif
811
812 // Set block parameters
813 for (size_t b=0; b<nBlocks; ++b) {
814 vmesh::GlobalID VBC_GID = blocks.at(b);
815 populations[popID].vmesh->getBlockInfo(VBC_GID, parameters);
817 }
818
819 //copy avgs data, here a conversion may happen between float and double
820 if (avgBuffer){
821 Realf *cellBlockData = populations[popID].blockContainer->getData(startLID);
822 for(uint64_t i = 0; i< WID3 * nBlocks ; i++){
823 cellBlockData[i] = avgBuffer[i];
824 }
825 }
826 }
827
832 inline void SpatialCell::remove_velocity_block(const vmesh::GlobalID& block,const uint popID) {
834 if (block == invalid_global_id()) {
835 //std::cerr << "not removing, block " << block << " is invalid" << std::endl;
836 return;
837 }
838
839 const vmesh::LocalID removedLID = populations[popID].vmesh->getLocalID(block);
840 if (removedLID == invalid_local_id()) {
841 //std::cerr << "not removing since block " << block << " does not exist" << std::endl;
842 return;
843 }
844
845 // Get local ID of the last block:
846 const vmesh::LocalID lastLID = populations[popID].vmesh->size()-1;
847 // If block to remove is already last:
848 if (lastLID == removedLID) {
849 // Just remove the block
850 populations[popID].vmesh->pop();
851 populations[popID].blockContainer->pop();
852 } else {
853 // Move the last block to the removed position
854 populations[popID].vmesh->move(lastLID,removedLID);
855 populations[popID].blockContainer->move(lastLID,removedLID);
856 }
857 }
858
862 inline void SpatialCell::set_mpi_transfer_type(const uint64_t type,bool atSysBoundaries) {
865 }
866
873
877 inline void SpatialCell::set_mpi_transfer_enabled(bool transferEnabled) {
878 this->mpiTransferEnabled=transferEnabled;
879 }
880
881} // namespaces
882
883#endif
for i
Definition Dispersion.m:24
bool checkMesh(const uint popID)
vmesh::LocalID get_number_of_velocity_blocks(const uint popID) const
void debug_population_check(const uint popID) const
void fetch_data(const vmesh::GlobalID &blockGID, const vmesh::VelocityMesh *vmesh, const Realf *src, Realf *array)
void updateSparseMinValue(const uint popID)
void set_population(const Population &pop, cuint popID)
const Real * get_velocity_grid_cell_size(const uint popID)
Real get_velocity_block_vx_min(const uint popID, const vmesh::GlobalID block) const
Real * get_block_parameters(const uint popID)
vmesh::VelocityMesh * get_velocity_mesh(const size_t &popID)
void scale_population(creal factor, cuint popID)
vmesh::GlobalID get_velocity_block_global_id(const vmesh::LocalID &blockLID, const uint popID) const
vmesh::VelocityBlockContainer * get_velocity_blocks(const size_t &popID)
void merge_values(const uint popID)
size_t count(const vmesh::GlobalID &block, const uint popID) const
static vmesh::GlobalID invalid_global_id()
std::tuple< void *, int, MPI_Datatype > get_mpi_datatype(const CellID cellID, const int sender_rank, const int receiver_rank, const bool receiving, const int neighborhood)
size_t size(const uint popID) const
std::array< Realf *, MAX_NEIGHBORS_PER_DIM > neighbor_block_data
static void set_mpi_transfer_direction(const int dimension)
void increment_population(const Population &pop, creal factor, cuint popID)
void set_mpi_transfer_enabled(bool transferEnabled)
void set_max_r_dt(const uint popID, const Real &value)
void adjustSingleCellVelocityBlocks(const uint popID, bool doDeleteEmpty=false)
vmesh::GlobalID get_velocity_block_parent(const uint popID, const vmesh::GlobalID &blockGID)
vmesh::LocalID get_velocity_block_local_id(const vmesh::GlobalID &blockGID, const uint popID) const
static bool setCommunicatedSpecies(const uint popID)
Real getVelocityBlockMinValue(const uint popID) const
Real get_velocity_block_vz_min(const uint popID, const vmesh::GlobalID block) const
Real get_velocity_block_vz_max(const uint popID, const vmesh::GlobalID block) const
void clear(const uint popID, bool shrink=false)
bool compute_block_has_content(const vmesh::GlobalID &block, const uint popID) const
static unsigned int invalid_block_index()
void prepare_to_receive_blocks(const uint popID)
Real get_velocity_block_vy_min(const uint popID, const vmesh::GlobalID block) const
std::vector< vmesh::GlobalID > * velocity_block_with_content_list
std::array< Real, vderivatives::N_V_DERIVATIVES > derivativesV
void add_values(const vmesh::GlobalID &targetGID, std::unordered_map< vmesh::GlobalID, Realf[(WID+2) *(WID+2) *(WID+2)]> &sourceData, const uint popID)
Real get_velocity_block_vy_max(const uint popID, const vmesh::GlobalID block) const
velocity_block_indices_t get_velocity_block_indices(const uint popID, const vmesh::GlobalID globalID)
void add_velocity_blocks(const uint popID, const std::vector< vmesh::GlobalID > &blocks, fileReal *avgBuffer)
std::vector< vmesh::GlobalID > * velocity_block_with_no_content_list
void remove_velocity_block(const vmesh::GlobalID &block, const uint popID)
std::array< Realf, WID3 > null_block_data
void get_velocity_block_size(const uint popID, const vmesh::GlobalID block, Real size[3])
void set_max_v_dt(const uint popID, const Real &value)
void setNewSizeClear(const uint popID, const vmesh::LocalID &newSize)
void fetch_acc_data(const vmesh::GlobalID &blockGID, const int &dim, vmesh::VelocityMesh *vmesh, const Realf *src, Realf *array, Real cellSizeFractions[2])
const Real & get_max_r_dt(const uint popID) const
vmesh::LocalID get_number_of_all_velocity_blocks() const
static void set_mpi_transfer_type(const uint64_t type, bool atSysBoundaries=false)
std::array< vmesh::LocalID, MAX_NEIGHBORS_PER_DIM > neighbor_number_of_blocks
std::vector< Population > & get_populations()
std::array< Real, bvolderivatives::N_BVOL_DERIVATIVES > derivativesBVOL
void adjust_velocity_blocks(const std::vector< SpatialCell * > &spatial_neighbors, const uint popID, bool doDeleteEmptyBlocks=true)
vmesh::GlobalID get_velocity_block_child(const uint popID, const vmesh::GlobalID &blockGID, const int &i_cell, const int &j_cell, const int &k_cell)
const vmesh::LocalID * get_velocity_grid_length(const uint popID)
Realf * get_data(const uint popID)
const Real & get_max_v_dt(const uint popID) const
Population & get_population(const uint popID)
vmesh::GlobalID find_velocity_block(vmesh::GlobalID cellIndices[3], const uint popID)
vmesh::LocalID velocity_block_with_content_list_size
void get_velocity_block_coordinates(const uint popID, const vmesh::GlobalID &globalID, Real *coords)
Real get_velocity_block_vx_max(const uint popID, const vmesh::GlobalID block) const
void update_velocity_block_content_lists(const uint popID)
std::array< Real, CellParams::N_SPATIAL_CELL_PARAMS > parameters
const SpatialCell & operator=(const SpatialCell &other)
static uint64_t get_mpi_transfer_type(void)
void get_velocity_block_children_local_ids(const vmesh::GlobalID &blockGID, std::vector< vmesh::LocalID > &childrenLIDs, const uint popID)
std::vector< spatial_cell::Population > populations
vmesh::GlobalID get_velocity_block(const uint popID, vmesh::GlobalID blockIndices[3]) const
static vmesh::LocalID invalid_local_id()
std::map< int, std::set< int > > face_neighbor_ranks
bool add_velocity_block(const vmesh::GlobalID &block, const uint popID)
const Real * get_velocity_grid_block_size(const uint popID)
static vmesh::LocalID invalidBlockIndex()
static vmesh::LocalID invalidLocalID()
static vmesh::GlobalID invalidGlobalID()
#define WID
Definition common.h:514
const int WID3
Definition common.h:517
const uint32_t cuint
Definition definitions.h:50
float Real
Definition definitions.h:41
uint64_t CellID
Definition definitions.h:54
float Realf
Definition definitions.h:33
const float creal
Definition definitions.h:42
dev_velocityBlockContainer[cellIdx] getData()[velocityIdx *WID3+k *WID2+j *WID+i]
const int blockSize
@ N_VELOCITY_BLOCK_PARAMS
Definition common.h:115
@ N_SPATIAL_CELL_PARAMS
Definition common.h:229
std::array< vmesh::LocalID, 3 > velocity_block_indices_t
std::array< unsigned int, 3 > velocity_cell_indices_t
uint32_t LocalID
Definition definitions.h:60
uint32_t GlobalID
Definition definitions.h:59
vmesh::VelocityBlockContainer * blockContainer
std::vector< char > compressed_state_buffer
void ResizeClear(const uint newSize)
const Population & operator=(const Population &other)
void Increment(const Population &other, creal factor)
vmesh::VelocityMesh * vmesh
Population(const Population &other)