189{
190 static const G4double pihalf = pi/2 ;
192
193 G4bool IsParallel = false ;
194 G4bool IsConverged = false ;
195
197
199
201 {
203 {
208 }
210 }
211 else
212 {
214 {
215 distance[j] = kInfinity;
217 isvalid[j] = false;
218 gxx[j].
set(kInfinity, kInfinity, kInfinity);
219 }
220 }
221
224
225#ifdef G4TWISTDEBUG
228#endif
229
231
232
233
237 G4bool tmpisvalid = false ;
238
239 std::vector<Intersection> xbuf ;
241
242
243
245
246 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
247 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
248
249
250
251
253 {
254 if ( std::fabs(p.
z()) <= L )
255 {
256 phi = p.
z() * fPhiTwist / L ;
257 u = (fDy1*(4*(-(fdeltaY*phi*v.
x()) + fPhiTwist*p.
y()*v.
x()
258 + fdeltaX*phi*v.
y() - fPhiTwist*p.
x()*v.
y())
259 + ((fDx3plus1 + fDx4plus2)*fPhiTwist
260 + 2*(fDx3minus1 + fDx4minus2)*phi)
261 *(v.
y()*std::cos(phi) - v.
x()*std::sin(phi))))
262 /(fPhiTwist*(4*fDy1* v.
x() - (fa1md1 + 4*fDy1*fTAlph)*v.
y())
263 *std::cos(phi) + fPhiTwist*(fa1md1*v.
x()
264 + 4*fDy1*(fTAlph*v.
x() + v.
y()))*std::sin(phi));
270
271 xbuf.push_back(xbuftmp) ;
272 }
273 else
274 {
275 distance[0] = kInfinity;
276 gxx[0].
set(kInfinity,kInfinity,kInfinity);
277 isvalid[0] = false ;
280 areacode[0], isvalid[0],
281 0, validate, &gp, &gv);
282 return 0;
283 }
284 }
285 else
286 {
287
289
290 c[7] = 57600*
291 fDy1*(fa1md1*phiyz +
292 fDy1*(-4*phixz + 4*fTAlph*phiyz
293 + (fDx3plus1 + fDx4plus2)*fPhiTwist*v.
z())) ;
294 c[6] = -57600*
295 fDy1*(4*fDy1*(phiyz + 2*fDz*v.
x() + fTAlph*(phixz - 2*fDz*v.
y()))
296 - 2*fDy1*(2*fdeltaX + fDx3minus1 + fDx4minus2
297 - 2*fdeltaY*fTAlph)*v.
z()
298 + fa1md1*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z()));
299 c[5] = 4800*
300 fDy1*(fa1md1*(-5*phiyz - 24*fDz*v.
x() + 12*fdeltaX*v.
z()) +
301 fDy1*(20*phixz - 4*(5*fTAlph*phiyz + 24*fDz*fTAlph*v.
x()
302 + 24*fDz*v.
y()) + (48*fdeltaY + (fDx3plus1 + fDx4plus2)
303 *fPhiTwist + 48*fdeltaX*fTAlph)*v.
z()));
304 c[4] = 4800*
305 fDy1*(fa1md1*(phixz - 10*fDz*v.
y() + 5*fdeltaY*v.
z())
306 + 2*fDy1*(2*phiyz + 20*fDz*v.
x()
307 + (-10*fdeltaX + fDx3minus1 + fDx4minus2)*v.
z()
308 + 2*fTAlph*(phixz - 10*fDz*v.
y() + 5*fdeltaY*v.
z())));
309 c[3] = -96*
310 fDy1*(-(fa1md1*(phiyz + 100*fDz*v.
x() - 50*fdeltaX*v.
z()))
311 + fDy1*(4*phixz - 400*fDz*v.
y()
312 + (200*fdeltaY - (fDx3plus1 + fDx4plus2)*fPhiTwist)*v.
z()
313 - 4*fTAlph*(phiyz + 100*fDz*v.
x() - 50*fdeltaX*v.
z())));
314 c[2] = 32*
315 fDy1*(4*fDy1*(7*fTAlph*phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y())
316 + 6*fDy1*(2*fdeltaX+fDx3minus1+fDx4minus2-2*fdeltaY*fTAlph)*v.
z()
317 + fa1md1*(7*phixz + 6*fDz*v.
y() - 3*fdeltaY*v.
z()));
318 c[1] = -8*
319 fDy1*(fa1md1*(-9*phiyz - 56*fDz*v.
x() + 28*fdeltaX*v.
z())
320 + 4*fDy1*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x()
321 - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()));
322 c[0] = 72*
323 fDy1*(fa1md1*(2*fDz*v.
y() - fdeltaY*v.
z())
324 + fDy1*(-8*fDz*v.
x() + 8*fDz*fTAlph*v.
y()
325 + 4*fdeltaX*v.
z() - 4*fdeltaY*fTAlph*v.
z()));
326
327#ifdef G4TWISTDEBUG
328 G4cout <<
"coef = " << c[0] <<
" "
329 << c[1] << " "
330 << c[2] << " "
331 << c[3] << " "
332 << c[4] << " "
333 << c[5] << " "
334 << c[6] << " "
336#endif
337
340
341 for (
G4int i = 0 ; i<num ; i++ )
342 {
343 if ( si[i]==0.0 )
344 {
345#ifdef G4TWISTDEBUG
346 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
347#endif
348 phi = std::fmod(srd[i] , pihalf) ;
349 u = (fDy1*(4*(phiyz + 2*fDz*phi*v.
y() - fdeltaY*phi*v.
z())
350 - ((fDx3plus1 + fDx4plus2)*fPhiTwist
351 + 2*(fDx3minus1 + fDx4minus2)*phi)*v.
z()*std::sin(phi)))
352 /(fPhiTwist*v.
z()*(4*fDy1*std::cos(phi)
353 + (fa1md1 + 4*fDy1*fTAlph)*std::sin(phi)));
359
360 xbuf.push_back(xbuftmp) ;
361
362#ifdef G4TWISTDEBUG
363 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
364#endif
365 }
366 }
367 }
368
369 nxx = (
G4int)xbuf.size() ;
370
377
378 for (auto & k : xbuf)
379 {
380#ifdef G4TWISTDEBUG
381 G4cout <<
"Solution " << k <<
" : "
382 << "reconstructed phiR = " << xbuf[k].phi
383 <<
", uR = " << xbuf[k].u <<
G4endl ;
384#endif
385
386 phi = k.phi ;
387 u = k.u ;
388
389 IsConverged = false ;
390
391 for (
G4int i = 1 ; i<maxint ; ++i )
392 {
393 xxonsurface = SurfacePoint(phi,u) ;
394 surfacenormal = NormAng(phi,u) ;
395
397 deltaX = ( tmpxx - xxonsurface ).mag() ;
398 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
399 if ( theta < 0.001 )
400 {
401 factor = 50 ;
402 IsParallel = true ;
403 }
404 else
405 {
406 factor = 1 ;
407 }
408
409#ifdef G4TWISTDEBUG
410 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist
411 <<
", " << deltaX <<
G4endl ;
413#endif
414
415 GetPhiUAtX(tmpxx, phi, u) ;
416
417
418#ifdef G4TWISTDEBUG
419 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
420#endif
421
422 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
423
424 }
425
426 if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0 ; }
427
428#ifdef G4TWISTDEBUG
429 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
432#endif
433
434 tmpisvalid = false ;
435
436 if ( IsConverged )
437 {
439 {
440 tmpareacode = GetAreaCode(tmpxx);
442 {
443 if (tmpdist >= 0) tmpisvalid = true;
444 }
445 }
447 {
448 tmpareacode = GetAreaCode(tmpxx, false);
450 {
451 if (tmpdist >= 0) { tmpisvalid = true; }
452 }
453 }
454 else
455 {
456 G4Exception(
"G4TwistTrapAlphaSide::DistanceToSurface()",
458 "Feature NOT implemented !");
459 }
460 }
461 else
462 {
463 tmpdist = kInfinity;
464 tmpisvalid = false ;
465 }
466
467
468
469 k.xx = tmpxx ;
470 k.distance = tmpdist ;
471 k.areacode = tmpareacode ;
472 k.isvalid = tmpisvalid ;
473
474 }
475
477
478#ifdef G4TWISTDEBUG
481#endif
482
483
484
486 xbuf.end() );
487
488
489
490
491 auto nxxtmp = (
G4int)xbuf.size() ;
492
493 if ( nxxtmp<2 || IsParallel )
494 {
495
496#ifdef G4TWISTDEBUG
498#endif
499
500 phi = fPhiTwist/2 ;
501 u = 0 ;
502
508
509 xbuf.push_back(xbuftmp) ;
510
511#ifdef G4TWISTDEBUG
513#endif
514
515 phi = -fPhiTwist/2 ;
516 u = 0 ;
517
523
524 xbuf.push_back(xbuftmp) ;
525
526 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
527 {
528
529#ifdef G4TWISTDEBUG
530 G4cout <<
"Solution " << k <<
" : "
531 << "reconstructed phiR = " << xbuf[k].phi
532 <<
", uR = " << xbuf[k].u <<
G4endl ;
533#endif
534
535 phi = xbuf[k].phi ;
536 u = xbuf[k].u ;
537
538 IsConverged = false ;
539
540 for (
G4int i = 1 ; i<maxint ; ++i )
541 {
542 xxonsurface = SurfacePoint(phi,u) ;
543 surfacenormal = NormAng(phi,u) ;
545 deltaX = ( tmpxx - xxonsurface ).mag();
546 theta = std::fabs(std::acos(v*surfacenormal) - pihalf);
547 if ( theta < 0.001 )
548 {
549 factor = 50 ;
550 }
551 else
552 {
553 factor = 1 ;
554 }
555
556#ifdef G4TWISTDEBUG
557 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist
558 <<
", " << deltaX <<
G4endl
559 <<
"X = " << tmpxx <<
G4endl ;
560#endif
561
562 GetPhiUAtX(tmpxx, phi, u) ;
563
564
565#ifdef G4TWISTDEBUG
566 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
567#endif
568
569 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
570
571 }
572
573 if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0; }
574
575#ifdef G4TWISTDEBUG
576 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
579#endif
580
581 tmpisvalid = false ;
582
583 if ( IsConverged )
584 {
586 {
587 tmpareacode = GetAreaCode(tmpxx);
589 {
590 if (tmpdist >= 0) { tmpisvalid = true; }
591 }
592 }
594 {
595 tmpareacode = GetAreaCode(tmpxx, false);
597 {
598 if (tmpdist >= 0) { tmpisvalid = true; }
599 }
600 }
601 else
602 {
603 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
605 "Feature NOT implemented !");
606 }
607 }
608 else
609 {
610 tmpdist = kInfinity;
611 tmpisvalid = false ;
612 }
613
614
615
616 xbuf[k].xx = tmpxx ;
617 xbuf[k].distance = tmpdist ;
618 xbuf[k].areacode = tmpareacode ;
619 xbuf[k].isvalid = tmpisvalid ;
620
621 }
622 }
623
624
626
627
629 xbuf.end() );
630
631#ifdef G4TWISTDEBUG
634#endif
635
636 nxx = (
G4int)xbuf.size() ;
637
638 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
639 {
640 distance[i] = xbuf[i].distance;
642 areacode[i] = xbuf[i].areacode ;
643 isvalid[i] = xbuf[i].isvalid ;
644
646 isvalid[i], nxx, validate, &gp, &gv);
647#ifdef G4TWISTDEBUG
648 G4cout <<
"element Nr. " << i
649 << ", local Intersection = " << xbuf[i].xx
650 << ", distance = " << xbuf[i].distance
651 << ", u = " << xbuf[i].u
652 << ", phi = " << xbuf[i].phi
653 << ", isvalid = " << xbuf[i].isvalid
655#endif
656
657 }
658
659#ifdef G4TWISTDEBUG
661 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
662 for (
G4int k= 0 ; k< nxx ; k++ )
663 {
664 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
667 }
668#endif
669
670 return nxx ;
671}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4bool DistanceSort(const Intersection &a, const Intersection &b)
G4bool EqualIntersection(const Intersection &a, const Intersection &b)
G4GLOB_DLL std::ostream G4cout
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)
G4int GetAreacode(G4int i) const
G4double GetDistance(G4int i) const
G4bool IsValid(G4int i) const
void SetCurrentStatus(G4int i, G4ThreeVector &xx, G4double &dist, G4int &areacode, G4bool &isvalid, G4int nxx, EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=nullptr)
G4ThreeVector GetXX(G4int i) const
void ResetfDone(EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=nullptr)
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