Returns the distance to surface, given point 'gp' and direction 'gv'.
194{
195
198
199 G4bool IsParallel = false ;
200 G4bool IsConverged = false ;
201
203
205
207 {
209 {
214 }
216 }
217
218
220 {
221 distance[i] = kInfinity;
223 isvalid[i] = false;
224 gxx[i].
set(kInfinity, kInfinity, kInfinity);
225 }
226
229
230#ifdef G4TWISTDEBUG
233#endif
234
236
237
238
242 G4bool tmpisvalid = false ;
243
244 std::vector<Intersection> xbuf ;
245 Intersection xbuftmp ;
246
247
248
250
251 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
252 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
253
254
255
257 {
258 if ( (std::fabs(p.
z()) <= L) && (fPhiTwist != 0.0) )
259 {
260 phi = p.
z() * fPhiTwist / L ;
261
262 q = (2.* fPhiTwist*((v.
x() - fTAlph*v.
y())*std::cos(phi)
263 + (fTAlph*v.
x() + v.
y())*std::sin(phi)));
264
265 if (q != 0.0)
266 {
267 u = (2*(-(fdeltaY*phi*v.
x()) + fPhiTwist*p.
y()*v.
x()
268 + fdeltaX*phi*v.
y() - fPhiTwist*p.
x()*v.
y())
269 + (fDx4plus2*fPhiTwist + 2*fDx4minus2*phi)
270 * (v.
y()*std::cos(phi) - v.
x()*std::sin(phi))) / q;
271 }
272 xbuftmp.phi = phi ;
273 xbuftmp.u = u ;
275 xbuftmp.distance = kInfinity ;
276 xbuftmp.isvalid = false ;
277
278 xbuf.push_back(xbuftmp) ;
279 }
280 else
281 {
282 distance[0] = kInfinity;
283 gxx[0].
set(kInfinity,kInfinity,kInfinity);
284 isvalid[0] = false ;
287 areacode[0], isvalid[0],
288 0, validate, &gp, &gv);
289
290 return 0;
291 }
292 }
293 else
294 {
296
297 c[7] = -14400*(-2*phixz + 2*fTAlph*phiyz + fDx4plus2*fPhiTwist*v.
z()) ;
298 c[6] = 28800*(phiyz + 2*fDz*v.
x() - (fdeltaX + fDx4minus2)*v.
z() + fTAlph*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z())) ;
299 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())) ;
300 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())) ;
301 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())) ;
302 c[2] = -16*(7*fTAlph* phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y() + 3*(fdeltaX + fDx4minus2 - fdeltaY*fTAlph)*v.
z()) ;
303 c[1] = 4*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x() - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()) ;
304 c[0] = 36*(2* fDz*(v.
x() - fTAlph*v.
y()) - fdeltaX*v.
z() + fdeltaY*fTAlph*v.
z()) ;
305
306#ifdef G4TWISTDEBUG
307 G4cout <<
"coef = " << c[0] <<
" "
308 << c[1] << " "
309 << c[2] << " "
310 << c[3] << " "
311 << c[4] << " "
312 << c[5] << " "
313 << c[6] << " "
315#endif
316
317 G4JTPolynomialSolver trapEq ;
319
320 for (
G4int i = 0 ; i<num ; ++i )
321 {
322 if ( (si[i]==0.0) && (fPhiTwist != 0.0) )
323 {
324#ifdef G4TWISTDEBUG
325 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
326#endif
327 phi = std::fmod(srd[i], pihalf) ;
328
329 u = (2*phiyz + 4*fDz*phi*v.
y() - 2*fdeltaY*phi*v.
z()
330 - fDx4plus2*fPhiTwist*v.
z()*std::sin(phi)
331 - 2*fDx4minus2*phi*v.
z()*std::sin(phi))
332 /(2*fPhiTwist*v.
z()*std::cos(phi)
333 + 2*fPhiTwist*fTAlph*v.
z()*std::sin(phi)) ;
334
335 xbuftmp.phi = phi ;
336 xbuftmp.u = u ;
338 xbuftmp.distance = kInfinity ;
339 xbuftmp.isvalid = false ;
340
341 xbuf.push_back(xbuftmp) ;
342
343#ifdef G4TWISTDEBUG
344 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
345#endif
346 }
347 }
348 }
349
350
351 nxx = (
G4int)xbuf.size() ;
352
356
360
361
362 for (auto & k : xbuf)
363 {
364#ifdef G4TWISTDEBUG
365 G4cout <<
"Solution " << k <<
" : "
366 << "reconstructed phiR = " << xbuf[k].phi
367 <<
", uR = " << xbuf[k].u <<
G4endl ;
368#endif
369
370 phi = k.phi ;
371 u = k.u ;
372
373 IsConverged = false ;
374
375 for (
G4int i = 1 ; i<maxint ; ++i )
376 {
377 xxonsurface = SurfacePoint(phi,u) ;
378 surfacenormal = NormAng(phi,u) ;
380 deltaX = ( tmpxx - xxonsurface ).mag() ;
381 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
382 if ( theta < 0.001 )
383 {
384 factor = 50 ;
385 IsParallel = true ;
386 }
387 else
388 {
389 factor = 1 ;
390 }
391
392#ifdef G4TWISTDEBUG
393 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
395#endif
396
397 GetPhiUAtX(tmpxx, phi, u) ;
398
399#ifdef G4TWISTDEBUG
400 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
401#endif
402
403 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
404
405 }
406
407 if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0. ; }
408
409#ifdef G4TWISTDEBUG
410 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
413#endif
414
415 tmpisvalid = false ;
416
417 if ( IsConverged )
418 {
420 {
421 tmpareacode = GetAreaCode(tmpxx);
423 {
424 if (tmpdist >= 0) { tmpisvalid = true; }
425 }
426 }
428 {
429 tmpareacode = GetAreaCode(tmpxx, false);
431 {
432 if (tmpdist >= 0) { tmpisvalid = true; }
433 }
434 }
435 else
436 {
439 "Feature NOT implemented !");
440 }
441 }
442 else
443 {
444 tmpdist = kInfinity;
445 tmpisvalid = false ;
446 }
447
448
449 k.xx = tmpxx ;
450 k.distance = tmpdist ;
451 k.areacode = tmpareacode ;
452 k.isvalid = tmpisvalid ;
453
454 }
455
456 std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;
457
458#ifdef G4TWISTDEBUG
461#endif
462
463
464 xbuf.erase(std::unique(xbuf.begin(),xbuf.end(),EqualIntersection),xbuf.end());
465
466
467
468 auto nxxtmp = (
G4int)xbuf.size() ;
469
470 if ( nxxtmp<2 || IsParallel )
471 {
472
473#ifdef G4TWISTDEBUG
475#endif
476
477 phi = fPhiTwist/2 ;
478 u = 0. ;
479 xbuftmp.phi = phi ;
480 xbuftmp.u = u ;
482 xbuftmp.distance = kInfinity ;
483 xbuftmp.isvalid = false ;
484
485 xbuf.push_back(xbuftmp) ;
486
487#ifdef G4TWISTDEBUG
489#endif
490
491 phi = -fPhiTwist/2 ;
492 u = 0. ;
493
494 xbuftmp.phi = phi ;
495 xbuftmp.u = u ;
497 xbuftmp.distance = kInfinity ;
498 xbuftmp.isvalid = false ;
499
500 xbuf.push_back(xbuftmp) ;
501
502 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
503 {
504#ifdef G4TWISTDEBUG
505 G4cout <<
"Solution " << k <<
" : "
506 << "reconstructed phiR = " << xbuf[k].phi
507 <<
", uR = " << xbuf[k].u <<
G4endl ;
508#endif
509
510 phi = xbuf[k].phi ;
511 u = xbuf[k].u ;
512
513 IsConverged = false ;
514
515 for (
G4int i = 1 ; i<maxint ; ++i )
516 {
517 xxonsurface = SurfacePoint(phi,u) ;
518 surfacenormal = NormAng(phi,u) ;
520 deltaX = ( tmpxx - xxonsurface ).mag() ;
521 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
522 if ( theta < 0.001 )
523 {
524 factor = 50 ;
525 }
526 else
527 {
528 factor = 1 ;
529 }
530
531#ifdef G4TWISTDEBUG
532 G4cout <<
"Step i = " << i <<
", distance = "
533 << tmpdist <<
", " << deltaX <<
G4endl ;
535#endif
536
537 GetPhiUAtX(tmpxx, phi, u) ;
538
539
540#ifdef G4TWISTDEBUG
541 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
542#endif
543
544 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
545
546 }
547
548 if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0. ; }
549
550#ifdef G4TWISTDEBUG
551 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
554#endif
555
556 tmpisvalid = false ;
557
558 if ( IsConverged )
559 {
561 {
562 tmpareacode = GetAreaCode(tmpxx);
564 {
565 if (tmpdist >= 0) { tmpisvalid = true; }
566 }
567 }
569 {
570 tmpareacode = GetAreaCode(tmpxx, false);
572 {
573 if (tmpdist >= 0) { tmpisvalid = true; }
574 }
575 }
576 else
577 {
578 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
580 "Feature NOT implemented !");
581 }
582 }
583 else
584 {
585 tmpdist = kInfinity;
586 tmpisvalid = false ;
587 }
588
589
590 xbuf[k].xx = tmpxx ;
591 xbuf[k].distance = tmpdist ;
592 xbuf[k].areacode = tmpareacode ;
593 xbuf[k].isvalid = tmpisvalid ;
594 }
595 }
596
597
598 std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;
599
600
601 xbuf.erase(std::unique(xbuf.begin(),xbuf.end(),EqualIntersection),xbuf.end());
602
603#ifdef G4TWISTDEBUG
606#endif
607
608 nxx = (
G4int)xbuf.size() ;
609
610 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
611 {
612 distance[i] = xbuf[i].distance;
614 areacode[i] = xbuf[i].areacode ;
615 isvalid[i] = xbuf[i].isvalid ;
616
617 fCurStatWithV.SetCurrentStatus(i, gxx[i], distance[i], areacode[i],
618 isvalid[i], nxx, validate, &gp, &gv);
619
620#ifdef G4TWISTDEBUG
621 G4cout <<
"element Nr. " << i
622 << ", local Intersection = " << xbuf[i].xx
623 << ", distance = " << xbuf[i].distance
624 << ", u = " << xbuf[i].u
625 << ", phi = " << xbuf[i].phi
626 << ", isvalid = " << xbuf[i].isvalid
628#endif
629
630 }
631
632#ifdef G4TWISTDEBUG
634 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
635 for (
G4int k= 0 ; k< nxx ; ++k )
636 {
637 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
640 }
641#endif
642
643 return nxx ;
644}
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