1use std::vec::Vec;
4
5use na::SVector;
6#[cfg(feature = "serde-serialize")]
7use serde::{Deserialize, Serialize};
8
9use super::{
10 super::{
11 field::{EField, LinkMatrix, Su3Adjoint},
12 lattice::LatticeCyclic,
13 simulation::{
14 LatticeState, LatticeStateWithEField, LatticeStateWithEFieldNew, SimulationStateLeap,
15 SimulationStateSynchronous,
16 },
17 thread::run_pool_parallel_rayon,
18 Real,
19 },
20 integrate_efield, integrate_link, CMatrix3, SymplecticIntegrator,
21};
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
51#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
52pub struct SymplecticEulerRayon;
53
54impl SymplecticEulerRayon {
55 pub const fn new() -> Self {
57 Self {}
58 }
59
60 fn link_matrix_integrate<State, const D: usize>(
66 link_matrix: &LinkMatrix,
67 e_field: &EField<D>,
68 lattice: &LatticeCyclic<D>,
69 delta_t: Real,
70 ) -> Vec<CMatrix3>
71 where
72 State: LatticeStateWithEField<D>,
73 {
74 run_pool_parallel_rayon(
75 lattice.get_links(),
76 &(link_matrix, e_field, lattice),
77 |link, (link_matrix, e_field, lattice)| {
78 integrate_link::<State, D>(link, link_matrix, e_field, lattice, delta_t)
79 },
80 )
81 }
82
83 fn e_field_integrate<State, const D: usize>(
89 link_matrix: &LinkMatrix,
90 e_field: &EField<D>,
91 lattice: &LatticeCyclic<D>,
92 delta_t: Real,
93 ) -> Vec<SVector<Su3Adjoint, D>>
94 where
95 State: LatticeStateWithEField<D>,
96 {
97 run_pool_parallel_rayon(
98 lattice.get_points(),
99 &(link_matrix, e_field, lattice),
100 |point, (link_matrix, e_field, lattice)| {
101 integrate_efield::<State, D>(point, link_matrix, e_field, lattice, delta_t)
102 },
103 )
104 }
105}
106
107impl Default for SymplecticEulerRayon {
108 fn default() -> Self {
110 Self::new()
111 }
112}
113
114impl std::fmt::Display for SymplecticEulerRayon {
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 write!(f, "Euler integrator using rayon")
117 }
118}
119
120impl<State, const D: usize> SymplecticIntegrator<State, SimulationStateLeap<State, D>, D>
121 for SymplecticEulerRayon
122where
123 State: SimulationStateSynchronous<D> + LatticeStateWithEField<D> + LatticeStateWithEFieldNew<D>,
124{
125 type Error = State::Error;
126
127 fn integrate_sync_sync(&self, l: &State, delta_t: Real) -> Result<State, Self::Error> {
128 let link_matrix = Self::link_matrix_integrate::<State, D>(
129 l.link_matrix(),
130 l.e_field(),
131 l.lattice(),
132 delta_t,
133 );
134 let e_field =
135 Self::e_field_integrate::<State, D>(l.link_matrix(), l.e_field(), l.lattice(), delta_t);
136
137 State::new(
138 l.lattice().clone(),
139 l.beta(),
140 EField::new(e_field),
141 LinkMatrix::new(link_matrix),
142 l.t() + 1,
143 )
144 }
145
146 fn integrate_leap_leap(
147 &self,
148 l: &SimulationStateLeap<State, D>,
149 delta_t: Real,
150 ) -> Result<SimulationStateLeap<State, D>, Self::Error> {
151 let link_matrix = LinkMatrix::new(Self::link_matrix_integrate::<State, D>(
152 l.link_matrix(),
153 l.e_field(),
154 l.lattice(),
155 delta_t,
156 ));
157
158 let e_field = EField::new(Self::e_field_integrate::<State, D>(
159 &link_matrix,
160 l.e_field(),
161 l.lattice(),
162 delta_t,
163 ));
164 SimulationStateLeap::<State, D>::new(
165 l.lattice().clone(),
166 l.beta(),
167 e_field,
168 link_matrix,
169 l.t() + 1,
170 )
171 }
172
173 fn integrate_sync_leap(
174 &self,
175 l: &State,
176 delta_t: Real,
177 ) -> Result<SimulationStateLeap<State, D>, Self::Error> {
178 let e_field = Self::e_field_integrate::<State, D>(
179 l.link_matrix(),
180 l.e_field(),
181 l.lattice(),
182 delta_t / 2_f64,
183 );
184
185 SimulationStateLeap::<State, D>::new(
187 l.lattice().clone(),
188 l.beta(),
189 EField::new(e_field),
190 l.link_matrix().clone(),
191 l.t(),
192 )
193 }
194
195 fn integrate_leap_sync(
196 &self,
197 l: &SimulationStateLeap<State, D>,
198 delta_t: Real,
199 ) -> Result<State, Self::Error> {
200 let link_matrix = LinkMatrix::new(Self::link_matrix_integrate::<State, D>(
201 l.link_matrix(),
202 l.e_field(),
203 l.lattice(),
204 delta_t,
205 ));
206 let e_field = EField::new(Self::e_field_integrate::<State, D>(
208 &link_matrix,
209 l.e_field(),
210 l.lattice(),
211 delta_t / 2_f64,
212 ));
213 State::new(
214 l.lattice().clone(),
215 l.beta(),
216 e_field,
217 link_matrix,
218 l.t() + 1,
219 )
220 }
221
222 fn integrate_symplectic(&self, l: &State, delta_t: Real) -> Result<State, Self::Error> {
223 let e_field_half = EField::new(Self::e_field_integrate::<State, D>(
227 l.link_matrix(),
228 l.e_field(),
229 l.lattice(),
230 delta_t / 2_f64,
231 ));
232 let link_matrix = LinkMatrix::new(Self::link_matrix_integrate::<State, D>(
233 l.link_matrix(),
234 &e_field_half,
235 l.lattice(),
236 delta_t,
237 ));
238 let e_field = EField::new(Self::e_field_integrate::<State, D>(
239 &link_matrix,
240 &e_field_half,
241 l.lattice(),
242 delta_t / 2_f64,
243 ));
244
245 State::new(
246 l.lattice().clone(),
247 l.beta(),
248 e_field,
249 link_matrix,
250 l.t() + 1,
251 )
252 }
253}