205{
206
209
210 G4bool IsParallel = false ;
211 G4bool IsConverged = false ;
212
214
216
218 {
220 {
225 }
227 }
228 else
229 {
231 {
232 distance[i] = kInfinity;
234 isvalid[i] = false;
235 gxx[i].
set(kInfinity, kInfinity, kInfinity);
236 }
237 }
238
241
242#ifdef G4TWISTDEBUG
245#endif
246
248
249
250
254 G4bool tmpisvalid = false ;
255
256 std::vector<Intersection> xbuf ;
258
259
260
262
263 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
264 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
265
266
267
269 {
270 if ( (std::fabs(p.
z()) <=
L) && fPhiTwist )
271 {
272 phi = p.
z() * fPhiTwist /
L ;
273
274 q = (2.* fPhiTwist*((v.
x() - fTAlph*v.
y())*std::cos(phi)
275 + (fTAlph*v.
x() + v.
y())*std::sin(phi)));
276
277 if (q)
278 {
279 u = (2*(-(fdeltaY*phi*v.
x()) + fPhiTwist*p.
y()*v.
x()
280 + fdeltaX*phi*v.
y() - fPhiTwist*p.
x()*v.
y())
281 + (fDx4plus2*fPhiTwist + 2*fDx4minus2*phi)
282 * (v.
y()*std::cos(phi) - v.
x()*std::sin(phi))) / q;
283 }
289
290 xbuf.push_back(xbuftmp) ;
291 }
292 else
293 {
294 distance[0] = kInfinity;
295 gxx[0].
set(kInfinity,kInfinity,kInfinity);
296 isvalid[0] = false ;
299 areacode[0], isvalid[0],
300 0, validate, &gp, &gv);
301
302 return 0;
303 }
304 }
305 else
306 {
308
309 c[7] = -14400*(-2*phixz + 2*fTAlph*phiyz + fDx4plus2*fPhiTwist*v.
z()) ;
310 c[6] = 28800*(phiyz + 2*fDz*v.
x() - (fdeltaX + fDx4minus2)*v.
z() + fTAlph*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z())) ;
311 c[5] = -1200*(10*phixz - 48*fDz*v.
y() + 24*fdeltaY*v.
z() + fDx4plus2*fPhiTwist*v.
z() - 2*fTAlph*(5*phiyz + 24*fDz*v.
x() - 12*fdeltaX*v.
z())) ;
312 c[4] = -2400*(phiyz + 10*fDz*v.
x() - 5*fdeltaX*v.
z() + fDx4minus2*v.
z() + fTAlph*(phixz - 10*fDz*v.
y() + 5*fdeltaY*v.
z())) ;
313 c[3] = 24*(2*phixz - 200*fDz*v.
y() + 100*fdeltaY*v.
z() - fDx4plus2*fPhiTwist*v.
z() - 2*fTAlph*(phiyz + 100*fDz*v.
x() - 50*fdeltaX*v.
z())) ;
314 c[2] = -16*(7*fTAlph* phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y() + 3*(fdeltaX + fDx4minus2 - fdeltaY*fTAlph)*v.
z()) ;
315 c[1] = 4*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x() - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()) ;
316 c[0] = 36*(2* fDz*(v.
x() - fTAlph*v.
y()) - fdeltaX*v.
z() + fdeltaY*fTAlph*v.
z()) ;
317
318#ifdef G4TWISTDEBUG
319 G4cout <<
"coef = " << c[0] <<
" "
320 << c[1] << " "
321 << c[2] << " "
322 << c[3] << " "
323 << c[4] << " "
324 << c[5] << " "
325 << c[6] << " "
327#endif
328
331
332 for (
G4int i = 0 ; i<num ; ++i )
333 {
334 if ( (si[i]==0.0) && fPhiTwist )
335 {
336#ifdef G4TWISTDEBUG
337 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
338#endif
339 phi = std::fmod(srd[i], pihalf) ;
340
341 u = (2*phiyz + 4*fDz*phi*v.
y() - 2*fdeltaY*phi*v.
z()
342 - fDx4plus2*fPhiTwist*v.
z()*std::sin(phi)
343 - 2*fDx4minus2*phi*v.
z()*std::sin(phi))
344 /(2*fPhiTwist*v.
z()*std::cos(phi)
345 + 2*fPhiTwist*fTAlph*v.
z()*std::sin(phi)) ;
346
352
353 xbuf.push_back(xbuftmp) ;
354
355#ifdef G4TWISTDEBUG
356 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
357#endif
358 }
359 }
360 }
361
362
363 nxx = (
G4int)xbuf.size() ;
364
368
372
373
374 for ( std::size_t k = 0 ; k<xbuf.size() ; ++k )
375 {
376#ifdef G4TWISTDEBUG
377 G4cout <<
"Solution " << k <<
" : "
378 << "reconstructed phiR = " << xbuf[k].phi
379 <<
", uR = " << xbuf[k].u <<
G4endl ;
380#endif
381
382 phi = xbuf[k].phi ;
383 u = xbuf[k].u ;
384
385 IsConverged = false ;
386
387 for (
G4int i = 1 ; i<maxint ; ++i )
388 {
389 xxonsurface = SurfacePoint(phi,u) ;
390 surfacenormal = NormAng(phi,u) ;
392 deltaX = ( tmpxx - xxonsurface ).mag() ;
393 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
394 if ( theta < 0.001 )
395 {
396 factor = 50 ;
397 IsParallel = true ;
398 }
399 else
400 {
401 factor = 1 ;
402 }
403
404#ifdef G4TWISTDEBUG
405 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
407#endif
408
409 GetPhiUAtX(tmpxx, phi, u) ;
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 {
451 "Feature NOT implemented !");
452 }
453 }
454 else
455 {
456 tmpdist = kInfinity;
457 tmpisvalid = false ;
458 }
459
460
461 xbuf[k].xx = tmpxx ;
462 xbuf[k].distance = tmpdist ;
463 xbuf[k].areacode = tmpareacode ;
464 xbuf[k].isvalid = tmpisvalid ;
465
466 }
467
469
470#ifdef G4TWISTDEBUG
473#endif
474
475
477
478
479
481
482 if ( nxxtmp<2 || IsParallel )
483 {
484
485#ifdef G4TWISTDEBUG
487#endif
488
489 phi = fPhiTwist/2 ;
490 u = 0. ;
496
497 xbuf.push_back(xbuftmp) ;
498
499#ifdef G4TWISTDEBUG
501#endif
502
503 phi = -fPhiTwist/2 ;
504 u = 0. ;
505
511
512 xbuf.push_back(xbuftmp) ;
513
514 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
515 {
516#ifdef G4TWISTDEBUG
517 G4cout <<
"Solution " << k <<
" : "
518 << "reconstructed phiR = " << xbuf[k].phi
519 <<
", uR = " << xbuf[k].u <<
G4endl ;
520#endif
521
522 phi = xbuf[k].phi ;
523 u = xbuf[k].u ;
524
525 IsConverged = false ;
526
527 for (
G4int i = 1 ; i<maxint ; ++i )
528 {
529 xxonsurface = SurfacePoint(phi,u) ;
530 surfacenormal = NormAng(phi,u) ;
532 deltaX = ( tmpxx - xxonsurface ).mag() ;
533 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
534 if ( theta < 0.001 )
535 {
536 factor = 50 ;
537 }
538 else
539 {
540 factor = 1 ;
541 }
542
543#ifdef G4TWISTDEBUG
544 G4cout <<
"Step i = " << i <<
", distance = "
545 << tmpdist <<
", " << deltaX <<
G4endl ;
547#endif
548
549 GetPhiUAtX(tmpxx, phi, u) ;
550
551
552#ifdef G4TWISTDEBUG
553 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
554#endif
555
556 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
557
558 }
559
560 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
561
562#ifdef G4TWISTDEBUG
563 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
566#endif
567
568 tmpisvalid = false ;
569
570 if ( IsConverged )
571 {
573 {
574 tmpareacode = GetAreaCode(tmpxx);
576 {
577 if (tmpdist >= 0) tmpisvalid = true;
578 }
579 }
581 {
582 tmpareacode = GetAreaCode(tmpxx, false);
584 {
585 if (tmpdist >= 0) tmpisvalid = true;
586 }
587 }
588 else
589 {
590 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
592 "Feature NOT implemented !");
593 }
594 }
595 else
596 {
597 tmpdist = kInfinity;
598 tmpisvalid = false ;
599 }
600
601
602 xbuf[k].xx = tmpxx ;
603 xbuf[k].distance = tmpdist ;
604 xbuf[k].areacode = tmpareacode ;
605 xbuf[k].isvalid = tmpisvalid ;
606 }
607 }
608
609
611
612
614
615#ifdef G4TWISTDEBUG
618#endif
619
620 nxx = (
G4int)xbuf.size() ;
621
622 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
623 {
624 distance[i] = xbuf[i].distance;
626 areacode[i] = xbuf[i].areacode ;
627 isvalid[i] = xbuf[i].isvalid ;
628
630 isvalid[i], nxx, validate, &gp, &gv);
631
632#ifdef G4TWISTDEBUG
633 G4cout <<
"element Nr. " << i
634 << ", local Intersection = " << xbuf[i].xx
635 << ", distance = " << xbuf[i].distance
636 << ", u = " << xbuf[i].u
637 << ", phi = " << xbuf[i].phi
638 << ", isvalid = " << xbuf[i].isvalid
640#endif
641
642 }
643
644#ifdef G4TWISTDEBUG
646 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
647 for (
G4int k= 0 ; k< nxx ; ++k )
648 {
649 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
652 }
653#endif
654
655 return nxx ;
656}
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