159 {
164 G4double* time = simulator->nextStateTime;
165
166 for (i = 0; i < 3; i++)
167 {
168 const G4int var = inf[i];
169 const G4int icf0 = 3 * var;
170 const G4int icf1 = icf0 + 1;
171 const G4int icf2 = icf1 + 1;
172
173 time[var] = t;
174
175 if (std::fabs(q[icf0] - x[icf0]) < lqu[var])
176 {
178 G4double cf0 = q[icf0] + lqu[var] - x[icf0];
181 G4double cf0Alt = q[icf0] - lqu[var] - x[icf0];
182
183 if (
unlikely(cf2 == 0 || (1000 * std::fabs(cf2)) < std::fabs(cf1)))
184 {
185 if (cf1 == 0) {
187 } else
188 {
189 mpr = -cf0 / cf1;
190 mpr2 = -cf0Alt / cf1;
191 if (mpr < 0 || (mpr2 > 0 && mpr2 < mpr)) { mpr = mpr2; }
192 }
193
195 }
196 else
197 {
198 static G4ThreadLocal unsigned long long okCalls=0LL, badCalls= 0LL;
199 constexpr G4double dangerZone = 1.0e+30;
201 bigCf2_pr = dangerZone;
203 if( std::abs(cf1) > dangerZone || std::fabs(cf2) > dangerZone )
204 {
205 badCalls++;
206 if( badCalls == 1
207 || ( badCalls < 1000 && badCalls % 20 == 0 )
208 || ( 1000 < badCalls && badCalls < 10000 && badCalls % 100 == 0 )
209 || ( 10000 < badCalls && badCalls < 100000 && badCalls % 1000 == 0 )
210 || ( 100000 < badCalls && badCalls % 10000 == 0 )
211 || ( std::fabs(cf1) > 1.5 * bigCf1_pr || std::fabs(cf2) > 1.5 * bigCf2_pr )
212 )
213 {
214 std::cout << " cf1 = " << std::setw(15) << cf1 << " cf2= " << std::setw(15) << cf2
215 << " badCall # " << badCalls << " of " << badCalls + okCalls
216 << " fraction = " << double(badCalls) / double(badCalls+okCalls);
217
218 if( std::fabs(cf1) > 1.5 * bigCf1_pr ) { bigCf1_pr = std::fabs(cf1); std::cout << " Bigger cf1 "; }
219 if( std::fabs(cf2) > 1.5 * bigCf2_pr ) { bigCf2_pr = std::fabs(cf2); std::cout << " Bigger cf2 "; }
220 std::cout << std::endl;
221 }
222 if( std::fabs(cf1) > 1.5 * bigCf1 ) { bigCf1 = std::fabs(cf1); }
223 if( std::fabs(cf2) > 1.5 * bigCf2 ) { bigCf2 = std::fabs(cf2); }
224 }
225 else
226 {
227 okCalls++;
228 }
229
230#ifdef REPORT_CRITICAL_PROBLEM
231 constexpr unsigned int exp_limit= 140;
233 assert( std::fabs( std::pow(10, exp_limit) - limit ) < 1.0e-14*limit );
235 +
G4Log(std::max( std::fabs(cf0), std::fabs(cf0Alt))) > 2*limit;
236 if( std::fabs(cf1) > limit
237 ||
G4Log(std::fabs(cf2))
238 +
G4Log(std::max( std::fabs(cf0), std::fabs(cf0Alt))) > 2*exp_limit )
239 {
241 ermsg <<
"QSS2: Coefficients exceed tolerable values -- beyond " << limit <<
G4endl;
242 if( std::fabs(cf1) > limit )
243 {
244 ermsg << " |cf1| = " << cf1 << " is > " << limit << " (limit)";
245 }
246 if( bad_cf2fac)
247 {
248 ermsg << " bad cf2-factor: cf2 = " << cf2
249 << " product is > " << 2*limit << " (limit)";
250 }
253 }
254#endif
257 G4double disc1 = cf1_2 - cf2_4 * cf0;
258 G4double disc2 = cf1_2 - cf2_4 * cf0Alt;
260
261 if (
unlikely(disc1 < 0 && disc2 < 0))
262 {
264 }
265 else if (disc2 < 0)
266 {
268 sd = std::sqrt(disc1);
269 r1 = (-cf1 + sd) / cf2_d2;
270 if (r1 > 0) {
271 mpr = r1;
272 } else {
274 }
275 r1 = (-cf1 - sd) / cf2_d2;
276 if ((r1 > 0) && (r1 < mpr)) { mpr = r1; }
277 }
278 else if (disc1 < 0)
279 {
281 sd = std::sqrt(disc2);
282 r1 = (-cf1 + sd) / cf2_d2;
283 if (r1 > 0) {
284 mpr = r1;
285 } else {
287 }
288 r1 = (-cf1 - sd) / cf2_d2;
289 if ((r1 > 0) && (r1 < mpr)) { mpr = r1; }
290 }
291 else
292 {
294 sd1 = std::sqrt(disc1);
295 sd2 = std::sqrt(disc2);
296 r1 = (-cf1 + sd1) / cf2_d2;
297 r2 = (-cf1 + sd2) / cf2_d2;
298 if (r1 > 0) { mpr = r1; }
300 r1 = (-cf1 - sd1) / cf2_d2;
301 if ((r1 > 0) && (r1 < mpr)) { mpr = r1; }
302 if (r2 > 0 && r2 < mpr) { mpr = r2; }
303 r2 = (-cf1 - sd2) / cf2_d2;
304 if ((r2 > 0) && (r2 < mpr)) { mpr = r2; }
305 }
306 }
307 time[var] += mpr;
308 }
309 }
310 }
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Log(G4double x)