EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_union_geometry.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ union 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 # Hubert Ho
29 # Marc Chamberland
30 #
31 ###############################################################################
32 */
33 
34 
40 #include "egs_union_geometry.h"
41 #include "egs_input.h"
42 #include "egs_functions.h"
43 
44 using namespace std;
45 
46 string EGS_UNIONG_LOCAL EGS_UnionGeometry::type = "EGS_UnionGeometry";
47 
48 void EGS_UnionGeometry::setMedia(EGS_Input *,int,const int *) {
49  egsWarning("EGS_UnionGeometry::setMedia: don't use this method. Use the\n"
50  " setMedia() methods of the geometry objects that make up this geometry\n");
51 }
52 
53 void EGS_UnionGeometry::setRelativeRho(int start, int end, EGS_Float rho) {
54  setRelativeRho(0);
55 }
56 
57 void EGS_UnionGeometry::setRelativeRho(EGS_Input *) {
58  egsWarning("EGS_UnionGeometry::setRelativeRho(): don't use this method. "
59  "Use the\n setRelativeRho() methods of the geometry objects that make "
60  "up this geometry\n");
61 }
62 
63 void EGS_UnionGeometry::setBScaling(int start, int end, EGS_Float bf) {
64  setBScaling(0);
65 }
66 
67 void EGS_UnionGeometry::setBScaling(EGS_Input *) {
68  egsWarning("EGS_UnionGeometry::setBScaling(): don't use this method. "
69  "Use the\n setBScaling() methods of the geometry objects that make "
70  "up this geometry\n");
71 }
72 
73 EGS_UnionGeometry::EGS_UnionGeometry(const vector<EGS_BaseGeometry *> &geoms,
74  const int *priorities, const string &Name) :
75  EGS_BaseGeometry(Name) {
76  ng = geoms.size();
77  if (ng <= 0) egsFatal("EGS_UnionGeometry::EGS_UnionGeometry: attempt "
78  " to construct a union geometry from zero geometries\n");
79  is_convex = false;
80  if (ng == 1) egsWarning("EGS_UnionGeometry::EGS_UnionGeometry: why "
81  "do you want to make a union out of a single geometry?\n");
82  g = new EGS_BaseGeometry* [ng];
83  nmax = 0;
84  int j;
85  int *order = new int [ng];
86  if (priorities) {
87  // user has definied priorities
88  // order them using a very simplistic algorithm
89  bool *is_used = new bool [ng];
90  for (j=0; j<ng; j++) {
91  is_used[j] = false;
92  }
93  for (j=0; j<ng; j++) {
94  int imax;
95  for (imax=0; imax<ng-1; imax++) if (!is_used[imax]) {
96  break;
97  }
98  int pmax = priorities[imax];
99  for (int i=0; i<ng; i++) {
100  if (!is_used[i] && priorities[i] > pmax) {
101  imax = i;
102  pmax = priorities[i];
103  }
104  }
105  order[j] = imax;
106  is_used[imax] = true;
107  }
108  delete [] is_used;
109  }
110  else {
111  // user has not definied priorities
112  for (j=0; j<ng; j++) {
113  order[j] = j;
114  }
115  }
116  has_rho_scaling = false;
117  // now put the geometries into the array of geometries in
118  // decreasing priority order.
119  for (j=0; j<ng; j++) {
120  int i = order[j];
121  g[i] = geoms[j];
122  g[i]->ref();
123  int n = g[i]->regions();
124  if (n > nmax) {
125  nmax = n;
126  }
127  if (!has_rho_scaling) {
129  }
130  }
131  has_B_scaling = false;
132  // now put the geometries into the array of geometries in
133  // decreasing priority order.
134  for (j=0; j<ng; j++) {
135  int i = order[j];
136  g[i] = geoms[j];
137  g[i]->ref();
138  int n = g[i]->regions();
139  if (n > nmax) {
140  nmax = n;
141  }
142  if (!has_B_scaling) {
143  has_B_scaling = g[i]->hasBScaling();
144  }
145  }
146  delete [] order;
147  if (!nmax) egsFatal("EGS_UnionGeometry::EGS_UnionGeometry: all geometries"
148  " have zero regions?\n");
149  nreg = nmax*ng;
150 }
151 
152 EGS_UnionGeometry::~EGS_UnionGeometry() {
153  for (int j=0; j<ng; j++) {
154  if (!g[j]->deref()) {
155  delete g[j];
156  }
157  }
158  delete [] g;
159 }
160 
161 void EGS_UnionGeometry::printInfo() const {
163  egsInformation(" geometries:\n");
164  for (int j=0; j<ng; j++) egsInformation(" %s (type %s)\n",
165  g[j]->getName().c_str(),g[j]->getType().c_str());
167  "=======================================================\n");
168 }
169 
170 extern "C" {
171 
172  EGS_UNIONG_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
173  if (!input) {
174  egsWarning("createGeometry(union): null input?\n");
175  return 0;
176  }
177  vector<EGS_BaseGeometry *> geoms;
178  vector<string> gnames;
179  int err = input->getInput("geometries",gnames);
180  if (err || gnames.size() < 1) {
181  egsWarning("createGeometry(union): missing/wrong 'geometries' input\n");
182  return 0;
183  }
184  for (unsigned int j=0; j<gnames.size(); j++) {
186  if (!gj) egsWarning("createGeometry(union): no geometry named %s "
187  "defined\n",gnames[j].c_str());
188  else {
189  geoms.push_back(gj);
190  }
191  }
192  if (geoms.size() < 1) {
193  egsWarning("createGeometry(union): must have at least one geometry\n");
194  return 0;
195  }
196  vector<int> pri;
197  err = input->getInput("priorities",pri);
198  int *p = 0;
199  if (!err) {
200  if (pri.size() == geoms.size()) {
201  p = new int [pri.size()];
202  for (int i=0; i<pri.size(); i++) {
203  p[i] = pri[i];
204  }
205  }
206  else egsWarning("createGeometry(union): the number of priorities (%d)"
207  " is not the same as the number of geometries (%d) => ignoring\n",
208  pri.size(),geoms.size());
209  }
210  EGS_BaseGeometry *result = new EGS_UnionGeometry(geoms,p);
211  result->setName(input);
212  result->setBoundaryTolerance(input);
213  result->setLabels(input);
214  if (p) {
215  delete [] p;
216  }
217  return result;
218  }
219 
220  void EGS_UnionGeometry::getLabelRegions(const string &str, vector<int> &regs) {
221 
222  // label defined in the sub-geometries
223  vector<int> gregs;
224  for (int i=0; i<ng; i++) {
225 
226  // add regions from set geometries
227  gregs.clear();
228  if (g[i]) {
229  g[i]->getLabelRegions(str, gregs);
230  }
231 
232  // shift region numbers according to indexing style
233  for (int j=0; j<gregs.size(); j++) {
234  gregs[j] += i*nmax;
235  }
236 
237  // add regions to the list
238  regs.insert(regs.end(), gregs.begin(), gregs.end());
239 
240  }
241 
242  // label defined in self (union geometry input block)
244 
245  }
246 
247 }
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
int deref()
Decrease the reference count to this geometry.
virtual void getLabelRegions(const string &str, vector< int > &regs)
Get the list of all regions labeled with str.
int nreg
Number of local regions in this geometry.
bool has_B_scaling
Does this geometry has B field scaling factor?
bool is_convex
Is this geometry convex?
bool has_rho_scaling
Does this geometry have relative mass density scvaling?
bool hasBScaling() const
Does this geometry object have a B field scaling feature?
void setName(EGS_Input *inp)
Set the name of the geometry from the input inp.
const string & getName() const
Get the name of this geometry.
bool hasRhoScaling() const
Does this geometry object have a mass density scaling feature?
int regions() const
Returns the number of local regions in this geometry.
int setLabels(EGS_Input *input)
Set the labels from an input block.
virtual void printInfo() const
Print information about this geometry.
int ref()
Increase the reference count to this geometry.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
void setBoundaryTolerance(EGS_Input *inp)
Set the value of the boundary tolerance 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 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
A geometry constructed as the union of other geometries.
void setMedia(EGS_Input *, int, const int *)
Don't set media when defining the union.
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.
EGS_UnionGeometry(const vector< EGS_BaseGeometry * > &geoms, const int *priorities=0, const string &Name="")
Construct a geometry union from the vector of geometries geom.
Global egspp functions header file.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:57
EGS_Input class header file.
A geometry union.
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.