5 #include "GeoModelKernel/GeoMaterial.h" 25 GeoMaterial::s_ionizationPotential[93] = {
27 GeoModelKernelUnits::eV,
29 GeoModelKernelUnits::eV,
31 GeoModelKernelUnits::eV,
33 GeoModelKernelUnits::eV,
35 GeoModelKernelUnits::eV,
37 GeoModelKernelUnits::eV,
39 GeoModelKernelUnits::eV,
41 GeoModelKernelUnits::eV,
43 GeoModelKernelUnits::eV,
45 GeoModelKernelUnits::eV,
47 GeoModelKernelUnits::eV,
49 GeoModelKernelUnits::eV,
51 GeoModelKernelUnits::eV,
53 GeoModelKernelUnits::eV,
55 GeoModelKernelUnits::eV,
57 GeoModelKernelUnits::eV,
59 GeoModelKernelUnits::eV,
61 GeoModelKernelUnits::eV,
63 GeoModelKernelUnits::eV,
65 GeoModelKernelUnits::eV,
67 GeoModelKernelUnits::eV,
69 GeoModelKernelUnits::eV,
71 GeoModelKernelUnits::eV,
73 GeoModelKernelUnits::eV,
75 GeoModelKernelUnits::eV,
77 GeoModelKernelUnits::eV,
79 GeoModelKernelUnits::eV,
81 GeoModelKernelUnits::eV,
83 GeoModelKernelUnits::eV,
85 GeoModelKernelUnits::eV,
87 GeoModelKernelUnits::eV,
89 GeoModelKernelUnits::eV,
91 GeoModelKernelUnits::eV,
93 GeoModelKernelUnits::eV,
95 GeoModelKernelUnits::eV,
97 GeoModelKernelUnits::eV,
99 GeoModelKernelUnits::eV,
101 GeoModelKernelUnits::eV,
103 GeoModelKernelUnits::eV,
105 GeoModelKernelUnits::eV,
107 GeoModelKernelUnits::eV,
109 GeoModelKernelUnits::eV,
111 GeoModelKernelUnits::eV,
113 GeoModelKernelUnits::eV,
115 GeoModelKernelUnits::eV,
117 GeoModelKernelUnits::eV,
119 GeoModelKernelUnits::eV,
121 GeoModelKernelUnits::eV,
123 GeoModelKernelUnits::eV,
125 GeoModelKernelUnits::eV,
127 GeoModelKernelUnits::eV,
129 GeoModelKernelUnits::eV,
131 GeoModelKernelUnits::eV,
133 GeoModelKernelUnits::eV,
135 GeoModelKernelUnits::eV,
137 GeoModelKernelUnits::eV,
139 GeoModelKernelUnits::eV,
141 GeoModelKernelUnits::eV,
143 GeoModelKernelUnits::eV,
145 GeoModelKernelUnits::eV,
147 GeoModelKernelUnits::eV,
149 GeoModelKernelUnits::eV,
151 GeoModelKernelUnits::eV,
153 GeoModelKernelUnits::eV,
155 GeoModelKernelUnits::eV,
157 GeoModelKernelUnits::eV,
159 GeoModelKernelUnits::eV,
161 GeoModelKernelUnits::eV,
163 GeoModelKernelUnits::eV,
165 GeoModelKernelUnits::eV,
167 GeoModelKernelUnits::eV,
169 GeoModelKernelUnits::eV,
171 GeoModelKernelUnits::eV,
173 GeoModelKernelUnits::eV,
175 GeoModelKernelUnits::eV,
177 GeoModelKernelUnits::eV,
179 GeoModelKernelUnits::eV,
181 GeoModelKernelUnits::eV,
183 GeoModelKernelUnits::eV,
185 GeoModelKernelUnits::eV,
187 GeoModelKernelUnits::eV,
189 GeoModelKernelUnits::eV,
191 GeoModelKernelUnits::eV,
193 GeoModelKernelUnits::eV,
195 GeoModelKernelUnits::eV,
197 GeoModelKernelUnits::eV,
199 GeoModelKernelUnits::eV,
201 GeoModelKernelUnits::eV,
203 GeoModelKernelUnits::eV,
205 GeoModelKernelUnits::eV,
207 GeoModelKernelUnits::eV,
209 GeoModelKernelUnits::eV,
211 GeoModelKernelUnits::eV
214 unsigned int GeoMaterial::s_lastID = 0;
216 GeoMaterial::GeoMaterial (
const std::string &Name,
double Density)
228 GeoMaterial::~GeoMaterial()
230 for (
size_t i = 0; i < m_element.size (); i++)
232 m_element[i]->unref ();
236 void GeoMaterial::add (
const GeoElement* element,
double fraction)
241 std::vector <const GeoElement *>::iterator e = std::find(m_element.begin(),m_element.end(),element);
242 if (e==m_element.end()) {
243 m_element.push_back (element);
244 m_fraction.push_back (fraction);
248 int n = e-m_element.begin();
249 m_fraction[n]+=fraction;
254 throw std::out_of_range (
"Element added after material locked");
258 void GeoMaterial::add (
const GeoMaterial* material,
double fraction)
262 for (
size_t e = 0; e < material->getNumElements (); e++)
264 add(material->m_element[e],fraction * material->m_fraction[e]);
269 throw std::out_of_range (
"Material added after material locked");
273 void GeoMaterial::lock ()
288 const double C0 = 0.00307 * GeoModelKernelUnits::cm3 / GeoModelKernelUnits::gram;
291 const double lambda0 = 35 * GeoModelKernelUnits::gram / GeoModelKernelUnits::cm2;
295 if (getNumElements () == 0)
297 throw std::out_of_range (
"Attempt to lock a material with no elements");
306 double dEDxConstant = 0, dEDxI0 = 0, NILinv = 0.0, radInv = 0.0;
309 double wSum=std::accumulate(m_fraction.begin(),m_fraction.end(),0.0);
310 if (fabs(wSum-1.0)>FLT_EPSILON)
312 if(std::getenv(
"GEOMODELKERNEL_VERBOSE")) {
313 std::cerr <<
"Warning in material " 315 <<
". Mass fractions sum to " 316 << wSum <<
"; renormalizing to 1.0" << std::endl;
319 double inv_wSum = 1. / wSum;
320 for (
size_t e=0;e<getNumElements();e++) {m_fraction[e]*=inv_wSum;}
323 const double inv_lambda0 = 1. / lambda0;
324 for (
size_t e = 0; e < getNumElements (); e++)
326 double w = getFraction (e);
327 double Z = m_element[e]->getZ ();
328 double A = m_element[e]->getA ();
329 double N = m_element[e]->getN ();
330 double dovera = m_density ? m_density / A : 0;
331 double n = m_fraction[e] * GeoModelKernelUnits::Avogadro * dovera;
332 int iZ = (int) (m_element[e]->getZ () + 0.5) - 1;
334 dEDxConstant += w * C0 * dovera * Z;
337 if (iZ >= 0 && iZ < (std::end(s_ionizationPotential)-std::begin(s_ionizationPotential)))
338 dEDxI0 += w * s_ionizationPotential[iZ];
339 NILinv += n * pow (N, 2.0 / 3.0) * GeoModelKernelUnits::amu * inv_lambda0;
341 double nAtomsPerVolume = A ? GeoModelKernelUnits::Avogadro*m_density*m_fraction[e]/A : 0.;
342 radInv += (nAtomsPerVolume*m_element[e]->getRadTsai());
344 m_dedDxConst = dEDxConstant;
346 m_intLength = NILinv ? 1.0 / NILinv : 0;
347 m_radLength = radInv ? 1.0 / radInv : 0;
350 double GeoMaterial::getDeDxConstant ()
const 353 throw std::out_of_range (
"Material accessed before lock");
357 double GeoMaterial::getDeDxI0 ()
const 360 throw std::out_of_range (
"Material accessed before lock");
364 double GeoMaterial::getDeDxMin ()
const 367 static const double ConstToMin = 11.528;
371 throw std::out_of_range (
"Material accessed before lock");
378 return m_dedDxConst * ConstToMin;
382 double GeoMaterial::getRadLength ()
const 385 throw std::out_of_range (
"Material accessed before lock");
389 double GeoMaterial::getIntLength ()
const 392 throw std::out_of_range (
"Material accessed before lock");
396 unsigned int GeoMaterial::getNumElements ()
const 399 throw std::out_of_range (
"Material accessed before lock");
400 return m_element.size ();
403 const GeoElement* GeoMaterial::getElement (
unsigned int i)
const 406 throw std::out_of_range (
"Material accessed before lock");
410 double GeoMaterial::getFraction (
int i)
const 413 throw std::out_of_range (
"Material accessed before lock");
414 return m_fraction[i];
This class represents chemical elements. Elements are allocated on the heap and deleted automatically...
void add(GeoGraphNode *graphNode)
Adds a Graph Node to the Geometry Graph.
This class represents materials. A material is a collection of elements. In addition it has a density...