39 #ifndef EGS_CD_GEOMETRY_
40 #define EGS_CD_GEOMETRY_
47 #ifdef BUILD_CDGEOMETRY_DLL
48 #define EGS_CDGEOMETRY_EXPORT __declspec(dllexport)
50 #define EGS_CDGEOMETRY_EXPORT __declspec(dllimport)
52 #define EGS_CDGEOMETRY_LOCAL
56 #ifdef HAVE_VISIBILITY
57 #define EGS_CDGEOMETRY_EXPORT __attribute__ ((visibility ("default")))
58 #define EGS_CDGEOMETRY_LOCAL __attribute__ ((visibility ("hidden")))
60 #define EGS_CDGEOMETRY_EXPORT
61 #define EGS_CDGEOMETRY_LOCAL
271 new_indexing =
false;
277 for (
int j=0; j<nbase; j++) {
301 if (!G1)
egsFatal(
"EGS_CDGeometry: got a null pointer to the"
302 " base geometry?\n");
304 new_indexing =
false;
307 if (nbase != G.size())
egsFatal(
"EGS_CDGeometry: number of passed"
308 " geometries (%d) is not the same as the number of regions (%d)\n",
313 for (
int j=0; j<nbase; j++) {
337 for (
int j=0; j<nbase; j++) {
339 if (!g[j]->
deref()) {
350 delete [] reg_to_base;
353 delete [] local_start;
358 int medium(
int ireg)
const {
366 ibase = reg_to_base[ireg];
367 ilocal = ireg - local_start[ibase];
371 ilocal = ireg-ibase*nmax;
373 return g[ibase] ? g[ibase]->medium(ilocal) : bg->medium(ibase);
377 if (ireg < 0 || ireg >= nreg) {
382 ibase = reg_to_base[ireg];
383 icd = ireg-local_start[ibase];
387 icd = ireg - ibase*nmax;
389 return g[ibase] ? g[ibase]->isRealRegion(icd) :
390 bg->isRealRegion(ibase);
394 int ibase = bg->isWhere(x);
399 return g[ibase]->isInside(x);
405 int ibase = bg->isWhere(x);
411 ir = g[ibase]->isWhere(x);
416 return new_indexing ? local_start[ibase] + ir : ibase*nmax + ir;
424 EGS_Float &t,
int *newmed = 0,
EGS_Vector *normal = 0) {
432 ibase = reg_to_base[ireg];
433 icd = ireg-local_start[ibase];
437 icd = ireg - ibase*nmax;
443 int ibase_new = bg->howfar(ibase,x,u,t,newmed,normal);
449 int icd_new = g[ibase]->howfar(icd,x,u,t,newmed,normal);
457 return new_indexing ? local_start[ibase] + icd_new :
458 ibase*nmax + icd_new;
463 if (ibase_new != ibase) {
473 int icd_new = g[ibase_new]->isWhere(tmp);
482 *newmed = g[ibase_new]->medium(icd_new);
484 return new_indexing ? local_start[ibase_new] + icd_new :
485 ibase_new*nmax + icd_new;
490 return new_indexing ? local_start[ibase_new] : ibase_new*nmax;
501 int ibase = bg->isWhere(x);
502 EGS_Float tb=0, ttot=0;
503 bool first_time =
true;
507 int *pmednew = newmed ? &mednew : 0;
523 int icd = g[ibase] ? g[ibase]->isWhere(x) : 0;
545 int ixold = new_indexing ? local_start[ibase] + icd :
553 int ixnew =
howfar(ixold,x,u,tb,0,pn);
556 if (ixnew >= 0 && tb <= boundaryTolerance) {
558 if (newmed) *newmed = g[ibase] ? g[ibase]->medium(icd) :
580 int ixnew_neg =
howfar(ixold,x,u*(-1),tb_neg,0,pn);
581 if (ixnew_neg < 0 && tb_neg <=
epsilon) {
584 *newmed = g[ibase] ? g[ibase]->medium(icd) : bg->medium(ibase);
587 *normal = (*pn)*(-1);
598 ibase_n = bg->howfar(ibase,x,u,t1);
599 if (ibase_n < 0 && t1 < boundaryTolerance) {
605 ibase_n = bg->howfar(ibase_n,xtmp,u,tb,pmednew,pn);
621 ic_n = g[ibase]->howfar(icd,x,u,t2);
622 if (ic_n < 0 && t2 < boundaryTolerance) {
627 ibase = bg->isWhere(xtmp);
630 ibase = bg->howfar(ibase,xtmp,u,tb,pmednew,pn);
645 if (t1 < boundaryTolerance && ibase_n >= 0 && g[ibase_n]) {
648 int icdx = g[ibase_n]->isWhere(xtmp);
657 if (t1 > boundaryTolerance && t2 > boundaryTolerance) {
659 egsWarning(
"EGS_CDGeometry::howfar: ireg<0, but position appears inside\n");
660 egsWarning(
" name=%s base name=%s inscribed name=%s\n",name.c_str(),
661 bg->getName().c_str(),g[ibase] ? g[ibase]->getName().c_str() :
"none");
662 egsWarning(
" x=(%g,%g,%g) u=(%g,%g,%g) ibase=%d icd=%d\n",
663 x.
x,x.
y,x.
z,u.
x,u.
y,u.
z,ibase,icd);
664 egsWarning(
" distance to boundaries: base=(%d,%g) inscribed=(%d,%g)\n",
678 ibase = bg->howfar(ireg,x,u,tb,pmednew,pn);
691 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
693 egsFatal(
"EGS_CDGeometry::howfar: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
704 return new_indexing ? local_start[ibase] : ibase*nmax;
709 icd = g[ibase]->isWhere(tmp);
715 *newmed = g[ibase]->medium(icd);
720 return new_indexing ? local_start[ibase] + icd :
727 EGS_Float tnew = t - ttot;
728 int ibase_new = bg->howfar(ibase,tmp,u,tnew,pmednew,pn);
731 int icd_new = g[ibase]->howfar(-1,tmp,u,tnew,pmednew,pn);
741 return new_indexing ? local_start[ibase] + icd_new :
742 ibase*nmax + icd_new;
748 if (ibase_new == ibase) {
755 ibase_new = bg->howfar(-1,tmp,u,tnew,pmednew,pn);
764 if (tnew < boundaryTolerance) {
780 ibase = reg_to_base[ireg];
781 icd = ireg - local_start[ibase];
785 icd = ireg - ibase*nmax;
787 EGS_Float t = bg->hownear(ibase,x);
788 if (!g[ibase] || t <= 0) {
791 EGS_Float t1 = g[ibase]->hownear(icd,x);
792 return (t1 < t ? t1 : t);
794 int ibase = bg->isWhere(x);
796 EGS_Float tt = bg->hownear(ireg,x);
799 EGS_Float t = bg->hownear(ibase,x);
801 EGS_Float t1 = g[ibase]->hownear(-1,x);
811 for (
int j=0; j<bg->regions(); ++j) {
813 nstep += g[j]->getMaxStep();
823 if (ireg >= 0 && ireg < nreg) {
824 int ibase = ireg/nmax;
826 g[ibase]->hasBooleanProperty(ireg - ibase*nmax,prop) :
827 bg->hasBooleanProperty(ibase,prop);
832 setPropertError(
"setBooleanProperty()");
835 setPropertError(
"addBooleanProperty()");
838 setPropertError(
"setBooleanProperty()");
841 setPropertError(
"addBooleanProperty()");
844 const string &
getType()
const {
851 if (ireg < 0 || ireg >= nbase*nmax) {
854 int ibase = ireg/nmax;
855 return g[ibase] ? g[ibase]->getRelativeRho(ireg-ibase*nmax) :
856 bg->getRelativeRho(ibase);
859 void setBScaling(
int start,
int end, EGS_Float bf);
862 if (ireg < 0 || ireg >= nbase*nmax) {
865 int ibase = ireg/nmax;
866 return g[ibase] ? g[ibase]->getBScaling(ireg-ibase*nmax) :
867 bg->getBScaling(ibase);
904 void setPropertError(
const char *funcname) {
905 egsFatal(
"EGS_CDGeometry::%s: don't use this method\n Define "
906 "properties in the constituent geometries instead\n");
909 void setHasRhoScaling() {
910 has_rho_scaling =
false;
911 if (bg->hasRhoScaling()) {
912 has_rho_scaling =
true;
915 for (
int j=0; j<nbase; j++) {
918 has_rho_scaling =
true;
925 void setHasBScaling() {
926 has_B_scaling =
false;
927 if (bg->hasBScaling()) {
928 has_B_scaling =
true;
931 for (
int j=0; j<nbase; j++) {
934 has_B_scaling =
true;
941 void setUpIndexing();
virtual const string & getType() const =0
Get the geometry type.
virtual bool isInside(const EGS_Vector &x)=0
Is the position x inside the geometry?
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
virtual bool hasBooleanProperty(int ireg, EGS_BPType prop) const
Is the boolean property prop set for region ireg ?
int regions() const
Returns the number of local regions in this geometry.
int deref()
Decrease the reference count to this geometry.
virtual int medium(int ireg) const
Returns the medium index in region ireg.
EGS_BaseGeometry(const string &Name)
Construct a geometry named Name.
virtual int getMaxStep() const
Returns the maximum number of steps through the geometry.
A class representing 3D vectors.
bool hasRhoScaling() const
Does this geometry object have a mass density scaling feature?
Global egspp functions header file.
virtual int isWhere(const EGS_Vector &x)=0
In which region is poisition x?
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.
const EGS_Float veryFar
A very large float.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual void setRelativeRho(int start, int end, EGS_Float rho)
Set the relative mass density in regions.
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.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
A "combinatorial dimension" geometry.
virtual void getLabelRegions(const string &str, vector< int > ®s)
Get the list of all regions labeled with str.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
virtual int inside(const EGS_Vector &x)=0
Returns the region index, if inside, or -1 if outside (obsolete)
bool hasBScaling() const
Does this geometry object have a B field scaling feature?
virtual EGS_Float hownear(int ireg, const EGS_Vector &x)=0
Calculate the distance to a boundary for position x in any direction.
virtual EGS_Float getRelativeRho(int ireg) const
Get the relative mass density in region ireg.
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
virtual bool isRealRegion(int ireg) const
Returnes true if ireg is a real region, false otherwise.
const EGS_Float epsilon
The epsilon constant for floating point comparisons.
EGS_BaseGeometry class header file.
virtual void addBooleanProperty(int bit)
Add a boolean property for the entire geometry by setting the bit'th bit.
virtual void setBooleanProperty(EGS_BPType prop)
Set the boolean properties of the entire geometry to prop.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.