EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_rz.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ rz geometry
5 # Copyright (C) 2016 Randle E. P. Taylor, Rowan M. Thomson,
6 # Marc J. P. Chamberland, Dave W. O. Rogers
7 #
8 # This file is part of EGSnrc.
9 #
10 # EGSnrc is free software: you can redistribute it and/or modify it under
11 # the terms of the GNU Affero General Public License as published by the
12 # Free Software Foundation, either version 3 of the License, or (at your
13 # option) any later version.
14 #
15 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
16 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
18 # more details.
19 #
20 # You should have received a copy of the GNU Affero General Public License
21 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
22 #
23 ###############################################################################
24 #
25 # Author: Randle Taylor, 2016
26 #
27 # Contributors: Marc Chamberland
28 # Rowan Thomson
29 # Dave Rogers
30 #
31 ###############################################################################
32 #
33 # egs_rz was developed for the Carleton Laboratory for Radiotherapy Physics.
34 #
35 ###############################################################################
36 */
37 
38 
44 #include <map>
45 #include "egs_input.h"
46 #include "egs_rz.h"
47 #include "../egs_cylinders/egs_cylinders.h"
48 #include "../egs_planes/egs_planes.h"
49 
50 
51 string EGS_RZGeometry::RZType = "EGS_RZ";
52 
53 EGS_RZGeometry::EGS_RZGeometry(vector<EGS_BaseGeometry *> geoms,
54  vector<EGS_Float> rads, vector<EGS_Float> zbs, const string &name) :
55  EGS_NDGeometry(geoms, name), radii(rads), zbounds(zbs) {
56 
57  /* we always set inner most radii to 0 (simplifies volume calcs) */
58  if (radii[0] != 0) {
59  radii.insert(radii.begin(), 0.);
60  }
61 
62  vector<EGS_Float> vol;
63  for (size_t r=0; r < radii.size()-1; r++) {
64 
65  EGS_Float rmin = radii[r];
66  EGS_Float rmax = radii[r+1];
67 
68  EGS_Float area = M_PI*(rmax*rmax - rmin*rmin);
69 
70  for (size_t plane = 0; plane < zbounds.size()-1; plane++) {
71  EGS_Float zmin = zbounds[plane];
72  EGS_Float zmax = zbounds[plane+1];
73  reg_vol.push_back((zmax-zmin)*area);
74  }
75  }
76 
77 };
78 
79 EGS_Float EGS_RZGeometry::getBound(int idir, int ind) {
80  if (idir == ZDIR && ind >= 0 && ind < (int)zbounds.size()) {
81  return zbounds[ind];
82  }
83  else if (idir == RDIR && ind >= 0 && ind < (int)radii.size()) {
84  return radii[ind];
85  }
86  return 0.;
87 }
88 
89 
91  if (dir == ZDIR) {
92  return zbounds.size() - 1;
93  }
94  else if (dir == RDIR) {
95  return radii.size() - 1;
96  }
97  return 0;
98 }
99 
100 EGS_Float EGS_RZGeometry::getVolume(int ireg) {
101  if (ireg < 0 || ireg >= nreg) {
102  return -1;
103  }
104  return reg_vol[ireg];
105 }
106 
107 
108 /* Initialization helpers for EGS_RZ */
109 namespace egs_rz {
110 
111 vector<EGS_Float> getRadiiByShells(EGS_Input *input) {
112 
113  vector<EGS_Float> radii;
114 
115  vector<int> nshells;
116  int err = input->getInput("number of shells", nshells);
117  if (err) {
118  return radii;
119  }
120 
121  vector<EGS_Float> thick;
122  err = input->getInput("shell thickness", thick);
123  if (err) {
124  return radii;
125  }
126 
127  EGS_Float cur_r = 0;
128  for (size_t shell_group=0; shell_group < min(thick.size(), nshells.size()); shell_group++) {
129 
130  for (int shell = 0; shell < nshells[shell_group]; shell++) {
131  cur_r += thick[shell_group];
132  radii.push_back(cur_r);
133 
134  }
135  }
136 
137  return radii;
138 
139 }
140 
141 vector<EGS_Float> getRadii(EGS_Input *input) {
142 
143  vector<EGS_Float> radii;
144  int err = input->getInput("radii", radii);
145  if (err) {
146  /* no explicit radii input so assume user will be specifying using shells */
147  radii = getRadiiByShells(input);
148  }
149 
150  return radii;
151 
152 }
153 
154 
155 vector<EGS_Float> EGS_RZ_LOCAL getZPlanesBySlabs(EGS_Input *input) {
156 
157  vector<EGS_Float> zplanes;
158 
159  EGS_Float zo = 0;
160 
161  int err = input->getInput("first plane", zo);
162  if (err) {
163  egsWarning("RZ: missing 'first plane' input. Assuming zo=0");
164  zo = 0;
165  }
166 
167  vector<int> nslabs;
168  err = input->getInput("number of slabs", nslabs);
169  if (err) {
170  return zplanes;
171  }
172 
173  vector<EGS_Float> thick;
174  err = input->getInput("slab thickness", thick);
175  if (err) {
176  return zplanes;
177  }
178 
179  EGS_Float cur_z = zo;
180  zplanes.push_back(zo);
181  for (size_t slab_group=0; slab_group < min(thick.size(), nslabs.size()); slab_group++) {
182 
183  for (int slab = 0; slab < nslabs[slab_group]; slab++) {
184  cur_z += thick[slab_group];
185  zplanes.push_back(cur_z);
186  }
187  }
188 
189  return zplanes;
190 
191 }
192 
193 vector<EGS_Float> EGS_RZ_LOCAL getZPlanes(EGS_Input *input) {
194 
195  vector<EGS_Float> zplanes;
196  int err = input->getInput("z-planes", zplanes);
197  if (err) {
198  zplanes = getZPlanesBySlabs(input);
199  }
200 
201  return zplanes;
202 
203 }
204 
205 bool allIncreasing(vector<EGS_Float> vec) {
206 
207  if (vec.size() == 0) {
208  return true;
209  }
210 
211  EGS_Float last = vec[0];
212  for (size_t i=1; i < vec.size(); i++) {
213  if (vec[i] <= last) {
214  return false;
215  }
216  last = vec[i];
217  }
218 
219  return true;
220 
221 }
222 
223 
224 };
225 
226 extern "C" {
227 
228  EGS_RZ_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
229 
230  if (!input) {
231  egsWarning("createGeometry(egs_rz): null input?\n");
232  return 0;
233  }
234 
235  vector<EGS_Float> radii = egs_rz::getRadii(input);
236  if (radii.size() == 0) {
237  egsWarning("createGeometry(rz): wrong/missing radii inputs\n");
238  return 0;
239  }
240  if (!egs_rz::allIncreasing(radii)) {
241  egsWarning("createGeometry(rz): radii must be monotonically increasing\n");
242  return 0;
243  }
244 
245  vector<EGS_Float> zplanes = egs_rz::getZPlanes(input);
246  if (zplanes.size() == 0) {
247  egsWarning("createGeometry(rz): wrong/missing z plane inputs\n");
248  return 0;
249  }
250 
252  EGS_PlanesZ *planes = new EGS_PlanesZ(zplanes, EGS_BaseGeometry::getUniqueName(), EGS_ZProjector("z-planes"));
253 
254  vector<EGS_BaseGeometry *> rz_geoms;
255  rz_geoms.push_back(planes);
256  rz_geoms.push_back(cyl);
257 
258  EGS_BaseGeometry *rz = new EGS_RZGeometry(rz_geoms, radii, zplanes);
259 
260  if (!rz) {
261  egsWarning("createGeometry(rz): failed to create nd geometry\n");
262  return 0;
263  }
264 
265  rz->setName(input);
266  rz->setMedia(input);
267  rz->setLabels(input);
268 
269  return rz;
270 
271  }
272 
273 }
EGS_Float getBound(int idir, int ind)
get RZ boundary for a given direction and directional index
Definition: egs_rz.cpp:79
EGS_Float getVolume(int ireg)
get mass of a given region
Definition: egs_rz.cpp:100
EGS_Input class header file.
A class representing 3D vectors.
Definition: egs_vector.h:56
a subclass of EGS_NDGeometry for conveniently defining an RZ geometry
Definition: egs_rz.h:115
int setLabels(EGS_Input *input)
Set the labels from an input block.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:57
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
static string getUniqueName()
Get a unique geometry name.
void setMedia(EGS_Input *inp)
Set the media in the geometry from the input pointed to by inp.
A set of parallel planes.
Definition: egs_planes.h:166
A set of concentric cylinders.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
A projector into the z-plane.
int getNRegDir(int dir)
get number of regions in a given direction
Definition: egs_rz.cpp:90
A class modeling a N-dimensional geometry.
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
EGS_RZGeometry(vector< EGS_BaseGeometry * > geoms, vector< EGS_Float > rads, vector< EGS_Float > zbs, const string &name="")
RZ geometry constructor.
Definition: egs_rz.cpp:53
int nreg
Number of local regions in this geometry.
int getInput(const string &key, vector< string > &values) const
Assign values to an array of strings from an input identified by key.
Definition: egs_input.cpp:338
An egs_nd_geometry wrapper to simplify RZ geometry creation.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.