EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_union_geometry.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ union geometry headers
5 # Copyright (C) 2015 National Research Council Canada
6 #
7 # This file is part of EGSnrc.
8 #
9 # EGSnrc is free software: you can redistribute it and/or modify it under
10 # the terms of the GNU Affero General Public License as published by the
11 # Free Software Foundation, either version 3 of the License, or (at your
12 # option) any later version.
13 #
14 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU Affero General Public License
20 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21 #
22 ###############################################################################
23 #
24 # Author: Iwan Kawrakow, 2005
25 #
26 # Contributors: Ernesto Mainegra-Hing
27 # Frederic Tessier
28 # Reid Townson
29 # Alexandre Demelo
30 #
31 ###############################################################################
32 */
33 
34 
40 #ifndef EGS_UNION_GEOMETRY_
41 #define EGS_UNION_GEOMETRY_
42 
43 #ifdef WIN32
44 
45  #ifdef BUILD_UNIONG_DLL
46  #define EGS_UNIONG_EXPORT __declspec(dllexport)
47  #else
48  #define EGS_UNIONG_EXPORT __declspec(dllimport)
49  #endif
50  #define EGS_UNIONG_LOCAL
51 
52 #else
53 
54  #ifdef HAVE_VISIBILITY
55  #define EGS_UNIONG_EXPORT __attribute__ ((visibility ("default")))
56  #define EGS_UNIONG_LOCAL __attribute__ ((visibility ("hidden")))
57  #else
58  #define EGS_UNIONG_EXPORT
59  #define EGS_UNIONG_LOCAL
60  #endif
61 
62 #endif
63 
64 
65 #include "egs_base_geometry.h"
66 
67 #include<vector>
68 using std::vector;
69 
134 class EGS_UNIONG_EXPORT EGS_UnionGeometry : public EGS_BaseGeometry {
135 
136 public:
137 
141  EGS_UnionGeometry(const vector<EGS_BaseGeometry *> &geoms,
142  const int *priorities = 0, const string &Name = "");
143 
145 
146  bool isRealRegion(int ireg) const {
147  if (ireg < 0 || ireg >= nreg) {
148  return false;
149  }
150  int j = ireg/nmax;
151  return g[j]->isRealRegion(ireg-j*nmax);
152  };
153 
154  bool isInside(const EGS_Vector &x) {
155  for (int j=0; j<ng; j++) if (g[j]->isInside(x)) {
156  return true;
157  }
158  return false;
159  };
160 
161  int isWhere(const EGS_Vector &x) {
162  for (int j=0; j<ng; j++) {
163  int ij = g[j]->isWhere(x);
164  if (ij >= 0) {
165  return ij + j*nmax;
166  }
167  }
168  return -1;
169  };
170 
171  int inside(const EGS_Vector &x) {
172  return isWhere(x);
173  };
174 
175  int medium(int ireg) const {
176  if (ireg < 0 || ireg >= nreg) {
177  return -1;
178  }
179  int j = ireg/nmax;
180  return g[j]->medium(ireg-j*nmax);
181  };
182 
183  int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u,
184  EGS_Float &t,int *newmed=0, EGS_Vector *normal=0) {
185  if (ireg >= 0) {
186  // we are inside, set current geometry
187  int jg = ireg/nmax;
188  // distance to boundary and new region in this geometry.
189  int inew = g[jg]->howfar(ireg-jg*nmax,x,u,t,newmed,normal);
190  // jgnew is the geometry after the step
191  int jgnew = inew >= 0 ? jg : -1;
192  // geometries are now ordered in decreasing priorities.
193  // Then,
194  // - if the particle remains in the current geometry,
195  // we only need to check geometries up to jg-1
196  // For these geometries the particle must be outside,
197  // otherwise it would have been in one of them
198  // - if the particle exits the current geometry, then
199  // we must also check jg+1...ng-1
200  for (int j=0; j<jg; j++) {
201  int ii = g[j]->howfar(-1,x,u,t,newmed,normal);
202  if (ii >= 0) {
203  jgnew = j;
204  inew = ii;
205  }
206  }
207  if (inew < 0) {
208  // the particle didn't enter any of the higher priority
209  // geometries but exits the current one.
210  // => we need to check if the particle is in one
211  // of the lower priority geometries at the exit point.
212  EGS_Vector xnew(x+u*t);
213  for (int j=jg+1; j<ng; j++) {
214  int ii = g[j]->isWhere(xnew);
215  if (ii >= 0) {
216  // when exiting jg, particle is in region ii of geometry j
217  // we don't need to check other geometries because they
218  // have a lower priority.
219  jgnew = j;
220  inew = ii;
221  break;
222  }
223  }
224  }
225  if (inew < 0) {
226  return inew;
227  }
228  if (newmed) {
229  *newmed = g[jgnew]->medium(inew);
230  }
231  return inew + jgnew*nmax;
232  }
233  // if here, we are currently outside of all geometries in the union.
234  int jg, inew=-1;
235  for (int j=0; j<ng; j++) {
236  int ii = g[j]->howfar(-1,x,u,t,newmed,normal);
237  if (ii >= 0) {
238  jg = j;
239  inew = ii;
240  }
241  }
242  return inew < 0 ? -1 : inew + jg*nmax;
243  };
244 
245  EGS_Float hownear(int ireg, const EGS_Vector &x) {
246  if (ireg >= 0) {
247  int jg = ireg/nmax;
248  EGS_Float tmin = g[jg]->hownear(ireg-jg*nmax,x);
249  if (tmin <= 0) {
250  return 0;
251  }
252  // tmin is now the perpendicular distance to a boundary
253  // in the current geometry.
254  // we need to check all geometries with higher priorities
255  // i.e., all geometries between 0 and jg-1.
256  // as their priorities are higher, we know that we are
257  // outside of such geometries.
258  for (int j=jg-1; j>=0; --j) {
259  EGS_Float t = g[j]->hownear(-1,x);
260  if (t < tmin) {
261  tmin = t;
262  if (tmin <= 0) {
263  return 0;
264  }
265  }
266  }
267  return tmin;
268  }
269  // if here, we are outside of all geomtries in the union.
270  EGS_Float tmin = veryFar;
271  for (int j=ng-1; j>=0; j--) {
272  EGS_Float t = g[j]->hownear(-1,x);
273  if (t < tmin) {
274  tmin = t;
275  }
276  if (tmin <= 0) {
277  return 0;
278  }
279  }
280  return tmin;
281  };
282 
283  void getNextGeom(EGS_RandomGenerator *rndm) {
284  // calls getNextGeom on its component geometries to update dynamic
285  // geometries in the simulation
286  for (int j=0; j<ng; j++) {
287  g[j]->getNextGeom(rndm);
288  }
289  };
290 
291  void updatePosition(EGS_Float time) {
292  // calls updatePosition on its component geometries to update dynamic
293  // geometries in the simulation
294  for (int j=0; j<ng; j++) {
295  g[j]->updatePosition(time);
296  }
297  };
298 
299  void containsDynamic(bool &hasdynamic) {
300  // calls containsDynamic on its component geometries (only calls if
301  // hasDynamic is false, as if it is true we already found one)
302  for (int j=0; j<ng; j++) {
303  if (!hasdynamic) {
304  g[j]->containsDynamic(hasdynamic);
305  }
306  }
307  };
308 
309  int getMaxStep() const {
310  int nstep = 1;
311  for (int j=0; j<ng; ++j) {
312  nstep += g[j]->getMaxStep();
313  }
314  return nstep;
315  };
316 
317  const string &getType() const {
318  return type;
319  };
320 
321  void printInfo() const;
322 
323  EGS_Float getRelativeRho(int ireg) const {
324  if (ireg < 0 || ireg >= nreg) {
325  return 1;
326  }
327  int jg = ireg/nmax;
328  return g[jg]->getRelativeRho(ireg-jg*nmax);
329  };
330  void setRelativeRho(int start, int end, EGS_Float rho);
331  void setRelativeRho(EGS_Input *);
332 
333  void setBScaling(int start, int end, EGS_Float rho);
334  void setBScaling(EGS_Input *);
335  EGS_Float getBScaling(int ireg) const {
336  if (ireg < 0 || ireg >= nreg) {
337  return 1;
338  }
339  int jg = ireg/nmax;
340  return g[jg]->getBScaling(ireg-jg*nmax);
341  };
342 
343  virtual void getLabelRegions(const string &str, vector<int> &regs);
344 
345 protected:
346 
348  int ng;
349  int nmax;
350  static string type;
351 
358  void setMedia(EGS_Input *,int,const int *);
359 
360 };
361 
362 #endif
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)
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 > &regs)
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.
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 int getMaxStep() const
Returns the maximum number of steps through the geometry.
virtual int medium(int ireg) const
Returns the medium index in region ireg.
virtual void setRelativeRho(int start, int end, EGS_Float rho)
Set the relative mass density in regions.
virtual void printInfo() const
Print information about this geometry.
virtual int isWhere(const EGS_Vector &x)=0
In which region is poisition x?
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
Base random number generator class. All random number generators should be derived from this class.
Definition: egs_rndm.h:67
A geometry constructed as the union of other geometries.
int nmax
max. number of regions in all of the geoms.
int ng
number of geometries.
static string type
the geometry type
EGS_BaseGeometry ** g
the geometries that form the union.
A class representing 3D vectors.
Definition: egs_vector.h:57
EGS_BaseGeometry class header file.
const EGS_Float veryFar
A very large float.