196{
197
200
201 G4bool IsParallel = false ;
202 G4bool IsConverged = false ;
203
205
207
215 }
217 } else {
218
219
222 distance[i] = kInfinity;
224 isvalid[i] = false;
225 gxx[i].
set(kInfinity, kInfinity, kInfinity);
226 }
227 }
228
231
232#ifdef G4TWISTDEBUG
235#endif
236
238
239
240
244 G4bool tmpisvalid = false ;
245
246 std::vector<Intersection> xbuf ;
248
249
250
252
253 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
254 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
255
256
257
259
260 if ( std::fabs(p.
z()) <= L ) {
261
262 phi = p.
z() * fPhiTwist / L ;
263
264 u = (2*(fdeltaY*phi*v.
x() - fPhiTwist*p.
y()*v.
x() - fdeltaX*phi*v.
y() + fPhiTwist*p.
x()*v.
y()) + (fDy2plus1*fPhiTwist + 2*fDy2minus1*phi)*(v.
x()*std::cos(phi) + v.
y()*std::sin(phi)))/(2.* fPhiTwist*(v.
y()*std::cos(phi) - v.
x()*std::sin(phi))) ;
265
271
272 xbuf.push_back(xbuftmp) ;
273
274 }
275
276 else {
277
278 distance[0] = kInfinity;
279 gxx[0].
set(kInfinity,kInfinity,kInfinity);
280 isvalid[0] = false ;
283 areacode[0], isvalid[0],
284 0, validate, &gp, &gv);
285
286 return 0;
287
288
289 }
290
291 }
292
293
294
295
296 else {
297
299
300 c[8] = -3600*(-2*phiyz + fDy2plus1*fPhiTwist*v.
z()) ;
301 c[7] = -7200*(phixz - 2*fDz*v.
y() + (fdeltaY + fDy2minus1)*v.
z()) ;
302 c[6] = 120*(-52*phiyz - 120*fDz*v.
x() + 60*fdeltaX*v.
z() + 11*fDy2plus1*fPhiTwist*v.
z()) ;
303 c[5] = 240*(16*phixz - 52*fDz*v.
y() + 26*fdeltaY*v.
z() + 11*fDy2minus1*v.
z()) ;
304 c[4] = 12*(127*phiyz + 640*fDz*v.
x() - 320*fdeltaX*v.
z() + 4*fDy2plus1*fPhiTwist*v.
z()) ;
305 c[3] = -404*phixz + 3048*fDz*v.
y() - 1524*fdeltaY*v.
z() + 96*fDy2minus1*v.
z() ;
306 c[2] = -72*phiyz + 404*(-2*fDz*v.
x() + fdeltaX*v.
z()) ;
307 c[1] = 12*(phixz - 12*fDz*v.
y() + 6*fdeltaY*v.
z()) ;
308 c[0] = 24*fDz*v.
x() - 12*fdeltaX*v.
z() ;
309
310
311#ifdef G4TWISTDEBUG
312 G4cout <<
"coef = " << c[0] <<
" "
313 << c[1] << " "
314 << c[2] << " "
315 << c[3] << " "
316 << c[4] << " "
317 << c[5] << " "
318 << c[6] << " "
319 << c[7] << " "
321#endif
322
325
326
327 for (
G4int i = 0 ; i<num ; i++ ) {
328 if ( si[i]==0.0 ) {
329#ifdef G4TWISTDEBUG
330 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
331#endif
332 phi = std::fmod(srd[i] , pihalf) ;
333
334 u = (1/std::cos(phi)*(2*phixz + 4*fDz*phi*v.
x() - 2*fdeltaX*phi*v.
z() + (fDy2plus1*fPhiTwist + 2*fDy2minus1*phi)*v.
z()* std::sin(phi)))/(2.*fPhiTwist*v.
z()) ;
335
341
342 xbuf.push_back(xbuftmp) ;
343
344#ifdef G4TWISTDEBUG
345 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
346#endif
347
348 }
349 }
350
351 }
352
353
354 nxx = xbuf.size() ;
355
362
363
364 for ( size_t k = 0 ; k<xbuf.size() ; k++ ) {
365
366#ifdef G4TWISTDEBUG
367 G4cout <<
"Solution " << k <<
" : "
368 << "reconstructed phiR = " << xbuf[k].phi
369 <<
", uR = " << xbuf[k].u <<
G4endl ;
370#endif
371
372 phi = xbuf[k].phi ;
373 u = xbuf[k].u ;
374
375 IsConverged = false ;
376
377 for (
G4int i = 1 ; i<maxint ; i++ ) {
378
379 xxonsurface = SurfacePoint(phi,u) ;
380 surfacenormal = NormAng(phi,u) ;
382 deltaX = ( tmpxx - xxonsurface ).mag() ;
383 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
384 if ( theta < 0.001 ) {
385 factor = 50 ;
386 IsParallel = true ;
387 }
388 else {
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
408
409 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
410
411
412#ifdef G4TWISTDEBUG
413 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
416#endif
417
418 tmpisvalid = false ;
419
420 if ( IsConverged ) {
421
423 tmpareacode = GetAreaCode(tmpxx);
425 if (tmpdist >= 0) tmpisvalid = true;
426 }
428 tmpareacode = GetAreaCode(tmpxx, false);
430 if (tmpdist >= 0) tmpisvalid = true;
431 }
432 } else {
433 G4Exception(
"G4TwistTrapParallelSide::DistanceToSurface()",
435 "Feature NOT implemented !");
436 }
437
438 }
439 else {
440 tmpdist = kInfinity;
441 tmpisvalid = false ;
442 }
443
444
445
446 xbuf[k].xx = tmpxx ;
447 xbuf[k].distance = tmpdist ;
448 xbuf[k].areacode = tmpareacode ;
449 xbuf[k].isvalid = tmpisvalid ;
450
451
452 }
453
454
456
457#ifdef G4TWISTDEBUG
460#endif
461
462
463
464 xbuf.erase( std::unique(xbuf.begin(), xbuf.end() ,
EqualIntersection ) , xbuf.end() ) ;
465
466
467
468
469 G4int nxxtmp = xbuf.size() ;
470
471 if ( nxxtmp<2 || IsParallel ) {
472
473
474#ifdef G4TWISTDEBUG
476#endif
477
478 phi = fPhiTwist/2 ;
479 u = 0 ;
480
486
487 xbuf.push_back(xbuftmp) ;
488
489
490#ifdef G4TWISTDEBUG
492#endif
493
494 phi = -fPhiTwist/2 ;
495 u = 0 ;
496
502
503 xbuf.push_back(xbuftmp) ;
504
505 for ( size_t k = nxxtmp ; k<xbuf.size() ; k++ ) {
506
507#ifdef G4TWISTDEBUG
508 G4cout <<
"Solution " << k <<
" : "
509 << "reconstructed phiR = " << xbuf[k].phi
510 <<
", uR = " << xbuf[k].u <<
G4endl ;
511#endif
512
513 phi = xbuf[k].phi ;
514 u = xbuf[k].u ;
515
516 IsConverged = false ;
517
518 for (
G4int i = 1 ; i<maxint ; i++ ) {
519
520 xxonsurface = SurfacePoint(phi,u) ;
521 surfacenormal = NormAng(phi,u) ;
523 deltaX = ( tmpxx - xxonsurface ).mag() ;
524 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
525 if ( theta < 0.001 ) {
526 factor = 50 ;
527 }
528 else {
529 factor = 1 ;
530 }
531
532#ifdef G4TWISTDEBUG
533 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
535#endif
536
537 GetPhiUAtX(tmpxx, phi, u) ;
538
539#ifdef G4TWISTDEBUG
540 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
541#endif
542
543 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
544
545 }
546
547
548
549 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
550
551
552#ifdef G4TWISTDEBUG
553 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
556#endif
557
558 tmpisvalid = false ;
559
560 if ( IsConverged ) {
561
563 tmpareacode = GetAreaCode(tmpxx);
565 if (tmpdist >= 0) tmpisvalid = true;
566 }
568 tmpareacode = GetAreaCode(tmpxx, false);
570 if (tmpdist >= 0) tmpisvalid = true;
571 }
572 } else {
573 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
575 "Feature NOT implemented !");
576 }
577
578 }
579 else {
580 tmpdist = kInfinity;
581 tmpisvalid = false ;
582 }
583
584
585
586 xbuf[k].xx = tmpxx ;
587 xbuf[k].distance = tmpdist ;
588 xbuf[k].areacode = tmpareacode ;
589 xbuf[k].isvalid = tmpisvalid ;
590
591
592 }
593
594
595 }
596
597
598
600
601
602 xbuf.erase( std::unique(xbuf.begin(), xbuf.end() ,
EqualIntersection ) , xbuf.end() ) ;
603
604#ifdef G4TWISTDEBUG
607#endif
608
609 nxx = xbuf.size() ;
610
611 for ( size_t i = 0 ; i<xbuf.size() ; i++ ) {
612
613 distance[i] = xbuf[i].distance;
615 areacode[i] = xbuf[i].areacode ;
616 isvalid[i] = xbuf[i].isvalid ;
617
619 isvalid[i], nxx, validate, &gp, &gv);
620
621#ifdef G4TWISTDEBUG
622 G4cout <<
"element Nr. " << i
623 << ", local Intersection = " << xbuf[i].xx
624 << ", distance = " << xbuf[i].distance
625 << ", u = " << xbuf[i].u
626 << ", phi = " << xbuf[i].phi
627 << ", isvalid = " << xbuf[i].isvalid
629#endif
630
631 }
632
633
634#ifdef G4TWISTDEBUG
635 G4cout <<
"G4TwistTrapParallelSide finished " <<
G4endl ;
636 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
637 for (
G4int k= 0 ; k< nxx ; k++ ) {
638 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
641 }
642#endif
643
644 return nxx ;
645
646}
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
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)