Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4MaterialPropertiesTable.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25
26////////////////////////////////////////////////////////////////////////
27// G4MaterialPropertiesTable Implementation
28////////////////////////////////////////////////////////////////////////
29//
30// File: G4MaterialPropertiesTable.cc
31// Version: 1.0
32// Created: 1996-02-08
33// Author: Juliet Armstrong
34// Updated: 2005-05-12 add SetGROUPVEL(), courtesy of
35// Horton-Smith (bug report #741), by P. Gumplinger
36// 2002-11-05 add named material constants by P. Gumplinger
37// 1999-11-05 Migration from G4RWTPtrHashDictionary to STL
38// by John Allison
39// 1997-03-26 by Peter Gumplinger
40// > cosmetics (only)
41//
42////////////////////////////////////////////////////////////////////////
43
45
46#include "G4Log.hh"
49#include "globals.hh"
50
51#include <algorithm>
52#include <cassert>
53
54#ifdef G4MULTITHREADED
55# include "G4AutoLock.hh"
56namespace
57{
58G4Mutex materialPropertyTableMutex = G4MUTEX_INITIALIZER;
59}
60#endif
61
63{
64 // elements of these 2 vectors must be in same order as
65 // the corresponding enums in G4MaterialPropertiesIndex.hh
66 fMatPropNames.assign(kNumberOfPropertyIndex, "");
67 fMatPropNames[kRINDEX] = "RINDEX";
68 fMatPropNames[kREFLECTIVITY] = "REFLECTIVITY";
69 fMatPropNames[kREALRINDEX] = "REALRINDEX";
70 fMatPropNames[kIMAGINARYRINDEX] = "IMAGINARYRINDEX";
71 fMatPropNames[kEFFICIENCY] = "EFFICIENCY";
72 fMatPropNames[kTRANSMITTANCE] = "TRANSMITTANCE";
73 fMatPropNames[kSPECULARLOBECONSTANT] = "SPECULARLOBECONSTANT";
74 fMatPropNames[kSPECULARSPIKECONSTANT] = "SPECULARSPIKECONSTANT";
75 fMatPropNames[kBACKSCATTERCONSTANT] = "BACKSCATTERCONSTANT";
76 fMatPropNames[kGROUPVEL] = "GROUPVEL";
77 fMatPropNames[kMIEHG] = "MIEHG";
78 fMatPropNames[kRAYLEIGH] = "RAYLEIGH";
79 fMatPropNames[kWLSCOMPONENT] = "WLSCOMPONENT";
80 fMatPropNames[kWLSABSLENGTH] = "WLSABSLENGTH";
81 fMatPropNames[kWLSCOMPONENT2] = "WLSCOMPONENT2";
82 fMatPropNames[kWLSABSLENGTH2] = "WLSABSLENGTH2";
83 fMatPropNames[kABSLENGTH] = "ABSLENGTH";
84 fMatPropNames[kPROTONSCINTILLATIONYIELD] = "PROTONSCINTILLATIONYIELD";
85 fMatPropNames[kDEUTERONSCINTILLATIONYIELD] ="DEUTERONSCINTILLATIONYIELD";
86 fMatPropNames[kTRITONSCINTILLATIONYIELD] = "TRITONSCINTILLATIONYIELD";
87 fMatPropNames[kALPHASCINTILLATIONYIELD] = "ALPHASCINTILLATIONYIELD";
88 fMatPropNames[kIONSCINTILLATIONYIELD] = "IONSCINTILLATIONYIELD";
89 fMatPropNames[kELECTRONSCINTILLATIONYIELD] ="ELECTRONSCINTILLATIONYIELD";
90 fMatPropNames[kSCINTILLATIONCOMPONENT1] = "SCINTILLATIONCOMPONENT1";
91 fMatPropNames[kSCINTILLATIONCOMPONENT2] = "SCINTILLATIONCOMPONENT2";
92 fMatPropNames[kSCINTILLATIONCOMPONENT3] = "SCINTILLATIONCOMPONENT3";
93 fMatPropNames[kCOATEDRINDEX] = "COATEDRINDEX";
94
95 fMP.assign(kNumberOfPropertyIndex, nullptr);
96
97 fMatConstPropNames.assign(kNumberOfConstPropertyIndex, "");
98 fMatConstPropNames[kSURFACEROUGHNESS] = "SURFACEROUGHNESS";
99 fMatConstPropNames[kISOTHERMAL_COMPRESSIBILITY] = "ISOTHERMAL_COMPRESSIBILITY";
100 fMatConstPropNames[kRS_SCALE_FACTOR] = "RS_SCALE_FACTOR";
101 fMatConstPropNames[kWLSMEANNUMBERPHOTONS] = "WLSMEANNUMBERPHOTONS";
102 fMatConstPropNames[kWLSTIMECONSTANT] = "WLSTIMECONSTANT";
103 fMatConstPropNames[kWLSMEANNUMBERPHOTONS2] = "WLSMEANNUMBERPHOTONS2";
104 fMatConstPropNames[kWLSTIMECONSTANT2] = "WLSTIMECONSTANT2";
105 fMatConstPropNames[kMIEHG_FORWARD] = "MIEHG_FORWARD";
106 fMatConstPropNames[kMIEHG_BACKWARD] = "MIEHG_BACKWARD";
107 fMatConstPropNames[kMIEHG_FORWARD_RATIO] = "MIEHG_FORWARD_RATIO";
108 fMatConstPropNames[kSCINTILLATIONYIELD] = "SCINTILLATIONYIELD";
109 fMatConstPropNames[kRESOLUTIONSCALE] = "RESOLUTIONSCALE";
110 fMatConstPropNames[kFERMIPOT] = "FERMIPOT";
111 fMatConstPropNames[kDIFFUSION] = "DIFFUSION";
112 fMatConstPropNames[kSPINFLIP] = "SPINFLIP";
113 fMatConstPropNames[kLOSS] = "LOSS";
114 fMatConstPropNames[kLOSSCS] = "LOSSCS";
115 fMatConstPropNames[kABSCS] = "ABSCS";
116 fMatConstPropNames[kSCATCS] = "SCATCS";
117 fMatConstPropNames[kMR_NBTHETA] = "MR_NBTHETA";
118 fMatConstPropNames[kMR_NBE] = "MR_NBE";
119 fMatConstPropNames[kMR_RRMS] = "MR_RRMS";
120 fMatConstPropNames[kMR_CORRLEN] = "MR_CORRLEN";
121 fMatConstPropNames[kMR_THETAMIN] = "MR_THETAMIN";
122 fMatConstPropNames[kMR_THETAMAX] = "MR_THETAMAX";
123 fMatConstPropNames[kMR_EMIN] = "MR_EMIN";
124 fMatConstPropNames[kMR_EMAX] = "MR_EMAX";
125 fMatConstPropNames[kMR_ANGNOTHETA] = "MR_ANGNOTHETA";
126 fMatConstPropNames[kMR_ANGNOPHI] = "MR_ANGNOPHI";
127 fMatConstPropNames[kMR_ANGCUT] = "MR_ANGCUT";
128 fMatConstPropNames[kSCINTILLATIONTIMECONSTANT1] = "SCINTILLATIONTIMECONSTANT1";
129 fMatConstPropNames[kSCINTILLATIONTIMECONSTANT2] = "SCINTILLATIONTIMECONSTANT2";
130 fMatConstPropNames[kSCINTILLATIONTIMECONSTANT3] = "SCINTILLATIONTIMECONSTANT3";
131 fMatConstPropNames[kSCINTILLATIONRISETIME1] = "SCINTILLATIONRISETIME1";
132 fMatConstPropNames[kSCINTILLATIONRISETIME2] = "SCINTILLATIONRISETIME2";
133 fMatConstPropNames[kSCINTILLATIONRISETIME3] = "SCINTILLATIONRISETIME3";
134 fMatConstPropNames[kSCINTILLATIONYIELD1] = "SCINTILLATIONYIELD1";
135 fMatConstPropNames[kSCINTILLATIONYIELD2] = "SCINTILLATIONYIELD2";
136 fMatConstPropNames[kSCINTILLATIONYIELD3] = "SCINTILLATIONYIELD3";
137 fMatConstPropNames[kPROTONSCINTILLATIONYIELD1] = "PROTONSCINTILLATIONYIELD1";
138 fMatConstPropNames[kPROTONSCINTILLATIONYIELD2] = "PROTONSCINTILLATIONYIELD2";
139 fMatConstPropNames[kPROTONSCINTILLATIONYIELD3] = "PROTONSCINTILLATIONYIELD3";
140 fMatConstPropNames[kDEUTERONSCINTILLATIONYIELD1] = "DEUTERONSCINTILLATIONYIELD1";
141 fMatConstPropNames[kDEUTERONSCINTILLATIONYIELD2] = "DEUTERONSCINTILLATIONYIELD2";
142 fMatConstPropNames[kDEUTERONSCINTILLATIONYIELD3] = "DEUTERONSCINTILLATIONYIELD3";
143 fMatConstPropNames[kTRITONSCINTILLATIONYIELD1] = "TRITONSCINTILLATIONYIELD1";
144 fMatConstPropNames[kTRITONSCINTILLATIONYIELD2] = "TRITONSCINTILLATIONYIELD2";
145 fMatConstPropNames[kTRITONSCINTILLATIONYIELD3] = "TRITONSCINTILLATIONYIELD3";
146 fMatConstPropNames[kALPHASCINTILLATIONYIELD1] = "ALPHASCINTILLATIONYIELD1";
147 fMatConstPropNames[kALPHASCINTILLATIONYIELD2] = "ALPHASCINTILLATIONYIELD2";
148 fMatConstPropNames[kALPHASCINTILLATIONYIELD3] = "ALPHASCINTILLATIONYIELD3";
149 fMatConstPropNames[kIONSCINTILLATIONYIELD1] = "IONSCINTILLATIONYIELD1";
150 fMatConstPropNames[kIONSCINTILLATIONYIELD2] = "IONSCINTILLATIONYIELD2";
151 fMatConstPropNames[kIONSCINTILLATIONYIELD3] = "IONSCINTILLATIONYIELD3";
152 fMatConstPropNames[kELECTRONSCINTILLATIONYIELD1] = "ELECTRONSCINTILLATIONYIELD1";
153 fMatConstPropNames[kELECTRONSCINTILLATIONYIELD2] = "ELECTRONSCINTILLATIONYIELD2";
154 fMatConstPropNames[kELECTRONSCINTILLATIONYIELD3] = "ELECTRONSCINTILLATIONYIELD3";
155 fMatConstPropNames[kCOATEDTHICKNESS] = "COATEDTHICKNESS";
156 fMatConstPropNames[kCOATEDFRUSTRATEDTRANSMISSION] = "COATEDFRUSTRATEDTRANSMISSION";
157 fMatConstPropNames[kPROTONSCINTILLATIONTIMECONSTANT1] = "PROTONSCINTILLATIONTIMECONSTANT1";
158 fMatConstPropNames[kPROTONSCINTILLATIONTIMECONSTANT2] = "PROTONSCINTILLATIONTIMECONSTANT2";
159 fMatConstPropNames[kPROTONSCINTILLATIONTIMECONSTANT3] = "PROTONSCINTILLATIONTIMECONSTANT3";
160 fMatConstPropNames[kDEUTERONSCINTILLATIONTIMECONSTANT1] = "DEUTERONSCINTILLATIONTIMECONSTANT1";
161 fMatConstPropNames[kDEUTERONSCINTILLATIONTIMECONSTANT2] = "DEUTERONSCINTILLATIONTIMECONSTANT2";
162 fMatConstPropNames[kDEUTERONSCINTILLATIONTIMECONSTANT3] = "DEUTERONSCINTILLATIONTIMECONSTANT3";
163 fMatConstPropNames[kTRITONSCINTILLATIONTIMECONSTANT1] = "TRITONSCINTILLATIONTIMECONSTANT1";
164 fMatConstPropNames[kTRITONSCINTILLATIONTIMECONSTANT2] = "TRITONSCINTILLATIONTIMECONSTANT2";
165 fMatConstPropNames[kTRITONSCINTILLATIONTIMECONSTANT3] = "TRITONSCINTILLATIONTIMECONSTANT3";
166 fMatConstPropNames[kALPHASCINTILLATIONTIMECONSTANT1] = "ALPHASCINTILLATIONTIMECONSTANT1";
167 fMatConstPropNames[kALPHASCINTILLATIONTIMECONSTANT2] = "ALPHASCINTILLATIONTIMECONSTANT2";
168 fMatConstPropNames[kALPHASCINTILLATIONTIMECONSTANT3] = "ALPHASCINTILLATIONTIMECONSTANT3";
169 fMatConstPropNames[kIONSCINTILLATIONTIMECONSTANT1] = "IONSCINTILLATIONTIMECONSTANT1";
170 fMatConstPropNames[kIONSCINTILLATIONTIMECONSTANT2] = "IONSCINTILLATIONTIMECONSTANT2";
171 fMatConstPropNames[kIONSCINTILLATIONTIMECONSTANT3] = "IONSCINTILLATIONTIMECONSTANT3";
172 fMatConstPropNames[kELECTRONSCINTILLATIONTIMECONSTANT1] = "ELECTRONSCINTILLATIONTIMECONSTANT1";
173 fMatConstPropNames[kELECTRONSCINTILLATIONTIMECONSTANT2] = "ELECTRONSCINTILLATIONTIMECONSTANT2";
174 fMatConstPropNames[kELECTRONSCINTILLATIONTIMECONSTANT3] = "ELECTRONSCINTILLATIONTIMECONSTANT3";
175 fMCP.assign(kNumberOfConstPropertyIndex, {0., false});
176}
177
179{
180 for (auto prop : fMP) {
181 delete (prop);
182 }
183}
184
186{
187 // Returns the constant material property index corresponding to a key
188
189 std::size_t index = std::distance(fMatConstPropNames.cbegin(),
190 std::find(fMatConstPropNames.cbegin(), fMatConstPropNames.cend(), key));
191 if (index < fMatConstPropNames.size()) {
192 return (G4int)index;
193 }
194
196 ed << "Constant Material Property Index for key " << key << " not found.";
197 G4Exception("G4MaterialPropertiesTable::GetConstPropertyIndex()", "mat200", FatalException, ed);
198 return 0;
199}
200
202{
203 // Returns the material property index corresponding to a key
204 std::size_t index = std::distance(
205 fMatPropNames.cbegin(), std::find(fMatPropNames.cbegin(), fMatPropNames.cend(), key));
206 if (index < fMatPropNames.size()) {
207 return (G4int)index;
208 }
210 ed << "Material Property Index for key " << key << " not found.";
211 G4Exception("G4MaterialPropertiesTable::GetPropertyIndex()", "mat201", FatalException, ed);
212 return 0;
213}
214
216{
217 // Returns the constant material property corresponding to an index
218 // fatal exception if property not found
219
220 if (index < (G4int)fMCP.size() && fMCP[index].second) {
221 return fMCP[index].first;
222 }
224 ed << "Constant Material Property " << fMatConstPropNames[index] << " not found.";
225 G4Exception("G4MaterialPropertiesTable::GetConstProperty()", "mat202", FatalException, ed);
226 return 0.;
227}
228
230{
231 // Returns the constant material property corresponding to a key
232 // fatal exception if property not found
233
235}
236
241
243{
244 // Returns true if a const property corresponding to 'index' exists
245
246 return index >= 0 && index < (G4int)fMCP.size() && fMCP[index].second;
247}
248
250{
251 // Returns true if a const property 'key' exists
252 std::size_t index = std::distance(fMatConstPropNames.cbegin(),
253 std::find(fMatConstPropNames.cbegin(), fMatConstPropNames.cend(), key));
254 if (index < fMatConstPropNames.size()) { // index is type std::size_t so >= 0
255 return ConstPropertyExists((G4int)index);
256 }
257 return false;
258}
259
261{
262 std::size_t index = std::distance(fMatConstPropNames.cbegin(),
263 std::find(fMatConstPropNames.cbegin(), fMatConstPropNames.cend(), key));
264 if (index < fMatConstPropNames.size()) { // index is type std::size_t so >= 0
265 return ConstPropertyExists((G4int)index);
266 }
267 return false;
268}
269
271{
272 // Returns a Material Property Vector corresponding to a key
273 if (std::find(fMatPropNames.cbegin(), fMatPropNames.cend(), key) != fMatPropNames.cend()) {
274 const G4int index = GetPropertyIndex(G4String(key));
275 return GetProperty(index);
276 }
277 return nullptr;
278}
279
281{
282 if (std::find(fMatPropNames.cbegin(), fMatPropNames.cend(), key) != fMatPropNames.cend()) {
283 const G4int index = GetPropertyIndex(G4String(key));
284 return GetProperty(index);
285 }
286 return nullptr;
287}
288
290{
291 // Returns a Material Property Vector corresponding to an index
292 // returns nullptr if the property has not been defined by user
293 if (index >= 0 && index < (G4int)fMP.size()) {
294 return fMP[index];
295 }
296 return nullptr;
297}
298
300 const std::vector<G4double>& photonEnergies, const std::vector<G4double>& propertyValues,
301 G4bool createNewKey, G4bool spline)
302{
303 if (photonEnergies.size() != propertyValues.size()) {
305 ed << "AddProperty error. Number of property values must be equal to the number of\n"
306 << "energy values. Property name: " << key;
307 G4Exception("G4MaterialPropertiesTable::AddProperty()", "mat204", FatalException, ed);
308 }
309
310 if (photonEnergies.size() == 1) {
312 ed << "AddProperty warning. A material property vector must have more than one value.\n"
313 << "Unless you will later add an entry, this is an error.\n"
314 << "Property name: " << key;
315 G4Exception("G4MaterialPropertiesTable::AddProperty()", "mat218", JustWarning, ed);
316 }
317
318 // G4PhysicsVector assumes energies are in increasing order
319 for (std::size_t i = 0; i < photonEnergies.size() - 1; ++i) {
320 if (photonEnergies.at(i + 1) < photonEnergies.at(i)) {
322 ed << "Energies in material property vector must be in increasing "
323 << "order. Key: " << key << " Energy: " << photonEnergies.at(i + 1);
324 G4Exception("G4MaterialPropertiesTable::AddProperty()", "mat215", FatalException, ed);
325 }
326 }
327
328 // if the key doesn't exist, add it if requested
329 if (std::find(fMatPropNames.cbegin(), fMatPropNames.cend(), key) == fMatPropNames.cend()) {
330 if (createNewKey) {
331 fMatPropNames.push_back(key);
332 fMP.push_back(nullptr);
333 }
334 else {
336 ed << "Attempting to create a new material property vector " << key << " without setting\n"
337 << "createNewKey parameter of AddProperty to true.";
338 G4Exception("G4MaterialPropertiesTable::AddProperty()", "mat205", FatalException, ed);
339 }
340 }
341
342 auto* mpv = new G4MaterialPropertyVector(photonEnergies, propertyValues, spline);
343 mpv->SetVerboseLevel(1);
344 if (spline) {
345 mpv->FillSecondDerivatives();
346 }
347 G4int index = GetPropertyIndex(key);
348 fMP[index] = mpv;
349
350 // if key is RINDEX, we calculate GROUPVEL -
351 // contribution from Tao Lin (IHEP, the JUNO experiment)
352 if (key == "RINDEX") {
353 CalculateGROUPVEL();
354 }
355
356 return mpv;
357}
358
360 G4double* photonEnergies, G4double* propertyValues, G4int numEntries, G4bool createNewKey,
361 G4bool spline)
362{
363 // Provides a way of adding a property to the Material Properties
364 // Table given a pair of arrays and a key
365 G4String k(key);
366
367 std::vector<G4double> energies(photonEnergies, photonEnergies + numEntries);
368 std::vector<G4double> values(propertyValues, propertyValues + numEntries);
369 return AddProperty(k, energies, values, createNewKey, spline);
370}
371
373 const G4String& key, G4MaterialPropertyVector* mpv, G4bool createNewKey)
374{
375 // Provides a way of adding a property to the Material Properties
376 // Table given an G4MaterialPropertyVector Reference and a key
377
378 // G4PhysicsVector assumes energies are in increasing order
379 if (mpv->GetVectorLength() > 1) {
380 for (std::size_t i = 0; i < mpv->GetVectorLength() - 1; ++i) {
381 if (mpv->Energy(i + 1) < mpv->Energy(i)) {
383 ed << "Energies in material property vector must be in increasing "
384 << "order. Key: " << key << " Energy: " << mpv->Energy(i + 1);
385 G4Exception("G4MaterialPropertiesTable::AddProperty()", "mat216", FatalException, ed);
386 }
387 }
388 }
389
390 if (mpv->GetVectorLength() <= 1) {
392 ed << "AddProperty warning. A material property vector must have more than one value.\n"
393 << "Unless you will later add an entry, this is an error.\n"
394 << "Property name: " << key;
395 G4Exception("G4MaterialPropertiesTable::AddProperty()", "mat219", JustWarning, ed);
396 }
397
398 // if the key doesn't exist, add it
399 if (std::find(fMatPropNames.cbegin(), fMatPropNames.cend(), key) == fMatPropNames.cend()) {
400 if (createNewKey) {
401 fMatPropNames.push_back(key);
402 fMP.push_back(nullptr);
403 }
404 else {
406 ed << "Attempting to create a new material property key " << key << " without setting\n"
407 << "createNewKey parameter of AddProperty to true.";
408 G4Exception("G4MaterialPropertiesTable::AddProperty()", "mat206", FatalException, ed);
409 }
410 }
411 G4int index = GetPropertyIndex(key);
412 fMP[index] = mpv;
413
414 // if key is RINDEX, we calculate GROUPVEL -
415 // contribution from Tao Lin (IHEP, the JUNO experiment)
416 if (key == "RINDEX") {
417 CalculateGROUPVEL();
418 }
419}
420
422 const char* key, G4MaterialPropertyVector* mpv, G4bool createNewKey)
423{
424 AddProperty(G4String(key), mpv, createNewKey);
425}
426
428{
429 // load a material property vector defined in Geant4 source
431 AddProperty(key, v);
432}
433
435 const G4String& key, G4double propertyValue, G4bool createNewKey)
436{
437 // Provides a way of adding a constant property to the Material Properties
438 // Table given a key
439 if (std::find(fMatConstPropNames.cbegin(), fMatConstPropNames.cend(), key) ==
440 fMatConstPropNames.cend())
441 {
442 if (createNewKey) {
443 fMatConstPropNames.push_back(key);
444 fMCP.emplace_back(0., true);
445 }
446 else {
448 ed << "Attempting to create a new material constant property key " << key
449 << " without setting\n"
450 << "createNewKey parameter of AddProperty to true.";
451 G4Exception("G4MaterialPropertiesTable::AddProperty()", "mat207", FatalException, ed);
452 }
453 }
454 G4int index = GetConstPropertyIndex(key);
455
456 fMCP[index] = std::pair<G4double, G4bool>{propertyValue, true};
457}
458
460 const char* key, G4double propertyValue, G4bool createNewKey)
461{
462 // Provides a way of adding a constant property to the Material Properties
463 // Table given a key
464 AddConstProperty(G4String(key), propertyValue, createNewKey);
465}
466
468{
469 G4int index = GetConstPropertyIndex(key);
470 if (index < (G4int)fMCP.size()) {
471 fMCP[index] = std::pair<G4double, G4bool>{0., false};
472 }
473}
474
479
481{
482 G4int index = GetPropertyIndex(key);
483 delete fMP[index];
484 fMP[index] = nullptr;
485}
486
488
490 const G4String& key, G4double aPhotonEnergy, G4double aPropertyValue)
491{
492 // Allows to add an entry pair directly to the Material Property Vector
493 // given a key.
494 if (std::find(fMatPropNames.cbegin(), fMatPropNames.cend(), key) == fMatPropNames.cend()) {
496 ed << "Material Property Vector " << key << " not found.";
497 G4Exception("G4MaterialPropertiesTable::AddEntry()", "mat214", FatalException, ed);
498 }
499 G4int index = GetPropertyIndex(key);
500
501 G4MaterialPropertyVector* targetVector = fMP[index];
502 if (targetVector != nullptr) {
503 // do not allow duplicate energies
504 for (std::size_t i = 0; i < targetVector->GetVectorLength(); ++i) {
505 if (aPhotonEnergy == targetVector->Energy(i)) {
507 ed << "Energy values in material property vector must be unique. "
508 << "Key: " << key;
509 G4Exception("G4MaterialPropertiesTable::AddEntry()", "mat217", FatalException, ed);
510 }
511 }
512
513 targetVector->InsertValues(aPhotonEnergy, aPropertyValue);
514 }
515 else {
517 ed << "Material Property Vector " << key << " not found.";
518 G4Exception("G4MaterialPropertiesTable::AddEntry()", "mat208", FatalException, ed);
519 }
520 if (key == "RINDEX") {
521 CalculateGROUPVEL();
522 }
523}
524
526 const char* key, G4double aPhotonEnergy, G4double aPropertyValue)
527{
528 AddEntry(G4String(key), aPhotonEnergy, aPropertyValue);
529}
530
532{
533 // material properties
534 G4int j = 0;
535 for (const auto& prop : fMP) {
536 if (prop != nullptr) {
537 G4cout << j << ": " << fMatPropNames[j] << G4endl;
538 prop->DumpValues();
539 }
540 ++j;
541 }
542 // material constant properties
543 j = 0;
544 for (const auto& cprop : fMCP) {
545 if (cprop.second) {
546 G4cout << j << ": " << fMatConstPropNames[j] << " " << cprop.first << G4endl;
547 }
548 ++j;
549 }
550}
551
552G4MaterialPropertyVector* G4MaterialPropertiesTable::CalculateGROUPVEL()
553{
554#ifdef G4MULTITHREADED
555 G4AutoLock mptm(&materialPropertyTableMutex);
556#endif
557
558 // check if "GROUPVEL" already exists. If so, remove it.
559 if (fMP[kGROUPVEL] != nullptr) {
560 this->RemoveProperty("GROUPVEL");
561 }
562
563 // fetch RINDEX data, give up if unavailable
565 if (rindex == nullptr) {
566 return nullptr;
567 }
568
569 // RINDEX exists but has no entries, give up
570 if (rindex->GetVectorLength() == 0) {
571 return nullptr;
572 }
573
574 // add GROUPVEL vector
575 auto* groupvel = new G4MaterialPropertyVector();
576 groupvel->SetVerboseLevel(1);
577
578 // fill GROUPVEL vector using RINDEX values
579 // rindex built-in "iterator" was advanced to first entry above
580 G4double E0 = rindex->Energy(0);
581 G4double n0 = (*rindex)[0];
582
583 if (E0 <= 0.) {
584 G4Exception("G4MaterialPropertiesTable::CalculateGROUPVEL()", "mat211", FatalException,
585 "Optical Photon Energy <= 0");
586 }
587
588 if (rindex->GetVectorLength() >= 2) {
589 // good, we have at least two entries in RINDEX
590 // get next energy/value pair
591
592 G4double E1 = rindex->Energy(1);
593 G4double n1 = (*rindex)[1];
594
595 if (E1 <= 0.) {
596 G4Exception("G4MaterialPropertiesTable::CalculateGROUPVEL()", "mat212", FatalException,
597 "Optical Photon Energy <= 0");
598 }
599
600 G4double vg;
601
602 // add entry at first photon energy
603 vg = c_light / (n0 + (n1 - n0) / G4Log(E1 / E0));
604
605 // allow only for 'normal dispersion' -> dn/d(logE) > 0
606 if ((vg < 0) || (vg > c_light / n0)) {
607 vg = c_light / n0;
608 }
609
610 groupvel->InsertValues(E0, vg);
611
612 // add entries at midpoints between remaining photon energies
613 for (std::size_t i = 2; i < rindex->GetVectorLength(); ++i) {
614 vg = c_light / (0.5 * (n0 + n1) + (n1 - n0) / G4Log(E1 / E0));
615
616 // allow only for 'normal dispersion' -> dn/d(logE) > 0
617 if ((vg < 0) || (vg > c_light / (0.5 * (n0 + n1)))) {
618 vg = c_light / (0.5 * (n0 + n1));
619 }
620 groupvel->InsertValues(0.5 * (E0 + E1), vg);
621
622 // get next energy/value pair, or exit loop
623 E0 = E1;
624 n0 = n1;
625 E1 = rindex->Energy(i);
626 n1 = (*rindex)[i];
627
628 if (E1 <= 0.) {
629 G4Exception("G4MaterialPropertiesTable::CalculateGROUPVEL()", "mat213", FatalException,
630 "Optical Photon Energy <= 0");
631 }
632 }
633
634 // add entry at last photon energy
635 vg = c_light / (n1 + (n1 - n0) / G4Log(E1 / E0));
636
637 // allow only for 'normal dispersion' -> dn/d(logE) > 0
638 if ((vg < 0) || (vg > c_light / n1)) {
639 vg = c_light / n1;
640 }
641 groupvel->InsertValues(E1, vg);
642 }
643 else // only one entry in RINDEX -- weird!
644 {
645 groupvel->InsertValues(E0, c_light / n0);
646 }
647
648 this->AddProperty("GROUPVEL", groupvel);
649
650 return groupvel;
651}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4double G4Log(G4double x)
Definition G4Log.hh:227
@ kSCINTILLATIONCOMPONENT1
@ kSCINTILLATIONCOMPONENT2
@ kSCINTILLATIONCOMPONENT3
@ kELECTRONSCINTILLATIONYIELD
@ kALPHASCINTILLATIONYIELD
@ kPROTONSCINTILLATIONYIELD
@ kDEUTERONSCINTILLATIONYIELD
@ kTRITONSCINTILLATIONYIELD
@ kSCINTILLATIONTIMECONSTANT1
@ kTRITONSCINTILLATIONYIELD1
@ kDEUTERONSCINTILLATIONYIELD3
@ kPROTONSCINTILLATIONTIMECONSTANT2
@ kALPHASCINTILLATIONTIMECONSTANT1
@ kELECTRONSCINTILLATIONTIMECONSTANT2
@ kDEUTERONSCINTILLATIONYIELD2
@ kELECTRONSCINTILLATIONTIMECONSTANT3
@ kDEUTERONSCINTILLATIONTIMECONSTANT1
@ kTRITONSCINTILLATIONTIMECONSTANT2
@ kTRITONSCINTILLATIONYIELD2
@ kNumberOfConstPropertyIndex
@ kALPHASCINTILLATIONYIELD2
@ kELECTRONSCINTILLATIONYIELD3
@ kTRITONSCINTILLATIONTIMECONSTANT1
@ kALPHASCINTILLATIONYIELD1
@ kALPHASCINTILLATIONTIMECONSTANT2
@ kPROTONSCINTILLATIONTIMECONSTANT3
@ kDEUTERONSCINTILLATIONTIMECONSTANT3
@ kELECTRONSCINTILLATIONYIELD2
@ kPROTONSCINTILLATIONYIELD2
@ kDEUTERONSCINTILLATIONYIELD1
@ kTRITONSCINTILLATIONTIMECONSTANT3
@ kISOTHERMAL_COMPRESSIBILITY
@ kTRITONSCINTILLATIONYIELD3
@ kSCINTILLATIONTIMECONSTANT3
@ kIONSCINTILLATIONTIMECONSTANT1
@ kIONSCINTILLATIONTIMECONSTANT3
@ kPROTONSCINTILLATIONYIELD3
@ kIONSCINTILLATIONTIMECONSTANT2
@ kALPHASCINTILLATIONTIMECONSTANT3
@ kELECTRONSCINTILLATIONYIELD1
@ kALPHASCINTILLATIONYIELD3
@ kSCINTILLATIONTIMECONSTANT2
@ kPROTONSCINTILLATIONYIELD1
@ kCOATEDFRUSTRATEDTRANSMISSION
@ kDEUTERONSCINTILLATIONTIMECONSTANT2
@ kPROTONSCINTILLATIONTIMECONSTANT1
@ kELECTRONSCINTILLATIONTIMECONSTANT1
G4PhysicsFreeVector G4MaterialPropertyVector
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4int GetConstPropertyIndex(const G4String &key) const
void AddConstProperty(const G4String &key, G4double propertyValue, G4bool createNewKey=false)
G4bool ConstPropertyExists(const G4String &key) const
void RemoveProperty(const G4String &key)
G4int GetPropertyIndex(const G4String &key) const
G4double GetConstProperty(const G4String &key) const
void AddEntry(const G4String &key, G4double aPhotonEnergy, G4double aPropertyValue)
G4MaterialPropertyVector * AddProperty(const G4String &key, const std::vector< G4double > &photonEnergies, const std::vector< G4double > &propertyValues, G4bool createNewKey=false, G4bool spline=false)
G4MaterialPropertyVector * GetProperty(const char *key) const
void RemoveConstProperty(const G4String &key)
void InsertValues(const G4double energy, const G4double value)
G4double Energy(const std::size_t index) const
std::size_t GetVectorLength() const
G4MaterialPropertyVector * GetProperty(const G4String &key, const G4String &mat)