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