Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4IonICRU73Data.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//
28// GEANT4 Class file
29//
30// Description: Data on stopping power
31//
32// Author: Vladimir Ivanchenko
33//
34// Creation date: 23.10.2021
35//
36//----------------------------------------------------------------------------
37//
38
39//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
40
41#include <fstream>
42#include <sstream>
43
44#include "G4IonICRU73Data.hh"
45#include "G4SystemOfUnits.hh"
46#include "G4PhysicsLogVector.hh"
48#include "G4EmParameters.hh"
51#include "G4Material.hh"
52#include "G4Element.hh"
53
54namespace {
55
56const G4String namesICRU73[31] = {
57"G4_A-150_TISSUE"
58"G4_ADIPOSE_TISSUE_ICRP"
59"G4_AIR"
60"G4_ALUMINUM_OXIDE"
61"G4_BONE_COMPACT_ICRU"
62"G4_BONE_CORTICAL_ICRP"
63"G4_C-552"
64"G4_CALCIUM_FLUORIDE"
65"G4_CARBON_DIOXIDE"
66"G4_KAPTON"
67"G4_LITHIUM_FLUORIDE"
68"G4_LITHIUM_TETRABORATE"
69"G4_LUCITE"
70"G4_METHANE"
71"G4_MUSCLE_STRIATED_ICRU"
72"G4_MYLAR"
73"G4_NYLON-6-6"
74"G4_PHOTO_EMULSION"
75"G4_PLASTIC_SC_VINYLTOLUENE"
76"G4_POLYCARBONATE"
77"G4_POLYETHYLENE"
78"G4_POLYSTYRENE"
79"G4_PROPANE"
80"G4_Pyrex_Glass"
81"G4_SILICON_DIOXIDE"
82"G4_SODIUM_IODIDE"
83"G4_TEFLON"
84"G4_TISSUE-METHANE"
85"G4_TISSUE-PROPANE"
86"G4_WATER"
87"G4_WATER_VAPOR"};
88 const G4String namesICRU90[3] = {"G4_AIR","G4_GRAPHITE","G4_WATER"};
89 const G4double densityCoef[3] = {0.996, 1.025, 0.998};
90 const G4int NZ = 27;
91 const G4int zdat[NZ] = { 5, 6, 7, 8, 13, 14, 15, 16, 22, 26,
92 28, 29, 30, 31, 32, 33, 34, 40, 47, 48,
93 49, 51, 52, 72, 73, 74, 79 };
94}
95
96//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
97
99{
100 fEmin = 0.025*CLHEP::MeV;
101 fEmax = 2.5*CLHEP::MeV;
102 fNbins = fNbinsPerDecade*G4lrint(std::log10(fEmax/fEmin));
103 fVector = new G4PhysicsFreeVector(fSpline);
104 for(G4int i=3; i<=ZPROJMAX; ++i) {
105 fMatData[i] = new std::vector<G4PhysicsLogVector*>;
106 }
107}
108
109//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
110
112{
113 delete fVector;
114 for(G4int i=3; i<=ZPROJMAX; ++i) {
115 auto v = fMatData[i];
116 if(nullptr != v) {
117 for(auto & dat : *v) {
118 delete dat;
119 }
120 delete v;
121 }
122 for(G4int j=1; j<=ZTARGMAX; ++j) {
123 delete fElmData[i][j];
124 }
125 }
126}
127
128//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
129
131 const G4double e, const G4double loge) const
132{
133 // if data does not exist the result is zero
134 if (Z > ZPROJMAX) { return 0.0; }
135
136 G4PhysicsLogVector* v = nullptr;
137 if (1 == mat->GetNumberOfElements()) {
138 G4int Z1 = (*(mat->GetElementVector()))[0]->GetZasInt();
139 if(Z1 > ZTARGMAX) { return 0.0; }
140 v = fElmData[Z][Z1];
141 }
142 else {
143 G4int idx = fMatIndex[mat->GetIndex()];
144 if (idx < 0) { return 0.0; }
145 v = (*(fMatData[Z]))[idx];
146 }
147 if(nullptr == v) { return 0.0; }
148 G4double res = (e > fEmin) ? v->LogVectorValue(e, loge)
149 : (*v)[0]*std::sqrt(e/fEmin);
150 return res;
151}
152
153//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
154
156{
157 // fill directory path
158 if(fDataDirectory.empty()) {
159 std::ostringstream ost;
160 ost << G4EmParameters::Instance()->GetDirLEDATA() << "/ion_stopping_data/";
161 fDataDirectory = ost.str();
162 }
163
164 const std::size_t nmat = G4Material::GetNumberOfMaterials();
165
166 // do nothing if for a new run list of materials is not changed
167 if(nmat == fMatIndex.size()) { return; }
168
169 // look over all materials and recompute all materials
170 // do not recompute element data if exist
171 if(1 < fVerbose) {
172 G4cout << "### G4IonICRU73Data::Initialise() for " << nmat
173 << " materials" << G4endl;
174 }
175 fMatIndex.resize(nmat, -1);
176 for(G4int j=3; j<=ZPROJMAX; ++j) {
177 fMatData[j]->resize(nmat, nullptr);
178 }
180 auto mtable = G4Material::GetMaterialTable();
181
182 for(G4int i=0; i<(G4int)nmat; ++i) {
183 const G4Material* mat = (*mtable)[i];
184 const G4String matname = mat->GetName();
185 G4int idx = (G4int)mat->GetIndex();
186 if(1 < fVerbose) {
187 G4cout << i << ". material: " << matname
188 << " idx=" << idx << " matIdx=" << fMatIndex[idx]
189 << G4endl;
190 }
191 if(fMatIndex[idx] == -1) {
192 G4bool isOK = false;
193
194 // for material in ICRU90
195 if(useICRU90) {
196 for(G4int j=0; j<3; ++j) {
197 if(matname == namesICRU90[j]) {
198 ReadMaterialData(mat, densityCoef[j], true);
199 isOK = true;
200 if(1 < fVerbose) {
201 G4cout << "ICRU90 material " << matname << G4endl;
202 }
203 break;
204 }
205 }
206 }
207 // for material in ICRU73
208 if(!isOK) {
209 for(G4int j=0; j<31; ++j) {
210 if(matname == namesICRU73[j]) {
211 ReadMaterialData(mat, 1.0, false);
212 isOK = true;
213 if(1 < fVerbose) {
214 G4cout << "ICRU73 material " << matname << G4endl;
215 }
216 break;
217 }
218 }
219 }
220 // dEdx is combined from element stopping power
221 // Target element Z <= ZTARGMAX
222 if(!isOK) {
223 const std::size_t nelm = mat->GetNumberOfElements();
224 auto elmv = mat->GetElementVector();
225 G4bool isOut = false;
226 for (std::size_t j=0; j<nelm; ++j) {
227 if ((*elmv)[j]->GetZasInt() > ZTARGMAX) {
228 isOut = true;
229 break;
230 }
231 }
232 if (!isOut) {
233 ReadElementData(mat, useICRU90);
234 isOK = true;
235 if(1 < fVerbose) {
236 G4cout << "Data via elements for " << matname << G4endl;
237 }
238 }
239 }
240 if(isOK) { fMatIndex[idx] = i; }
241 }
242 if(1 < fVerbose) {
243 G4cout << " matData: " << fMatData[i] << G4endl;
244 }
245 }
246}
247
248//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
249
250void G4IonICRU73Data::ReadMaterialData(const G4Material* mat,
251 const G4double coeff,
252 const G4bool useICRU90)
253{
254 const G4String name = mat->GetName();
255 const G4int idx = (G4int)mat->GetIndex();
256 for(G4int Z=3; Z<=ZPROJMAX; ++Z) {
257 std::ostringstream ost;
258 ost << fDataDirectory << "icru";
259 G4int Z1 = Z;
260 G4double scale = 1.0;
261 if(useICRU90 && Z <= 18) {
262 ost << "90";
263 } else {
264 ost << "73";
265 for(G4int i=0; i<NZ; ++i) {
266 if(Z == zdat[i]) {
267 break;
268 } else if(i == NZ-1) {
269 Z1 = zdat[NZ - 1];
270 scale = (G4double)(Z*Z)/(G4double)(Z1*Z1);
271 } else if(Z > zdat[i] && Z < zdat[i+1]) {
272 if(Z - zdat[i] <= zdat[i + 1] - Z) {
273 Z1 = zdat[i];
274 } else {
275 Z1 = zdat[i+1];
276 }
277 scale = (G4double)(Z*Z)/(G4double)(Z1*Z1);
278 break;
279 }
280 }
281 }
282 if(nullptr == (*(fMatData[Z1]))[idx]) {
283 ost << "/z" << Z1 << "_" << name << ".dat";
284 G4PhysicsLogVector* v = RetrieveVector(ost, false);
285 if(nullptr != v) {
286 const G4double fact = coeff *
287 mat->GetDensity() * CLHEP::MeV * 1000 * CLHEP::cm2 / CLHEP::g;
288 v->ScaleVector(CLHEP::MeV, fact);
289 if(2 < fVerbose) {
290 G4cout << "### Data for " << name
291 << " and projectile Z=" << Z1 << G4endl;
292 G4cout << *v << G4endl;
293 }
294 (*(fMatData[Z1]))[idx] = v;
295 }
296 }
297 if(Z != Z1) {
298 auto v2 = (*(fMatData[Z1]))[idx];
299 if(nullptr != v2) {
300 auto v1 = new G4PhysicsLogVector(*v2);
301 (*(fMatData[Z]))[idx] = v1;
302 v1->ScaleVector(1.0, scale);
303 }
304 }
305 }
306}
307
308//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
309
310void G4IonICRU73Data::ReadElementData(const G4Material* mat, G4bool useICRU90)
311{
312 const G4ElementVector* elmv = mat->GetElementVector();
313 const G4double* dens = mat->GetFractionVector();
314 const G4int nelm = (G4int)mat->GetNumberOfElements();
315 for(G4int Z=3; Z<=ZPROJMAX; ++Z) {
316 if (1 < fVerbose) {
317 G4cout << "ReadElementData for " << mat->GetName() << " Z=" << Z
318 << " Nelm=" << nelm << G4endl;
319 }
320 G4PhysicsLogVector* v = nullptr;
321 if(1 == nelm) {
322 v = FindOrBuildElementData(Z, (*elmv)[0]->GetZasInt(), useICRU90);
323 } else {
324 v = new G4PhysicsLogVector(fEmin, fEmax, fNbins, fSpline);
325 for(G4int i=0; i<=fNbins; ++i) {
326 G4double dedx = 0.0;
327 for(G4int j=0; j<nelm; ++j) {
328 G4PhysicsLogVector* v1 =
329 FindOrBuildElementData(Z, (*elmv)[j]->GetZasInt(), useICRU90);
330 dedx += (*v1)[i]*dens[j];
331 }
332 v->PutValue(i, dedx);
333 }
334 if(fSpline) { v->FillSecondDerivatives(); }
335 (*(fMatData[Z]))[(G4int)mat->GetIndex()] = v;
336 }
337 // scale data for correct units
338 if(nullptr != v) {
339 const G4double fact =
340 mat->GetDensity() * CLHEP::MeV * 1000 * CLHEP::cm2 / CLHEP::g;
341 v->ScaleVector(CLHEP::MeV, fact);
342 if(2 < fVerbose) {
343 G4cout << "### Data for "<< mat->GetName()
344 << " for projectile Z=" << Z << G4endl;
345 G4cout << *v << G4endl;
346 }
347 }
348 }
349}
350
351//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
352
354G4IonICRU73Data::FindOrBuildElementData(const G4int Z, const G4int Z1,
355 G4bool useICRU90)
356{
357 G4PhysicsLogVector* v = nullptr;
358 if(Z <= ZPROJMAX && Z1 <= ZTARGMAX) {
359 v = fElmData[Z][Z1];
360 if(nullptr == v) {
361 G4int Z2 = Z1;
362 G4bool isICRU90 = (useICRU90 && Z <= 18 &&
363 (Z1 == 1 || Z1 == 6 || Z1 == 7 || Z1 == 8));
364
365 G4double scale = 1.0;
366 if(!isICRU90) {
367 for(G4int i=0; i<NZ; ++i) {
368 if(Z1 == zdat[i]) {
369 break;
370 } else if(i == NZ-1) {
371 Z2 = zdat[NZ - 1];
372 scale = (G4double)Z1/(G4double)Z2;
373 } else if(Z1 > zdat[i] && Z1 < zdat[i+1]) {
374 if(Z1 - zdat[i] <= zdat[i + 1] - Z1) {
375 Z2 = zdat[i];
376 } else {
377 Z2 = zdat[i+1];
378 }
379 scale = (G4double)Z1/(G4double)Z2;
380 break;
381 }
382 }
383 }
384
385 std::ostringstream ost;
386 ost << fDataDirectory << "icru";
387 if(isICRU90) { ost << "90"; }
388 else { ost << "73"; }
389 ost << "/z" << Z << "_" << Z2 << ".dat";
390 v = RetrieveVector(ost, false);
391 fElmData[Z][Z2] = v;
392 if(Z1 != Z2 && nullptr != v) {
393 fElmData[Z][Z1] = new G4PhysicsLogVector(*v);
394 fElmData[Z][Z1]->ScaleVector(1.0, scale);
395 }
396 }
397 }
398 return v;
399}
400
401//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
402
404G4IonICRU73Data::RetrieveVector(std::ostringstream& ost, G4bool warn)
405{
406 G4PhysicsLogVector* v = nullptr;
407 std::ifstream filein(ost.str().c_str());
408 if (!filein.is_open()) {
409 if(warn) {
411 ed << "Data file <" << ost.str().c_str()
412 << "> is not opened";
413 G4Exception("G4IonICRU73Data::RetrieveVector(..)","em013",
414 FatalException, ed, "Check G4LEDATA");
415 }
416 } else {
417 if(fVerbose > 0) {
418 G4cout << "File " << ost.str()
419 << " is opened by G4IonICRU73Data" << G4endl;
420 }
421
422 // retrieve data from DB
423 if(!fVector->Retrieve(filein, true)) {
425 ed << "Data file <" << ost.str().c_str()
426 << "> is not retrieved!";
427 G4Exception("G4IonICRU73Data::RetrieveVector(..)","had015",
428 FatalException, ed, "Check G4LEDATA");
429 } else {
430 if(fSpline) { fVector->FillSecondDerivatives(); }
431 fVector->EnableLogBinSearch(G4EmParameters::Instance()->NumberForFreeVector());
432 v = new G4PhysicsLogVector(fEmin, fEmax, fNbins, fSpline);
433 for(G4int i=0; i<=fNbins; ++i) {
434 G4double e = v->Energy(i);
435 G4double dedx = fVector->Value(e);
436 v->PutValue(i, dedx);
437 }
438 if(fSpline) { v->FillSecondDerivatives(); }
439 if(fVerbose > 2) { G4cout << *v << G4endl; }
440 }
441 }
442 return v;
443}
444
445//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
std::vector< const G4Element * > G4ElementVector
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
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
static G4EmParameters * Instance()
G4bool UseICRU90Data() const
const G4String & GetDirLEDATA() const
G4double GetDEDX(const G4Material *, const G4int Z, const G4double e, const G4double loge) const
G4double GetDensity() const
const G4ElementVector * GetElementVector() const
const G4double * GetFractionVector() const
static std::size_t GetNumberOfMaterials()
std::size_t GetIndex() const
static G4MaterialTable * GetMaterialTable()
std::size_t GetNumberOfElements() const
const G4String & GetName() const
void EnableLogBinSearch(const G4int n=1)
void PutValue(const std::size_t index, const G4double value)
void ScaleVector(const G4double factorE, const G4double factorV)
G4double Energy(const std::size_t index) const
G4double LogVectorValue(const G4double energy, const G4double theLogEnergy) const
G4bool Retrieve(std::ifstream &fIn, G4bool ascii=false)
G4double Value(const G4double energy, std::size_t &lastidx) const
void FillSecondDerivatives(const G4SplineType=G4SplineType::Base, const G4double dir1=0.0, const G4double dir2=0.0)
const char * name(G4int ptype)
int G4lrint(double ad)
Definition templates.hh:134