41 #ifndef EGS_CD_GEOMETRY_
42 #define EGS_CD_GEOMETRY_
49 #ifdef BUILD_CDGEOMETRY_DLL
50 #define EGS_CDGEOMETRY_EXPORT __declspec(dllexport)
52 #define EGS_CDGEOMETRY_EXPORT __declspec(dllimport)
54 #define EGS_CDGEOMETRY_LOCAL
58 #ifdef HAVE_VISIBILITY
59 #define EGS_CDGEOMETRY_EXPORT __attribute__ ((visibility ("default")))
60 #define EGS_CDGEOMETRY_LOCAL __attribute__ ((visibility ("hidden")))
62 #define EGS_CDGEOMETRY_EXPORT
63 #define EGS_CDGEOMETRY_LOCAL
273 new_indexing =
false;
279 for (
int j=0; j<nbase; j++) {
303 if (!G1)
egsFatal(
"EGS_CDGeometry: got a null pointer to the"
304 " base geometry?\n");
306 new_indexing =
false;
309 if (nbase != G.size())
egsFatal(
"EGS_CDGeometry: number of passed"
310 " geometries (%d) is not the same as the number of regions (%d)\n",
315 for (
int j=0; j<nbase; j++) {
339 for (
int j=0; j<nbase; j++) {
341 if (!g[j]->
deref()) {
352 delete [] reg_to_base;
355 delete [] local_start;
360 int medium(
int ireg)
const {
368 ibase = reg_to_base[ireg];
369 ilocal = ireg - local_start[ibase];
373 ilocal = ireg-ibase*nmax;
375 return g[ibase] ? g[ibase]->medium(ilocal) : bg->medium(ibase);
379 if (ireg < 0 || ireg >= nreg) {
384 ibase = reg_to_base[ireg];
385 icd = ireg-local_start[ibase];
389 icd = ireg - ibase*nmax;
391 return g[ibase] ? g[ibase]->isRealRegion(icd) :
392 bg->isRealRegion(ibase);
396 int ibase = bg->isWhere(x);
401 return g[ibase]->isInside(x);
407 int ibase = bg->isWhere(x);
413 ir = g[ibase]->isWhere(x);
418 return new_indexing ? local_start[ibase] + ir : ibase*nmax + ir;
426 EGS_Float &t,
int *newmed = 0,
EGS_Vector *normal = 0) {
434 ibase = reg_to_base[ireg];
435 icd = ireg-local_start[ibase];
439 icd = ireg - ibase*nmax;
445 int ibase_new = bg->howfar(ibase,x,u,t,newmed,normal);
451 int icd_new = g[ibase]->howfar(icd,x,u,t,newmed,normal);
459 return new_indexing ? local_start[ibase] + icd_new :
460 ibase*nmax + icd_new;
465 if (ibase_new != ibase) {
475 int icd_new = g[ibase_new]->isWhere(tmp);
484 *newmed = g[ibase_new]->medium(icd_new);
486 return new_indexing ? local_start[ibase_new] + icd_new :
487 ibase_new*nmax + icd_new;
492 return new_indexing ? local_start[ibase_new] : ibase_new*nmax;
503 int ibase = bg->isWhere(x);
504 EGS_Float tb=0, ttot=0;
505 bool first_time =
true;
509 int *pmednew = newmed ? &mednew : 0;
525 int icd = g[ibase] ? g[ibase]->isWhere(x) : 0;
547 int ixold = new_indexing ? local_start[ibase] + icd :
555 int ixnew =
howfar(ixold,x,u,tb,0,pn);
558 if (ixnew >= 0 && tb <= boundaryTolerance) {
560 if (newmed) *newmed = g[ibase] ? g[ibase]->medium(icd) :
582 int ixnew_neg =
howfar(ixold,x,u*(-1),tb_neg,0,pn);
583 if (ixnew_neg < 0 && tb_neg <=
epsilon) {
586 *newmed = g[ibase] ? g[ibase]->medium(icd) : bg->medium(ibase);
589 *normal = (*pn)*(-1);
600 ibase_n = bg->howfar(ibase,x,u,t1);
601 if (ibase_n < 0 && t1 < boundaryTolerance) {
607 ibase_n = bg->howfar(ibase_n,xtmp,u,tb,pmednew,pn);
623 ic_n = g[ibase]->howfar(icd,x,u,t2);
624 if (ic_n < 0 && t2 < boundaryTolerance) {
629 ibase = bg->isWhere(xtmp);
632 ibase = bg->howfar(ibase,xtmp,u,tb,pmednew,pn);
647 if (t1 < boundaryTolerance && ibase_n >= 0 && g[ibase_n]) {
650 int icdx = g[ibase_n]->isWhere(xtmp);
659 if (t1 > boundaryTolerance && t2 > boundaryTolerance) {
661 egsWarning(
"EGS_CDGeometry::howfar: ireg<0, but position appears inside\n");
662 egsWarning(
" name=%s base name=%s inscribed name=%s\n",name.c_str(),
663 bg->getName().c_str(),g[ibase] ? g[ibase]->getName().c_str() :
"none");
664 egsWarning(
" x=(%g,%g,%g) u=(%g,%g,%g) ibase=%d icd=%d\n",
665 x.
x,x.
y,x.
z,u.
x,u.
y,u.
z,ibase,icd);
666 egsWarning(
" distance to boundaries: base=(%d,%g) inscribed=(%d,%g)\n",
680 ibase = bg->howfar(ireg,x,u,tb,pmednew,pn);
693 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
695 egsFatal(
"EGS_CDGeometry::howfar: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
706 return new_indexing ? local_start[ibase] : ibase*nmax;
711 icd = g[ibase]->isWhere(tmp);
717 *newmed = g[ibase]->medium(icd);
722 return new_indexing ? local_start[ibase] + icd :
729 EGS_Float tnew = t - ttot;
730 int ibase_new = bg->howfar(ibase,tmp,u,tnew,pmednew,pn);
733 int icd_new = g[ibase]->howfar(-1,tmp,u,tnew,pmednew,pn);
743 return new_indexing ? local_start[ibase] + icd_new :
744 ibase*nmax + icd_new;
750 if (ibase_new == ibase) {
757 ibase_new = bg->howfar(-1,tmp,u,tnew,pmednew,pn);
766 if (tnew < boundaryTolerance) {
782 ibase = reg_to_base[ireg];
783 icd = ireg - local_start[ibase];
787 icd = ireg - ibase*nmax;
789 EGS_Float t = bg->hownear(ibase,x);
790 if (!g[ibase] || t <= 0) {
793 EGS_Float t1 = g[ibase]->hownear(icd,x);
794 return (t1 < t ? t1 : t);
796 int ibase = bg->isWhere(x);
798 EGS_Float tt = bg->hownear(ireg,x);
801 EGS_Float t = bg->hownear(ibase,x);
803 EGS_Float t1 = g[ibase]->hownear(-1,x);
813 for (
int j=0; j<bg->regions(); ++j) {
815 nstep += g[j]->getMaxStep();
825 for (
int j=0; j<bg->regions(); ++j) {
826 g[j]->getNextGeom(rndm);
828 bg->getNextGeom(rndm);
831 void updatePosition(EGS_Float time) {
832 for (
int j=0; j<bg->regions(); j++) {
833 g[j]->updatePosition(time);
835 bg->updatePosition(time);
838 void containsDynamic(
bool &hasdynamic) {
839 for (
int j=0; j<bg->regions(); j++) {
841 g[j]->containsDynamic(hasdynamic);
845 bg->containsDynamic(hasdynamic);
851 if (ireg >= 0 && ireg < nreg) {
852 int ibase = ireg/nmax;
854 g[ibase]->hasBooleanProperty(ireg - ibase*nmax,prop) :
855 bg->hasBooleanProperty(ibase,prop);
860 setPropertError(
"setBooleanProperty()");
863 setPropertError(
"addBooleanProperty()");
866 setPropertError(
"setBooleanProperty()");
869 setPropertError(
"addBooleanProperty()");
872 const string &
getType()
const {
879 if (ireg < 0 || ireg >= nbase*nmax) {
882 int ibase = ireg/nmax;
883 return g[ibase] ? g[ibase]->getRelativeRho(ireg-ibase*nmax) :
884 bg->getRelativeRho(ibase);
887 void setBScaling(
int start,
int end, EGS_Float bf);
890 if (ireg < 0 || ireg >= nbase*nmax) {
893 int ibase = ireg/nmax;
894 return g[ibase] ? g[ibase]->getBScaling(ireg-ibase*nmax) :
895 bg->getBScaling(ibase);
932 void setPropertError(
const char *funcname) {
933 egsFatal(
"EGS_CDGeometry::%s: don't use this method\n Define "
934 "properties in the constituent geometries instead\n");
937 void setHasRhoScaling() {
938 has_rho_scaling =
false;
940 has_rho_scaling =
true;
943 for (
int j=0; j<nbase; j++) {
946 has_rho_scaling =
true;
953 void setHasBScaling() {
954 has_B_scaling =
false;
956 has_B_scaling =
true;
959 for (
int j=0; j<nbase; j++) {
962 has_B_scaling =
true;
969 void setUpIndexing();
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual EGS_Float hownear(int ireg, const EGS_Vector &x)=0
Calculate the distance to a boundary for position x in any direction.
virtual int inside(const EGS_Vector &x)=0
Returns the region index, if inside, or -1 if outside (obsolete)
int deref()
Decrease the reference count to this geometry.
virtual bool hasBooleanProperty(int ireg, EGS_BPType prop) const
Is the boolean property prop set for region ireg ?
virtual EGS_Float getBScaling(int ireg) const
Get the B field scaling factor in region ireg.
virtual void setBScaling(int start, int end, EGS_Float bf)
Set the B field scaling factor in regions.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
virtual const string & getType() const =0
Get the geometry type.
virtual void getLabelRegions(const string &str, vector< int > ®s)
Get the list of all regions labeled with str.
virtual int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed=0, EGS_Vector *normal=0)=0
Calculate the distance to a boundary from x along the direction u.
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
bool hasBScaling() const
Does this geometry object have a B field scaling feature?
virtual bool isRealRegion(int ireg) const
Returnes true if ireg is a real region, false otherwise.
virtual bool isInside(const EGS_Vector &x)=0
Is the position x inside the geometry?
virtual EGS_Float getRelativeRho(int ireg) const
Get the relative mass density in region ireg.
virtual void setBooleanProperty(EGS_BPType prop)
Set the boolean properties of the entire geometry to prop.
virtual int getMaxStep() const
Returns the maximum number of steps through the geometry.
bool hasRhoScaling() const
Does this geometry object have a mass density scaling feature?
virtual int medium(int ireg) const
Returns the medium index in region ireg.
int regions() const
Returns the number of local regions in this geometry.
virtual void setRelativeRho(int start, int end, EGS_Float rho)
Set the relative mass density in regions.
virtual void addBooleanProperty(int bit)
Add a boolean property for the entire geometry by setting the bit'th bit.
EGS_BaseGeometry(const string &Name)
Construct a geometry named Name.
virtual int isWhere(const EGS_Vector &x)=0
In which region is poisition x?
A "combinatorial dimension" geometry.
Base random number generator class. All random number generators should be derived from this class.
A class representing 3D vectors.
EGS_BaseGeometry class header file.
Global egspp functions header file.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
const EGS_Float epsilon
The epsilon constant for floating point comparisons.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.
const EGS_Float veryFar
A very large float.