EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_conical_shell.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ conical shell shape
5 # Copyright (C) 2016 Randle E. P. Taylor, Rowan M. Thomson,
6 # Marc J. P. Chamberland, D. 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_conical_shell was developed for the Carleton Laboratory for
34 # Radiotherapy Physics.
35 #
36 ###############################################################################
37 */
38 
39 
45 #include "egs_conical_shell.h"
46 #include "egs_input.h"
47 #include "egs_functions.h"
48 #include <iostream>
49 #include <fstream>
50 
51 
52 CSSSLayer::CSSSLayer(EGS_Float t, EGS_Float rit, EGS_Float rot, EGS_Float rib, EGS_Float rob, EGS_Float z):
53  thick(t), ri_top(rit), ro_top(rot), ri_bot(rib), ro_bot(rob), zo(z) {
54 
55  ro_max = max(ro_top, ro_bot);
56  ro_min = min(ro_top, ro_bot);
57 
58  ri_max = max(ri_top, ri_bot);
59  ri_min = min(ri_top, ri_bot);
60 
61  o_slope = (ro_bot - ro_top)/thick;
62  i_slope = (ri_bot - ri_top)/thick;
63 
64  const_width = ((ro_bot - ri_bot) - (ro_top - ri_top)) < 1E-5;
65 
66  vout = M_PI/3.*(3*ro_max+thick*fabs(o_slope))*thick*thick*fabs(o_slope);
67  vout += M_PI*ro_min*ro_min*thick;
68 
69  vin = M_PI/3.*(3*ri_max+thick*fabs(i_slope))*thick*thick*fabs(i_slope);
70  vin += M_PI*ri_min*ri_min*thick;
71 
72  volume = vout - vin;
73 
74 }
75 
76 EGS_Vector CSSSLayer::getPoint(EGS_RandomGenerator *rndm) {
77 
78  EGS_Float r, z;
79 
80  if (const_width) {
81  getRZEqualWidth(rndm, r, z);
82  }
83  else {
84  getRZRejection(rndm, r, z);
85 
86  }
87 
88  EGS_Vector point = getPointInCircleAtZ(rndm, r, z);
89  point.z += zo;
90  return point;
91 }
92 
93 void CSSSLayer::getRZEqualWidth(EGS_RandomGenerator *rndm, EGS_Float &r, EGS_Float &z) {
94 
95  z = thick*(rndm->getUniform());
96  EGS_Float ri = getRiAtZ(z);
97  EGS_Float ro = getRoAtZ(z);
98  r = ri+(ro-ri)*sqrt(rndm->getUniform());
99 }
100 
101 void CSSSLayer::getRZRejection(EGS_RandomGenerator *rndm, EGS_Float &r, EGS_Float &z) {
102 
103  int count = 0;
104 
105  while (1) {
106  z = thick*(rndm->getUniform());
107  r = ri_min+(ro_max-ri_min)*rndm->getUniform();
108 
109  if (r <= getRoAtZ(z) && r >= getRiAtZ(z)) {
110  EGS_Vector point = getPointInCircleAtZ(rndm, r, z);
111  point.z += zo;
112  return;
113  }
114 
115  if (count++ > 1000) {
116  egsWarning("egs_conical_shell: Less than .1%% of random points are being accepted");
117  }
118 
119  }
120 
121 }
122 
123 
124 EGS_Vector CSSSLayer::getPointInCircleAtZ(EGS_RandomGenerator *rndm, EGS_Float r, EGS_Float z) {
125 
126  EGS_Float cphi, sphi;
127  rndm->getAzimuth(cphi,sphi);
128  return EGS_Vector(r*cphi, r*sphi, z);
129 
130 };
131 
132 EGS_Float CSSSLayer::getRoAtZ(EGS_Float z) {
133  return o_slope*z+ro_top;
134 }
135 
136 EGS_Float CSSSLayer::getRiAtZ(EGS_Float z) {
137  return i_slope*z+ri_top;
138 }
139 
140 
141 
144  EGS_BaseShape(Name, f), layer_sampler(0), xo(Xo) {
145  otype = "conicalShellStack";
146  total_thick = 0;
147 };
148 
151 
152  int lyr= layer_sampler->sample(rndm) ;
153  CSSSLayer *layer = layers[lyr];
154  EGS_Vector point = layer->getPoint(rndm);
155  return xo + point;
156 
157 };
158 
159 void EGS_ConicalShellStackShape::addLayer(EGS_Float thick,
160  EGS_Float ri_top, EGS_Float ro_top, EGS_Float ri_bot,EGS_Float ro_bot) {
161 
162  CSSSLayer *layer = new CSSSLayer(thick, ri_top, ro_top, ri_bot, ro_bot, total_thick);
163  layers.push_back(layer);
164  total_thick += thick;
165 
166  volumes.push_back(layer->volume);
167 
168  setLayerSampler();
169 
170 }
171 
172 
173 void EGS_ConicalShellStackShape::addLayer(EGS_Float thick, EGS_Float ri_bot,EGS_Float ro_bot) {
174 
175  EGS_Float ri_top = layers[layers.size()-1]->ri_bot;
176  EGS_Float ro_top = layers[layers.size()-1]->ro_bot;
177 
178  addLayer(thick, ri_top, ro_top, ri_bot, ro_bot);
179 
180 }
181 
182 void EGS_ConicalShellStackShape::setLayerSampler() {
183 
184  if (layer_sampler) {
185  delete layer_sampler;
186  }
187 
188  layer_sampler = new EGS_SimpleAliasTable(volumes.size(), &volumes[0]);
189 }
190 
191 
192 extern "C" {
193 
194  EGS_CONICAL_SHELL_EXPORT EGS_BaseShape *createShape(EGS_Input *input, EGS_ObjectFactory *f) {
195 
196  if (!input) {
197  egsWarning("createShape(conicalShell): null input?\n");
198  return 0;
199  }
200 
201 
202  vector<EGS_Float> xo;
203  int err = input->getInput("midpoint", xo);
204  if (err || xo.size() != 3) {
205  xo.clear();
206  xo.push_back(0);
207  xo.push_back(0);
208  xo.push_back(0);
209  }
210 
211  EGS_ConicalShellStackShape *result = new EGS_ConicalShellStackShape(EGS_Vector(xo[0],xo[1],xo[2]));
212  result->setName(input);
213 
214  EGS_Input *layer;
215  int nl = 0;
216  while ((layer = input->takeInputItem("layer"))) {
217  vector<EGS_Float> rtop, rbot;
218  EGS_Float thick;
219  err = layer->getInput("thickness", thick);
220  if (err) {
221  egsWarning(
222  "createShape(EGS_ConicalShellStackShape): missing 'thickness'"
223  " input for layer %d\n --> layer ignored\n", nl
224  );
225  }
226  else {
227 
228  err = layer->getInput("top radii",rtop);
229  if (err && nl==0) {
230  egsWarning("createGeometry(EGS_ConeStack): missing 'top radii' input for 1st layer\n");
231  }
232  else {
233  err=0;
234  }
235 
236  int err1 = layer->getInput("bottom radii",rbot);
237  if (err1) {
238  egsWarning("createGeometry(EGS_ConeStack): missing 'bottom radii' input for layer %d\n",nl);
239  }
240  if (err || err1) {
241  egsWarning(" --> layer ignored\n");
242  }
243  else {
244 
245  EGS_Float rit, rot, rib, rob;
246  if (rbot.size() < 2) {
247  rib = 0;
248  rob = rbot[0];
249  }
250  else {
251  rib = rbot[0];
252  rob = rbot[1];
253  }
254 
255  if (rtop.size() == 0) {
256  result->addLayer(thick, rib, rob);
257  }
258  else if (rtop.size() < 2) {
259  rit = 0;
260  rot = rtop[0];
261  result->addLayer(thick, rit, rot, rib, rob);
262  }
263  else {
264  rit = rtop[0];
265  rot = rtop[1];
266  result->addLayer(thick, rit, rot, rib, rob);
267  }
268  }
269  }
270  delete layer;
271  ++nl;
272  }
273 
274  return result;
275  }
276 
277 }
Base shape class. All shapes in the EGSnrc C++ class library are derived from EGS_BaseShape.
Definition: egs_shapes.h:114
EGS_ConicalShellStackShape(const EGS_Vector &Xo, const string &Name="", EGS_ObjectFactory *f=0)
Construct a sphere of radius r with midpoint Xo.
EGS_Vector getPoint(EGS_RandomGenerator *rndm)
Returns a random point within the conical shell.
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_Input * takeInputItem(const string &key, bool self=true)
Get the property named key.
Definition: egs_input.cpp:226
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 object factory.
void setName(EGS_Input *inp)
Set the name of the object from the information provided by inp.
string otype
The object type.
Base random number generator class. All random number generators should be derived from this class.
Definition: egs_rndm.h:67
void getAzimuth(EGS_Float &cphi, EGS_Float &sphi)
Sets cphi and sphi to the cosine and sine of a random angle uniformely distributed between 0 and .
Definition: egs_rndm.h:138
EGS_Float getUniform()
Returns a random number uniformly distributed between zero (inclusive) and 1 (exclusive).
Definition: egs_rndm.h:103
A class for sampling random bins from a given probability distribution using the alias table techniqu...
int sample(EGS_RandomGenerator *rndm) const
Sample a random bin.
A class representing 3D vectors.
Definition: egs_vector.h:57
EGS_Float z
z-component
Definition: egs_vector.h:63
a conical stack shell shape
Global egspp functions header file.
EGS_Input class header file.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.
A conical shell shape.