Skip to content

Commit e75045d

Browse files
committed
Merge branch 'dev/main' of github.com:haykh/entity into dev/output
2 parents ecf0753 + 57d1317 commit e75045d

File tree

4 files changed

+105
-16
lines changed

4 files changed

+105
-16
lines changed

src/framework/archetypes.hpp

+83
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "fields.h"
77
#include "meshblock.h"
8+
#include "qmath.h"
89
#include "sim_params.h"
910

1011
#ifdef NTTINY_ENABLED
@@ -94,6 +95,88 @@ namespace ntt {
9495
}
9596
};
9697

98+
template <Dimension D, SimulationEngine S>
99+
struct Maxwellian {
100+
Maxwellian(const Meshblock<D, S>& mblock) : pool { *(mblock.random_pool_ptr) } {}
101+
// Juttner-Synge distribution
102+
Inline void JS(vec_t<Dim3>& v, const real_t& temp) const {
103+
typename RandomNumberPool_t::generator_type rand_gen = pool.get_state();
104+
real_t u { ZERO }, eta { ZERO }, theta { ZERO };
105+
real_t X1 { ZERO }, X2 { ZERO };
106+
if (temp < 0.1) {
107+
// Juttner-Synge distribution using the Box-Muller method - non-relativistic
108+
while (AlmostEqual(u, ZERO)) {
109+
u = rand_gen.frand();
110+
}
111+
eta = math::sqrt(-TWO * math::log(u));
112+
while (AlmostEqual(theta, ZERO)) {
113+
theta = constant::TWO_PI * rand_gen.frand();
114+
}
115+
u = eta * math::cos(theta) * math::sqrt(temp);
116+
} else {
117+
// Juttner-Synge distribution using the Sobol method - relativistic
118+
u = ONE;
119+
while (SQR(eta) <= SQR(u)) {
120+
while (AlmostEqual(X1, ZERO)) {
121+
X1 = rand_gen.frand() * rand_gen.frand() * rand_gen.frand();
122+
}
123+
u = -temp * math::log(X1);
124+
X1 = rand_gen.frand();
125+
while (AlmostEqual(X1, 0)) {
126+
X1 = rand_gen.frand();
127+
}
128+
eta = u - temp * math::log(X1);
129+
}
130+
}
131+
X1 = rand_gen.frand();
132+
X2 = rand_gen.frand();
133+
v[0] = u * (TWO * X1 - ONE);
134+
v[2] = TWO * u * math::sqrt(X1 * (ONE - X1));
135+
v[1] = v[2] * math::cos(constant::TWO_PI * X2);
136+
v[2] = v[2] * math::sin(constant::TWO_PI * X2);
137+
pool.free_state(rand_gen);
138+
}
139+
// Boost a symmetric distribution to a relativistic speed using flipping method
140+
// https://arxiv.org/pdf/1504.03910.pdf
141+
Inline void boost(vec_t<Dim3>& v,
142+
const real_t& boost_vel,
143+
const short& boost_direction) const {
144+
typename RandomNumberPool_t::generator_type rand_gen = pool.get_state();
145+
real_t boost_beta { boost_vel / math::sqrt(ONE + SQR(boost_vel)) };
146+
real_t boost_gamma { boost_vel / boost_beta };
147+
real_t ut { math::sqrt(ONE + SQR(v[0]) + SQR(v[1]) + SQR(v[2])) };
148+
if (-boost_beta * v[boost_direction] > ut * rand_gen.frand()) {
149+
v[boost_direction] = -v[boost_direction];
150+
}
151+
pool.free_state(rand_gen);
152+
v[boost_direction] = boost_gamma * (v[boost_direction] + boost_beta * ut);
153+
}
154+
155+
Inline void operator()(vec_t<Dim3>& v,
156+
const real_t& temp,
157+
const real_t& boost_vel = ZERO,
158+
const short& boost_direction = 0) const {
159+
if (AlmostEqual(temp, ZERO)) {
160+
v[0] = ZERO;
161+
v[1] = ZERO;
162+
v[2] = ZERO;
163+
} else {
164+
JS(v, temp);
165+
}
166+
if (!AlmostEqual(boost_vel, ZERO)) {
167+
if (boost_direction < 0) {
168+
boost(v, -boost_vel, -boost_direction - 1);
169+
} else if (boost_direction > 0) {
170+
boost(v, boost_vel, boost_direction - 1);
171+
}
172+
// no boost when boost_direction == 0
173+
}
174+
}
175+
176+
private:
177+
RandomNumberPool_t pool;
178+
};
179+
97180
/* -------------------------------------------------------------------------- */
98181
/* Spatial distribution */
99182
/* -------------------------------------------------------------------------- */

src/framework/meshblock/meshblock.h

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#include <vector>
1212

1313
namespace ntt {
14+
namespace dir {
15+
enum Direction { x = 1, y = 2, z = 3, r = 1, theta = 2, phi = 3, x1 = 1, x2 = 2, x3 = 3 };
16+
} // namespace dir
17+
1418
enum class CellLayer {
1519
allLayer,
1620
activeLayer,

src/pic/pgen/inputs/weibel.toml

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ deposit_ON = true
1515
current_filters = 25
1616

1717
[units]
18-
ppc0 = 32.0
18+
ppc0 = 16.0
1919
larmor0 = 1.0
2020
skindepth0 = 1.0
2121

@@ -51,10 +51,10 @@ maxnpart = 1e8
5151
pusher = "Boris"
5252

5353
[problem]
54-
udrift_1 = -10.0
55-
udrift_2 = -10.0
56-
udrift_3 = 10.0
57-
udrift_4 = 10.0
54+
drift_p = 10.0
55+
drift_b = 10.0
56+
temperature_p = 0.1
57+
temperature_b = 0.1
5858

5959
[visualization]
6060
fields = ["Bx", "By", "mass_density"]

src/pic/pgen/weibel.hpp

+13-11
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,31 @@
1212
namespace ntt {
1313

1414
template <Dimension D, SimulationEngine S>
15-
struct Drift : public EnergyDistribution<D, S> {
16-
Drift(const SimulationParams& params, const Meshblock<D, S>& mblock)
15+
struct WeibelInit : public EnergyDistribution<D, S> {
16+
WeibelInit(const SimulationParams& params, const Meshblock<D, S>& mblock)
1717
: EnergyDistribution<D, S>(params, mblock),
18-
udrift1 { params.get<real_t>("problem", "udrift1", -10.0) },
19-
udrift2 { params.get<real_t>("problem", "udrift2", -10.0) },
20-
udrift3 { params.get<real_t>("problem", "udrift3", 10.0) },
21-
udrift4 { params.get<real_t>("problem", "udrift4", 10.0) } {}
18+
maxwellian { mblock },
19+
drift_p { params.get<real_t>("problem", "drift_p", 10.0) },
20+
drift_b { params.get<real_t>("problem", "drift_b", 10.0) },
21+
temp_p { params.get<real_t>("problem", "temperature_p", 0.0) },
22+
temp_b { params.get<real_t>("problem", "temperature_b", 0.0) } {}
2223
Inline void operator()(const coord_t<D>&,
2324
vec_t<Dim3>& v,
2425
const int& species) const override {
2526
if (species == 1) {
26-
v[2] = udrift1;
27+
maxwellian(v, temp_p, drift_p, -dir::z);
2728
} else if (species == 2) {
28-
v[2] = udrift2;
29+
maxwellian(v, temp_p, drift_p, -dir::z);
2930
} else if (species == 3) {
30-
v[2] = udrift3;
31+
maxwellian(v, temp_b, drift_b, dir::z);
3132
} else if (species == 4) {
32-
v[2] = udrift4;
33+
maxwellian(v, temp_b, drift_b, dir::z);
3334
}
3435
}
3536

3637
private:
37-
const real_t udrift1, udrift2, udrift3, udrift4;
38+
const Maxwellian<D, S> maxwellian;
39+
const real_t drift_p, drift_b, temp_p, temp_b;
3840
};
3941

4042
template <Dimension D, SimulationEngine S>

0 commit comments

Comments
 (0)