IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
NonStandardFDTDSolver.hpp
Go to the documentation of this file.
1
6namespace ippl {
7
8 template <typename EMField, typename SourceField, fdtd_bc boundary_conditions>
10 SourceField& source, EMField& E, EMField& B)
11 : FDTDSolverBase<EMField, SourceField, boundary_conditions>(source, E, B) {
12 auto hx = source.get_mesh().getMeshSpacing();
13 if ((hx[2] / hx[0]) * (hx[2] / hx[0]) + (hx[2] / hx[1]) * (hx[2] / hx[1]) >= 1) {
14 throw IpplException("NonStandardFDTDSolver Constructor",
15 "Dispersion-free CFL condition not satisfiable\n");
16 }
17 initialize();
18 }
19
27 template <typename EMField, typename SourceField, fdtd_bc boundary_conditions>
29 const auto& ldom = this->layout_mp->getLocalNDIndex();
30 const int nghost = this->A_n.getNghost();
31 const auto aview = this->A_n.getView();
32 const auto anp1view = this->A_np1.getView();
33 const auto anm1view = this->A_nm1.getView();
34 const auto source_view = Maxwell<EMField, SourceField>::JN_mp->getView();
35
36 const scalar calA =
37 0.25
38 * (1
39 + 0.02
40 / (static_cast<scalar>(Kokkos::pow(this->hr_m[2] / this->hr_m[0], 2))
41 + static_cast<scalar>(Kokkos::pow(this->hr_m[2] / this->hr_m[1], 2))));
43 .a1 =
44 2
45 * (1
46 - (1 - 2 * calA) * static_cast<scalar>(Kokkos::pow(this->dt / this->hr_m[0], 2))
47 - (1 - 2 * calA) * static_cast<scalar>(Kokkos::pow(this->dt / this->hr_m[1], 2))
48 - static_cast<scalar>(Kokkos::pow(this->dt / this->hr_m[2], 2))),
49 .a2 = static_cast<scalar>(Kokkos::pow(this->dt / this->hr_m[0], 2)),
50 .a4 = static_cast<scalar>(Kokkos::pow(this->dt / this->hr_m[1], 2)),
51 .a6 = static_cast<scalar>(Kokkos::pow(this->dt / this->hr_m[2], 2))
52 - 2 * calA * static_cast<scalar>(Kokkos::pow(this->dt / this->hr_m[0], 2))
53 - 2 * calA * static_cast<scalar>(Kokkos::pow(this->dt / this->hr_m[1], 2)),
54 .a8 = static_cast<scalar>(Kokkos::pow(this->dt, 2))};
55 Vector<uint32_t, Dim> true_nr = this->nr_m;
56 true_nr += (nghost * 2);
57 constexpr uint32_t one_if_absorbing_otherwise_0 =
58 boundary_conditions == absorbing
59 ? 1
60 : 0; // 1 if absorbing, 0 otherwise, indicates the start index of the field
61 Kokkos::parallel_for(
62 ippl::getRangePolicy(aview, nghost), KOKKOS_LAMBDA(size_t i, size_t j, size_t k) {
63 // global indices
64 uint32_t ig = i + ldom.first()[0];
65 uint32_t jg = j + ldom.first()[1];
66 uint32_t kg = k + ldom.first()[2];
67 // check if at a boundary of the field
68 uint32_t val =
69 uint32_t(ig == one_if_absorbing_otherwise_0)
70 + (uint32_t(jg == one_if_absorbing_otherwise_0) << 1)
71 + (uint32_t(kg == one_if_absorbing_otherwise_0) << 2)
72 + (uint32_t(ig == true_nr[0] - one_if_absorbing_otherwise_0 - 1) << 3)
73 + (uint32_t(jg == true_nr[1] - one_if_absorbing_otherwise_0 - 1) << 4)
74 + (uint32_t(kg == true_nr[2] - one_if_absorbing_otherwise_0 - 1) << 5);
75 // update the interior field values
76 if (!val) {
77 anp1view(i, j, k) =
78 -anm1view(i, j, k) + ndisp.a1 * aview(i, j, k)
79 + ndisp.a2
80 * (calA * aview(i + 1, j, k - 1) + (1 - 2 * calA) * aview(i + 1, j, k)
81 + calA * aview(i + 1, j, k + 1))
82 + ndisp.a2
83 * (calA * aview(i - 1, j, k - 1) + (1 - 2 * calA) * aview(i - 1, j, k)
84 + calA * aview(i - 1, j, k + 1))
85 + ndisp.a4
86 * (calA * aview(i, j + 1, k - 1) + (1 - 2 * calA) * aview(i, j + 1, k)
87 + calA * aview(i, j + 1, k + 1))
88 + ndisp.a4
89 * (calA * aview(i, j - 1, k - 1) + (1 - 2 * calA) * aview(i, j - 1, k)
90 + calA * aview(i, j - 1, k + 1))
91 + ndisp.a6 * aview(i, j, k + 1) + ndisp.a6 * aview(i, j, k - 1)
92 + ndisp.a8 * source_view(i, j, k);
93 }
94 });
95 Kokkos::fence();
96 this->A_np1.fillHalo();
97 this->applyBCs();
98 }
99
106 template <typename EMField, typename SourceField, fdtd_bc boundary_conditions>
108 // get layout and mesh
109 this->layout_mp = &(this->JN_mp->getLayout());
110 this->mesh_mp = &(this->JN_mp->get_mesh());
111
112 // get mesh spacing, domain, and mesh size
113 this->hr_m = this->mesh_mp->getMeshSpacing();
114 this->dt = this->hr_m[2];
115 this->domain_m = this->layout_mp->getDomain();
116 for (unsigned int i = 0; i < Dim; ++i)
117 this->nr_m[i] = this->domain_m[i].length();
118
119 // initialize fields
120 this->A_nm1.initialize(*this->mesh_mp, *this->layout_mp);
121 this->A_n.initialize(*this->mesh_mp, *this->layout_mp);
122 this->A_np1.initialize(*this->mesh_mp, *this->layout_mp);
123
124 this->A_nm1 = 0.0;
125 this->A_n = 0.0;
126 this->A_np1 = 0.0;
127
128 // set the mesh domain
129 if constexpr (boundary_conditions == periodic) {
130 this->setPeriodicBoundaryConditions();
131 }
132 };
133} // namespace ippl
Definition IpplException.h:6
Base class for FDTD solvers in the ippl library.
Definition FDTDSolverBase.h:28
Definition Maxwell.h:20
void step() override
Advances the simulation by one time step.
Definition NonStandardFDTDSolver.hpp:28
NonStandardFDTDSolver(SourceField &source, EMField &E, EMField &B)
Constructs a NonStandardFDTDSolver.
Definition NonStandardFDTDSolver.hpp:9
void initialize() override
Initializes the solver.
Definition NonStandardFDTDSolver.hpp:107
Definition Vector.h:23
Definition Archive.h:20
RangePolicy< View::rank, typenameView::execution_space, PolicyArgs... >::policy_type getRangePolicy(const View &view, int shift=0)
Definition ParallelDispatch.h:56
A structure representing nondispersive coefficients.
Definition NonStandardFDTDSolver.h:67