Belle II Software development
BelleCrystal Class Reference

a Belle crystal in Geant4 More...

#include <BelleCrystal.h>

Inheritance diagram for BelleCrystal:

Public Member Functions

 BelleCrystal (const G4String &pName)
 Constructor for "nominal" BelleCrystal.
 
 BelleCrystal (const G4String &pName, int, const G4ThreeVector *)
 Constructor.
 
virtual ~BelleCrystal ()
 Destructor.
 
Plane_t GetSidePlane (G4int n) const
 Get side plane.
 
G4double GetCubicVolume ()
 get the Cubic volume
 
G4double GetSurfaceArea ()
 get the surface area
 
void ComputeDimensions (G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
 compute the dimensions
 
G4bool CalculateExtent (const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const
 calculate the extent of the volume
 
EInside Inside (const G4ThreeVector &p) const
 Return whether point inside/outside/on surface, using tolerance.
 
G4ThreeVector SurfaceNormal (const G4ThreeVector &p) const
 Calculate side nearest to p, and return normal.
 
G4double DistanceToIn (const G4ThreeVector &p, const G4ThreeVector &v) const
 Calculate exact shortest distance to any boundary from outside.
 
G4double DistanceToIn (const G4ThreeVector &p) const
 Calculate exact shortest distance to any boundary from outside.
 
G4double DistanceToOut (const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const
 Calculate exact shortest distance to any boundary from inside.
 
G4double DistanceToOut (const G4ThreeVector &p) const
 Calculate exact shortest distance to any boundary from inside.
 
G4GeometryType GetEntityType () const
 Get entity type.
 
G4ThreeVector GetPointOnSurface () const
 get point on surface
 
G4VSolid * Clone () const
 Make a clone of the object.
 
std::ostream & StreamInfo (std::ostream &os) const
 Stream object contents to an output stream.
 
void DescribeYourselfTo (G4VGraphicsScene &scene) const
 Visualisation functions.
 
G4Polyhedron * CreatePolyhedron () const
 create polyhedron
 
void BoundingLimits (G4ThreeVector &pMin, G4ThreeVector &pMax) const
 Two vectors define an axis-parallel bounding box for the shape.
 
 BelleCrystal (__void__ &)
 Fake default constructor for usage restricted to direct object persistency for clients requiring preallocation of memory for persistifiable objects.
 
 BelleCrystal (const BelleCrystal &rhs)
 copy constructor
 
BelleCrystaloperator= (const BelleCrystal &rhs)
 assignment operator
 
G4ThreeVector vertex (unsigned int i) const
 return ith vertex
 

Protected Member Functions

G4bool MakePlane (const G4ThreeVector &p1, const G4ThreeVector &p2, const G4ThreeVector &p3, const G4ThreeVector &p4, Plane_t &plane) const
 Calculate the coef's of the plane p1->p2->p3->p4->p1 where the ThreeVectors 1-4 are in anti-clockwise order when viewed from in front of the plane (i.e.
 

Private Member Functions

G4ThreeVector GetPointOnTriangle (int) const
 Returns a random point on the surface of one of the faces.
 
double area (int, double &) const
 triangle area
 
double getvolarea () const
 get volume area
 
const unsigned int * ivertx (unsigned int i) const
 get the ith vertex
 

Private Attributes

unsigned int nsides
 the number of sides
 
double fDz
 Dz.
 
std::vector< Plane_tfPlanes
 vector of planes
 
std::vector< Point_tfx
 vector of points
 
std::vector< double > fareas
 vector of area values
 

Detailed Description

a Belle crystal in Geant4

Definition at line 37 of file BelleCrystal.h.

Constructor & Destructor Documentation

◆ BelleCrystal() [1/4]

BelleCrystal ( const G4String &  pName)
explicit

Constructor for "nominal" BelleCrystal.

Definition at line 145 of file BelleCrystal.cc.

146 : G4CSGSolid(pName), nsides(0), fDz(0)
147{
148}
unsigned int nsides
the number of sides
Definition: BelleCrystal.h:144

◆ BelleCrystal() [2/4]

BelleCrystal ( const G4String &  pName,
int  n,
const G4ThreeVector *  pt 
)

Constructor.

Definition at line 47 of file BelleCrystal.cc.

49 : G4CSGSolid(pName), nsides(n), fPlanes(nsides), fx(2 * nsides)
50{
51#if PERFCOUNTER==1
52 memset(fcounter, 0, sizeof(fcounter));
53#endif
54#ifdef MATCHNAME
55 // cppcheck-suppress ConfigurationNotChecked
56 fmatch = GetName() == QUOTE(MATCHNAME);
57 cout.precision(17);
58#endif
59 // ref = new G4Trap("dummy",pt);
60 fDz = abs(pt[2 * nsides - 1].z());
61 for (unsigned int i = 0; i < 2 * nsides; i++) {
62 fx[i].x = pt[i].x();
63 fx[i].y = pt[i].y();
64 }
65 // cout<<pName<<" "<<fx.data()<<endl;
66 // for(int i=0; i<2*nsides + 2*(nsides-2); i++) ivertx(i);
67
68 auto isConvex = [](std::vector<Point_t>::const_iterator begin, std::vector<Point_t>::const_iterator end) -> bool {
69 bool sign = false;
70 int np = end - begin;
71 for (int i0 = 0; i0 < np; i0++)
72 {
73 int i1 = (i0 + 1) % np, i2 = (i0 + 2) % np;
74 const Point_t& r2 = *(begin + i2), &r1 = *(begin + i1), &r0 = *(begin + i0);
75 double dx1 = r2.x - r1.x, dy1 = r2.y - r1.y;
76 double dx2 = r0.x - r1.x, dy2 = r0.y - r1.y;
77 double x = dx1 * dy2 - dy1 * dx2;
78 if (i0 == 0) sign = x > 0;
79 else {
80 if (sign != (x > 0)) return false;
81 }
82 }
83 return true;
84 };
85
86 auto isClockwise = [](std::vector<Point_t>::const_iterator begin, std::vector<Point_t>::const_iterator end) -> bool {
87 std::vector<Point_t>::const_iterator it = begin;
88 Point_t r0 = *it++;
89 double sum = 0;
90 for (; it != end;)
91 {
92 Point_t r1 = *it++; sum += (r1.x - r0.x) * (r1.y + r0.y);
93 r0 = r1;
94 }
95 Point_t r1 = *begin; sum += (r1.x - r0.x) * (r1.y + r0.y);
96 return sum > 0;
97 };
98
99 if (!isConvex(fx.begin(), fx.begin() + nsides)) {
100 std::ostringstream message;
101 message << "At -z polygon is not convex: " << GetName();
102 G4Exception("BelleCrystal::BelleCrystal()", "BelleCrystal", FatalException, message);
103 }
104 if (!isConvex(fx.begin() + nsides, fx.end())) {
105 std::ostringstream message;
106 message << "At +z polygon is not convex: " << GetName();
107 G4Exception("BelleCrystal::BelleCrystal()", "BelleCrystal", FatalException, message);
108 }
109
110 if (isClockwise(fx.begin(), fx.begin() + nsides)) {
111 std::ostringstream message;
112 message << "At -z polygon is not in anti-clockwise order: " << GetName();
113 G4Exception("BelleCrystal::BelleCrystal()", "BelleCrystal", FatalException, message);
114 }
115 if (isClockwise(fx.begin() + nsides, fx.end())) {
116 std::ostringstream message;
117 message << "At +z polygon is not in anti-clockwise order: " << GetName();
118 G4Exception("BelleCrystal::BelleCrystal()", "BelleCrystal", FatalException, message);
119 }
120
121 // sanity check
122 const G4ThreeVector* pm = pt, *pp = pt + nsides;
123 bool zm = pm[0].z() < 0, zp = pp[0].z() > 0;
124 for (unsigned int i = 1; i < nsides; i++) {
125 zm = zm && (pm[i - 1].z() - pm[i].z()) < kCarTolerance;
126 zp = zp && (pp[i - 1].z() - pp[i].z()) < kCarTolerance;
127 }
128 bool zpm = abs(pm[0].z() + pp[0].z()) < kCarTolerance;
129 if (!(zm && zp && zpm)) {
130 std::ostringstream message;
131 message << "Invalid vertice coordinates for Solid: " << GetName() << " " << zp << " " << zm << " " << zpm;
132 G4Exception("BelleCrystal::BelleCrystal()", "BelleCrystal", FatalException, message);
133 }
134 if (nsides > 3) {
135 for (unsigned int i = 0; i < nsides; i++)
136 MakePlane(pt[i], pt[i + nsides], pt[((i + 1) % (nsides)) + nsides], pt[(i + 1) % nsides], fPlanes[i]);
137 } else {
138 std::ostringstream message;
139 message << "Wrong number of sides for Belle Crystal: " << GetName() << " nsides = " << nsides;
140 G4Exception("BelleCrystal::BelleCrystal()", "BelleCrystal", FatalException, message);
141 }
142}
std::vector< Plane_t > fPlanes
vector of planes
Definition: BelleCrystal.h:146
G4bool MakePlane(const G4ThreeVector &p1, const G4ThreeVector &p2, const G4ThreeVector &p3, const G4ThreeVector &p4, Plane_t &plane) const
Calculate the coef's of the plane p1->p2->p3->p4->p1 where the ThreeVectors 1-4 are in anti-clockwise...
std::vector< Point_t > fx
vector of points
Definition: BelleCrystal.h:147
struct for Point
Definition: BelleCrystal.h:31
double y
y coordinate
Definition: BelleCrystal.h:33
double x
x coordinate
Definition: BelleCrystal.h:32

◆ ~BelleCrystal()

~BelleCrystal ( )
virtual

Destructor.

Definition at line 158 of file BelleCrystal.cc.

159{
160#if PERFCOUNTER==1
161 cout << GetName() << " ";
162 for (int i = 0; i < 6; i++) cout << counter[i] << " "; cout << endl;
163 exit(0);
164#endif
165 // delete ref;
166}

◆ BelleCrystal() [3/4]

BelleCrystal ( __void__ &  a)
explicit

Fake default constructor for usage restricted to direct object persistency for clients requiring preallocation of memory for persistifiable objects.

Definition at line 152 of file BelleCrystal.cc.

153 : G4CSGSolid(a), nsides(0), fDz(0)
154{
155}

◆ BelleCrystal() [4/4]

BelleCrystal ( const BelleCrystal rhs)

copy constructor

Definition at line 169 of file BelleCrystal.cc.

170 : G4CSGSolid(rhs), nsides(rhs.nsides), fDz(rhs.fDz), fPlanes(rhs.fPlanes), fx(rhs.fx)
171{
172}

Member Function Documentation

◆ area()

double area ( int  it,
double &  vol 
) const
private

triangle area

Definition at line 648 of file BelleCrystal.cc.

649{
650 const unsigned int* iv = ivertx(it);
651 G4ThreeVector p0 = vertex(iv[0]), p1 = vertex(iv[1]), p2 = vertex(iv[2]);
652 // std::cout<<it<<" "<<p0<<" "<<p1<<" "<<p2<<std::endl;
653 G4ThreeVector n = (p1 - p0).cross(p2 - p0);
654 vol = n * p0;
655 return 0.5 * n.mag();
656}
const unsigned int * ivertx(unsigned int i) const
get the ith vertex
G4ThreeVector vertex(unsigned int i) const
return ith vertex

◆ BoundingLimits()

void BoundingLimits ( G4ThreeVector &  pMin,
G4ThreeVector &  pMax 
) const

Two vectors define an axis-parallel bounding box for the shape.

Definition at line 733 of file BelleCrystal.cc.

734{
735 // All extremums will be at vertices
736 int np = 2 * nsides;
737 G4ThreeVector pt;
738
739 // Placeholder vectors
740 const double inf = std::numeric_limits<double>::infinity();
741 G4ThreeVector minimum(inf, inf, inf), maximum(-inf, -inf, -inf);
742
743 for (int i = 0; i < np; i++) {
744 pt = vertex(i);
745
746 // Assign new minimum and new maximum
747 minimum = min(minimum, pt);
748 maximum = max(maximum, pt);
749 }
750
751 // Assign
752 pMin = minimum;
753 pMax = maximum;
754}

◆ CalculateExtent()

G4bool CalculateExtent ( const EAxis  pAxis,
const G4VoxelLimits &  pVoxelLimit,
const G4AffineTransform &  pTransform,
G4double &  pMin,
G4double &  pMax 
) const

calculate the extent of the volume

Definition at line 254 of file BelleCrystal.cc.

258{
259 const double inf = std::numeric_limits<double>::infinity();
260 G4ThreeVector v0(inf, inf, inf), v1(-inf, -inf, -inf);
261 for (unsigned int i = 0; i < 2 * nsides; i++) {
262 G4ThreeVector v = pTransform.TransformPoint(vertex(i));
263 v0 = min(v0, v);
264 v1 = max(v1, v);
265 }
266 G4ThreeVector b0(bb.GetMinXExtent(), bb.GetMinYExtent(), bb.GetMinZExtent());
267 G4ThreeVector b1(bb.GetMaxXExtent(), bb.GetMaxYExtent(), bb.GetMaxZExtent());
268
269 v0 = max(v0, b0);
270 v1 = min(v1, b1);
271
272 switch (pAxis) {
273 case kXAxis: pMin = v0.x(); pMax = v1.x(); break;
274 case kYAxis: pMin = v0.y(); pMax = v1.y(); break;
275 case kZAxis: pMin = v0.z(); pMax = v1.z(); break;
276 default: break;
277 }
278
279 G4bool flag = false;
280 if ((pMin < inf) || (pMax > -inf)) {
281 flag = true;
282 // Add tolerance to avoid precision troubles
283 pMin -= kCarTolerance ;
284 pMax += kCarTolerance ;
285 }
286 // do {
287 // double t_pMin, t_pMax;
288 // bool t_flag = ref->CalculateExtent(pAxis, bb, pTransform, t_pMin, t_pMax);
289 // if(flag!=t_flag||abs(t_pMin-pMin)>kCarTolerance||abs(t_pMax-pMax)>kCarTolerance){
290 // cout<<GetName()<<" "<<pAxis<<" "<<bb<<" "<<pTransform<<t_pMin-pMin<<" "<<t_pMax-pMax<<endl;
291 // exit(0);
292 // }
293 // } while(0);
294 return flag;
295}
const std::vector< double > v1
MATLAB generated random vector.

◆ Clone()

G4VSolid * Clone ( ) const

Make a clone of the object.

Definition at line 547 of file BelleCrystal.cc.

548{
549 return new BelleCrystal(*this);
550}
a Belle crystal in Geant4
Definition: BelleCrystal.h:37

◆ ComputeDimensions()

void ComputeDimensions ( G4VPVParameterisation *  p,
const G4int  n,
const G4VPhysicalVolume *  pRep 
)

compute the dimensions

Definition at line 230 of file BelleCrystal.cc.

233{
234 G4Exception("BelleCrystal::ComputeDimensions()",
235 "GeomSolids0001", FatalException,
236 "BelleCrystal does not support Parameterisation.");
237 // std::cout<<"ComputeDimensions"<<std::endl;
238 // p->ComputeDimensions(*this,n,pRep);
239}

◆ CreatePolyhedron()

G4Polyhedron * CreatePolyhedron ( ) const

create polyhedron

Definition at line 724 of file BelleCrystal.cc.

725{
726 int np = 2 * nsides;
727 vector<G4ThreeVector> pt(np);
728 for (int i = 0; i < np; i++) pt[i] = vertex(i);
729 return new PolyhedronBelleCrystal(np, pt.data());
730}
Belle crystal in polyhedron.
Definition: BelleCrystal.h:153

◆ DescribeYourselfTo()

void DescribeYourselfTo ( G4VGraphicsScene &  scene) const

Visualisation functions.

Definition at line 703 of file BelleCrystal.cc.

704{
705 scene.AddSolid(*this);
706}

◆ DistanceToIn() [1/2]

G4double DistanceToIn ( const G4ThreeVector &  p) const

Calculate exact shortest distance to any boundary from outside.

Definition at line 382 of file BelleCrystal.cc.

383{
384 // return ref->DistanceToIn(p);
385 COUNTER(2);
386 MATCHOUT("DistanceToIn(p) " << p.x() << " " << p.y() << " " << p.z());
387 G4double d = std::fabs(p.z()) - fDz;
388 unsigned int i = 0;
389 do {
390 const Plane_t& t = fPlanes[i++];
391 d = max(t.n * p + t.d, d);
392 } while (i < nsides);
393 d = max(d, 0.0);
394
395 // if(abs(d - ref->DistanceToIn(p))>kCarTolerance){
396 // cout<<GetName()<<" "<<p<<" "<<d-ref->DistanceToIn(p)<<endl;
397 // exit(0);
398 // }
399 // if(fmatch&&d==0.0) cout<<"inside\n";
400 return d;
401}
struct for plane
Definition: BelleCrystal.h:24

◆ DistanceToIn() [2/2]

G4double DistanceToIn ( const G4ThreeVector &  p,
const G4ThreeVector &  v 
) const

Calculate exact shortest distance to any boundary from outside.

Definition at line 430 of file BelleCrystal.cc.

432{
433 // return ref->DistanceToIn(p,v);
434 COUNTER(4);
435 MATCHOUT("DistanceToIn(p,v) " << p.x() << " " << p.y() << " " << p.z() << " " << v.x() << " " << v.y() << " " << v.z());
436 G4double delta = 0.5 * kCarTolerance;
437 double tin = 0, tout = kInfinity;
438 auto outside = [delta, &tin, &tout](double d, double nv) -> bool {
439 double t = -d / nv;
440 if (nv < 0)
441 tin = max(tin, t);
442 else
443 {
444 if (d >= -delta) return true;
445 tout = min(tout, t);
446 }
447 return false;
448 };
449
450 unsigned int i = 0;
451 do {
452 const Plane_t& t = fPlanes[i++];
453 if (outside(t.n * p + t.d, t.n * v)) {tin = kInfinity; goto exit;}
454 } while (i < nsides);
455 do {
456 if (outside(p.z() - fDz, v.z())) {tin = kInfinity; goto exit;}
457 if (outside(-p.z() - fDz, -v.z())) {tin = kInfinity; goto exit;}
458 } while (0);
459exit:
460 double res = (tin > tout) ? kInfinity : tin;
461 // G4int oldprc = cout.precision(16);
462 // if(nsides==5) cout<<GetName()<<" "<<p.x()<<" "<<p.y()<<" "<<p.z()<<" "<<v.x()<<" "<<v.y()<<" "<<v.z()<<" "<<res<<endl;
463 // cout.precision(oldprc);
464
465 // if(abs(res - ref->DistanceToIn(p,v))>kCarTolerance){
466 // cout<<GetName()<<" "<<p<<" "<<v<<" "<<res-ref->DistanceToIn(p,v)<<endl;
467 // exit(0);
468 // }
469 return res;
470}

◆ DistanceToOut() [1/2]

G4double DistanceToOut ( const G4ThreeVector &  p) const

Calculate exact shortest distance to any boundary from inside.

Definition at line 405 of file BelleCrystal.cc.

406{
407 // return ref->DistanceToOut(p);
408 COUNTER(3);
409 MATCHOUT("DistanceToOut(p) " << p.x() << " " << p.y() << " " << p.z());
410 G4double d = fDz - std::fabs(p.z());
411 unsigned int i = 0;
412 do {
413 const Plane_t& t = fPlanes[i++];
414 d = min(-(t.n * p + t.d), d);
415 } while (i < nsides);
416 d = max(d, 0.0);
417 // if(abs(d - ref->DistanceToOut(p))>0){
418 // cout<<GetName()<<" "<<p<<" "<<d<<" "<<ref->DistanceToOut(p)<<" "<<fDz-ref->GetZHalfLength()<<endl;
419 // exit(0);
420 // }
421 return d;
422}

◆ DistanceToOut() [2/2]

G4double DistanceToOut ( const G4ThreeVector &  p,
const G4ThreeVector &  v,
const G4bool  calcNorm = false,
G4bool *  validNorm = 0,
G4ThreeVector *  n = 0 
) const

Calculate exact shortest distance to any boundary from inside.

Definition at line 474 of file BelleCrystal.cc.

476{
477 // return ref->DistanceToOut(p,v,calcNorm,IsValid,n);
478 COUNTER(5);
479 MATCHOUT("DistanceToOut(p,v) " << p.x() << " " << p.y() << " " << p.z() << " " << v.x() << " " << v.y() << " " << v.z() << " " <<
480 calcNorm);
481 const G4double delta = 0.5 * kCarTolerance;
482 unsigned int iside = 10;
483 G4double lmin = kInfinity;
484
485 auto outside = [delta, &lmin, &iside](double d, double nv, unsigned int i) -> bool {
486 if (d > delta) // definitely outside
487 {
488 lmin = 0; iside = i; return true;
489 } else
490 {
491 bool c = nv > 0;
492 if (d < -delta) { // definitely inside
493 if (c) { // has to point to the same direction
494 d = -d;
495 if (d < nv * lmin) {lmin = d / nv; iside = i;}
496 }
497 } else { // surface
498 if (c) { // points outside
499 lmin = 0; iside = i; return true;
500 }
501 }
502 }
503 return false;
504 };
505
506 unsigned int i = 0;
507 do {
508 const Plane_t& t = fPlanes[i];
509 if (outside(t.n * p + t.d, t.n * v, i++)) goto exit;
510 } while (i < nsides);
511 do {
512 if (outside(p.z() - fDz, v.z(), i++)) goto exit;
513 if (outside(-p.z() - fDz, -v.z(), i++)) goto exit;
514 } while (0);
515exit:
516 if (calcNorm) {
517 *IsValid = true;
518 if (iside < nsides) {
519 *n = fPlanes[iside].n;
520 } else if (iside == nsides) {
521 *n = G4ThreeVector(0, 0, 1);
522 } else {
523 *n = G4ThreeVector(0, 0, -1);
524 }
525 }
526 // G4int oldprc = cout.precision(16);
527 // if(nsides==5) cout<<GetName()<<" "<<p.x()<<" "<<p.y()<<" "<<p.z()<<" "<<v.x()<<" "<<v.y()<<" "<<v.z()<<" "<<calcNorm<<" "<<lmin<<endl;
528 // cout.precision(oldprc);
529 // do {
530 // G4bool t_IsValid; G4ThreeVector t_n;
531 // double t_lmin = ref->DistanceToOut(p,v,calcNorm,&t_IsValid,&t_n);
532 // if(abs(lmin - t_lmin)>kCarTolerance||*IsValid!=t_IsValid||(*n - t_n).mag()>kCarTolerance){
533 // cout<<GetName()<<" "<<p<<" "<<v<<" "<<lmin-t_lmin<<(*n-t_n)<<endl;
534 // exit(0);
535 // }
536 // } while(0);
537 return lmin;
538}

◆ GetCubicVolume()

G4double GetCubicVolume ( )

get the Cubic volume

Definition at line 674 of file BelleCrystal.cc.

675{
676 // cout<<GetName()<<" GetCubicVolume "<<fCubicVolume<<endl;
677 if (fCubicVolume == 0.0) {
678 fCubicVolume = getvolarea();
679 fSurfaceArea = fareas.back();
680 }
681 return fCubicVolume;
682}
std::vector< double > fareas
vector of area values
Definition: BelleCrystal.h:149
double getvolarea() const
get volume area

◆ GetEntityType()

G4GeometryType GetEntityType ( ) const

Get entity type.

Definition at line 541 of file BelleCrystal.cc.

542{
543 return G4String("BelleCrystal");
544}

◆ GetPointOnSurface()

G4ThreeVector GetPointOnSurface ( ) const

get point on surface

Definition at line 694 of file BelleCrystal.cc.

695{
696 if (fareas.size() == 0) getvolarea();
697 double r = CLHEP::RandFlat::shoot(0., fareas.back());
698 std::vector<double>::const_iterator it = std::lower_bound(fareas.begin(), fareas.end(), r);
699 return (it != fareas.end()) ? GetPointOnTriangle(it - fareas.begin()) : GetPointOnSurface();
700}
G4ThreeVector GetPointOnTriangle(int) const
Returns a random point on the surface of one of the faces.
G4ThreeVector GetPointOnSurface() const
get point on surface

◆ GetPointOnTriangle()

G4ThreeVector GetPointOnTriangle ( int  it) const
private

Returns a random point on the surface of one of the faces.

Definition at line 634 of file BelleCrystal.cc.

635{
636 // barycentric coordinates
637 double a1 = CLHEP::RandFlat::shoot(0., 1.), a2 = CLHEP::RandFlat::shoot(0., 1.);
638 if (a1 + a2 > 1) { a1 = 1 - a1; a2 = 1 - a2;}
639 double a0 = 1 - (a1 + a2);
640 const unsigned int* iv = ivertx(it);
641 G4ThreeVector p0 = vertex(iv[0]), p1 = vertex(iv[1]), p2 = vertex(iv[2]);
642 G4ThreeVector r1(p0.x()*a0 + p1.x()*a1 + p2.x()*a2,
643 p0.y()*a0 + p1.y()*a1 + p2.y()*a2,
644 p0.z()*a0 + p1.z()*a1 + p2.z()*a2);
645 return r1;
646}

◆ GetSidePlane()

Plane_t GetSidePlane ( G4int  n) const
inline

Get side plane.

Definition at line 48 of file BelleCrystal.h.

48{return fPlanes[n];}

◆ GetSurfaceArea()

G4double GetSurfaceArea ( )

get the surface area

Definition at line 684 of file BelleCrystal.cc.

685{
686 if (fSurfaceArea == 0.0) {
687 fCubicVolume = getvolarea();
688 fSurfaceArea = fareas.back();
689 }
690 return fSurfaceArea;
691}

◆ getvolarea()

double getvolarea ( ) const
private

get volume area

Definition at line 658 of file BelleCrystal.cc.

659{
660 fareas.clear();
661 int nt = 2 * nsides + 2 * (nsides - 2); // total number of triangles
662 fareas.reserve(nt);
663 double totarea = 0, totvol = 0;
664 for (int i = 0; i < nt; i++) {
665 double v, s = area(i, v);
666 totarea += s;
667 totvol += v;
668 fareas.push_back(totarea);
669 // cout<<i<<" "<<s<<" "<<v<<endl;
670 }
671 return totvol / 6;
672}
double area(int, double &) const
triangle area

◆ Inside()

EInside Inside ( const G4ThreeVector &  p) const

Return whether point inside/outside/on surface, using tolerance.

Definition at line 298 of file BelleCrystal.cc.

299{
300 COUNTER(0);
301 MATCHOUT("Inside(p) " << p.x() << " " << p.y() << " " << p.z());
302 // return ref->Inside(p);
303 double d = std::fabs(p.z()) - fDz;
304 unsigned int i = 0;
305 do {
306 const Plane_t& t = fPlanes[i++];
307 d = max(t.n * p + t.d, d);
308 } while (i < nsides);
309 const G4double delta = 0.5 * kCarTolerance;
310 int in = 0;
311 in += d <= delta;
312 in += d <= -delta;
313
314 EInside res = EInside(in);
315 // if(res != ref->Inside(p)){
316 // cout<<GetName()<<" "<<p<<endl;
317 // exit(0);
318 // }
319 return res;
320}

◆ ivertx()

const unsigned int * ivertx ( unsigned int  i) const
private

get the ith vertex

Definition at line 572 of file BelleCrystal.cc.

573{
574 static unsigned int vert[3];
575 // if(nsides==4) return ivertx4[it];
576 if (nsides == 0) return ivertx4[it];
577 // else if(nsides==5) { vert[0] = ivertx5[it][0], vert[1] = ivertx5[it][1], vert[2] = ivertx5[it][2];}
578 else {
579 if (it < 2 * nsides) {
580 int j = it / 2;
581 if ((it & 1) == 0) {
582 vert[0] = j, vert[2] = j + nsides, vert[1] = ((j + 1) % nsides) + nsides;
583 } else {
584 vert[0] = j, vert[2] = ((j + 1) % nsides) + nsides, vert[1] = (j + 1) % nsides;
585 }
586 } else if (it < 2 * nsides + (nsides - 2)) {
587 int j = it - 2 * nsides;
588 vert[0] = 0, vert[2] = 1 + j, vert[1] = 2 + j;
589 } else {
590 int j = it - (2 * nsides + (nsides - 2));
591 vert[0] = nsides, vert[2] = nsides + 2 + j, vert[1] = nsides + 1 + j;
592 }
593 }
594 // cout<<it<<" {"<<vert[0]<<", "<<vert[1]<<", "<<vert[2]<<"}"<<endl;
595 return vert;
596}

◆ MakePlane()

G4bool MakePlane ( const G4ThreeVector &  p1,
const G4ThreeVector &  p2,
const G4ThreeVector &  p3,
const G4ThreeVector &  p4,
Plane_t plane 
) const
protected

Calculate the coef's of the plane p1->p2->p3->p4->p1 where the ThreeVectors 1-4 are in anti-clockwise order when viewed from in front of the plane (i.e.

from normal direction).

Return true if the ThreeVectors are coplanar + set coef;s false if ThreeVectors are not coplanar

Definition at line 198 of file BelleCrystal.cc.

201{
202 G4ThreeVector v12 = p2 - p1;
203 G4ThreeVector v13 = p3 - p1;
204 G4ThreeVector v14 = p4 - p1;
205 G4ThreeVector Vcross = v12.cross(v13);
206
207 if (std::fabs(Vcross.dot(v14) / (Vcross.mag()*v14.mag())) > kCoplanar_Tolerance) {
208 std::ostringstream message;
209 message << "Vertices are not in the same plane: " << GetName() << " volume =" << Vcross.dot(v14);
210 G4Exception("BelleCrystal::MakePlane()", "BelleCrystal", FatalException, message);
211 }
212
213 double a = +(p4.y() - p2.y()) * (p3.z() - p1.z()) - (p3.y() - p1.y()) * (p4.z() - p2.z());
214 double b = -(p4.x() - p2.x()) * (p3.z() - p1.z()) + (p3.x() - p1.x()) * (p4.z() - p2.z());
215 double c = +(p4.x() - p2.x()) * (p3.y() - p1.y()) - (p3.x() - p1.x()) * (p4.y() - p2.y());
216 double sd = sqrt(a * a + b * b + c * c); // so now vector plane.(a,b,c) is unit
217 a /= sd;
218 b /= sd;
219 c /= sd;
220 plane.n = G4ThreeVector(a, b, c);
221 plane.d = -(a * p1.x() + b * p1.y() + c * p1.z());
222
223 // plane.n = (p4-p2).cross(p3-p1).unit();
224 // plane.d =-(plane.n*p1);
225 return true;
226}
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28

◆ operator=()

BelleCrystal & operator= ( const BelleCrystal rhs)

assignment operator

Definition at line 175 of file BelleCrystal.cc.

176{
177 // Check assignment to self
178 if (this == &rhs) { return *this; }
179
180 // Copy base class data
181 G4CSGSolid::operator=(rhs);
182
183 // Copy data
184 nsides = rhs.nsides;
185 fDz = rhs.fDz;
186 fx = rhs.fx;
187 fPlanes = rhs.fPlanes;
188
189 return *this;
190}

◆ StreamInfo()

std::ostream & StreamInfo ( std::ostream &  os) const

Stream object contents to an output stream.

Definition at line 553 of file BelleCrystal.cc.

554{
555 G4int oldprc = os.precision(16);
556 os << "-----------------------------------------------------------\n"
557 << " *** Dump for solid - " << GetName() << " ***\n"
558 << " ===================================================\n"
559 << " Solid type: BelleCrystal\n"
560 << " Parameters: \n"
561 << " crystal side plane equations:\n"
562 << "-----------------------------------------------------------\n";
563 os.precision(oldprc);
564
565 return os;
566}

◆ SurfaceNormal()

G4ThreeVector SurfaceNormal ( const G4ThreeVector &  p) const

Calculate side nearest to p, and return normal.

Definition at line 324 of file BelleCrystal.cc.

325{
326 // return ref->SurfaceNormal(p);
327 COUNTER(1);
328 MATCHOUT("SurfaceNormal(p) " << p.x() << " " << p.y() << " " << p.z());
329 const G4double delta = 0.5 * kCarTolerance;
330 G4double safe = kInfinity;
331 unsigned int iside = 0, kside = 0;
332 vector<double> adist(nsides + 2);
333 auto dist = [delta, &safe, &iside, &kside, &adist](double d, unsigned int i) -> void {
334 d = std::abs(d);
335 adist[i] = d;
336 iside = (d < safe) ? i : iside;
337 safe = min(d, safe);
338 kside += d < delta;
339 };
340
341 unsigned int i = 0;
342 do {
343 const Plane_t& t = fPlanes[i];
344 dist(t.n * p + t.d, i++);
345 } while (i < nsides);
346 do {
347 dist(p.z() - fDz, i++);
348 dist(p.z() + fDz, i++);
349 } while (0);
350
351 G4ThreeVector res;
352 if (kside > 1) {
353 i = 0;
354 do {
355 if (adist[i++] < delta) res += fPlanes[i].n;
356 } while (i < nsides);
357 do {
358 if (adist[i++] < delta) res.setZ(res.z() + 1.0);
359 if (adist[i++] < delta) res.setZ(res.z() - 1.0);
360 } while (0);
361 res = res.unit();
362 } else {
363 if (iside < nsides) {
364 res = fPlanes[iside].n;
365 } else if (iside == nsides) {
366 res = G4ThreeVector(0, 0, 1);
367 } else {
368 res = G4ThreeVector(0, 0, -1);
369 }
370 }
371 // if((res- ref->SurfaceNormal(p)).mag()>kCarTolerance){
372 // cout<<GetName()<<" "<<p<<" "<<res-ref->SurfaceNormal(p)<<endl;
373 // exit(0);
374 // }
375
376 return res;
377}

◆ vertex()

G4ThreeVector vertex ( unsigned int  i) const

return ith vertex

Definition at line 612 of file BelleCrystal.cc.

613{
614 double Dz = (i < nsides) ? -fDz : fDz;
615
616 // if(nsides==4) {
617 // const unsigned char w = 2, mask = ((1<<w)-1);
618 // unsigned int map = PACK(0,2,w,0)+PACK(0,3,w,1)+PACK(1,2,w,2)+PACK(1,3,w,3); // 20 bits
619 // map >>= (2*w)*(i%4);
620 // int k0 = map&mask, k1 = (map>>2)&mask;
621 // return crossplanes(fPlanes[k0],fPlanes[k1],Dz);
622 // } else if(nsides==5){
623 // const unsigned char w = 3, mask = ((1<<w)-1);
624 // unsigned int map = PACK(0,4,w,0)+PACK(1,0,w,1)+PACK(2,1,w,2)+PACK(3,2,w,3)+PACK(4,3,w,4); // 30 bits
625 // map >>= (2*w)*(i%5);
626 // int k0 = map&mask, k1 = (map>>w)&mask;
627 // return crossplanes(fPlanes[k0],fPlanes[k1],Dz);
628 // }
629 return G4ThreeVector(fx[i].x, fx[i].y, Dz);
630}

Member Data Documentation

◆ fareas

std::vector<double> fareas
mutableprivate

vector of area values

Definition at line 149 of file BelleCrystal.h.

◆ fDz

double fDz
private

Dz.

Definition at line 145 of file BelleCrystal.h.

◆ fPlanes

std::vector<Plane_t> fPlanes
private

vector of planes

Definition at line 146 of file BelleCrystal.h.

◆ fx

std::vector<Point_t> fx
private

vector of points

Definition at line 147 of file BelleCrystal.h.

◆ nsides

unsigned int nsides
private

the number of sides

Definition at line 144 of file BelleCrystal.h.


The documentation for this class was generated from the following files: