49 string EGS_cSpheres::type =
"EGS_cSpheres";
52 EGS_cSpheres::EGS_cSpheres(
int ns,
const EGS_Float *radius,
53 const EGS_Vector &position,
const string &Name) :
58 R2=
new EGS_Float [ns];
62 for (
int i=0; i<ns; i++) {
63 R2[i]=radius[i]*radius[i];
71 for (
int ireg=0; ireg < ns; ireg++) {
72 rbounds.push_back(radius[ireg]);
73 EGS_Float router = rbounds[ireg];
74 EGS_Float rinner = ireg > 0 ? rbounds[ireg-1] : 0;
75 vol.push_back((4./3.)*M_PI*(router*router*router - rinner*rinner*rinner));
79 bool EGS_cSpheres::isInside(
const EGS_Vector &x) {
81 EGS_Float r_sq=tmp.length2();
82 if (r_sq>R2[
nreg-1]) {
88 int EGS_cSpheres::isWhere(
const EGS_Vector &x) {
90 EGS_Float r_sq=tmp.length2();
91 if (r_sq>R2[
nreg-1]) {
101 int EGS_cSpheres::inside(
const EGS_Vector &x) {
104 EGS_Float r_sq=tmp.length2();
107 if (r_sq>R2[
nreg-1]) {
140 EGS_Float last_d,last_t,last_aa,last_bb2,last_R2b2,last_tmp;
143 EGS_Float EGS_cSpheres::howfarToOutside(
int ireg,
const EGS_Vector &x,
149 EGS_Float aa = xp*u, aa2 = aa*aa;
150 EGS_Float bb2 = xp.length2();
151 EGS_Float R2b2 = R2[
nreg-1] - bb2;
155 EGS_Float tmp = sqrt(aa2 + R2b2);
156 return aa > 0 ? R2b2/(tmp + aa) : tmp - aa;
159 int EGS_cSpheres::howfar(
int ireg,
const EGS_Vector &x,
161 int direction_flag=-1;
166 double aa = xp*u, aa2 = aa*aa;
167 double bb2 = xp.length2();
169 double rad=0, R2b2, tmp;
178 if (aa >= 0 || !ireg) {
184 R2b2 = R2[ireg] - bb2;
185 if (R2b2 <= 0 && aa > 0) {
186 d = halfBoundaryTolerance;
195 egsWarning(
"EGS_cSpheres::howfar: something is wrong\n");
196 egsWarning(
" we think we are in region %d, but R2b2=%g",
201 d = aa > 0 ? R2b2/(tmp + aa) : tmp - aa;
206 direction_flag=ireg+1;
207 if (direction_flag >=
nreg) {
217 R2b2 = R2[ireg-1] - bb2;
220 R2b2 = R2[ireg] - bb2;
229 direction_flag=ireg+1;
230 if (direction_flag >=
nreg) {
237 d = -R2b2/(tmp - aa);
238 direction_flag=ireg-1;
239 rad = R[direction_flag];
246 R2b2 = R2[
nreg-1] - bb2;
249 d = -R2b2/(sqrt(tmp) - aa);
250 direction_flag=
nreg-1;
251 rad = R[direction_flag];
263 egsWarning(
"ireg=%d inew=%d aa=%g bb2=%g\n",ireg,direction_flag,aa,bb2);
282 if (direction_flag >= 0) {
283 *newmed =
medium(direction_flag);
293 return direction_flag;
299 EGS_Float EGS_cSpheres::hownear(
int ireg,
const EGS_Vector &x) {
301 EGS_Float r=xp.length();
308 EGS_Float dd=r-R[ireg-1];
321 void EGS_cSpheres::printInfo()
const {
325 for (
int j=0; j<
nreg; j++) {
329 "\n=======================================================\n");
333 if (idir == RDIR && ind ==0) {
336 else if (idir == RDIR && ind>0 && ind <=
nreg) {
337 return rbounds[ind-1];
352 if (ireg >= 0 && ireg <
nreg) {
360 string EGS_cSphericalShell::type =
"EGS_cSphericalShell";
363 EGS_cSphericalShell::EGS_cSphericalShell(
int ns,
const EGS_Float *radius,
364 const EGS_Vector &position,
const string &Name) :
371 R2 =
new EGS_Float [ns];
372 R =
new EGS_Float [ns];
374 for (
int i=0; i<ns; i++) {
375 R2[i] = radius[i]*radius[i];
383 for (
int ireg=0; ireg <
nreg; ireg++) {
384 EGS_Float rinner = R[ireg];
385 EGS_Float router = R[ireg + 1];
386 vol.push_back((4./3.)*M_PI*(router*router*router - rinner*rinner*rinner));
390 bool EGS_cSphericalShell::isInside(
const EGS_Vector &x) {
391 EGS_Float r_sq = (x - xo).length2();
392 return (r_sq >= R2[0]) && (r_sq <= R2[
nreg]);
395 int EGS_cSphericalShell::isWhere(
const EGS_Vector &x) {
397 EGS_Float r_sq = (x - xo).length2();
399 if ((r_sq < R2[0]) || (r_sq > R2[
nreg])) {
406 int EGS_cSphericalShell::inside(
const EGS_Vector &x) {
409 EGS_Float r_sq=tmp.length2();
412 if (r_sq > R2[
nreg] || r_sq < R2[0]) {
416 for (
int shell = 1; shell <
nreg + 1; shell++) {
417 if (r_sq <= R2[shell]) {
426 EGS_Float EGS_cSphericalShell::howfarToOutside(
int ireg,
const EGS_Vector &x,
433 EGS_Float aa2 = aa*aa;
434 EGS_Float bb2 = xp.length2();
435 EGS_Float R2b2 = R2[
nreg] - bb2;
436 EGS_Float R2b2in = R2[0] - bb2;
437 if (R2b2in <= 0 || R2b2 <= 0) {
447 if (R2b2 <= 0 && aa > 0) {
457 egsWarning(
"EGS_cSphericalShell::howfarToOutside: something is wrong\n");
458 egsWarning(
" we think we are in region %d, but R2b2=%g", ireg,R2b2);
462 d = aa > 0 ? R2b2/(tmp + aa) : tmp - aa;
470 R2b2 = R2[
nreg] - bb2;
482 d = -R2b2/(tmp - aa);
496 int EGS_cSphericalShell::howfar(
int ireg,
const EGS_Vector &x,
498 int direction_flag=-1;
503 double aa = xp*u, aa2 = aa*aa;
504 double bb2 = xp.length2();
506 double rad=0, R2b2, tmp;
520 R2b2 = R2[ireg + 1] - bb2;
521 if (R2b2 <= 0 && aa > 0) {
531 egsWarning(
"EGS_cSphericalShell::howfar: something is wrong\n");
532 egsWarning(
" we think we are in region %d, but R2b2=%g",
537 d = aa > 0 ? R2b2/(tmp + aa) : tmp - aa;
542 direction_flag = ireg + 1;
543 if (direction_flag >=
nreg) {
553 R2b2 = R2[ireg] - bb2;
556 R2b2 = R2[ireg+1] - bb2;
565 direction_flag= ireg + 1;
566 if (direction_flag >=
nreg) {
573 d = -R2b2/(tmp - aa);
574 direction_flag= ireg - 1;
586 tmp = sqrt(aa2 + R2b2);
587 d = aa > 0 ? R2b2/(tmp + aa) : tmp - aa;
589 rad = -R[direction_flag];
594 R2b2 = R2[
nreg] - bb2;
597 d = -R2b2/(sqrt(tmp) - aa);
598 direction_flag=
nreg-1;
609 if (direction_flag >= 0) {
610 *newmed =
medium(direction_flag);
620 return direction_flag;
626 EGS_Float EGS_cSphericalShell::hownear(
int ireg,
const EGS_Vector &x) {
629 EGS_Float r = xp.length();
630 EGS_Float d, dout,din;
633 dout = R[ireg+1] - r;
637 else if (r <= R[0] +
epsilon) {
647 EGS_Float EGS_cSphericalShell::getBound(
int idir,
int ind) {
648 if (idir == RDIR && ind >= 0 && ind <=
nreg) {
655 int EGS_cSphericalShell::getNRegDir(
int dir) {
663 EGS_Float EGS_cSphericalShell::getVolume(
int ireg) {
664 if (ireg >= 0 && ireg <
nreg) {
671 void EGS_cSphericalShell::printInfo()
const {
675 for (
int j=0; j<
nreg+1; j++) {
679 "\n=======================================================\n");
686 egsWarning(
"createGeometry(spheres): null input?\n");
690 vector<EGS_Float> Xo;
691 int err = input->
getInput(
"midpoint",Xo);
692 if (!err && Xo.size() == 3) {
699 vector<EGS_Float> radii;
700 err = input->
getInput(
"radii",radii);
702 egsWarning(
"createGeometry(spheres): wrong/missing 'radii' input\n");
705 else if ((type ==
"shell") && (radii.size() < 2)) {
706 egsWarning(
"createGeometry(spheres): You must specify at least two radii for a spherical shell\n");
710 EGS_Float *r =
new EGS_Float [radii.size()];
711 for (
int j=0; j<radii.size(); j++) {
716 if (type !=
"shell") {
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
static int findRegion(EGS_Float xp, int np, const EGS_Float *p)
Find the bin to which xp belongs, given np bin edges p.
int nreg
Number of local regions in this geometry.
bool is_convex
Is this geometry convex?
EGS_Float boundaryTolerance
Boundary tolerance for geometries that need it.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
virtual int getNRegDir(int idir)
virtual int medium(int ireg) const
Returns the medium index in region ireg.
int setLabels(EGS_Input *input)
Set the labels from an input block.
virtual EGS_Float getBound(int idir, int ind)
Returns region boundaries in direction determined by idir.
virtual void printInfo() const
Print information about this geometry.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
A class representing 3D vectors.
A set of concentric spheres.
EGS_Float getBound(int idir, int ind)
Implement getBound for spherical regions.
int getNRegDir(int dir)
Implement geNRegDir for spherical regions.
EGS_Float getVolume(int ireg)
Implement getVolume for spherical regions.
Implements a spherical shell geometry with a hollow centre.
Global egspp functions header file.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
A set of concentric spheres.
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
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.