207{
208
211
212 G4bool IsParallel = false ;
213 G4bool IsConverged = false ;
214
216
218
226 }
228 } else {
229
230
233 distance[i] = kInfinity;
235 isvalid[i] = false;
236 gxx[i].
set(kInfinity, kInfinity, kInfinity);
237 }
238 }
239
242
243#ifdef G4TWISTDEBUG
246#endif
247
249
250
251
255 G4bool tmpisvalid = false ;
256
257 std::vector<Intersection> xbuf ;
259
260
261
263
264 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
265 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
266
267
268
270
271 if ( (std::fabs(p.
z()) <= L) && fPhiTwist ) {
272
273 phi = p.
z() * fPhiTwist / L ;
274
275 q = (2.* fPhiTwist*((v.
x() - fTAlph*v.
y())*std::cos(phi)
276 + (fTAlph*v.
x() + v.
y())*std::sin(phi)));
277
278 if (q) {
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 }
284
290
291 xbuf.push_back(xbuftmp) ;
292
293 }
294
295 else {
296
297 distance[0] = kInfinity;
298 gxx[0].
set(kInfinity,kInfinity,kInfinity);
299 isvalid[0] = false ;
302 areacode[0], isvalid[0],
303 0, validate, &gp, &gv);
304
305 return 0;
306
307
308 }
309
310 }
311
312
313
314
315 else {
316
318
319 c[7] = -14400*(-2*phixz + 2*fTAlph*phiyz + fDx4plus2*fPhiTwist*v.
z()) ;
320 c[6] = 28800*(phiyz + 2*fDz*v.
x() - (fdeltaX + fDx4minus2)*v.
z() + fTAlph*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z())) ;
321 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())) ;
322 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())) ;
323 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())) ;
324 c[2] = -16*(7*fTAlph* phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y() + 3*(fdeltaX + fDx4minus2 - fdeltaY*fTAlph)*v.
z()) ;
325 c[1] = 4*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x() - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()) ;
326 c[0] = 36*(2* fDz*(v.
x() - fTAlph*v.
y()) - fdeltaX*v.
z() + fdeltaY*fTAlph*v.
z()) ;
327
328
329#ifdef G4TWISTDEBUG
330 G4cout <<
"coef = " << c[0] <<
" "
331 << c[1] << " "
332 << c[2] << " "
333 << c[3] << " "
334 << c[4] << " "
335 << c[5] << " "
336 << c[6] << " "
338#endif
339
342
343
344 for (
G4int i = 0 ; i<num ; i++ ) {
345 if ( (si[i]==0.0) && fPhiTwist ) {
346#ifdef G4TWISTDEBUG
347 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
348#endif
349 phi = std::fmod(srd[i] , pihalf) ;
350
351 u = (2*phiyz + 4*fDz*phi*v.
y() - 2*fdeltaY*phi*v.
z()
352 - fDx4plus2*fPhiTwist*v.
z()*std::sin(phi)
353 - 2*fDx4minus2*phi*v.
z()*std::sin(phi))
354 /(2*fPhiTwist*v.
z()*std::cos(phi)
355 + 2*fPhiTwist*fTAlph*v.
z()*std::sin(phi)) ;
356
362
363 xbuf.push_back(xbuftmp) ;
364
365#ifdef G4TWISTDEBUG
366 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
367#endif
368
369 }
370 }
371
372 }
373
374
375 nxx = xbuf.size() ;
376
383
384
385 for ( size_t k = 0 ; k<xbuf.size() ; k++ ) {
386
387#ifdef G4TWISTDEBUG
388 G4cout <<
"Solution " << k <<
" : "
389 << "reconstructed phiR = " << xbuf[k].phi
390 <<
", uR = " << xbuf[k].u <<
G4endl ;
391#endif
392
393 phi = xbuf[k].phi ;
394 u = xbuf[k].u ;
395
396 IsConverged = false ;
397
398 for (
G4int i = 1 ; i<maxint ; i++ ) {
399
400 xxonsurface = SurfacePoint(phi,u) ;
401 surfacenormal = NormAng(phi,u) ;
403 deltaX = ( tmpxx - xxonsurface ).mag() ;
404 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
405 if ( theta < 0.001 ) {
406 factor = 50 ;
407 IsParallel = true ;
408 }
409 else {
410 factor = 1 ;
411 }
412
413#ifdef G4TWISTDEBUG
414 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
416#endif
417
418 GetPhiUAtX(tmpxx, phi, u) ;
419
420#ifdef G4TWISTDEBUG
421 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
422#endif
423
424 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
425
426 }
427
428
429
430 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
431
432#ifdef G4TWISTDEBUG
433 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
436#endif
437
438 tmpisvalid = false ;
439
440 if ( IsConverged ) {
441
443 tmpareacode = GetAreaCode(tmpxx);
445 if (tmpdist >= 0) tmpisvalid = true;
446 }
448 tmpareacode = GetAreaCode(tmpxx, false);
450 if (tmpdist >= 0) tmpisvalid = true;
451 }
452 } else {
455 "Feature NOT implemented !");
456 }
457
458 }
459 else {
460 tmpdist = kInfinity;
461 tmpisvalid = false ;
462 }
463
464
465
466 xbuf[k].xx = tmpxx ;
467 xbuf[k].distance = tmpdist ;
468 xbuf[k].areacode = tmpareacode ;
469 xbuf[k].isvalid = tmpisvalid ;
470
471
472 }
473
474
476
477#ifdef G4TWISTDEBUG
480#endif
481
482
483
484 xbuf.erase( std::unique(xbuf.begin(), xbuf.end() ,
EqualIntersection ) , xbuf.end() ) ;
485
486
487
488
489 G4int nxxtmp = xbuf.size() ;
490
491 if ( nxxtmp<2 || IsParallel ) {
492
493
494#ifdef G4TWISTDEBUG
496#endif
497
498 phi = fPhiTwist/2 ;
499 u = 0 ;
500
501
502
508
509 xbuf.push_back(xbuftmp) ;
510
511
512#ifdef G4TWISTDEBUG
514#endif
515
516 phi = -fPhiTwist/2 ;
517 u = 0 ;
518
524
525 xbuf.push_back(xbuftmp) ;
526
527 for ( size_t k = nxxtmp ; k<xbuf.size() ; k++ ) {
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 factor = 50 ;
549 }
550 else {
551 factor = 1 ;
552 }
553
554#ifdef G4TWISTDEBUG
555 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
557#endif
558
559 GetPhiUAtX(tmpxx, phi, u) ;
560
561#ifdef G4TWISTDEBUG
562 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
563#endif
564
565 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
566
567 }
568
569
570
571 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
572
573#ifdef G4TWISTDEBUG
574 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
577#endif
578
579 tmpisvalid = false ;
580
581 if ( IsConverged ) {
582
584 tmpareacode = GetAreaCode(tmpxx);
586 if (tmpdist >= 0) tmpisvalid = true;
587 }
589 tmpareacode = GetAreaCode(tmpxx, false);
591 if (tmpdist >= 0) tmpisvalid = true;
592 }
593 } else {
594 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
596 "Feature NOT implemented !");
597 }
598
599 }
600 else {
601 tmpdist = kInfinity;
602 tmpisvalid = false ;
603 }
604
605
606
607 xbuf[k].xx = tmpxx ;
608 xbuf[k].distance = tmpdist ;
609 xbuf[k].areacode = tmpareacode ;
610 xbuf[k].isvalid = tmpisvalid ;
611
612
613 }
614
615
616 }
617
618
619
621
622
623 xbuf.erase( std::unique(xbuf.begin(), xbuf.end() ,
EqualIntersection ) , xbuf.end() ) ;
624
625#ifdef G4TWISTDEBUG
628#endif
629
630 nxx = xbuf.size() ;
631
632 for ( size_t i = 0 ; i<xbuf.size() ; i++ ) {
633
634 distance[i] = xbuf[i].distance;
636 areacode[i] = xbuf[i].areacode ;
637 isvalid[i] = xbuf[i].isvalid ;
638
640 isvalid[i], nxx, validate, &gp, &gv);
641
642#ifdef G4TWISTDEBUG
643 G4cout <<
"element Nr. " << i
644 << ", local Intersection = " << xbuf[i].xx
645 << ", distance = " << xbuf[i].distance
646 << ", u = " << xbuf[i].u
647 << ", phi = " << xbuf[i].phi
648 << ", isvalid = " << xbuf[i].isvalid
650#endif
651
652 }
653
654
655#ifdef G4TWISTDEBUG
657 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
658 for (
G4int k= 0 ; k< nxx ; k++ ) {
659 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
662 }
663#endif
664
665 return nxx ;
666
667}
G4bool DistanceSort(const Intersection &a, const Intersection &b)
G4bool EqualIntersection(const Intersection &a, const Intersection &b)
G4DLLIMPORT std::ostream G4cout
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)
G4int GetAreacode(G4int i) const
G4double GetDistance(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=0)
G4bool IsValid(G4int i) const
G4ThreeVector GetXX(G4int i) const
void ResetfDone(EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=0)
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