Skip to content

Commit 7c5c81b

Browse files
committed
Copypaste vlasov neighbors from vlasiator
1 parent 846dd40 commit 7c5c81b

File tree

1 file changed

+58
-51
lines changed

1 file changed

+58
-51
lines changed

dccrg.hpp

Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2832,69 +2832,77 @@ template <
28322832
return ret;
28332833
}
28342834

2835-
std::map<int, std::vector<uint64_t>> get_vlasov_neighbors(
2835+
std::set<uint64_t> get_vlasov_neighbors(
28362836
const uint64_t cell,
28372837
const int neighborhood_id,
28382838
const int dimension,
28392839
const int stencil_width
28402840
) const {
2841-
std::map<int, std::vector<uint64_t>> ret;
2842-
int my_ref {mapping.get_refinement_level(cell)};
2843-
std::vector<std::pair<uint64_t, std::array<int, 4>>> neighs;
2841+
std::set<uint64_t> ret;
28442842
const auto* p = get_neighbors_of(cell, neighborhood_id);
28452843
if (!p) {
28462844
std::cerr << "Cell " << cell << ", neighborhood " << neighborhood_id << ", dimension " << dimension << " not found" << std::endl;
28472845
return ret;
28482846
}
28492847

2850-
neighs = *p;
2851-
// We still need to sort since more refined cells are in xyz order
2852-
std::stable_sort(neighs.begin(), neighs.end(),
2853-
[this, dimension] (const std::pair<uint64_t, std::array<int, 4>>& a, const std::pair<uint64_t, std::array<int, 4>>& b) {
2854-
return distance_to_double(a.second)[dimension] < distance_to_double(b.second)[dimension];
2848+
// Create list of unique distances
2849+
std::set<int> distances_plus;
2850+
std::set<int> distances_minus;
2851+
std::set<uint64_t> found_neighbors_plus;
2852+
std::set<uint64_t> found_neighbors_minus;
2853+
/** Using sets of cells as well, we should only get one distance per
2854+
(potentially less refined) cell. This should result in safe behaviour
2855+
as long as the neighborhood of a cell does not contain cells with a
2856+
refinement level more than 1 level apart from the cell itself.
2857+
*/
2858+
for (const auto& [neighbor, coords] : *p) {
2859+
if(coords[dimension] > 0) {
2860+
if (!found_neighbors_plus.count(neighbor)) {
2861+
distances_plus.insert(coords[dimension]);
2862+
found_neighbors_plus.insert(neighbor);
2863+
}
28552864
}
2856-
);
2857-
2858-
auto it = neighs.cbegin();
2859-
while (it < neighs.cend() && it->second[dimension] < 0) {
2860-
++it;
2861-
}
2862-
2863-
int found {0};
2864-
std::uint64_t previous_cell {error_cell};
2865-
double previous_offset {0.0};
2866-
for (auto neg = std::make_reverse_iterator(it); neg != neighs.crend(); ++neg) {
2867-
double offset = distance_to_double(neg->second)[dimension];
2868-
if (neg->first == previous_cell || neg->first == error_cell) {
2869-
continue;
2870-
} else if (offset < previous_offset) {
2871-
if (++found > stencil_width)
2872-
break;
2865+
if(coords[dimension] < 0) {
2866+
if (!found_neighbors_minus.count(neighbor)) {
2867+
distances_minus.insert(-coords[dimension]);
2868+
found_neighbors_minus.insert(neighbor);
2869+
}
28732870
}
2874-
2875-
ret[-found].push_back(neg->first);
2876-
previous_cell = neg->first;
28772871
}
28782872

2879-
while (it < neighs.cend() && it->second[dimension] <= 0) {
2880-
++it;
2881-
}
2882-
2883-
found = 0;
2884-
previous_cell = error_cell;
2885-
previous_offset = 0.0;
2886-
for (auto pos = it; pos != neighs.cend(); ++pos) {
2887-
double offset = distance_to_double(pos->second)[dimension];
2888-
if (pos->first == previous_cell || pos->first == error_cell) {
2889-
continue;
2890-
} else if (offset > previous_offset) {
2891-
if (++found > stencil_width)
2892-
break;
2893-
}
2894-
2895-
ret[found].push_back(pos->first);
2896-
previous_cell = pos->first;
2897-
}
2873+
int iSrc = stencil_width - 1;
2874+
// Iterate through positive distances for VLASOV_STENCIL_WIDTH elements starting from the smallest distance.
2875+
for (const auto& distance : distances_plus) {
2876+
if (iSrc < 0)
2877+
break; // found enough elements
2878+
for (const auto& [neighbor, coords] : *p) {
2879+
if (neighbor == error_cell)
2880+
continue;
2881+
if (coords[dimension] == distance) {
2882+
if (ret.count(neighbor))
2883+
continue;
2884+
ret.insert(neighbor);
2885+
}
2886+
} // end loop over neighbors
2887+
iSrc--;
2888+
} // end loop over positive distances
2889+
2890+
iSrc = stencil_width - 1;
2891+
// Iterate through negtive distances for VLASOV_STENCIL_WIDTH elements starting from the smallest distance.
2892+
for (const auto& distance : distances_minus) {
2893+
if (iSrc < 0)
2894+
break; // found enough elements
2895+
for (const auto& [neighbor, coords] : *p) {
2896+
if (neighbor == error_cell)
2897+
continue;
2898+
if (coords[dimension] == distance) {
2899+
if (ret.count(neighbor))
2900+
continue;
2901+
ret.insert(neighbor);
2902+
}
2903+
} // end loop over neighbors
2904+
iSrc--;
2905+
} // end loop over negative distances
28982906

28992907
return ret;
29002908
}
@@ -2922,9 +2930,8 @@ template <
29222930

29232931
std::set<uint64_t> ret;
29242932
for (int dim = 0; dim < 3; ++dim) {
2925-
for (auto& [dist, cells] : get_vlasov_neighbors(cell, partitioning_neighborhood_id + dim, dim, stencil_width)) {
2926-
ret.insert(cells.begin(), cells.end());
2927-
}
2933+
auto neighs_dim = get_vlasov_neighbors(cell, partitioning_neighborhood_id + dim, dim, stencil_width);
2934+
ret.insert(neighs_dim.begin(), neighs_dim.end());
29282935
}
29292936
return ret;
29302937
}

0 commit comments

Comments
 (0)