Returns the distance to surface, given point 'gp' and direction 'gv'.
183{
186
187 G4bool IsParallel = false ;
188 G4bool IsConverged = false ;
189
191
193
195 {
197 {
202 }
204 }
205
206
208 {
209 distance[j] = kInfinity;
211 isvalid[j] = false;
212 gxx[j].
set(kInfinity, kInfinity, kInfinity);
213 }
214
217
218#ifdef G4TWISTDEBUG
221#endif
222
224
225
226
230 G4bool tmpisvalid = false ;
231
232 std::vector<Intersection> xbuf ;
233 Intersection xbuftmp ;
234
235
236
238
239 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
240 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
241
242
243
244
246 {
247 if ( std::fabs(p.
z()) <= L )
248 {
249 phi = p.
z() * fPhiTwist / L ;
250 u = (fDy1*(4*(-(fdeltaY*phi*v.
x()) + fPhiTwist*p.
y()*v.
x()
251 + fdeltaX*phi*v.
y() - fPhiTwist*p.
x()*v.
y())
252 + ((fDx3plus1 + fDx4plus2)*fPhiTwist
253 + 2*(fDx3minus1 + fDx4minus2)*phi)
254 *(v.
y()*std::cos(phi) - v.
x()*std::sin(phi))))
255 /(fPhiTwist*(4*fDy1* v.
x() - (fa1md1 + 4*fDy1*fTAlph)*v.
y())
256 *std::cos(phi) + fPhiTwist*(fa1md1*v.
x()
257 + 4*fDy1*(fTAlph*v.
x() + v.
y()))*std::sin(phi));
258 xbuftmp.phi = phi ;
259 xbuftmp.u = u ;
261 xbuftmp.distance = kInfinity ;
262 xbuftmp.isvalid = false ;
263
264 xbuf.push_back(xbuftmp) ;
265 }
266 else
267 {
268 distance[0] = kInfinity;
269 gxx[0].
set(kInfinity,kInfinity,kInfinity);
270 isvalid[0] = false ;
273 areacode[0], isvalid[0],
274 0, validate, &gp, &gv);
275 return 0;
276 }
277 }
278 else
279 {
280
282
283 c[7] = 57600*
284 fDy1*(fa1md1*phiyz +
285 fDy1*(-4*phixz + 4*fTAlph*phiyz
286 + (fDx3plus1 + fDx4plus2)*fPhiTwist*v.
z())) ;
287 c[6] = -57600*
288 fDy1*(4*fDy1*(phiyz + 2*fDz*v.
x() + fTAlph*(phixz - 2*fDz*v.
y()))
289 - 2*fDy1*(2*fdeltaX + fDx3minus1 + fDx4minus2
290 - 2*fdeltaY*fTAlph)*v.
z()
291 + fa1md1*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z()));
292 c[5] = 4800*
293 fDy1*(fa1md1*(-5*phiyz - 24*fDz*v.
x() + 12*fdeltaX*v.
z()) +
294 fDy1*(20*phixz - 4*(5*fTAlph*phiyz + 24*fDz*fTAlph*v.
x()
295 + 24*fDz*v.
y()) + (48*fdeltaY + (fDx3plus1 + fDx4plus2)
296 *fPhiTwist + 48*fdeltaX*fTAlph)*v.
z()));
297 c[4] = 4800*
298 fDy1*(fa1md1*(phixz - 10*fDz*v.
y() + 5*fdeltaY*v.
z())
299 + 2*fDy1*(2*phiyz + 20*fDz*v.
x()
300 + (-10*fdeltaX + fDx3minus1 + fDx4minus2)*v.
z()
301 + 2*fTAlph*(phixz - 10*fDz*v.
y() + 5*fdeltaY*v.
z())));
302 c[3] = -96*
303 fDy1*(-(fa1md1*(phiyz + 100*fDz*v.
x() - 50*fdeltaX*v.
z()))
304 + fDy1*(4*phixz - 400*fDz*v.
y()
305 + (200*fdeltaY - (fDx3plus1 + fDx4plus2)*fPhiTwist)*v.
z()
306 - 4*fTAlph*(phiyz + 100*fDz*v.
x() - 50*fdeltaX*v.
z())));
307 c[2] = 32*
308 fDy1*(4*fDy1*(7*fTAlph*phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y())
309 + 6*fDy1*(2*fdeltaX+fDx3minus1+fDx4minus2-2*fdeltaY*fTAlph)*v.
z()
310 + fa1md1*(7*phixz + 6*fDz*v.
y() - 3*fdeltaY*v.
z()));
311 c[1] = -8*
312 fDy1*(fa1md1*(-9*phiyz - 56*fDz*v.
x() + 28*fdeltaX*v.
z())
313 + 4*fDy1*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x()
314 - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()));
315 c[0] = 72*
316 fDy1*(fa1md1*(2*fDz*v.
y() - fdeltaY*v.
z())
317 + fDy1*(-8*fDz*v.
x() + 8*fDz*fTAlph*v.
y()
318 + 4*fdeltaX*v.
z() - 4*fdeltaY*fTAlph*v.
z()));
319
320#ifdef G4TWISTDEBUG
321 G4cout <<
"coef = " << c[0] <<
" "
322 << c[1] << " "
323 << c[2] << " "
324 << c[3] << " "
325 << c[4] << " "
326 << c[5] << " "
327 << c[6] << " "
329#endif
330
331 G4JTPolynomialSolver trapEq ;
333
334 for (
G4int i = 0 ; i<num ; i++ )
335 {
336 if ( si[i]==0.0 )
337 {
338#ifdef G4TWISTDEBUG
339 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
340#endif
341 phi = std::fmod(srd[i] , pihalf) ;
342 u = (fDy1*(4*(phiyz + 2*fDz*phi*v.
y() - fdeltaY*phi*v.
z())
343 - ((fDx3plus1 + fDx4plus2)*fPhiTwist
344 + 2*(fDx3minus1 + fDx4minus2)*phi)*v.
z()*std::sin(phi)))
345 /(fPhiTwist*v.
z()*(4*fDy1*std::cos(phi)
346 + (fa1md1 + 4*fDy1*fTAlph)*std::sin(phi)));
347 xbuftmp.phi = phi ;
348 xbuftmp.u = u ;
350 xbuftmp.distance = kInfinity ;
351 xbuftmp.isvalid = false ;
352
353 xbuf.push_back(xbuftmp) ;
354
355#ifdef G4TWISTDEBUG
356 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
357#endif
358 }
359 }
360 }
361
362 nxx = (
G4int)xbuf.size() ;
363
370
371 for (auto & k : xbuf)
372 {
373#ifdef G4TWISTDEBUG
374 G4cout <<
"Solution " << k <<
" : "
375 << "reconstructed phiR = " << xbuf[k].phi
376 <<
", uR = " << xbuf[k].u <<
G4endl ;
377#endif
378
379 phi = k.phi ;
380 u = k.u ;
381
382 IsConverged = false ;
383
384 for (
G4int i = 1 ; i<maxint ; ++i )
385 {
386 xxonsurface = SurfacePoint(phi,u) ;
387 surfacenormal = NormAng(phi,u) ;
388
390 deltaX = ( tmpxx - xxonsurface ).mag() ;
391 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
392 if ( theta < 0.001 )
393 {
394 factor = 50 ;
395 IsParallel = true ;
396 }
397 else
398 {
399 factor = 1 ;
400 }
401
402#ifdef G4TWISTDEBUG
403 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist
404 <<
", " << deltaX <<
G4endl ;
406#endif
407
408 GetPhiUAtX(tmpxx, phi, u) ;
409
410
411#ifdef G4TWISTDEBUG
412 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
413#endif
414
415 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
416
417 }
418
419 if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0 ; }
420
421#ifdef G4TWISTDEBUG
422 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
425#endif
426
427 tmpisvalid = false ;
428
429 if ( IsConverged )
430 {
432 {
433 tmpareacode = GetAreaCode(tmpxx);
435 {
436 if (tmpdist >= 0) { tmpisvalid = true; }
437 }
438 }
440 {
441 tmpareacode = GetAreaCode(tmpxx, false);
443 {
444 if (tmpdist >= 0) { tmpisvalid = true; }
445 }
446 }
447 else
448 {
449 G4Exception(
"G4TwistTrapAlphaSide::DistanceToSurface()",
451 "Feature NOT implemented !");
452 }
453 }
454 else
455 {
456 tmpdist = kInfinity;
457 tmpisvalid = false ;
458 }
459
460
461
462 k.xx = tmpxx ;
463 k.distance = tmpdist ;
464 k.areacode = tmpareacode ;
465 k.isvalid = tmpisvalid ;
466
467 }
468
469 std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;
470
471#ifdef G4TWISTDEBUG
474#endif
475
476
477
478 xbuf.erase( std::unique(xbuf.begin(), xbuf.end() , EqualIntersection ),
479 xbuf.end() );
480
481
482
483
484 auto nxxtmp = (
G4int)xbuf.size() ;
485
486 if ( nxxtmp<2 || IsParallel )
487 {
488
489#ifdef G4TWISTDEBUG
491#endif
492
493 phi = fPhiTwist/2 ;
494 u = 0 ;
495
496 xbuftmp.phi = phi ;
497 xbuftmp.u = u ;
499 xbuftmp.distance = kInfinity ;
500 xbuftmp.isvalid = false ;
501
502 xbuf.push_back(xbuftmp) ;
503
504#ifdef G4TWISTDEBUG
506#endif
507
508 phi = -fPhiTwist/2 ;
509 u = 0 ;
510
511 xbuftmp.phi = phi ;
512 xbuftmp.u = u ;
514 xbuftmp.distance = kInfinity ;
515 xbuftmp.isvalid = false ;
516
517 xbuf.push_back(xbuftmp) ;
518
519 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
520 {
521
522#ifdef G4TWISTDEBUG
523 G4cout <<
"Solution " << k <<
" : "
524 << "reconstructed phiR = " << xbuf[k].phi
525 <<
", uR = " << xbuf[k].u <<
G4endl ;
526#endif
527
528 phi = xbuf[k].phi ;
529 u = xbuf[k].u ;
530
531 IsConverged = false ;
532
533 for (
G4int i = 1 ; i<maxint ; ++i )
534 {
535 xxonsurface = SurfacePoint(phi,u) ;
536 surfacenormal = NormAng(phi,u) ;
538 deltaX = ( tmpxx - xxonsurface ).mag();
539 theta = std::fabs(std::acos(v*surfacenormal) - pihalf);
540 if ( theta < 0.001 )
541 {
542 factor = 50 ;
543 }
544 else
545 {
546 factor = 1 ;
547 }
548
549#ifdef G4TWISTDEBUG
550 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist
551 <<
", " << deltaX <<
G4endl
552 <<
"X = " << tmpxx <<
G4endl ;
553#endif
554
555 GetPhiUAtX(tmpxx, phi, u) ;
556
557
558#ifdef G4TWISTDEBUG
559 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
560#endif
561
562 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
563
564 }
565
566 if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0; }
567
568#ifdef G4TWISTDEBUG
569 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
572#endif
573
574 tmpisvalid = false ;
575
576 if ( IsConverged )
577 {
579 {
580 tmpareacode = GetAreaCode(tmpxx);
582 {
583 if (tmpdist >= 0) { tmpisvalid = true; }
584 }
585 }
587 {
588 tmpareacode = GetAreaCode(tmpxx, false);
590 {
591 if (tmpdist >= 0) { tmpisvalid = true; }
592 }
593 }
594 else
595 {
596 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
598 "Feature NOT implemented !");
599 }
600 }
601 else
602 {
603 tmpdist = kInfinity;
604 tmpisvalid = false ;
605 }
606
607
608
609 xbuf[k].xx = tmpxx ;
610 xbuf[k].distance = tmpdist ;
611 xbuf[k].areacode = tmpareacode ;
612 xbuf[k].isvalid = tmpisvalid ;
613
614 }
615 }
616
617
618 std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;
619
620
621 xbuf.erase( std::unique(xbuf.begin(), xbuf.end() , EqualIntersection ) ,
622 xbuf.end() );
623
624#ifdef G4TWISTDEBUG
627#endif
628
629 nxx = (
G4int)xbuf.size() ;
630
631 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
632 {
633 distance[i] = xbuf[i].distance;
635 areacode[i] = xbuf[i].areacode ;
636 isvalid[i] = xbuf[i].isvalid ;
637
638 fCurStatWithV.SetCurrentStatus(i, gxx[i], distance[i], areacode[i],
639 isvalid[i], nxx, validate, &gp, &gv);
640#ifdef G4TWISTDEBUG
641 G4cout <<
"element Nr. " << i
642 << ", local Intersection = " << xbuf[i].xx
643 << ", distance = " << xbuf[i].distance
644 << ", u = " << xbuf[i].u
645 << ", phi = " << xbuf[i].phi
646 << ", isvalid = " << xbuf[i].isvalid
648#endif
649
650 }
651
652#ifdef G4TWISTDEBUG
654 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
655 for (
G4int k= 0 ; k< nxx ; k++ )
656 {
657 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
660 }
661#endif
662
663 return nxx ;
664}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)
static const G4int sOutside
G4ThreeVector ComputeLocalDirection(const G4ThreeVector &gp) const
G4bool IsInside(G4int areacode, G4bool testbitmode=false) const
G4ThreeVector ComputeLocalPoint(const G4ThreeVector &gp) const
G4bool IsOutside(G4int areacode) const
CurrentStatus fCurStatWithV
G4double DistanceToPlaneWithV(const G4ThreeVector &p, const G4ThreeVector &v, const G4ThreeVector &x0, const G4ThreeVector &n0, G4ThreeVector &xx)
G4ThreeVector ComputeGlobalPoint(const G4ThreeVector &lp) const