3030#include < pmacc/lockstep.hpp>
3131#include < pmacc/mappings/kernel/AreaMapping.hpp>
3232#include < pmacc/math/Vector.hpp>
33+ #include < pmacc/math/functions/Round.hpp>
3334#include < pmacc/math/operation.hpp>
3435#include < pmacc/memory/shared/Allocate.hpp>
3536#include < pmacc/mpi/MPIReduce.hpp>
@@ -64,13 +65,13 @@ namespace picongpu::particles::fusion
6465 T truncated = static_cast <long long >(x);
6566 T fraction = x - truncated;
6667
67- if (fraction >= 0.5 )
68+ if (fraction >= T{ 0.5 } )
6869 {
69- return truncated + 1.0 ;
70+ return truncated + T{ 1.0 } ;
7071 }
71- if (fraction <= -0.5 )
72+ if (fraction <= T{ -0.5 } )
7273 {
73- return truncated - 1.0 ;
74+ return truncated - T{ 1.0 } ;
7475 }
7576 return truncated;
7677 }
@@ -85,10 +86,10 @@ namespace picongpu::particles::fusion
8586 float_COLL c4)
8687 {
8788 // clang-format off
88- return (W1 >= 0 .0_X && W1 <= c3 &&
89- W3 >= 0 .0_X && W3 <= c3 &&
90- W2 >= 0 .0_X && W2 <= c4 &&
91- W4 >= 0 .0_X && W4 <= c4);
89+ return (W1 >= 0 .0_COLL && W1 <= c3 &&
90+ W3 >= 0 .0_COLL && W3 <= c3 &&
91+ W2 >= 0 .0_COLL && W2 <= c4 &&
92+ W4 >= 0 .0_COLL && W4 <= c4);
9293 // clang-format on
9394 }
9495
@@ -118,8 +119,7 @@ namespace picongpu::particles::fusion
118119 float_COLL q4,
119120 float_COLL m4)
120121 {
121- constexpr float_COLL tolerance
122- = static_cast <precision::float_COLL>(10 ) * std::numeric_limits<float_COLL>::epsilon ();
122+ constexpr float_COLL tolerance = 10 .0_COLL * std::numeric_limits<float_COLL>::epsilon ();
123123
124124 float_COLL const Q = q1 + q2;
125125 float_COLL const M = m1 + m2;
@@ -130,7 +130,7 @@ namespace picongpu::particles::fusion
130130 {
131131 float_COLL const c3 = (Q * m4 - q4 * M) / det;
132132 float_COLL const c4 = (q3 * M - Q * m3) / det;
133- bool const ok = (c3 >= 0 .0_X && c4 >= 0 .0_X );
133+ bool const ok = (c3 >= 0 .0_COLL && c4 >= 0 .0_COLL );
134134 return StoichiometryCaps{c3, c4, ok};
135135 }
136136
@@ -140,17 +140,17 @@ namespace picongpu::particles::fusion
140140 if (std::abs (sQ ) > tolerance)
141141 {
142142 float_COLL const c = Q / sQ ; // c3=c4 ensures global charge; mass follows when q/m are identical
143- return StoichiometryCaps{c, c, c >= 0 .0_X };
143+ return StoichiometryCaps{c, c, c >= 0 .0_COLL };
144144 }
145145
146146 // If both products are effectively neutral, rely on mass-only symmetric split
147147 float_COLL const sM = m3 + m4;
148148 if (std::abs (sM ) > tolerance)
149149 {
150150 float_COLL const c = M / sM ;
151- return StoichiometryCaps{c, c, c >= 0 .0_X };
151+ return StoichiometryCaps{c, c, c >= 0 .0_COLL };
152152 }
153- return StoichiometryCaps{0 .0_X , 0 .0_X , false };
153+ return StoichiometryCaps{0 .0_COLL , 0 .0_COLL , false };
154154 }
155155
156156 // New: local mass+charge solver under caps. Solve site-1 2x2 and derive site-2 via caps.
@@ -166,12 +166,11 @@ namespace picongpu::particles::fusion
166166 float_COLL c3,
167167 float_COLL c4)
168168 {
169- constexpr float_COLL tolerance
170- = static_cast <precision::float_COLL>(10 ) * std::numeric_limits<float_COLL>::epsilon ();
169+ constexpr float_COLL tolerance = 10 .0_COLL * std::numeric_limits<float_COLL>::epsilon ();
171170
172171 float_COLL const det = q3 * m4 - q4 * m3;
173172 if (std::abs (det) < tolerance)
174- return WeightResult{0 .0_X , 0 .0_X , 0 .0_X , 0 .0_X , false };
173+ return WeightResult{0 .0_COLL , 0 .0_COLL , 0 .0_COLL , 0 .0_COLL , false };
175174
176175 // Solve for site-1 weights (W1,W2)
177176 float_COLL const W1 = (q1 * m4 - q4 * m1) / det;
@@ -181,7 +180,7 @@ namespace picongpu::particles::fusion
181180
182181 // Check bounds
183182 if (!areWeightsValidWithCaps (W1, W2, W3, W4, c3, c4))
184- return WeightResult{0 .0_X , 0 .0_X , 0 .0_X , 0 .0_X , false };
183+ return WeightResult{0 .0_COLL , 0 .0_COLL , 0 .0_COLL , 0 .0_COLL , false };
185184
186185 // Verify site-2 consistency
187186 float_COLL const q2_chk = W3 * q3 + W4 * q4;
@@ -199,13 +198,12 @@ namespace picongpu::particles::fusion
199198 float_COLL c3,
200199 float_COLL c4)
201200 {
202- constexpr float_COLL tolerance
203- = static_cast <precision::float_COLL>(10 ) * std::numeric_limits<float_COLL>::epsilon ();
201+ constexpr float_COLL tolerance = 10 .0_COLL * std::numeric_limits<float_COLL>::epsilon ();
204202
205203 // Both neutral: minimize macro creation -> put all at site 2
206204 if (std::abs (q3) < tolerance && std::abs (q4) < tolerance)
207205 {
208- return WeightResult{0 .0_X , 0 .0_X , c3, c4, true };
206+ return WeightResult{0 .0_COLL , 0 .0_COLL , c3, c4, true };
209207 }
210208
211209 // Second product neutral
@@ -214,7 +212,7 @@ namespace picongpu::particles::fusion
214212 float_COLL const W1 = q1 / q3;
215213 float_COLL const W3 = c3 - W1;
216214 // Place all neutral at site 2
217- float_COLL const W2 = 0 .0_X ;
215+ float_COLL const W2 = 0 .0_COLL ;
218216 float_COLL const W4 = c4;
219217 bool const ok = areWeightsValidWithCaps (W1, W2, W3, W4, c3, c4)
220218 && (std::abs (q1 - (W1 * q3 + W2 * q4)) < tolerance);
@@ -226,7 +224,7 @@ namespace picongpu::particles::fusion
226224 {
227225 float_COLL const W2 = q1 / q4;
228226 float_COLL const W4 = c4 - W2;
229- float_COLL const W1 = 0 .0_X ;
227+ float_COLL const W1 = 0 .0_COLL ;
230228 float_COLL const W3 = c3;
231229 bool const ok = areWeightsValidWithCaps (W1, W2, W3, W4, c3, c4)
232230 && (std::abs (q1 - (W1 * q3 + W2 * q4)) < tolerance);
@@ -236,18 +234,18 @@ namespace picongpu::particles::fusion
236234 // Both charged: try single-product split first
237235 {
238236 float_COLL const W1a = q1 / q3;
239- if (W1a >= 0 .0_X && W1a <= c3)
237+ if (W1a >= 0 .0_COLL && W1a <= c3)
240238 {
241239 float_COLL const W1 = W1a;
242- float_COLL const W2 = 0 .0_X ;
240+ float_COLL const W2 = 0 .0_COLL ;
243241 float_COLL const W3 = c3 - W1;
244242 float_COLL const W4 = c4;
245243 return WeightResult{W1, W2, W3, W4, true };
246244 }
247245 float_COLL const W2a = q1 / q4;
248- if (W2a >= 0 .0_X && W2a <= c4)
246+ if (W2a >= 0 .0_COLL && W2a <= c4)
249247 {
250- float_COLL const W1 = 0 .0_X ;
248+ float_COLL const W1 = 0 .0_COLL ;
251249 float_COLL const W2 = W2a;
252250 float_COLL const W3 = c3;
253251 float_COLL const W4 = c4 - W2;
@@ -261,7 +259,7 @@ namespace picongpu::particles::fusion
261259 {
262260 float_COLL const W1 = c3;
263261 float_COLL const W2 = (q1 - q3 * W1) / q4;
264- float_COLL const W3 = 0 .0_X ;
262+ float_COLL const W3 = 0 .0_COLL ;
265263 float_COLL const W4 = c4 - W2;
266264 bool const ok = areWeightsValidWithCaps (W1, W2, W3, W4, c3, c4);
267265 return WeightResult{W1, W2, W3, W4, ok};
@@ -271,7 +269,7 @@ namespace picongpu::particles::fusion
271269 float_COLL const W2 = c4;
272270 float_COLL const W1 = (q1 - q4 * W2) / q3;
273271 float_COLL const W3 = c3 - W1;
274- float_COLL const W4 = 0 .0_X ;
272+ float_COLL const W4 = 0 .0_COLL ;
275273 bool const ok = areWeightsValidWithCaps (W1, W2, W3, W4, c3, c4);
276274 return WeightResult{W1, W2, W3, W4, ok};
277275 }
@@ -334,9 +332,9 @@ namespace picongpu::particles::fusion
334332 IdGenerator& idGen,
335333 T_ParAccessor0 const & r1,
336334 T_ParAccessor1 const & r2,
337- float_X& productWeighting,
338- float3_X& mom1,
339- float3_X& mom2,
335+ float_X const productWeighting,
336+ float3_X const & mom1,
337+ float3_X const & mom2,
340338 T_ParAccessor2& p1r1, // product 1 at pos 1
341339 T_ParAccessor2& p1r2, // product 1 at pos 2
342340 T_ParAccessor3& p2r1, // product 2 at pos 1
@@ -357,11 +355,10 @@ namespace picongpu::particles::fusion
357355 targetClone5.derive (worker, idGen, r2);
358356
359357
360- static constexpr float_COLL tolerance
361- = static_cast <float_COLL>(10 ) * std::numeric_limits<float_COLL>::epsilon ();
358+ static constexpr float_COLL tolerance = 10 .0_COLL * std::numeric_limits<float_COLL>::epsilon ();
362359 // Charges must be non-negative
363360 static_assert (
364- q1 >= 0 .0_X && q2 >= 0 .0_X && q3 >= 0 .0_X && q4 >= 0 .0_X ,
361+ q1 >= 0 .0_COLL && q2 >= 0 .0_COLL && q3 >= 0 .0_COLL && q4 >= 0 .0_COLL ,
365362 " All charges must be non-negative" );
366363
367364 // Compute stoichiometric caps from species (can be fractional)
0 commit comments