EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_cd_geometry.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ cd geometry
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: Frederic Tessier
27 # Ernesto Mainegra-Hing
28 #
29 ###############################################################################
30 */
31 
32 
38 #include "egs_cd_geometry.h"
39 #include "egs_input.h"
40 
41 #ifdef NO_SSTREAM
42  #include <strstream>
43  #define S_STREAM std::istrstream
44 #else
45  #include <sstream>
46  #define S_STREAM std::istringstream
47 #endif
48 
49 string EGS_CDGeometry::type = "EGS_CDGeometry";
50 
51 void EGS_CDGeometry::setMedia(EGS_Input *,int,const int *) {
52  egsWarning("EGS_CDGeometry::setMedia: don't use this method. Use the\n"
53  " setMedia() methods of the geometry objects that make up this geometry\n");
54 }
55 
56 void EGS_CDGeometry::setRelativeRho(int start, int end, EGS_Float rho) {
57  egsWarning("EGS_CDGeometry::setRelativeRho(): don't use this method\n"
58  " Use the setRelativeRho() methods of the geometry objects that make"
59  " up this geometry\n");
60 }
61 
62 void EGS_CDGeometry::setRelativeRho(EGS_Input *) {
63  egsWarning("EGS_CDGeometry::setRelativeRho(): don't use this method\n"
64  " Use the setRelativeRho() methods of the geometry objects that make"
65  " up this geometry\n");
66 }
67 
68 void EGS_CDGeometry::setBScaling(int start, int end, EGS_Float bf) {
69  egsWarning("EGS_CDGeometry::setBScaling(): don't use this method\n"
70  " Use the setBScaling() methods of the geometry objects that make"
71  " up this geometry\n");
72 }
73 
74 void EGS_CDGeometry::setBScaling(EGS_Input *) {
75  egsWarning("EGS_CDGeometry::setBScaling(): don't use this method\n"
76  " Use the setBScaling() methods of the geometry objects that make"
77  " up this geometry\n");
78 }
79 
80 void EGS_CDGeometry::setUpIndexing() {
81  int nr = 0;
82  int j;
83  for (j=0; j<nbase; j++) {
84  if (g[j]) {
85  nr += g[j]->regions();
86  }
87  else {
88  ++nr;
89  }
90  }
91  reg_to_base = new int [nr];
92  local_start = new int [nbase];
93  int ir=0;
94  for (j=0; j<nbase; j++) {
95  local_start[j] = ir;
96  if (g[j]) {
97  int n = g[j]->regions();
98  for (int i=0; i<n; i++) {
99  reg_to_base[ir++] = j;
100  }
101  }
102  else {
103  reg_to_base[ir++] = j;
104  }
105  }
106  new_indexing = true;
107  nreg = nr;
108 }
109 
110 
111 extern "C" {
112 
113  EGS_CDGEOMETRY_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
114  if (!input) {
115  egsWarning("createGeometry(CD_Geometry): null input?\n");
116  return 0;
117  }
118  EGS_Input *ij;
119  while ((ij = input->takeInputItem("geometry",false)) != 0) {
121  delete ij;
122  }
123  string bg_name;
124  int err = input->getInput("base geometry",bg_name);
125  if (err) {
126  egsWarning("createGeometry(CD_Geometry): no 'base geometry' input\n");
127  return 0;
128  }
130  if (!g) {
131  egsWarning("createGeometry(CD_Geometry): no geometry named %s is"
132  " defined\n",bg_name.c_str());
133  return 0;
134  }
135  int nreg = g->regions();
136  if (nreg < 1) {
137  egsWarning("createGeometry(CD_Geometry): the base geometry has %d"
138  " regions?\n",nreg);
139  return 0;
140  }
141  EGS_BaseGeometry **G = new EGS_BaseGeometry* [nreg];
142  int j;
143  for (j=0; j<nreg; j++) {
144  G[j] = 0;
145  }
146  int ng = 0;
147  string aux;
148  err = 0;
149  while ((ij = input->takeInputItem("set geometry")) != 0) {
150  vector<string> aux;
151  ij->getInput("set geometry",aux);
152  int istart, iend;
153  string name;
154  bool is_ok = true;
155  if (aux.size() == 2) {
156  string auxx = aux[0];
157  auxx += ' ';
158  auxx += aux[1];
159  auxx += ' ';
160  S_STREAM in(auxx.c_str());
161  in >> istart >> name;
162  if (in.fail() || !in.good()) {
163  egsWarning("createGeometry(CD_Geometry): parse error in\n"
164  " set geometry = %s\n",auxx.c_str());
165  err++;
166  is_ok = false;
167  }
168  else {
169  if (istart < 0 || istart > nreg-1) {
170  istart = -1;
171  iend = -2;
172  }
173  else {
174  iend = istart+1;
175  }
176  }
177  }
178  else if (aux.size() == 3) {
179  string auxx = aux[0];
180  auxx += ' ';
181  auxx += aux[1];
182  auxx += ' ';
183  auxx += aux[2];
184  auxx += ' ';
185  S_STREAM in(auxx.c_str());
186  in >> istart >> iend >> name;
187  if (in.fail() || !in.good()) {
188  egsWarning("createGeometry(CD_Geometry): parse error in\n"
189  " set geometry = %s\n",auxx.c_str());
190  err++;
191  is_ok = false;
192  }
193  else {
194  if (istart < 0) {
195  istart = 0;
196  }
197  if (iend > nreg) {
198  iend = nreg;
199  }
200  }
201  }
202  else {
203  err++;
204  is_ok = false;
205  }
206  if (is_ok) {
208  if (!gj) {
209  egsWarning("createGeometry(CD_Geometry): no geometry named %s"
210  " is defined\n",name.c_str());
211  err++;
212  }
213  else {
214  for (int j=istart; j<iend; j++) {
215  if (G[j] && G[j] != gj) {
216  G[j]->deref();
217  }
218  /*
219  if( !G[j] ) gj->ref();
220  else {
221  if( G[j] != gj ) G[j]->deref();
222  }
223  */
224  G[j] = gj;
225  gj->ref();
226  ng++;
227  }
228  }
229  }
230  delete ij;
231  }
232  if (err) {
233  egsWarning("createGeometry(CD_Geometry): %d errors\n",err);
234  for (j=0; j<nreg; j++) {
235  if (G[j]) {
236  if (!G[j]->deref()) {
237  delete G[j];
238  }
239  }
240  }
241  delete [] G[j];
242  return 0;
243  }
244  if (!ng)
245  egsWarning("createGeometry(CD_Geometry): no geometries in addition to"
246  " the base geometry defined?\n"
247  " Hope you know what you are doing\n");
248  g->ref();
249  int indexing = 0;
250  input->getInput("new indexing style",indexing);
251  EGS_BaseGeometry *result = new EGS_CDGeometry(g,G,"",indexing);
252  delete [] G;
253  result->setName(input);
254  result->setBoundaryTolerance(input);
255  result->setLabels(input);
256  return result;
257 
258  }
259 
260 
261  void EGS_CDGeometry::getLabelRegions(const string &str, vector<int> &regs) {
262 
263  // label defined in the base geometry
264  vector<int> bgregs;
265  bg->getLabelRegions(str, bgregs);
266 
267  // expand base regions to global region lists
268  int rstart = 0;
269  int rend = 0;
270  for (int i=0; i<bgregs.size(); i++) {
271  if (new_indexing) {
272  rstart = local_start[bgregs[i]];
273  if (bgregs[i] < nbase-1) {
274  rend = local_start[bgregs[i]+1];
275  }
276  else {
277  rend = nreg;
278  }
279  }
280  else {
281  rstart = bgregs[i]*nmax;
282  rend = (bgregs[i]+1)*nmax;
283  }
284  for (int j=rstart; j<rend; j++) {
285  regs.push_back(j);
286  }
287  }
288 
289  // label defined in the set geometries
290  vector<int> gregs;
291  int shift=0;
292  for (int i=0; i<nbase; i++) {
293 
294  // add regions from set geometries
295  gregs.clear();
296  if (g[i]) {
297  g[i]->getLabelRegions(str, gregs);
298  }
299 
300  // shift region numbers according to indexing style
301  if (new_indexing) {
302  shift = local_start[i];
303  }
304  else {
305  shift = i*nmax;
306  }
307  for (int j=0; j<gregs.size(); j++) {
308  gregs[j] += shift;
309  }
310 
311  // add regions to the list
312  regs.insert(regs.end(), gregs.begin(), gregs.end());
313 
314  }
315 
316  // label defined in self (cd input block)
318 
319  }
320 
321 }
int regions() const
Returns the number of local regions in this geometry.
int deref()
Decrease the reference count to this geometry.
EGS_Input class header file.
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.
A CD-geometry: header.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance from the input inp.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
A &quot;combinatorial dimension&quot; geometry.
virtual void getLabelRegions(const string &str, vector< int > &regs)
Get the list of all regions labeled with str.
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
int ref()
Increase the reference count to this geometry.
static EGS_BaseGeometry * createSingleGeometry(EGS_Input *inp)
Create a single geometry from the input inp.
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
int nreg
Number of local regions in this geometry.
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
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.