199{
200
201 static const G4double pihalf = pi/2 ;
203
204 G4bool IsParallel = false ;
205 G4bool IsConverged = false ;
206
208
210
212 {
214 {
219 }
221 }
222 else
223 {
225 {
226 distance[i] = kInfinity;
228 isvalid[i] = false;
229 gxx[i].
set(kInfinity, kInfinity, kInfinity);
230 }
231 }
232
235
236#ifdef G4TWISTDEBUG
239#endif
240
242
243
244
248 G4bool tmpisvalid = false ;
249
250 std::vector<Intersection> xbuf ;
252
253
254
256
257 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
258 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
259
260
261
263 {
264 if ( (std::fabs(p.
z()) <= L) && (fPhiTwist != 0.0) )
265 {
266 phi = p.
z() * fPhiTwist / L ;
267
268 q = (2.* fPhiTwist*((v.
x() - fTAlph*v.
y())*std::cos(phi)
269 + (fTAlph*v.
x() + v.
y())*std::sin(phi)));
270
271 if (q != 0.0)
272 {
273 u = (2*(-(fdeltaY*phi*v.
x()) + fPhiTwist*p.
y()*v.
x()
274 + fdeltaX*phi*v.
y() - fPhiTwist*p.
x()*v.
y())
275 + (fDx4plus2*fPhiTwist + 2*fDx4minus2*phi)
276 * (v.
y()*std::cos(phi) - v.
x()*std::sin(phi))) / q;
277 }
283
284 xbuf.push_back(xbuftmp) ;
285 }
286 else
287 {
288 distance[0] = kInfinity;
289 gxx[0].
set(kInfinity,kInfinity,kInfinity);
290 isvalid[0] = false ;
293 areacode[0], isvalid[0],
294 0, validate, &gp, &gv);
295
296 return 0;
297 }
298 }
299 else
300 {
302
303 c[7] = -14400*(-2*phixz + 2*fTAlph*phiyz + fDx4plus2*fPhiTwist*v.
z()) ;
304 c[6] = 28800*(phiyz + 2*fDz*v.
x() - (fdeltaX + fDx4minus2)*v.
z() + fTAlph*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z())) ;
305 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())) ;
306 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())) ;
307 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())) ;
308 c[2] = -16*(7*fTAlph* phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y() + 3*(fdeltaX + fDx4minus2 - fdeltaY*fTAlph)*v.
z()) ;
309 c[1] = 4*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x() - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()) ;
310 c[0] = 36*(2* fDz*(v.
x() - fTAlph*v.
y()) - fdeltaX*v.
z() + fdeltaY*fTAlph*v.
z()) ;
311
312#ifdef G4TWISTDEBUG
313 G4cout <<
"coef = " << c[0] <<
" "
314 << c[1] << " "
315 << c[2] << " "
316 << c[3] << " "
317 << c[4] << " "
318 << c[5] << " "
319 << c[6] << " "
321#endif
322
325
326 for (
G4int i = 0 ; i<num ; ++i )
327 {
328 if ( (si[i]==0.0) && (fPhiTwist != 0.0) )
329 {
330#ifdef G4TWISTDEBUG
331 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
332#endif
333 phi = std::fmod(srd[i], pihalf) ;
334
335 u = (2*phiyz + 4*fDz*phi*v.
y() - 2*fdeltaY*phi*v.
z()
336 - fDx4plus2*fPhiTwist*v.
z()*std::sin(phi)
337 - 2*fDx4minus2*phi*v.
z()*std::sin(phi))
338 /(2*fPhiTwist*v.
z()*std::cos(phi)
339 + 2*fPhiTwist*fTAlph*v.
z()*std::sin(phi)) ;
340
346
347 xbuf.push_back(xbuftmp) ;
348
349#ifdef G4TWISTDEBUG
350 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
351#endif
352 }
353 }
354 }
355
356
357 nxx = (
G4int)xbuf.size() ;
358
362
366
367
368 for (auto & k : xbuf)
369 {
370#ifdef G4TWISTDEBUG
371 G4cout <<
"Solution " << k <<
" : "
372 << "reconstructed phiR = " << xbuf[k].phi
373 <<
", uR = " << xbuf[k].u <<
G4endl ;
374#endif
375
376 phi = k.phi ;
377 u = k.u ;
378
379 IsConverged = false ;
380
381 for (
G4int i = 1 ; i<maxint ; ++i )
382 {
383 xxonsurface = SurfacePoint(phi,u) ;
384 surfacenormal = NormAng(phi,u) ;
386 deltaX = ( tmpxx - xxonsurface ).mag() ;
387 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
388 if ( theta < 0.001 )
389 {
390 factor = 50 ;
391 IsParallel = true ;
392 }
393 else
394 {
395 factor = 1 ;
396 }
397
398#ifdef G4TWISTDEBUG
399 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
401#endif
402
403 GetPhiUAtX(tmpxx, phi, u) ;
404
405#ifdef G4TWISTDEBUG
406 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
407#endif
408
409 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
410
411 }
412
413 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
414
415#ifdef G4TWISTDEBUG
416 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
419#endif
420
421 tmpisvalid = false ;
422
423 if ( IsConverged )
424 {
426 {
427 tmpareacode = GetAreaCode(tmpxx);
429 {
430 if (tmpdist >= 0) tmpisvalid = true;
431 }
432 }
434 {
435 tmpareacode = GetAreaCode(tmpxx, false);
437 {
438 if (tmpdist >= 0) tmpisvalid = true;
439 }
440 }
441 else
442 {
445 "Feature NOT implemented !");
446 }
447 }
448 else
449 {
450 tmpdist = kInfinity;
451 tmpisvalid = false ;
452 }
453
454
455 k.xx = tmpxx ;
456 k.distance = tmpdist ;
457 k.areacode = tmpareacode ;
458 k.isvalid = tmpisvalid ;
459
460 }
461
463
464#ifdef G4TWISTDEBUG
467#endif
468
469
471
472
473
474 auto nxxtmp = (
G4int)xbuf.size() ;
475
476 if ( nxxtmp<2 || IsParallel )
477 {
478
479#ifdef G4TWISTDEBUG
481#endif
482
483 phi = fPhiTwist/2 ;
484 u = 0. ;
490
491 xbuf.push_back(xbuftmp) ;
492
493#ifdef G4TWISTDEBUG
495#endif
496
497 phi = -fPhiTwist/2 ;
498 u = 0. ;
499
505
506 xbuf.push_back(xbuftmp) ;
507
508 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
509 {
510#ifdef G4TWISTDEBUG
511 G4cout <<
"Solution " << k <<
" : "
512 << "reconstructed phiR = " << xbuf[k].phi
513 <<
", uR = " << xbuf[k].u <<
G4endl ;
514#endif
515
516 phi = xbuf[k].phi ;
517 u = xbuf[k].u ;
518
519 IsConverged = false ;
520
521 for (
G4int i = 1 ; i<maxint ; ++i )
522 {
523 xxonsurface = SurfacePoint(phi,u) ;
524 surfacenormal = NormAng(phi,u) ;
526 deltaX = ( tmpxx - xxonsurface ).mag() ;
527 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
528 if ( theta < 0.001 )
529 {
530 factor = 50 ;
531 }
532 else
533 {
534 factor = 1 ;
535 }
536
537#ifdef G4TWISTDEBUG
538 G4cout <<
"Step i = " << i <<
", distance = "
539 << tmpdist <<
", " << deltaX <<
G4endl ;
541#endif
542
543 GetPhiUAtX(tmpxx, phi, u) ;
544
545
546#ifdef G4TWISTDEBUG
547 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
548#endif
549
550 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
551
552 }
553
554 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
555
556#ifdef G4TWISTDEBUG
557 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
560#endif
561
562 tmpisvalid = false ;
563
564 if ( IsConverged )
565 {
567 {
568 tmpareacode = GetAreaCode(tmpxx);
570 {
571 if (tmpdist >= 0) tmpisvalid = true;
572 }
573 }
575 {
576 tmpareacode = GetAreaCode(tmpxx, false);
578 {
579 if (tmpdist >= 0) tmpisvalid = true;
580 }
581 }
582 else
583 {
584 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
586 "Feature NOT implemented !");
587 }
588 }
589 else
590 {
591 tmpdist = kInfinity;
592 tmpisvalid = false ;
593 }
594
595
596 xbuf[k].xx = tmpxx ;
597 xbuf[k].distance = tmpdist ;
598 xbuf[k].areacode = tmpareacode ;
599 xbuf[k].isvalid = tmpisvalid ;
600 }
601 }
602
603
605
606
608
609#ifdef G4TWISTDEBUG
612#endif
613
614 nxx = (
G4int)xbuf.size() ;
615
616 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
617 {
618 distance[i] = xbuf[i].distance;
620 areacode[i] = xbuf[i].areacode ;
621 isvalid[i] = xbuf[i].isvalid ;
622
624 isvalid[i], nxx, validate, &gp, &gv);
625
626#ifdef G4TWISTDEBUG
627 G4cout <<
"element Nr. " << i
628 << ", local Intersection = " << xbuf[i].xx
629 << ", distance = " << xbuf[i].distance
630 << ", u = " << xbuf[i].u
631 << ", phi = " << xbuf[i].phi
632 << ", isvalid = " << xbuf[i].isvalid
634#endif
635
636 }
637
638#ifdef G4TWISTDEBUG
640 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
641 for (
G4int k= 0 ; k< nxx ; ++k )
642 {
643 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
646 }
647#endif
648
649 return nxx ;
650}
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