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