190{
193
194 G4bool IsParallel = false ;
195 G4bool IsConverged = false ;
196
198
200
202 {
204 {
209 }
211 }
212 else
213 {
215 {
216 distance[i] = kInfinity;
218 isvalid[i] = false;
219 gxx[i].
set(kInfinity, kInfinity, kInfinity);
220 }
221 }
222
225
226#ifdef G4TWISTDEBUG
229#endif
230
232
233
234
238 G4bool tmpisvalid = false ;
239
240 std::vector<Intersection> xbuf ;
242
243
244
246
247 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
248 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
249
250
251
253 {
254 if ( std::fabs(p.
z()) <= L )
255 {
256 phi = p.
z() * fPhiTwist /
L ;
257
258 u = (2*(fdeltaY*phi*v.
x() - fPhiTwist*p.
y()*v.
x() - fdeltaX*phi*v.
y()
259 + fPhiTwist*p.
x()*v.
y()) + (fDy2plus1*fPhiTwist
260 + 2*fDy2minus1*phi)*(v.
x()*std::cos(phi) + v.
y()*std::sin(phi)))
261 / (2.* fPhiTwist*(v.
y()*std::cos(phi) - v.
x()*std::sin(phi)));
262
268
269 xbuf.push_back(xbuftmp) ;
270 }
271 else
272 {
273 distance[0] = kInfinity;
274 gxx[0].
set(kInfinity,kInfinity,kInfinity);
275 isvalid[0] = false ;
278 areacode[0], isvalid[0],
279 0, validate, &gp, &gv);
280
281 return 0;
282 }
283 }
284 else
285 {
287
288 c[8] = -3600*(-2*phiyz + fDy2plus1*fPhiTwist*v.
z()) ;
289 c[7] = -7200*(phixz - 2*fDz*v.
y() + (fdeltaY + fDy2minus1)*v.
z()) ;
290 c[6] = 120*(-52*phiyz - 120*fDz*v.
x() + 60*fdeltaX*v.
z()
291 + 11*fDy2plus1*fPhiTwist*v.
z()) ;
292 c[5] = 240*(16*phixz - 52*fDz*v.
y() + 26*fdeltaY*v.
z()
293 + 11*fDy2minus1*v.
z()) ;
294 c[4] = 12*(127*phiyz + 640*fDz*v.
x() - 320*fdeltaX*v.
z()
295 + 4*fDy2plus1*fPhiTwist*v.
z()) ;
296 c[3] = -404*phixz + 3048*fDz*v.
y() - 1524*fdeltaY*v.
z()
297 + 96*fDy2minus1*v.
z() ;
298 c[2] = -72*phiyz + 404*(-2*fDz*v.
x() + fdeltaX*v.
z()) ;
299 c[1] = 12*(phixz - 12*fDz*v.
y() + 6*fdeltaY*v.
z()) ;
300 c[0] = 24*fDz*v.
x() - 12*fdeltaX*v.
z() ;
301
302
303#ifdef G4TWISTDEBUG
304 G4cout <<
"coef = " << c[0] <<
" "
305 << c[1] << " "
306 << c[2] << " "
307 << c[3] << " "
308 << c[4] << " "
309 << c[5] << " "
310 << c[6] << " "
311 << c[7] << " "
313#endif
314
317
318 for (
G4int i = 0 ; i<num ; ++i )
319 {
320 if ( si[i]==0.0 )
321 {
322#ifdef G4TWISTDEBUG
323 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
324#endif
325 phi = std::fmod(srd[i] , pihalf) ;
326 u = (1/std::cos(phi)*(2*phixz + 4*fDz*phi*v.
x()
327 - 2*fdeltaX*phi*v.
z() + (fDy2plus1*fPhiTwist
328 + 2*fDy2minus1*phi)*v.
z()* std::sin(phi)))/(2.*fPhiTwist*v.
z()) ;
329
335
336 xbuf.push_back(xbuftmp) ;
337
338#ifdef G4TWISTDEBUG
339 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
340#endif
341
342 }
343 }
344 }
345
346 nxx = (
G4int)xbuf.size() ;
347
354
355
356 for ( std::size_t k = 0 ; k<xbuf.size() ; ++k )
357 {
358#ifdef G4TWISTDEBUG
359 G4cout <<
"Solution " << k <<
" : "
360 << "reconstructed phiR = " << xbuf[k].phi
361 <<
", uR = " << xbuf[k].u <<
G4endl ;
362#endif
363
364 phi = xbuf[k].phi ;
365 u = xbuf[k].u ;
366
367 IsConverged = false ;
368
369 for (
G4int i = 1 ; i<maxint ; ++i )
370 {
371 xxonsurface = SurfacePoint(phi,u) ;
372 surfacenormal = NormAng(phi,u) ;
374 deltaX = ( tmpxx - xxonsurface ).mag() ;
375 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
376 if ( theta < 0.001 )
377 {
378 factor = 50 ;
379 IsParallel = true ;
380 }
381 else
382 {
383 factor = 1 ;
384 }
385
386#ifdef G4TWISTDEBUG
387 G4cout <<
"Step i = " << i <<
", distance = "
388 << tmpdist <<
", " << deltaX <<
G4endl ;
390#endif
391
392 GetPhiUAtX(tmpxx, phi, u);
393
394#ifdef G4TWISTDEBUG
395 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
396#endif
397
398 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
399 }
400
401 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
402
403#ifdef G4TWISTDEBUG
404 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
407#endif
408
409 tmpisvalid = false ;
410
411 if ( IsConverged )
412 {
414 {
415 tmpareacode = GetAreaCode(tmpxx);
417 {
418 if (tmpdist >= 0) tmpisvalid = true;
419 }
420 }
422 {
423 tmpareacode = GetAreaCode(tmpxx, false);
425 {
426 if (tmpdist >= 0) tmpisvalid = true;
427 }
428 }
429 else
430 {
431 G4Exception(
"G4TwistTrapParallelSide::DistanceToSurface()",
433 "Feature NOT implemented !");
434 }
435 }
436 else
437 {
438 tmpdist = kInfinity;
439 tmpisvalid = false ;
440 }
441
442
443 xbuf[k].xx = tmpxx ;
444 xbuf[k].distance = tmpdist ;
445 xbuf[k].areacode = tmpareacode ;
446 xbuf[k].isvalid = tmpisvalid ;
447 }
448
450
451#ifdef G4TWISTDEBUG
454#endif
455
456
458
459
460
461
463
464 if ( nxxtmp<2 || IsParallel )
465 {
466
467#ifdef G4TWISTDEBUG
469#endif
470
471 phi = fPhiTwist/2 ;
472 u = 0 ;
473
479
480 xbuf.push_back(xbuftmp) ;
481
482#ifdef G4TWISTDEBUG
484#endif
485
486 phi = -fPhiTwist/2 ;
487 u = 0 ;
488
494
495 xbuf.push_back(xbuftmp) ;
496
497 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
498 {
499#ifdef G4TWISTDEBUG
500 G4cout <<
"Solution " << k <<
" : "
501 << "reconstructed phiR = " << xbuf[k].phi
502 <<
", uR = " << xbuf[k].u <<
G4endl ;
503#endif
504
505 phi = xbuf[k].phi ;
506 u = xbuf[k].u ;
507
508 IsConverged = false ;
509
510 for (
G4int i = 1 ; i<maxint ; ++i )
511 {
512 xxonsurface = SurfacePoint(phi,u) ;
513 surfacenormal = NormAng(phi,u) ;
515 deltaX = ( tmpxx - xxonsurface ).mag() ;
516 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
517 if ( theta < 0.001 )
518 {
519 factor = 50 ;
520 }
521 else
522 {
523 factor = 1 ;
524 }
525
526#ifdef G4TWISTDEBUG
527 G4cout <<
"Step i = " << i <<
", distance = "
528 << tmpdist <<
", " << deltaX <<
G4endl ;
530#endif
531
532 GetPhiUAtX(tmpxx, phi, u) ;
533
534#ifdef G4TWISTDEBUG
535 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
536#endif
537
538 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
539 }
540
541 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
542
543#ifdef G4TWISTDEBUG
544 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
547#endif
548
549 tmpisvalid = false ;
550
551 if ( IsConverged )
552 {
554 {
555 tmpareacode = GetAreaCode(tmpxx);
557 {
558 if (tmpdist >= 0) tmpisvalid = true;
559 }
560 }
562 {
563 tmpareacode = GetAreaCode(tmpxx, false);
565 {
566 if (tmpdist >= 0) tmpisvalid = true;
567 }
568 }
569 else
570 {
571 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
573 "Feature NOT implemented !");
574 }
575
576 }
577 else
578 {
579 tmpdist = kInfinity;
580 tmpisvalid = false ;
581 }
582
583
584 xbuf[k].xx = tmpxx ;
585 xbuf[k].distance = tmpdist ;
586 xbuf[k].areacode = tmpareacode ;
587 xbuf[k].isvalid = tmpisvalid ;
588
589 }
590 }
591
592
594
595
597
598#ifdef G4TWISTDEBUG
601#endif
602
603 nxx = (
G4int)xbuf.size() ;
604
605 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
606 {
607 distance[i] = xbuf[i].distance;
609 areacode[i] = xbuf[i].areacode ;
610 isvalid[i] = xbuf[i].isvalid ;
611
613 isvalid[i], nxx, validate, &gp, &gv);
614#ifdef G4TWISTDEBUG
615 G4cout <<
"element Nr. " << i
616 << ", local Intersection = " << xbuf[i].xx
617 << ", distance = " << xbuf[i].distance
618 << ", u = " << xbuf[i].u
619 << ", phi = " << xbuf[i].phi
620 << ", isvalid = " << xbuf[i].isvalid
622#endif
623 }
624
625#ifdef G4TWISTDEBUG
626 G4cout <<
"G4TwistTrapParallelSide finished " <<
G4endl ;
627 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
628 for (
G4int k= 0 ; k< nxx ; ++k )
629 {
630 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
633 }
634#endif
635
636 return nxx ;
637}
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