38 const Realf*
const dz,
39 const Vec*
const values,
44 const int lengthOfPencil,
46 Realf** blockDataPointer,
47 const Realf*
const targetRatios,
48 const unsigned int*
const vcell_transpose
52 vmesh->getIndices(blockGID, block_indices[0], block_indices[1], block_indices[2]);
61 for (
int i = VLASOV_STENCIL_WIDTH;
i < (int)lengthOfPencil-VLASOV_STENCIL_WIDTH;
i++){
63 Realf* block_data_m1 = blockDataPointer[
i - 1];
64 Realf* block_data = blockDataPointer[
i];
65 Realf* block_data_p1 = blockDataPointer[
i + 1];
68 Realf areaRatio_m1 = targetRatios[
i - 1];
69 Realf areaRatio = targetRatios[
i];
70 Realf areaRatio_p1 = targetRatios[
i + 1];
74 for (uint
k = 0;
k <
WID; ++
k) {
76 const Vec z_translation = cell_vz *
dt / dz[
i];
80 Vecb positiveTranslationDirection = (z_translation > Vec(0.0));
88 z_1 =
select(positiveTranslationDirection, 1.0 - z_translation, 0.0);
89 z_2 =
select(positiveTranslationDirection, 1.0, - z_translation);
98 for (uint planeVector = 0; planeVector < VEC_PER_PLANE; planeVector++) {
112 const Vec ngbr_target_density =
113 z_2 * ( a[0] + z_2 * ( a[1] + z_2 * a[2] ) ) -
114 z_1 * ( a[0] + z_1 * ( a[1] + z_1 * a[2] ) );
118 if (areaRatio && block_data) {
119 const Vec selfContribution = (values[
i_trans_ps_blockv_pencil(planeVector,
k,
i, lengthOfPencil)] - ngbr_target_density) * areaRatio;
120 selfContribution.store(vector);
123 for (uint iv = 0; iv < VECL; iv++) {
124 block_data[vcell_transpose[iv + planeVector * VECL +
k *
WID2]] += vector[iv];
127 if (areaRatio_p1 && block_data_p1) {
128 const Vec p1Contribution =
select(positiveTranslationDirection, ngbr_target_density
129 * dz[
i] / dz[
i + 1], Vec(0.0)) * areaRatio_p1;
130 p1Contribution.store(vector);
133 for (uint iv = 0; iv < VECL; iv++) {
134 block_data_p1[vcell_transpose[iv + planeVector * VECL +
k *
WID2]] += vector[iv];
137 if (areaRatio_m1 && block_data_m1) {
138 const Vec m1Contribution =
select(!positiveTranslationDirection, ngbr_target_density
139 * dz[
i] / dz[
i - 1], Vec(0.0)) * areaRatio_m1;
140 m1Contribution.store(vector);
143 for (uint iv = 0; iv < VECL; iv++) {
144 block_data_m1[vcell_transpose[iv + planeVector * VECL +
k *
WID2]] += vector[iv];
214bool trans_map_1d_amr(
const dccrg::Dccrg<spatial_cell::SpatialCell,dccrg::Cartesian_Geometry>& mpiGrid,
215 const vector<CellID>& localPropagatedCells,
216 const vector<CellID>& remoteTargetCells,
218 const uint dimension,
223 phiprof::Timer setupTimer {
"trans-amr-setup"};
227 if(localPropagatedCells.size() == 0) {
231 uint cell_indices_to_id[3];
232 unsigned int vcell_transpose[
WID3];
238 cell_indices_to_id[0]=
WID2;
239 cell_indices_to_id[1]=
WID;
240 cell_indices_to_id[2]=1;
245 cell_indices_to_id[0]=1;
246 cell_indices_to_id[1]=
WID2;
247 cell_indices_to_id[2]=
WID;
252 cell_indices_to_id[0]=1;
253 cell_indices_to_id[1]=
WID;
254 cell_indices_to_id[2]=
WID2;
257 cerr << __FILE__ <<
":"<< __LINE__ <<
" Wrong dimension, abort"<<endl;
263 vector<CellID> allCells(localPropagatedCells);
264 allCells.insert(allCells.end(), remoteTargetCells.begin(), remoteTargetCells.end());
265 const uint nAllCells = allCells.size();
268 std::vector<SpatialCell*> allCellsPointer(nAllCells);
271 #pragma omp parallel for schedule(static)
272 for(uint celli = 0; celli < allCells.size(); celli++){
273 allCellsPointer[celli] = mpiGrid[allCells[celli]];
276 #pragma omp parallel for collapse(2) schedule(static)
277 for (uint
k=0;
k<
WID; ++
k) {
278 for (uint
j=0;
j<
WID; ++
j) {
279 for (uint
i=0;
i<
WID; ++
i) {
281 i * cell_indices_to_id[0] +
282 j * cell_indices_to_id[1] +
283 k * cell_indices_to_id[2];
284 vcell_transpose[
i +
j *
WID +
k *
WID2] = cell;
291 for (uint
i=0;
i<localPropagatedCells.size();
i++) {
294 const std::vector<CellID> centerIds =
DimensionPencils[dimension].getIds(ip);
295 cuint myPencilCount = std::count(centerIds.begin(), centerIds.end(), localPropagatedCells[
i]);
305 phiprof::Timer buildBlockListTimer {
"trans-amr-buildBlockList"};
312 std::unordered_set<vmesh::GlobalID> thread_unionOfBlocksSet;
313 #pragma omp for schedule(dynamic)
314 for (
unsigned int i=0;
i<allCellsPointer.size();
i++) {
315 auto cell = &allCellsPointer[
i];
318 thread_unionOfBlocksSet.insert(cvmesh->
getGlobalID(block_i));
323 unionOfBlocksSet.insert(thread_unionOfBlocksSet.begin(), thread_unionOfBlocksSet.end());
327 buildBlockListTimer.stop();
332 int mappingTimerId = phiprof::initializeTimer(
"trans-amr-mapping");
333 int loadTimerId = phiprof::initializeTimer(
"trans-amr-load source data");
334 int memsetTimerId = phiprof::initializeTimer(
"trans-amr-MemSet");
335 int propagateTimerId = phiprof::initializeTimer(
"trans-amr-propagatePencil");
342 phiprof::Timer mappingTimer {mappingTimerId};
352 #pragma omp for schedule(dynamic,1) collapse(2)
353 for(uint blocki = 0; blocki < blocksSize; blocki++) {
354 for (uint nBin = 0; nBin < binsSize; ++nBin) {
358 phiprof::Timer loadTimer {loadTimerId};
361 int nonEmptyBlocks = 0;
365 for (
int b = 0; b < L; b++) {
372 cellBlockData[start + b] = srcCell->
get_data(blockLID,popID);
375 cellBlockData[start + b] = NULL;
378 if(nonEmptyBlocks == 0) {
383 Vec* blockDataSource = blockDataBuffer.data() + start*
WID3/VECL;
389 phiprof::Timer memsetTimer {memsetTimerId};
392 SpatialCell* target_cell = mpiGrid[target_cell_id];
400 memset(blockData, 0,
WID3*
sizeof(
Realf));
406 phiprof::Timer propagateTimer {propagateTimerId};
419 const Realf scalingthreshold = mpiGrid[
DimensionPencils[dimension].ids[start + VLASOV_STENCIL_WIDTH]]->getVelocityBlockMinValue(popID);
423 const Vec* blockDataSource = blockDataBuffer.data() +start*
WID3/VECL;
494 dccrg::Dccrg<SpatialCell,dccrg::Cartesian_Geometry>& mpiGrid,
495 const uint dimension,
501 vector<CellID> receive_cells;
504 vector<CellID> receive_origin_cells;
505 vector<uint> receive_origin_index;
507 int neighborhood = 0;
523 cerr << __FILE__ <<
":"<< __LINE__ <<
" Wrong dimension, abort"<<endl;
540 cerr << __FILE__ <<
":"<< __LINE__ <<
" Wrong dimension, abort"<<endl;
550 for (
auto rc : remote_cells) {
563 for (
auto lc : local_cells) {
574 vector<Realf*> receiveBuffers;
575 vector<Realf*> sendBuffers;
577 for (
auto c : local_cells) {
585 vector<CellID> p_nbrs;
586 vector<CellID> n_nbrs;
588 phiprof::Timer neighTimer {
"get face neighbors"};
589 for (
const auto& [neighbor, dir] : mpiGrid.get_face_neighbors_of(
c)) {
590 if(dir == ((
int)dimension + 1) * direction) {
591 p_nbrs.push_back(neighbor);
594 if(dir == -1 * ((
int)dimension + 1) * direction) {
595 n_nbrs.push_back(neighbor);
605 phiprof::Timer sendsTimer {
"setup sends"};
606 if (!all_of(p_nbrs.begin(), p_nbrs.end(), [&mpiGrid](
CellID i){return mpiGrid.is_local(i);})) {
609 for (
const auto& nbr : p_nbrs) {
625 if(mpiGrid.get_refinement_level(
c) >= mpiGrid.get_refinement_level(nbr)) {
626 sendIndex = mySiblingIndex;
638 if(send_cells.find(nbr) == send_cells.end()) {
642 send_cells.insert(nbr);
669 phiprof::Timer recvsTimer {
"setup recvs"};
671 if (!all_of(n_nbrs.begin(), n_nbrs.end(), [&mpiGrid](
CellID i){return mpiGrid.is_local(i);})) {
674 for (
const auto& nbr : n_nbrs) {
696 if(mpiGrid.get_refinement_level(nbr) >= mpiGrid.get_refinement_level(
c)) {
709 recvIndex = mySiblingIndex;
713 auto mySiblings = mpiGrid.get_all_children(mpiGrid.get_parent(
c));
714 auto myIndices = mpiGrid.mapping.get_indices(
c);
720 auto sibling = mySiblings.at(i_sib);
721 auto sibIndices = mpiGrid.mapping.get_indices(sibling);
722 auto* scell = mpiGrid[sibling];
729 && mpiGrid.get_process(sibling) != mpiGrid.get_process(nbr)
730 && myIndices.at(dimension) == sibIndices.at(dimension)
743 receive_cells.push_back(
c);
744 receive_origin_cells.push_back(nbr);
745 receive_origin_index.push_back(recvIndex);
754 MPI_Barrier(MPI_COMM_WORLD);
757 phiprof::Timer commTimer {
"update neighbour vel block data"};
760 mpiGrid.update_copies_of_remote_neighbors(neighborhood);
762 MPI_Barrier(MPI_COMM_WORLD);
767 phiprof::Timer reduceTimer {
"merge retreived data"};
769 for (
size_t c = 0;
c < receive_cells.size(); ++
c) {
771 SpatialCell* origin_cell = mpiGrid[receive_origin_cells[
c]];
773 if(!receive_cell || !origin_cell) {
782 blockData[vCell] += neighborData[vCell];
788 for (
auto c : send_cells) {
792 for(
unsigned int vCell = 0; vCell <
WID3 *
spatial_cell->get_number_of_velocity_blocks(popID); ++vCell) {
794 blockData[vCell] = 0;
799 for (
auto p : receiveBuffers) {
802 for (
auto p : sendBuffers) {
void propagatePencil(const Realf *const dz, const Vec *const values, const uint dimension, const uint blockGID, const Realf dt, const vmesh::VelocityMesh *vmesh, const int lengthOfPencil, const Realf threshold, Realf **blockDataPointer, const Realf *const targetRatios, const unsigned int *const vcell_transpose)