Peano
Loading...
Searching...
No Matches
initial_conditions.h
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <cmath>
5#include <functional>
6
7#include <lang/assert.h>
8#include <lang/type.h>
9
10template<typename Tree, auto InitialConditionsCallback>
12
13 using fp = Tree::Geo::P;
14 static constexpr auto N = Tree::Geo::D::N;
15
16 Tree::Geo::Region globalIcArea;
17
18 Tree::Geo::Point insertionLow;
19 Tree::Geo::Point insertionHigh;
20
22
23 NumVec<fp, N> getItemIdxAfterPoint(const Tree::Geo::Point &point) const {
24
25 NumVec<fp, N> itemLowIdx;
26
27 for (u32 axis = 0; axis < N; axis++) {
28 auto a_minus_A = point[axis] - this->insertionLow[axis];
29 auto B_minus_A = this->insertionHigh[axis] - this->insertionLow[axis];
30 auto n = (i64) this->npart - 1;
31
32 auto ia = n * (a_minus_A / B_minus_A);
33 auto i = std::ceil(ia);
34 auto iClamped = std::clamp(i, (fp) 0, (fp) this->npart);
35 itemLowIdx[axis] = iClamped;
36 }
37
38 return itemLowIdx;
39 }
40
41public:
42 void operator()(Tree *tree) {
43 const auto leafWorkArea = this->globalIcArea.intersection(tree->range);
44 if (leafWorkArea.size() == 0) return;
45
46 assert(leafWorkArea.size() <= tree->range.size())
47
48 auto itemIdxLow = this->getItemIdxAfterPoint(leafWorkArea.low);
49 auto itemIdxHigh = this->getItemIdxAfterPoint(leafWorkArea.high);
50
51 auto axisWiseItemCounts = itemIdxHigh - itemIdxLow;
52 decltype(axisWiseItemCounts) scales;
53
54 u32 itemCount = axisWiseItemCounts.prod();
55
56 auto *lastInsertionLeaf = tree;
57
58 for (u32 itemLinearIdx = 0; itemLinearIdx < itemCount; itemLinearIdx++) {
59 auto itemIdx = itemIdxLow;
60
61 u32 scale = 1;
62 for (u32 axis = 0; axis < N; axis++) {
63 itemIdx[axis] += (i64) (itemLinearIdx / scale) % (i64) axisWiseItemCounts[axis];
64 scale *= axisWiseItemCounts[axis];
65 }
66
67 auto iDivN = itemIdx.template castAs<fp>() / (this->npart - 1);
68 auto pos = this->insertionLow + (this->insertionHigh - this->insertionLow) * iDivN;
69
70 auto item = InitialConditionsCallback(pos);
71 lastInsertionLeaf = lastInsertionLeaf->insert(item);
72
73 assert(lastInsertionLeaf != nullptr)
74 }
75 }
76
77 InitialConditionsTask(Tree::Geo::Region area, u32 npart) : globalIcArea(area), npart(npart) {
78 auto areaInclusive = area;
79
80 for (i32 axis = 0; axis < Tree::Geo::D::N; axis++) {
81 areaInclusive.high[axis] = std::nexttoward(areaInclusive.high[axis], areaInclusive.low[axis]);
82 }
83
84 this->insertionLow = areaInclusive.low;
85 this->insertionHigh = areaInclusive.high;
86 }
87};
#define assert(...)
Definition LinuxAMD.h:28
Tree::Geo::Region globalIcArea
InitialConditionsTask(Tree::Geo::Region area, u32 npart)
void operator()(Tree *tree)
Tree::Geo::Point insertionLow
static constexpr auto N
NumVec< fp, N > getItemIdxAfterPoint(const Tree::Geo::Point &point) const
Tree::Geo::Point insertionHigh
std::uint32_t u32
Definition type.h:11
std::int64_t i64
Definition type.h:12
std::int32_t i32
Definition type.h:10