|
| 1 | +#ifndef PROBLEM_GENERATOR_H |
| 2 | +#define PROBLEM_GENERATOR_H |
| 3 | + |
| 4 | +#include "enums.h" |
| 5 | +#include "global.h" |
| 6 | + |
| 7 | +#include "arch/kokkos_aliases.h" |
| 8 | +#include "arch/traits.h" |
| 9 | + |
| 10 | +#include "archetypes/problem_generator.h" |
| 11 | +#include "framework/domain/metadomain.h" |
| 12 | + |
| 13 | +namespace user { |
| 14 | + using namespace ntt; |
| 15 | + |
| 16 | + template <Dimension D> |
| 17 | + struct InitFields { |
| 18 | + InitFields(real_t b0, real_t angle, real_t rho) : b0 { b0 }, angle { angle }, rho { rho } {} |
| 19 | + |
| 20 | + Inline auto bx1(const coord_t<D>& x_Ph) const -> real_t { |
| 21 | + return b0 * math::cos(angle); |
| 22 | + } |
| 23 | + |
| 24 | + Inline auto bx2(const coord_t<D>& x_Ph) const -> real_t { |
| 25 | + return ZERO; |
| 26 | + } |
| 27 | + |
| 28 | + Inline auto ex1(const coord_t<D>& x_Ph) const -> real_t { |
| 29 | + return rho * x_Ph[0]; |
| 30 | + } |
| 31 | + |
| 32 | + private: |
| 33 | + const real_t b0, angle, rho; |
| 34 | + }; |
| 35 | + |
| 36 | + template <Dimension D> |
| 37 | + struct MFields { |
| 38 | + MFields(real_t b0, real_t angle) : b0 { b0 }, angle { angle } {} |
| 39 | + |
| 40 | + Inline auto bx1(const coord_t<D>& x_Ph) const -> real_t { |
| 41 | + return b0 * math::cos(angle); |
| 42 | + } |
| 43 | + |
| 44 | + Inline auto bx2(const coord_t<D>& x_Ph) const -> real_t { |
| 45 | + return b0 * math::sin(angle); |
| 46 | + } |
| 47 | + |
| 48 | + private: |
| 49 | + const real_t b0, angle; |
| 50 | + }; |
| 51 | + |
| 52 | + template <Dimension D> |
| 53 | + struct DriveFields : public InitFields<D> { |
| 54 | + DriveFields(real_t time, real_t b0, real_t angle, real_t omega, real_t r, real_t theta) |
| 55 | + : InitFields<D> { b0, angle } |
| 56 | + , time { time } |
| 57 | + , Omega { omega } |
| 58 | + , R { r } |
| 59 | + , theta { theta } {} |
| 60 | + |
| 61 | + using InitFields<D>::bx1; |
| 62 | + using InitFields<D>::bx2; |
| 63 | + |
| 64 | + Inline auto bx3(const coord_t<D>&) const -> real_t { |
| 65 | + return ZERO; |
| 66 | + } |
| 67 | + |
| 68 | + Inline auto ex1(const coord_t<D>& x_Ph) const -> real_t { |
| 69 | + return Omega * bx2(x_Ph) * R * math::sin(theta); |
| 70 | + } |
| 71 | + |
| 72 | + Inline auto ex2(const coord_t<D>& x_Ph) const -> real_t { |
| 73 | + return -Omega * bx1(x_Ph) * R * math::sin(theta); |
| 74 | + } |
| 75 | + |
| 76 | + Inline auto ex3(const coord_t<D>&) const -> real_t { |
| 77 | + return ZERO; |
| 78 | + } |
| 79 | + |
| 80 | + private: |
| 81 | + const real_t time, Omega, R, theta; |
| 82 | + }; |
| 83 | + |
| 84 | + template <SimEngine::type S, class M> |
| 85 | + struct PGen : public arch::ProblemGenerator<S, M> { |
| 86 | + // compatibility traits for the problem generator |
| 87 | + static constexpr auto engines { traits::compatible_with<SimEngine::SRPIC>::value }; |
| 88 | + static constexpr auto metrics { |
| 89 | + traits::compatible_with<Metric::Minkowski>::value |
| 90 | + }; |
| 91 | + static constexpr auto dimensions { traits::compatible_with<Dim::_1D>::value }; |
| 92 | + |
| 93 | + // for easy access to variables in the child class |
| 94 | + using arch::ProblemGenerator<S, M>::D; |
| 95 | + using arch::ProblemGenerator<S, M>::C; |
| 96 | + using arch::ProblemGenerator<S, M>::params; |
| 97 | + |
| 98 | + const real_t B0, angle, R, Omega, rho, theta, skin0, larmor0; |
| 99 | + InitFields<D> init_flds; |
| 100 | + |
| 101 | + inline PGen(const SimulationParams& p, const Metadomain<S, M>& m) |
| 102 | + : arch::ProblemGenerator<S, M>(p) |
| 103 | + , B0 { p.template get<real_t>("setup.B0", ONE) } |
| 104 | + , R { p.template get<real_t>("setup.R") } |
| 105 | + , Omega { static_cast<real_t>(constant::TWO_PI) / |
| 106 | + p.template get<real_t>("setup.period", ONE) } |
| 107 | + , angle { p.template get<real_t>("setup.angle", ZERO) } |
| 108 | + , theta { p.template get<real_t>("setup.theta", ZERO) } |
| 109 | + , skin0 { p.template get<real_t>("scales.skindepth0") } |
| 110 | + , larmor0 { p.template get<real_t>("scales.larmor0") } |
| 111 | + , rho { TWO * B0 * Omega * SQR(skin0) / larmor0} |
| 112 | + , init_flds { B0, angle, rho} {} |
| 113 | + |
| 114 | + inline PGen() {} |
| 115 | + |
| 116 | + auto AtmFields(real_t time) const -> DriveFields<D> { |
| 117 | + return DriveFields<D> { time, B0, angle, Omega, R, theta}; |
| 118 | + } |
| 119 | + |
| 120 | + auto MatchFields(real_t) const -> MFields<D> { |
| 121 | + return MFields<D> { B0, angle }; |
| 122 | + } |
| 123 | + }; |
| 124 | + |
| 125 | +} // namespace user |
| 126 | + |
| 127 | +#endif |
0 commit comments