184{
185 static const G4double pihalf = pi/2 ;
187
188 G4bool IsParallel = false ;
189 G4bool IsConverged = false ;
190
192
194
196 {
198 {
203 }
205 }
206 else
207 {
209 {
210 distance[i] = kInfinity;
212 isvalid[i] = false;
213 gxx[i].
set(kInfinity, kInfinity, kInfinity);
214 }
215 }
216
219
220#ifdef G4TWISTDEBUG
223#endif
224
226
227
228
232 G4bool tmpisvalid = false ;
233
234 std::vector<Intersection> xbuf ;
236
237
238
240
241 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
242 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
243
244
245
247 {
248 if ( std::fabs(p.
z()) <= L )
249 {
250 phi = p.
z() * fPhiTwist / L ;
251
252 u = (2*(fdeltaY*phi*v.
x() - fPhiTwist*p.
y()*v.
x() - fdeltaX*phi*v.
y()
253 + fPhiTwist*p.
x()*v.
y()) + (fDy2plus1*fPhiTwist
254 + 2*fDy2minus1*phi)*(v.
x()*std::cos(phi) + v.
y()*std::sin(phi)))
255 / (2.* fPhiTwist*(v.
y()*std::cos(phi) - v.
x()*std::sin(phi)));
256
262
263 xbuf.push_back(xbuftmp) ;
264 }
265 else
266 {
267 distance[0] = kInfinity;
268 gxx[0].
set(kInfinity,kInfinity,kInfinity);
269 isvalid[0] = false ;
272 areacode[0], isvalid[0],
273 0, validate, &gp, &gv);
274
275 return 0;
276 }
277 }
278 else
279 {
281
282 c[8] = -3600*(-2*phiyz + fDy2plus1*fPhiTwist*v.
z()) ;
283 c[7] = -7200*(phixz - 2*fDz*v.
y() + (fdeltaY + fDy2minus1)*v.
z()) ;
284 c[6] = 120*(-52*phiyz - 120*fDz*v.
x() + 60*fdeltaX*v.
z()
285 + 11*fDy2plus1*fPhiTwist*v.
z()) ;
286 c[5] = 240*(16*phixz - 52*fDz*v.
y() + 26*fdeltaY*v.
z()
287 + 11*fDy2minus1*v.
z()) ;
288 c[4] = 12*(127*phiyz + 640*fDz*v.
x() - 320*fdeltaX*v.
z()
289 + 4*fDy2plus1*fPhiTwist*v.
z()) ;
290 c[3] = -404*phixz + 3048*fDz*v.
y() - 1524*fdeltaY*v.
z()
291 + 96*fDy2minus1*v.
z() ;
292 c[2] = -72*phiyz + 404*(-2*fDz*v.
x() + fdeltaX*v.
z()) ;
293 c[1] = 12*(phixz - 12*fDz*v.
y() + 6*fdeltaY*v.
z()) ;
294 c[0] = 24*fDz*v.
x() - 12*fdeltaX*v.
z() ;
295
296
297#ifdef G4TWISTDEBUG
298 G4cout <<
"coef = " << c[0] <<
" "
299 << c[1] << " "
300 << c[2] << " "
301 << c[3] << " "
302 << c[4] << " "
303 << c[5] << " "
304 << c[6] << " "
305 << c[7] << " "
307#endif
308
311
312 for (
G4int i = 0 ; i<num ; ++i )
313 {
314 if ( si[i]==0.0 )
315 {
316#ifdef G4TWISTDEBUG
317 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
318#endif
319 phi = std::fmod(srd[i] , pihalf) ;
320 u = (1/std::cos(phi)*(2*phixz + 4*fDz*phi*v.
x()
321 - 2*fdeltaX*phi*v.
z() + (fDy2plus1*fPhiTwist
322 + 2*fDy2minus1*phi)*v.
z()* std::sin(phi)))/(2.*fPhiTwist*v.
z()) ;
323
329
330 xbuf.push_back(xbuftmp) ;
331
332#ifdef G4TWISTDEBUG
333 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
334#endif
335
336 }
337 }
338 }
339
340 nxx = (
G4int)xbuf.size() ;
341
348
349
350 for (auto & k : xbuf)
351 {
352#ifdef G4TWISTDEBUG
353 G4cout <<
"Solution " << k <<
" : "
354 << "reconstructed phiR = " << xbuf[k].phi
355 <<
", uR = " << xbuf[k].u <<
G4endl ;
356#endif
357
358 phi = k.phi ;
359 u = k.u ;
360
361 IsConverged = false ;
362
363 for (
G4int i = 1 ; i<maxint ; ++i )
364 {
365 xxonsurface = SurfacePoint(phi,u) ;
366 surfacenormal = NormAng(phi,u) ;
368 deltaX = ( tmpxx - xxonsurface ).mag() ;
369 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
370 if ( theta < 0.001 )
371 {
372 factor = 50 ;
373 IsParallel = true ;
374 }
375 else
376 {
377 factor = 1 ;
378 }
379
380#ifdef G4TWISTDEBUG
381 G4cout <<
"Step i = " << i <<
", distance = "
382 << tmpdist <<
", " << deltaX <<
G4endl ;
384#endif
385
386 GetPhiUAtX(tmpxx, phi, u);
387
388#ifdef G4TWISTDEBUG
389 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
390#endif
391
392 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
393 }
394
395 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
396
397#ifdef G4TWISTDEBUG
398 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
401#endif
402
403 tmpisvalid = false ;
404
405 if ( IsConverged )
406 {
408 {
409 tmpareacode = GetAreaCode(tmpxx);
411 {
412 if (tmpdist >= 0) tmpisvalid = true;
413 }
414 }
416 {
417 tmpareacode = GetAreaCode(tmpxx, false);
419 {
420 if (tmpdist >= 0) tmpisvalid = true;
421 }
422 }
423 else
424 {
425 G4Exception(
"G4TwistTrapParallelSide::DistanceToSurface()",
427 "Feature NOT implemented !");
428 }
429 }
430 else
431 {
432 tmpdist = kInfinity;
433 tmpisvalid = false ;
434 }
435
436
437 k.xx = tmpxx ;
438 k.distance = tmpdist ;
439 k.areacode = tmpareacode ;
440 k.isvalid = tmpisvalid ;
441 }
442
444
445#ifdef G4TWISTDEBUG
448#endif
449
450
452
453
454
455
456 auto nxxtmp = (
G4int)xbuf.size() ;
457
458 if ( nxxtmp<2 || IsParallel )
459 {
460
461#ifdef G4TWISTDEBUG
463#endif
464
465 phi = fPhiTwist/2 ;
466 u = 0 ;
467
473
474 xbuf.push_back(xbuftmp) ;
475
476#ifdef G4TWISTDEBUG
478#endif
479
480 phi = -fPhiTwist/2 ;
481 u = 0 ;
482
488
489 xbuf.push_back(xbuftmp) ;
490
491 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
492 {
493#ifdef G4TWISTDEBUG
494 G4cout <<
"Solution " << k <<
" : "
495 << "reconstructed phiR = " << xbuf[k].phi
496 <<
", uR = " << xbuf[k].u <<
G4endl ;
497#endif
498
499 phi = xbuf[k].phi ;
500 u = xbuf[k].u ;
501
502 IsConverged = false ;
503
504 for (
G4int i = 1 ; i<maxint ; ++i )
505 {
506 xxonsurface = SurfacePoint(phi,u) ;
507 surfacenormal = NormAng(phi,u) ;
509 deltaX = ( tmpxx - xxonsurface ).mag() ;
510 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
511 if ( theta < 0.001 )
512 {
513 factor = 50 ;
514 }
515 else
516 {
517 factor = 1 ;
518 }
519
520#ifdef G4TWISTDEBUG
521 G4cout <<
"Step i = " << i <<
", distance = "
522 << tmpdist <<
", " << deltaX <<
G4endl ;
524#endif
525
526 GetPhiUAtX(tmpxx, phi, u) ;
527
528#ifdef G4TWISTDEBUG
529 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
530#endif
531
532 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
533 }
534
535 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
536
537#ifdef G4TWISTDEBUG
538 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
541#endif
542
543 tmpisvalid = false ;
544
545 if ( IsConverged )
546 {
548 {
549 tmpareacode = GetAreaCode(tmpxx);
551 {
552 if (tmpdist >= 0) tmpisvalid = true;
553 }
554 }
556 {
557 tmpareacode = GetAreaCode(tmpxx, false);
559 {
560 if (tmpdist >= 0) tmpisvalid = true;
561 }
562 }
563 else
564 {
565 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
567 "Feature NOT implemented !");
568 }
569
570 }
571 else
572 {
573 tmpdist = kInfinity;
574 tmpisvalid = false ;
575 }
576
577
578 xbuf[k].xx = tmpxx ;
579 xbuf[k].distance = tmpdist ;
580 xbuf[k].areacode = tmpareacode ;
581 xbuf[k].isvalid = tmpisvalid ;
582
583 }
584 }
585
586
588
589
591
592#ifdef G4TWISTDEBUG
595#endif
596
597 nxx = (
G4int)xbuf.size() ;
598
599 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
600 {
601 distance[i] = xbuf[i].distance;
603 areacode[i] = xbuf[i].areacode ;
604 isvalid[i] = xbuf[i].isvalid ;
605
607 isvalid[i], nxx, validate, &gp, &gv);
608#ifdef G4TWISTDEBUG
609 G4cout <<
"element Nr. " << i
610 << ", local Intersection = " << xbuf[i].xx
611 << ", distance = " << xbuf[i].distance
612 << ", u = " << xbuf[i].u
613 << ", phi = " << xbuf[i].phi
614 << ", isvalid = " << xbuf[i].isvalid
616#endif
617 }
618
619#ifdef G4TWISTDEBUG
620 G4cout <<
"G4TwistTrapParallelSide finished " <<
G4endl ;
621 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
622 for (
G4int k= 0 ; k< nxx ; ++k )
623 {
624 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
627 }
628#endif
629
630 return nxx ;
631}
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