74 algorithm(ionAlgorithm),
77 maxCacheEntries(maxCacheSize) {
80 G4cerr <<
"G4IonDEDXHandler::G4IonDEDXHandler() "
81 <<
" Pointer to G4VIonDEDXTable object is null-pointer."
86 G4cerr <<
"G4IonDEDXHandler::G4IonDEDXHandler() "
87 <<
" Pointer to G4VIonDEDXScalingAlgorithm object is null-pointer."
91 if(maxCacheEntries <= 0) {
92 G4cerr <<
"G4IonDEDXHandler::G4IonDEDXHandler() "
93 <<
" Cache size <=0. Resetting to 5."
108 DEDXTableBraggRule::iterator iter = stoppingPowerTableBragg.begin();
109 DEDXTableBraggRule::iterator iter_end = stoppingPowerTableBragg.end();
111 for(;iter != iter_end; iter++)
delete iter ->
second;
112 stoppingPowerTableBragg.clear();
114 stoppingPowerTable.clear();
116 if(table != 0)
delete table;
117 if(algorithm != 0)
delete algorithm;
126 G4bool isApplicable =
true;
128 if(table == 0 || algorithm == 0) {
129 isApplicable =
false;
133 G4int atomicNumberIon = particle -> GetAtomicNumber();
134 G4int atomicNumberBase =
135 algorithm -> AtomicNumberBaseIon(atomicNumberIon, material);
137 G4IonKey key = std::make_pair(atomicNumberBase, material);
139 DEDXTable::iterator iter = stoppingPowerTable.find(key);
140 if(iter == stoppingPowerTable.end()) isApplicable =
false;
157 if(kineticEnergy <= 0.0) dedx = 0.0;
163 factor *= algorithm -> ScalingFactorDEDX(particle,
174 dedx = factor * value.
dedxVector -> GetValue(scaledKineticEnergy, b);
176 if(dedx < 0.0) dedx = 0.0;
181 G4cout <<
"G4IonDEDXHandler::GetDEDX() E = "
182 << kineticEnergy /
MeV <<
" MeV * "
185 <<
" MeV, dE/dx = " << dedx /
MeV *
cm <<
" MeV/cm"
186 <<
", material = " << material ->
GetName()
199 G4int atomicNumberIon = particle -> GetAtomicNumber();
210 G4int atomicNumberIon,
213 G4bool isApplicable =
true;
215 if(table == 0 || algorithm == 0) {
216 isApplicable =
false;
220 G4int atomicNumberBase =
221 algorithm -> AtomicNumberBaseIon(atomicNumberIon, material);
225 G4IonKey key = std::make_pair(atomicNumberBase, material);
227 DEDXTable::iterator iter = stoppingPowerTable.find(key);
228 if(iter != stoppingPowerTable.end())
return isApplicable;
232 const G4String& chemFormula = material -> GetChemicalFormula();
235 isApplicable = table -> BuildPhysicsVector(atomicNumberBase, chemFormula);
238 stoppingPowerTable[key] =
239 table -> GetPhysicsVector(atomicNumberBase, chemFormula);
243 isApplicable = table -> BuildPhysicsVector(atomicNumberBase, materialName);
245 stoppingPowerTable[key] =
246 table -> GetPhysicsVector(atomicNumberBase, materialName);
251 const G4ElementVector* elementVector = material -> GetElementVector() ;
253 std::vector<G4PhysicsVector*> dEdxTable;
255 size_t nmbElements = material -> GetNumberOfElements();
257 for(
size_t i = 0; i < nmbElements; i++) {
259 G4int atomicNumberMat =
G4int((*elementVector)[i] -> GetZ());
261 isApplicable = table -> BuildPhysicsVector(atomicNumberBase, atomicNumberMat);
266 table -> GetPhysicsVector(atomicNumberBase, atomicNumberMat);
267 dEdxTable.push_back(dEdx);
278 if(dEdxTable.size() > 0) {
280 size_t nmbdEdxBins = dEdxTable[0] -> GetVectorLength();
281 G4double lowerEdge = dEdxTable[0] -> GetLowEdgeEnergy(0);
282 G4double upperEdge = dEdxTable[0] -> GetLowEdgeEnergy(nmbdEdxBins-1);
288 dEdxBragg -> SetSpline(useSplines);
290 const G4double* massFractionVector = material -> GetFractionVector();
293 for(
size_t j = 0; j < nmbdEdxBins; j++) {
295 G4double edge = dEdxTable[0] -> GetLowEdgeEnergy(j);
298 for(
size_t i = 0; i < nmbElements; i++) {
300 value += (dEdxTable[i] -> GetValue(edge ,b)) *
301 massFractionVector[i];
304 dEdxBragg -> PutValues(j, edge, value);
308 G4cout <<
"G4IonDEDXHandler::BuildPhysicsVector() for ion with Z="
309 << atomicNumberBase <<
" in "
316 stoppingPowerTable[key] = dEdxBragg;
317 stoppingPowerTableBragg[key] = dEdxBragg;
334 G4int atomicNumberIon = particle -> GetAtomicNumber();
335 G4int atomicNumberBase =
336 algorithm -> AtomicNumberBaseIon(atomicNumberIon, material);
338 G4IonKey key = std::make_pair(atomicNumberBase, material);
340 DEDXTable::iterator iter = stoppingPowerTable.find(key);
342 if(iter != stoppingPowerTable.end()) {
347 algorithm -> ScalingFactorEnergy(particle, material) / nmbNucleons;
349 size_t nmbdEdxBins = value.
dedxVector -> GetVectorLength();
353 value.
dedxVector -> GetLowEdgeEnergy(nmbdEdxBins-1);
354 value.
density = material -> GetDensity();
365 G4cout <<
"G4IonDEDXHandler::UpdateCacheValue() for "
366 << particle -> GetParticleName() <<
" in "
380 G4CacheKey key = std::make_pair(particle, material);
383 CacheEntryList::iterator* pointerIter =
384 (CacheEntryList::iterator*) cacheKeyPointers[key];
387 entry.value = UpdateCacheValue(particle, material);
390 cacheEntries.push_front(entry);
392 CacheEntryList::iterator* pointerIter1 =
393 new CacheEntryList::iterator();
394 *pointerIter1 = cacheEntries.begin();
395 cacheKeyPointers[key] = pointerIter1;
397 if(
G4int(cacheEntries.size()) > maxCacheEntries) {
399 G4CacheEntry lastEntry = cacheEntries.back();
401 void* pointerIter2 = cacheKeyPointers[lastEntry.key];
402 CacheEntryList::iterator* listPointerIter =
403 (CacheEntryList::iterator*) pointerIter2;
405 cacheEntries.erase(*listPointerIter);
407 delete listPointerIter;
408 cacheKeyPointers.erase(lastEntry.key);
412 entry = *(*pointerIter);
426 CacheIterPointerMap::iterator iter = cacheKeyPointers.begin();
427 CacheIterPointerMap::iterator iter_end = cacheKeyPointers.end();
429 for(;iter != iter_end; iter++) {
430 void* pointerIter = iter ->
second;
431 CacheEntryList::iterator* listPointerIter =
432 (CacheEntryList::iterator*) pointerIter;
434 delete listPointerIter;
437 cacheEntries.clear();
438 cacheKeyPointers.clear();
451 G4double atomicMassNumber = particle -> GetAtomicMass();
452 G4double materialDensity = material -> GetDensity();
454 G4cout <<
"# dE/dx table for " << particle -> GetParticleName()
455 <<
" in material " << material ->
GetName()
456 <<
" of density " << materialDensity /
g *
cm3
459 <<
"# Projectile mass number A1 = " << atomicMassNumber
461 <<
"# Energy range (per nucleon) of tabulation: "
467 <<
"# ------------------------------------------------------"
471 << std::setw(14) <<
"E/A1"
472 << std::setw(14) <<
"dE/dx"
473 << std::setw(14) <<
"1/rho*dE/dx"
477 << std::setw(14) <<
"(MeV)"
478 << std::setw(14) <<
"(MeV/cm)"
479 << std::setw(14) <<
"(MeV*cm2/mg)"
481 <<
"# ------------------------------------------------------"
486 G4double energyLowerBoundary = lowerBoundary * atomicMassNumber;
487 G4double energyUpperBoundary = upperBoundary * atomicMassNumber;
491 energyLowerBoundary = std::log(energyLowerBoundary);
492 energyUpperBoundary = std::log(energyUpperBoundary);
495 G4double deltaEnergy = (energyUpperBoundary - energyLowerBoundary) /
499 for(
int i = 0; i < nmbBins + 1; i++) {
502 if(logScaleEnergy) energy = std::exp(energy);
507 << std::setw(14) << energy / atomicMassNumber /
MeV
508 << std::setw(14) << loss /
MeV *
cm
509 << std::setw(14) << loss / materialDensity / (
MeV*
cm2/(0.001*
g))