EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_stack_geometry.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ stack 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 # Marc Chamberland
28 # Ernesto Mainegra-Hing
29 # Reid Townson
30 # Hannah Gallop
31 #
32 ###############################################################################
33 */
34 
35 
42 #include "egs_stack_geometry.h"
43 #include "egs_input.h"
44 #include "egs_functions.h"
45 
46 string EGS_StackGeometry::type = "EGS_StackGeometry";
47 
48 static bool EGS_STACKG_LOCAL inputSet = false;
49 
50 EGS_StackGeometry::EGS_StackGeometry(const vector<EGS_BaseGeometry *> &geoms,
51  const string &Name) : EGS_BaseGeometry(Name) {
52  if (geoms.size() < 2) egsFatal("EGS_StackGeometry::EGS_StackGeometry: "
53  " less than 2 geometries is not mermitted\n");
54  ng = geoms.size();
55  g = new EGS_BaseGeometry* [ng];
56  nmax = 1;
57  has_rho_scaling = false;
58  for (int j=0; j<ng; j++) {
59  g[j] = geoms[j];
60  g[j]->ref();
61  int n = g[j]->regions();
62  if (n > nmax) {
63  nmax = n;
64  }
65  if (!has_rho_scaling) {
67  }
68  }
69  has_B_scaling = false;
70  for (int j=0; j<ng; j++) {
71  g[j] = geoms[j];
72  g[j]->ref();
73  int n = g[j]->regions();
74  if (n > nmax) {
75  nmax = n;
76  }
77  if (!has_B_scaling) {
78  has_B_scaling = g[j]->hasBScaling();
79  }
80  }
81  nreg = ng*nmax;
82  is_convex = false;
83 }
84 
85 EGS_StackGeometry::~EGS_StackGeometry() {
86  for (int j=0; j<ng; j++)
87  if (!g[j]->deref()) {
88  delete g[j];
89  }
90  delete [] g;
91 }
92 
93 void EGS_StackGeometry::printInfo() const {
95  egsInformation(" geometries:\n");
96  for (int j=0; j<ng; j++) egsInformation(" %s (type %s)\n",
97  g[j]->getName().c_str(),g[j]->getType().c_str());
99  "=======================================================\n");
100 }
101 
102 void EGS_StackGeometry::setMedia(EGS_Input *,int,const int *) {
103  egsWarning("EGS_StackGeometry::setMedia: don't use this method. Use the\n"
104  " setMedia() methods of the geometry objects that make up this geometry\n");
105 }
106 
107 void EGS_StackGeometry::setRelativeRho(int start, int end, EGS_Float rho) {
108  setRelativeRho(0);
109 }
110 
111 void EGS_StackGeometry::setRelativeRho(EGS_Input *) {
112  egsWarning("EGS_StackGeometry::setRelativeRho(): don't use this method.\n"
113  " Use the setRelativeRho methods of the geometry objects that make up"
114  " this geometry\n");
115 }
116 
117 void EGS_StackGeometry::setBScaling(int start, int end, EGS_Float rho) {
118  setBScaling(0);
119 }
120 
121 void EGS_StackGeometry::setBScaling(EGS_Input *) {
122  egsWarning("EGS_StackGeometry::setBScaling(): don't use this method.\n"
123  " Use the setBScaling methods of the geometry objects that make up"
124  " this geometry\n");
125 }
126 
127 extern "C" {
128 
129  static void setInputs() {
130  inputSet = true;
131 
132  setBaseGeometryInputs(false);
133 
134  geomBlockInput->getSingleInput("library")->setValues({"egs_gstack"});
135 
136  // Format: name, isRequired, description, vector string of allowed values
137  geomBlockInput->addSingleInput("geometries", true, "A list of names of previously defined geometries");
138  geomBlockInput->addSingleInput("tolerance", false, "A small floating number boundaryTolerance");
139  }
140 
141  EGS_STACKG_EXPORT string getExample() {
142  string example;
143  example = {
144  R"(
145  # Example of egs_gstack
146  :start geometry:
147  name = my_gstack
148  library = egs_gstack
149  geometries = geom1 geom2
150  # create geometries called geom1 geom2
151  tolerance = 1e-4
152  :stop geometry:
153 )"};
154  return example;
155  }
156 
157  EGS_STACKG_EXPORT shared_ptr<EGS_BlockInput> getInputs() {
158  if(!inputSet) {
159  setInputs();
160  }
161  return geomBlockInput;
162  }
163 
164  EGS_STACKG_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) {
165  if (!input) {
166  egsWarning("createGeometry(stack): null input?\n");
167  return 0;
168  }
169  vector<string> gnames;
170  vector<EGS_BaseGeometry *> geoms;
171  int err = input->getInput("geometries",gnames);
172  if (err || gnames.size() < 2) {
173  egsWarning("createGeometry(stack): missing/wrong 'geometries' input\n");
174  return 0;
175  }
176  for (unsigned int j=0; j<gnames.size(); j++) {
178  if (!gj) egsWarning("createGeometry(stack): no geometry named %s "
179  " defined\n",gnames[j].c_str());
180  else {
181  geoms.push_back(gj);
182  }
183  }
184  if (geoms.size() < 2) {
185  egsWarning("createGeometry(stack): must have at least 2 geometries\n");
186  return 0;
187  }
188  EGS_BaseGeometry *result = new EGS_StackGeometry(geoms);
189  result->setName(input);
190  result->setBoundaryTolerance(input);
191  result->setLabels(input);
192  EGS_Float tol = epsilon;
193  err = input->getInput("tolerance",tol);
194  if (!err) {
195  result->setBoundaryTolerance(tol);
196  }
197  return result;
198  }
199 
200  int EGS_StackGeometry::getGlobalRegionOffset(const string geomName) {
201  // Look for the named geometry in the inscribed geometries
202  for (int i=0; i<ng; i++) {
203  if (g[i] && g[i]->getName() == geomName) {
204  return i*nmax;
205  }
206  }
207 
208  // If it's not found above, search through the inscribed geometries in case they are composite geometries
209  for (int i=0; i<ng; i++) {
210  int shift = g[i]->getGlobalRegionOffset(geomName);
211  if (shift >= 0) {
212  shift += i*nmax;
213  return shift;
214  }
215  }
216 
217  // Return -1 for not found
218  return -1;
219  }
220 
221  void EGS_StackGeometry::getLabelRegions(const string &str, vector<int> &regs, bool sanitize) {
222 
223  vector<int> local_regs;
224 
225  // label defined in the stacked geometries
226  for (int i=0; i<ng; i++) {
227  local_regs.clear();
228  g[i]->getLabelRegions(str, local_regs, sanitize);
229  for (int j=0; j<local_regs.size(); j++) {
230  regs.push_back(i*nmax + local_regs[j]);
231  }
232  }
233 
234  // label defined in self (stack input block)
235  EGS_BaseGeometry::getLabelRegions(str, regs, sanitize);
236 
237  }
238 
239 
240 }
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual int getGlobalRegionOffset(const string geomName)
Get the global region number for the first region in the geometry.
int deref()
Decrease the reference count to this geometry.
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?
virtual bool hasRhoScaling()
Does this geometry object have a mass density 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.
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.
virtual void getLabelRegions(const string &str, vector< int > &regs, bool sanitize=true)
Get the list of all regions labeled with str.
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:341
A stack of geometries.
EGS_StackGeometry(const vector< EGS_BaseGeometry * > &geoms, const string &Name="")
Construct a geometry stack from the vector of geometries geom.
Global egspp functions header file.
EGS_GLIB_EXPORT EGS_BaseGeometry * createGeometry(EGS_Input *input)
Definition: egs_glib.cpp:84
EGS_Input class header file.
A geometry stack: header.
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.
const EGS_Float epsilon
The epsilon constant for floating point comparisons.
Definition: egs_functions.h:62
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.