Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4AdjointCSManager.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#include "G4AdjointCSManager.hh"
29
30#include "G4AdjointCSMatrix.hh"
31#include "G4AdjointElectron.hh"
32#include "G4AdjointGamma.hh"
34#include "G4AdjointProton.hh"
35#include "G4Electron.hh"
36#include "G4Element.hh"
37#include "G4ElementTable.hh"
38#include "G4Gamma.hh"
41#include "G4PhysicsLogVector.hh"
42#include "G4PhysicsTable.hh"
44#include "G4Proton.hh"
45#include "G4SystemOfUnits.hh"
46#include "G4VEmAdjointModel.hh"
47#include "G4VEmProcess.hh"
49
50G4ThreadLocal G4AdjointCSManager* G4AdjointCSManager::fInstance = nullptr;
51
52constexpr G4double G4AdjointCSManager::fTmin;
53constexpr G4double G4AdjointCSManager::fTmax;
54constexpr G4int G4AdjointCSManager::fNbins;
55
56///////////////////////////////////////////////////////
58{
59 if(fInstance == nullptr)
60 {
62 fInstance = inst.Instance();
63 }
64 return fInstance;
65}
66
67///////////////////////////////////////////////////////
68G4AdjointCSManager::G4AdjointCSManager()
69{
73}
74
75///////////////////////////////////////////////////////
77{
78 for (auto& p : fAdjointCSMatricesForProdToProj) {
79 for (auto p1 : p) {
80 if (p1) {
81 delete p1;
82 p1 = nullptr;
83 }
84 }
85 p.clear();
86 }
87 fAdjointCSMatricesForProdToProj.clear();
88
89 for (auto& p : fAdjointCSMatricesForScatProjToProj) {
90 for (auto p1 : p) {
91 if (p1) {
92 delete p1;
93 p1 = nullptr;
94 }
95 }
96 p.clear();
97 }
98 fAdjointCSMatricesForScatProjToProj.clear();
99
100 for (auto p : fAdjointModels) {
101 if (p) {
102 delete p;
103 p = nullptr;
104 }
105 }
106 fAdjointModels.clear();
107
108 for (auto p : fTotalAdjSigmaTable) {
109 p->clearAndDestroy();
110 delete p;
111 p = nullptr;
112 }
113 fTotalAdjSigmaTable.clear();
114
115 for (auto p : fSigmaTableForAdjointModelScatProjToProj) {
116 p->clearAndDestroy();
117 delete p;
118 p = nullptr;
119 }
120 fSigmaTableForAdjointModelScatProjToProj.clear();
121
122 for (auto p : fSigmaTableForAdjointModelProdToProj) {
123 p->clearAndDestroy();
124 delete p;
125 p = nullptr;
126 }
127 fSigmaTableForAdjointModelProdToProj.clear();
128
129 for (auto p : fTotalFwdSigmaTable) {
130 p->clearAndDestroy();
131 delete p;
132 p = nullptr;
133 }
134 fTotalFwdSigmaTable.clear();
135
136 for (auto p : fForwardProcesses) {
137 delete p;
138 p = nullptr;
139 }
140 fForwardProcesses.clear();
141
142 for (auto p : fForwardLossProcesses) {
143 delete p;
144 p = nullptr;
145 }
146 fForwardLossProcesses.clear();
147}
148
149///////////////////////////////////////////////////////
151{
152 fAdjointModels.push_back(aModel);
153 fSigmaTableForAdjointModelScatProjToProj.push_back(new G4PhysicsTable);
154 fSigmaTableForAdjointModelProdToProj.push_back(new G4PhysicsTable);
155 return fAdjointModels.size() - 1;
156}
157
158///////////////////////////////////////////////////////
160 G4ParticleDefinition* aFwdPartDef)
161{
162 G4ParticleDefinition* anAdjPartDef =
163 GetAdjointParticleEquivalent(aFwdPartDef);
164 if(anAdjPartDef && aProcess)
165 {
166 RegisterAdjointParticle(anAdjPartDef);
167
168 for(std::size_t i = 0; i < fAdjointParticlesInAction.size(); ++i)
169 {
170 if(anAdjPartDef->GetParticleName() ==
171 fAdjointParticlesInAction[i]->GetParticleName())
172 fForwardProcesses[i]->push_back(aProcess);
173 }
174 }
175}
176
177///////////////////////////////////////////////////////
179 G4VEnergyLossProcess* aProcess, G4ParticleDefinition* aFwdPartDef)
180{
181 G4ParticleDefinition* anAdjPartDef =
182 GetAdjointParticleEquivalent(aFwdPartDef);
183 if(anAdjPartDef && aProcess)
184 {
185 RegisterAdjointParticle(anAdjPartDef);
186 for(std::size_t i = 0; i < fAdjointParticlesInAction.size(); ++i)
187 {
188 if(anAdjPartDef->GetParticleName() ==
189 fAdjointParticlesInAction[i]->GetParticleName())
190 fForwardLossProcesses[i]->push_back(aProcess);
191
192 }
193 }
194}
195
196///////////////////////////////////////////////////////
198{
199 G4bool found = false;
200 for(auto p : fAdjointParticlesInAction)
201 {
202 if(p->GetParticleName() == aPartDef->GetParticleName())
203 {
204 found = true;
205 }
206 }
207 if(!found)
208 {
209 fForwardLossProcesses.push_back(new std::vector<G4VEnergyLossProcess*>());
210 fTotalFwdSigmaTable.push_back(new G4PhysicsTable);
211 fTotalAdjSigmaTable.push_back(new G4PhysicsTable);
212 fForwardProcesses.push_back(new std::vector<G4VEmProcess*>());
213 fAdjointParticlesInAction.push_back(aPartDef);
214 fEminForFwdSigmaTables.push_back(std::vector<G4double>());
215 fEminForAdjSigmaTables.push_back(std::vector<G4double>());
216 fEkinofFwdSigmaMax.push_back(std::vector<G4double>());
217 fEkinofAdjSigmaMax.push_back(std::vector<G4double>());
218 }
219}
220
221///////////////////////////////////////////////////////
223{
224 if(fCSMatricesBuilt)
225 return;
226 // The Tcut and Tmax matrices will be computed probably just once.
227 // When Tcut changes, some PhysicsTable will be recomputed
228 // for each MaterialCutCouple but not all the matrices.
229 // The Tcut defines a lower limit in the energy of the projectile before
230 // scattering. In the Projectile to Scattered Projectile case we have
231 // E_ScatProj<E_Proj-Tcut
232 // Therefore in the adjoint case we have
233 // Eproj> E_ScatProj+Tcut
234 // This implies that when computing the adjoint CS we should integrate over
235 // Epro from E_ScatProj+Tcut to Emax
236 // In the Projectile to Secondary case Tcut plays a role only in the fact that
237 // Esecond should be greater than Tcut to have the possibility to have any
238 // adjoint process.
239 // To avoid recomputing matrices for all changes of MaterialCutCouple,
240 // we propose to compute the matrices only once for the minimum possible Tcut
241 // and then to interpolate the probability for a new Tcut (implemented in
242 // G4VAdjointEmModel)
243
244 fAdjointCSMatricesForScatProjToProj.clear();
245 fAdjointCSMatricesForProdToProj.clear();
246 const G4ElementTable* theElementTable = G4Element::GetElementTable();
247 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
248
249 G4cout << "========== Computation of cross section matrices for adjoint "
250 "models =========="
251 << G4endl;
252 for(const auto& aModel : fAdjointModels)
253 {
254 G4cout << "Build adjoint cross section matrices for " << aModel->GetName()
255 << G4endl;
256 if(aModel->GetUseMatrix())
257 {
258 std::vector<G4AdjointCSMatrix*>* aListOfMat1 =
259 new std::vector<G4AdjointCSMatrix*>();
260 std::vector<G4AdjointCSMatrix*>* aListOfMat2 =
261 new std::vector<G4AdjointCSMatrix*>();
262 if(aModel->GetUseMatrixPerElement())
263 {
264 if(aModel->GetUseOnlyOneMatrixForAllElements())
265 {
266 std::vector<G4AdjointCSMatrix*> two_matrices =
267 BuildCrossSectionsModelAndElement(aModel, 1, 1, 80);
268 aListOfMat1->push_back(two_matrices[0]);
269 aListOfMat2->push_back(two_matrices[1]);
270 }
271 else
272 {
273 for(const auto& anElement : *theElementTable)
274 {
275 G4int Z = G4lrint(anElement->GetZ());
276 G4int A = G4lrint(anElement->GetN());
277 std::vector<G4AdjointCSMatrix*> two_matrices =
278 BuildCrossSectionsModelAndElement(aModel, Z, A, 40);
279 aListOfMat1->push_back(two_matrices[0]);
280 aListOfMat2->push_back(two_matrices[1]);
281 }
282 }
283 }
284 else
285 { // Per material case
286 for(const auto& aMaterial : *theMaterialTable)
287 {
288 std::vector<G4AdjointCSMatrix*> two_matrices =
289 BuildCrossSectionsModelAndMaterial(aModel, aMaterial, 40);
290 aListOfMat1->push_back(two_matrices[0]);
291 aListOfMat2->push_back(two_matrices[1]);
292 }
293 }
294 fAdjointCSMatricesForProdToProj.push_back(*aListOfMat1);
295 fAdjointCSMatricesForScatProjToProj.push_back(*aListOfMat2);
296 aModel->SetCSMatrices(aListOfMat1, aListOfMat2);
297 }
298 else
299 {
300 G4cout << "The model " << aModel->GetName()
301 << " does not use cross section matrices" << G4endl;
302 std::vector<G4AdjointCSMatrix*> two_empty_matrices;
303 fAdjointCSMatricesForProdToProj.push_back(two_empty_matrices);
304 fAdjointCSMatricesForScatProjToProj.push_back(two_empty_matrices);
305 }
306 }
307 G4cout << " All adjoint cross section matrices are computed!"
308 << G4endl;
309 G4cout
310 << "======================================================================"
311 << G4endl;
312
313 fCSMatricesBuilt = true;
314}
315
316///////////////////////////////////////////////////////
318{
319 if(fSigmaTableBuilt)
320 return;
321
322 const G4ProductionCutsTable* theCoupleTable =
324
325 // Prepare the Sigma table for all AdjointEMModel, will be filled later on
326 for(std::size_t i = 0; i < fAdjointModels.size(); ++i)
327 {
328 fSigmaTableForAdjointModelScatProjToProj[i]->clearAndDestroy();
329 fSigmaTableForAdjointModelProdToProj[i]->clearAndDestroy();
330 for(std::size_t j = 0; j < theCoupleTable->GetTableSize(); ++j)
331 {
332 fSigmaTableForAdjointModelScatProjToProj[i]->push_back(
333 new G4PhysicsLogVector(fTmin, fTmax, fNbins));
334 fSigmaTableForAdjointModelProdToProj[i]->push_back(
335 new G4PhysicsLogVector(fTmin, fTmax, fNbins));
336 }
337 }
338
339 for(std::size_t i = 0; i < fAdjointParticlesInAction.size(); ++i)
340 {
341 G4ParticleDefinition* thePartDef = fAdjointParticlesInAction[i];
342 DefineCurrentParticle(thePartDef);
343 fTotalFwdSigmaTable[i]->clearAndDestroy();
344 fTotalAdjSigmaTable[i]->clearAndDestroy();
345 fEminForFwdSigmaTables[i].clear();
346 fEminForAdjSigmaTables[i].clear();
347 fEkinofFwdSigmaMax[i].clear();
348 fEkinofAdjSigmaMax[i].clear();
349
350 for(std::size_t j = 0; j < theCoupleTable->GetTableSize(); ++j)
351 {
352 const G4MaterialCutsCouple* couple =
353 theCoupleTable->GetMaterialCutsCouple((G4int)j);
354
355 // make first the total fwd CS table for FwdProcess
356 G4PhysicsVector* aVector = new G4PhysicsLogVector(fTmin, fTmax, fNbins);
357 G4bool Emin_found = false;
358 G4double sigma_max = 0.;
359 G4double e_sigma_max = 0.;
360 for(std::size_t l = 0; l < fNbins; ++l)
361 {
362 G4double totCS = 0.;
363 G4double e = aVector->Energy(l);
364 for(std::size_t k = 0; k < fForwardProcesses[i]->size(); ++k)
365 {
366 totCS += (*fForwardProcesses[i])[k]->GetCrossSection(e, couple);
367 }
368 for(std::size_t k = 0; k < fForwardLossProcesses[i]->size(); ++k)
369 {
370 if(thePartDef == fAdjIon)
371 { // e is considered already as the scaled energy
372 std::size_t mat_index = couple->GetIndex();
373 G4VEmModel* currentModel =
374 (*fForwardLossProcesses[i])[k]->SelectModelForMaterial(e,
375 mat_index);
376 G4double chargeSqRatio = currentModel->GetChargeSquareRatio(
377 fFwdIon, couple->GetMaterial(), e / fMassRatio);
378 (*fForwardLossProcesses[i])[k]->SetDynamicMassCharge(fMassRatio,
379 chargeSqRatio);
380 }
381 G4double e1 = e / fMassRatio;
382 totCS += (*fForwardLossProcesses[i])[k]->GetLambda(e1, couple);
383 }
384 aVector->PutValue(l, totCS);
385 if(totCS > sigma_max)
386 {
387 sigma_max = totCS;
388 e_sigma_max = e;
389 }
390 if(totCS > 0 && !Emin_found)
391 {
392 fEminForFwdSigmaTables[i].push_back(e);
393 Emin_found = true;
394 }
395 }
396
397 fEkinofFwdSigmaMax[i].push_back(e_sigma_max);
398
399 if(!Emin_found)
400 fEminForFwdSigmaTables[i].push_back(fTmax);
401
402 fTotalFwdSigmaTable[i]->push_back(aVector);
403
404 Emin_found = false;
405 sigma_max = 0;
406 e_sigma_max = 0.;
407 G4PhysicsVector* aVector1 = new G4PhysicsLogVector(fTmin, fTmax, fNbins);
408 for(std::size_t eindex = 0; eindex < fNbins; ++eindex)
409 {
410 G4double e = aVector1->Energy(eindex);
412 couple, thePartDef,
413 e * 0.9999999 / fMassRatio); // fMassRatio needed for ions
414 aVector1->PutValue(eindex, totCS);
415 if(totCS > sigma_max)
416 {
417 sigma_max = totCS;
418 e_sigma_max = e;
419 }
420 if(totCS > 0 && !Emin_found)
421 {
422 fEminForAdjSigmaTables[i].push_back(e);
423 Emin_found = true;
424 }
425 }
426 fEkinofAdjSigmaMax[i].push_back(e_sigma_max);
427 if(!Emin_found)
428 fEminForAdjSigmaTables[i].push_back(fTmax);
429
430 fTotalAdjSigmaTable[i]->push_back(aVector1);
431 }
432 }
433 fSigmaTableBuilt = true;
434}
435
436///////////////////////////////////////////////////////
438 G4ParticleDefinition* aPartDef, G4double Ekin,
439 const G4MaterialCutsCouple* aCouple)
440{
441 DefineCurrentMaterial(aCouple);
442 DefineCurrentParticle(aPartDef);
443 return (((*fTotalAdjSigmaTable[fCurrentParticleIndex])[fCurrentMatIndex])
444 ->Value(Ekin * fMassRatio));
445}
446
447///////////////////////////////////////////////////////
449 G4ParticleDefinition* aPartDef, G4double Ekin,
450 const G4MaterialCutsCouple* aCouple)
451{
452 DefineCurrentMaterial(aCouple);
453 DefineCurrentParticle(aPartDef);
454 return (((*fTotalFwdSigmaTable[fCurrentParticleIndex])[fCurrentMatIndex])
455 ->Value(Ekin * fMassRatio));
456}
457
458///////////////////////////////////////////////////////
460 G4double Ekin_nuc, std::size_t index_model, G4bool is_scat_proj_to_proj,
461 const G4MaterialCutsCouple* aCouple)
462{
463 DefineCurrentMaterial(aCouple);
464 if(is_scat_proj_to_proj)
465 return (((*fSigmaTableForAdjointModelScatProjToProj[index_model])
466 [fCurrentMatIndex])->Value(Ekin_nuc));
467 else
468 return (
469 ((*fSigmaTableForAdjointModelProdToProj[index_model])[fCurrentMatIndex])
470 ->Value(Ekin_nuc));
471}
472
473///////////////////////////////////////////////////////
475 const G4MaterialCutsCouple* aCouple,
476 G4double& emin_adj,
477 G4double& emin_fwd)
478{
479 DefineCurrentMaterial(aCouple);
480 DefineCurrentParticle(aPartDef);
481 emin_adj = fEminForAdjSigmaTables[fCurrentParticleIndex][fCurrentMatIndex] /
482 fMassRatio;
483 emin_fwd = fEminForFwdSigmaTables[fCurrentParticleIndex][fCurrentMatIndex] /
484 fMassRatio;
485}
486
487///////////////////////////////////////////////////////
489 const G4MaterialCutsCouple* aCouple,
490 G4double& e_sigma_max,
491 G4double& sigma_max)
492{
493 DefineCurrentMaterial(aCouple);
494 DefineCurrentParticle(aPartDef);
495 e_sigma_max = fEkinofFwdSigmaMax[fCurrentParticleIndex][fCurrentMatIndex];
496 sigma_max = ((*fTotalFwdSigmaTable[fCurrentParticleIndex])[fCurrentMatIndex])
497 ->Value(e_sigma_max);
498 e_sigma_max /= fMassRatio;
499}
500
501///////////////////////////////////////////////////////
503 const G4MaterialCutsCouple* aCouple,
504 G4double& e_sigma_max,
505 G4double& sigma_max)
506{
507 DefineCurrentMaterial(aCouple);
508 DefineCurrentParticle(aPartDef);
509 e_sigma_max = fEkinofAdjSigmaMax[fCurrentParticleIndex][fCurrentMatIndex];
510 sigma_max = ((*fTotalAdjSigmaTable[fCurrentParticleIndex])[fCurrentMatIndex])
511 ->Value(e_sigma_max);
512 e_sigma_max /= fMassRatio;
513}
514
515///////////////////////////////////////////////////////
517 G4ParticleDefinition* aPartDef, G4double PreStepEkin,
518 const G4MaterialCutsCouple* aCouple, G4bool& fwd_is_used)
519{
520 static G4double lastEkin = 0.;
521 static G4ParticleDefinition* lastPartDef;
522
523 G4double corr_fac = 1.;
524 if(fForwardCSMode && aPartDef)
525 {
526 if(lastEkin != PreStepEkin || aPartDef != lastPartDef ||
527 aCouple != fCurrentCouple)
528 {
529 DefineCurrentMaterial(aCouple);
530 G4double preadjCS = GetTotalAdjointCS(aPartDef, PreStepEkin, aCouple);
531 G4double prefwdCS = GetTotalForwardCS(aPartDef, PreStepEkin, aCouple);
532 lastEkin = PreStepEkin;
533 lastPartDef = aPartDef;
534 if(prefwdCS > 0. && preadjCS > 0.)
535 {
536 fForwardCSUsed = true;
537 fLastCSCorrectionFactor = prefwdCS / preadjCS;
538 }
539 else
540 {
541 fForwardCSUsed = false;
542 fLastCSCorrectionFactor = 1.;
543 }
544 }
545 corr_fac = fLastCSCorrectionFactor;
546 }
547 else
548 {
549 fForwardCSUsed = false;
550 fLastCSCorrectionFactor = 1.;
551 }
552 fwd_is_used = fForwardCSUsed;
553 return corr_fac;
554}
555
556///////////////////////////////////////////////////////
558 G4ParticleDefinition* aPartDef, G4double PreStepEkin, G4double AfterStepEkin,
559 const G4MaterialCutsCouple* aCouple, G4double step_length)
560{
561 G4double corr_fac = 1.;
562 G4double after_fwdCS = GetTotalForwardCS(aPartDef, AfterStepEkin, aCouple);
563 G4double pre_adjCS = GetTotalAdjointCS(aPartDef, PreStepEkin, aCouple);
564 if(!fForwardCSUsed || pre_adjCS == 0. || after_fwdCS == 0.)
565 {
566 G4double pre_fwdCS = GetTotalForwardCS(aPartDef, PreStepEkin, aCouple);
567 corr_fac *= std::exp((pre_adjCS - pre_fwdCS) * step_length);
568 fLastCSCorrectionFactor = 1.;
569 }
570 else
571 {
572 fLastCSCorrectionFactor = after_fwdCS / pre_adjCS;
573 }
574 return corr_fac;
575}
576
577///////////////////////////////////////////////////////
579{
580 return 1. / fLastCSCorrectionFactor;
581}
582
583///////////////////////////////////////////////////////
585 G4Material* aMaterial, G4VEmAdjointModel* aModel, G4double PrimEnergy,
586 G4double Tcut, G4bool isScatProjToProj, std::vector<G4double>& CS_Vs_Element)
587{
588 G4double EminSec = 0.;
589 G4double EmaxSec = 0.;
590
591 static G4double lastPrimaryEnergy = 0.;
592 static G4double lastTcut = 0.;
593 static G4Material* lastMaterial = nullptr;
594
595 if(isScatProjToProj)
596 {
597 EminSec = aModel->GetSecondAdjEnergyMinForScatProjToProj(PrimEnergy, Tcut);
598 EmaxSec = aModel->GetSecondAdjEnergyMaxForScatProjToProj(PrimEnergy);
599 }
600 else if(PrimEnergy > Tcut || !aModel->GetApplyCutInRange())
601 {
602 EminSec = aModel->GetSecondAdjEnergyMinForProdToProj(PrimEnergy);
603 EmaxSec = aModel->GetSecondAdjEnergyMaxForProdToProj(PrimEnergy);
604 }
605 if(EminSec >= EmaxSec)
606 return 0.;
607
608 G4bool need_to_compute = false;
609 if(aMaterial != lastMaterial || PrimEnergy != lastPrimaryEnergy ||
610 Tcut != lastTcut)
611 {
612 lastMaterial = aMaterial;
613 lastPrimaryEnergy = PrimEnergy;
614 lastTcut = Tcut;
615 fIndexOfAdjointEMModelInAction.clear();
616 fIsScatProjToProj.clear();
617 fLastAdjointCSVsModelsAndElements.clear();
618 need_to_compute = true;
619 }
620
621 std::size_t ind = 0;
622 if(!need_to_compute)
623 {
624 need_to_compute = true;
625 for(std::size_t i = 0; i < fIndexOfAdjointEMModelInAction.size(); ++i)
626 {
627 std::size_t ind1 = fIndexOfAdjointEMModelInAction[i];
628 if(aModel == fAdjointModels[ind1] &&
629 isScatProjToProj == fIsScatProjToProj[i])
630 {
631 need_to_compute = false;
632 CS_Vs_Element = fLastAdjointCSVsModelsAndElements[ind];
633 }
634 ++ind;
635 }
636 }
637
638 if(need_to_compute)
639 {
640 std::size_t ind_model = 0;
641 for(std::size_t i = 0; i < fAdjointModels.size(); ++i)
642 {
643 if(aModel == fAdjointModels[i])
644 {
645 ind_model = i;
646 break;
647 }
648 }
649 G4double Tlow = Tcut;
650 if(!fAdjointModels[ind_model]->GetApplyCutInRange())
651 Tlow = fAdjointModels[ind_model]->GetLowEnergyLimit();
652 fIndexOfAdjointEMModelInAction.push_back(ind_model);
653 fIsScatProjToProj.push_back(isScatProjToProj);
654 CS_Vs_Element.clear();
655 if(!aModel->GetUseMatrix())
656 {
657 CS_Vs_Element.push_back(aModel->AdjointCrossSection(
658 fCurrentCouple, PrimEnergy, isScatProjToProj));
659 }
660 else if(aModel->GetUseMatrixPerElement())
661 {
662 std::size_t n_el = aMaterial->GetNumberOfElements();
664 {
665 G4AdjointCSMatrix* theCSMatrix;
666 if(isScatProjToProj)
667 {
668 theCSMatrix = fAdjointCSMatricesForScatProjToProj[ind_model][0];
669 }
670 else
671 theCSMatrix = fAdjointCSMatricesForProdToProj[ind_model][0];
672 G4double CS = 0.;
673 if(PrimEnergy > Tlow)
674 CS = ComputeAdjointCS(PrimEnergy, theCSMatrix, Tlow);
675 G4double factor = 0.;
676 for(G4int i = 0; i < (G4int)n_el; ++i)
677 { // this could be computed only once
678 factor += aMaterial->GetElement(i)->GetZ() *
679 aMaterial->GetVecNbOfAtomsPerVolume()[i];
680 }
681 CS *= factor;
682 CS_Vs_Element.push_back(CS);
683 }
684 else
685 {
686 for(G4int i = 0; i < (G4int)n_el; ++i)
687 {
688 std::size_t ind_el = aMaterial->GetElement(i)->GetIndex();
689 G4AdjointCSMatrix* theCSMatrix;
690 if(isScatProjToProj)
691 {
692 theCSMatrix =
693 fAdjointCSMatricesForScatProjToProj[ind_model][ind_el];
694 }
695 else
696 theCSMatrix = fAdjointCSMatricesForProdToProj[ind_model][ind_el];
697 G4double CS = 0.;
698 if(PrimEnergy > Tlow)
699 CS = ComputeAdjointCS(PrimEnergy, theCSMatrix, Tlow);
700 CS_Vs_Element.push_back(CS *
701 (aMaterial->GetVecNbOfAtomsPerVolume()[i]));
702 }
703 }
704 }
705 else
706 {
707 std::size_t ind_mat = aMaterial->GetIndex();
708 G4AdjointCSMatrix* theCSMatrix;
709 if(isScatProjToProj)
710 {
711 theCSMatrix = fAdjointCSMatricesForScatProjToProj[ind_model][ind_mat];
712 }
713 else
714 theCSMatrix = fAdjointCSMatricesForProdToProj[ind_model][ind_mat];
715 G4double CS = 0.;
716 if(PrimEnergy > Tlow)
717 CS = ComputeAdjointCS(PrimEnergy, theCSMatrix, Tlow);
718 CS_Vs_Element.push_back(CS);
719 }
720 fLastAdjointCSVsModelsAndElements.push_back(CS_Vs_Element);
721 }
722
723 G4double CS = 0.;
724 for(const auto& cs_vs_el : CS_Vs_Element)
725 {
726 // We could put the progressive sum of the CS instead of the CS of an
727 // element itself
728 CS += cs_vs_el;
729 }
730 return CS;
731}
732
733///////////////////////////////////////////////////////
735 G4Material* aMaterial, G4VEmAdjointModel* aModel, G4double PrimEnergy,
736 G4double Tcut, G4bool isScatProjToProj)
737{
738 std::vector<G4double> CS_Vs_Element;
739 G4double CS = ComputeAdjointCS(aMaterial, aModel, PrimEnergy, Tcut,
740 isScatProjToProj, CS_Vs_Element);
741 G4double SumCS = 0.;
742 std::size_t ind = 0;
743 for(std::size_t i = 0; i < CS_Vs_Element.size(); ++i)
744 {
745 SumCS += CS_Vs_Element[i];
746 if(G4UniformRand() <= SumCS / CS)
747 {
748 ind = i;
749 break;
750 }
751 }
752
753 return const_cast<G4Element*>(aMaterial->GetElement((G4int)ind));
754}
755
756///////////////////////////////////////////////////////
758 const G4MaterialCutsCouple* aCouple, G4ParticleDefinition* aPartDef,
759 G4double Ekin)
760{
761 G4double TotalCS = 0.;
762
763 DefineCurrentMaterial(aCouple);
764
765 std::vector<G4double> CS_Vs_Element;
766 G4double CS;
767 G4VEmAdjointModel* adjModel = nullptr;
768 for(std::size_t i = 0; i < fAdjointModels.size(); ++i)
769 {
770 G4double Tlow = 0.;
771 adjModel = fAdjointModels[i];
772 if(!adjModel->GetApplyCutInRange())
773 Tlow = adjModel->GetLowEnergyLimit();
774 else
775 {
778 std::size_t idx = 56;
779 if(theDirSecondPartDef->GetParticleName() == "gamma")
780 idx = 0;
781 else if(theDirSecondPartDef->GetParticleName() == "e-")
782 idx = 1;
783 else if(theDirSecondPartDef->GetParticleName() == "e+")
784 idx = 2;
785 if(idx < 56)
786 {
787 const std::vector<G4double>* aVec =
789 idx);
790 Tlow = (*aVec)[aCouple->GetIndex()];
791 }
792 }
793 if(Ekin <= adjModel->GetHighEnergyLimit() &&
794 Ekin >= adjModel->GetLowEnergyLimit())
795 {
796 if(aPartDef ==
798 {
799 CS = ComputeAdjointCS(fCurrentMaterial, adjModel, Ekin, Tlow, true,
800 CS_Vs_Element);
801 TotalCS += CS;
802 (*fSigmaTableForAdjointModelScatProjToProj[i])[fCurrentMatIndex]
803 ->PutValue(fNbins, CS);
804 }
805 if(aPartDef ==
807 {
808 CS = ComputeAdjointCS(fCurrentMaterial, adjModel, Ekin, Tlow, false,
809 CS_Vs_Element);
810 TotalCS += CS;
811 (*fSigmaTableForAdjointModelProdToProj[i])[fCurrentMatIndex]->PutValue(
812 fNbins, CS);
813 }
814 }
815 else
816 {
817 (*fSigmaTableForAdjointModelScatProjToProj[i])[fCurrentMatIndex]
818 ->PutValue(fNbins, 0.);
819 (*fSigmaTableForAdjointModelProdToProj[i])[fCurrentMatIndex]->PutValue(
820 fNbins, 0.);
821 }
822 }
823 return TotalCS;
824}
825
826///////////////////////////////////////////////////////
827std::vector<G4AdjointCSMatrix*>
828G4AdjointCSManager::BuildCrossSectionsModelAndElement(G4VEmAdjointModel* aModel,
829 G4int Z, G4int A,
830 G4int nbin_pro_decade)
831{
832 G4AdjointCSMatrix* theCSMatForProdToProjBackwardScattering =
833 new G4AdjointCSMatrix(false);
834 G4AdjointCSMatrix* theCSMatForScatProjToProjBackwardScattering =
835 new G4AdjointCSMatrix(true);
836
837 // make the vector of primary energy of the adjoint particle.
838 G4double EkinMin = aModel->GetLowEnergyLimit();
839 G4double EkinMaxForScat = aModel->GetHighEnergyLimit() * 0.999;
840 G4double EkinMaxForProd = aModel->GetHighEnergyLimit() * 0.999;
841 if(aModel->GetSecondPartOfSameType())
842 EkinMaxForProd = EkinMaxForProd / 2.;
843
844 // Product to projectile backward scattering
845 G4double dE = std::pow(10., 1. / nbin_pro_decade);
846 G4double E2 =
847 std::pow(10., double(int(std::log10(EkinMin) * nbin_pro_decade) + 1) /
848 nbin_pro_decade) / dE;
849 G4double E1 = EkinMin;
850 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
851 while(E1 < EkinMaxForProd)
852 {
853 E1 = std::max(EkinMin, E2);
854 E1 = std::min(EkinMaxForProd, E1);
855 std::vector<std::vector<double>*> aMat =
857 nbin_pro_decade);
858 if(aMat.size() >= 2)
859 {
860 std::vector<double>* log_ESecVec = aMat[0];
861 std::vector<double>* log_CSVec = aMat[1];
862 G4double log_adjointCS = log_CSVec->back();
863 // normalise CSVec such that it becomes a probability vector
864 for(std::size_t j = 0; j < log_CSVec->size(); ++j)
865 {
866 if(j == 0)
867 (*log_CSVec)[j] = 0.;
868 else
869 (*log_CSVec)[j] =
870 std::log(1. - std::exp((*log_CSVec)[j] - log_adjointCS) + 1e-50);
871 }
872 (*log_CSVec)[log_CSVec->size() - 1] =
873 (*log_CSVec)[log_CSVec->size() - 2] - std::log(1000.);
874 theCSMatForProdToProjBackwardScattering->AddData(
875 std::log(E1), log_adjointCS, log_ESecVec, log_CSVec, 0);
876 }
877 E1 = E2;
878 E2 *= dE;
879 }
880
881 // Scattered projectile to projectile backward scattering
882 E2 = std::pow(10., G4double(int(std::log10(EkinMin) * nbin_pro_decade) + 1) /
883 nbin_pro_decade) / dE;
884 E1 = EkinMin;
885 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
886 while(E1 < EkinMaxForScat)
887 {
888 E1 = std::max(EkinMin, E2);
889 E1 = std::min(EkinMaxForScat, E1);
890 std::vector<std::vector<G4double>*> aMat =
892 E1, Z, A, nbin_pro_decade);
893 if(aMat.size() >= 2)
894 {
895 std::vector<G4double>* log_ESecVec = aMat[0];
896 std::vector<G4double>* log_CSVec = aMat[1];
897 G4double log_adjointCS = log_CSVec->back();
898 // normalise CSVec such that it becomes a probability vector
899 for(std::size_t j = 0; j < log_CSVec->size(); ++j)
900 {
901 if(j == 0)
902 (*log_CSVec)[j] = 0.;
903 else
904 (*log_CSVec)[j] =
905 std::log(1. - std::exp((*log_CSVec)[j] - log_adjointCS) + 1e-50);
906 }
907 (*log_CSVec)[log_CSVec->size() - 1] =
908 (*log_CSVec)[log_CSVec->size() - 2] - std::log(1000.);
909 theCSMatForScatProjToProjBackwardScattering->AddData(
910 std::log(E1), log_adjointCS, log_ESecVec, log_CSVec, 0);
911 }
912 E1 = E2;
913 E2 *= dE;
914 }
915
916 std::vector<G4AdjointCSMatrix*> res;
917 res.push_back(theCSMatForProdToProjBackwardScattering);
918 res.push_back(theCSMatForScatProjToProjBackwardScattering);
919
920 return res;
921}
922
923///////////////////////////////////////////////////////
924std::vector<G4AdjointCSMatrix*>
925G4AdjointCSManager::BuildCrossSectionsModelAndMaterial(
926 G4VEmAdjointModel* aModel, G4Material* aMaterial, G4int nbin_pro_decade)
927{
928 G4AdjointCSMatrix* theCSMatForProdToProjBackwardScattering =
929 new G4AdjointCSMatrix(false);
930 G4AdjointCSMatrix* theCSMatForScatProjToProjBackwardScattering =
931 new G4AdjointCSMatrix(true);
932
933 G4double EkinMin = aModel->GetLowEnergyLimit();
934 G4double EkinMaxForScat = aModel->GetHighEnergyLimit() * 0.999;
935 G4double EkinMaxForProd = aModel->GetHighEnergyLimit() * 0.999;
936 if(aModel->GetSecondPartOfSameType())
937 EkinMaxForProd /= 2.;
938
939 // Product to projectile backward scattering
940 G4double dE = std::pow(10., 1. / nbin_pro_decade);
941 G4double E2 =
942 std::pow(10., double(int(std::log10(EkinMin) * nbin_pro_decade) + 1) /
943 nbin_pro_decade) / dE;
944 G4double E1 = EkinMin;
945 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
946 while(E1 < EkinMaxForProd)
947 {
948 E1 = std::max(EkinMin, E2);
949 E1 = std::min(EkinMaxForProd, E1);
950 std::vector<std::vector<G4double>*> aMat =
952 aMaterial, E1, nbin_pro_decade);
953 if(aMat.size() >= 2)
954 {
955 std::vector<G4double>* log_ESecVec = aMat[0];
956 std::vector<G4double>* log_CSVec = aMat[1];
957 G4double log_adjointCS = log_CSVec->back();
958
959 // normalise CSVec such that it becomes a probability vector
960 for(std::size_t j = 0; j < log_CSVec->size(); ++j)
961 {
962 if(j == 0)
963 (*log_CSVec)[j] = 0.;
964 else
965 (*log_CSVec)[j] =
966 std::log(1. - std::exp((*log_CSVec)[j] - log_adjointCS));
967 }
968 (*log_CSVec)[log_CSVec->size() - 1] =
969 (*log_CSVec)[log_CSVec->size() - 2] - std::log(1000.);
970 theCSMatForProdToProjBackwardScattering->AddData(
971 std::log(E1), log_adjointCS, log_ESecVec, log_CSVec, 0);
972 }
973
974 E1 = E2;
975 E2 *= dE;
976 }
977
978 // Scattered projectile to projectile backward scattering
979 E2 =
980 std::pow(10., G4double(G4int(std::log10(EkinMin) * nbin_pro_decade) + 1) /
981 nbin_pro_decade) /
982 dE;
983 E1 = EkinMin;
984 while(E1 < EkinMaxForScat)
985 {
986 E1 = std::max(EkinMin, E2);
987 E1 = std::min(EkinMaxForScat, E1);
988 std::vector<std::vector<G4double>*> aMat =
990 aMaterial, E1, nbin_pro_decade);
991 if(aMat.size() >= 2)
992 {
993 std::vector<G4double>* log_ESecVec = aMat[0];
994 std::vector<G4double>* log_CSVec = aMat[1];
995 G4double log_adjointCS = log_CSVec->back();
996
997 for(std::size_t j = 0; j < log_CSVec->size(); ++j)
998 {
999 if(j == 0)
1000 (*log_CSVec)[j] = 0.;
1001 else
1002 (*log_CSVec)[j] =
1003 std::log(1. - std::exp((*log_CSVec)[j] - log_adjointCS));
1004 }
1005 (*log_CSVec)[log_CSVec->size() - 1] =
1006 (*log_CSVec)[log_CSVec->size() - 2] - std::log(1000.);
1007
1008 theCSMatForScatProjToProjBackwardScattering->AddData(
1009 std::log(E1), log_adjointCS, log_ESecVec, log_CSVec, 0);
1010 }
1011 E1 = E2;
1012 E2 *= dE;
1013 }
1014
1015 std::vector<G4AdjointCSMatrix*> res;
1016 res.push_back(theCSMatForProdToProjBackwardScattering);
1017 res.push_back(theCSMatForScatProjToProjBackwardScattering);
1018
1019 return res;
1020}
1021
1022///////////////////////////////////////////////////////
1024 G4ParticleDefinition* theFwdPartDef)
1025{
1026 if(theFwdPartDef->GetParticleName() == "e-")
1028 else if(theFwdPartDef->GetParticleName() == "gamma")
1030 else if(theFwdPartDef->GetParticleName() == "proton")
1032 else if(theFwdPartDef == fFwdIon)
1033 return fAdjIon;
1034 return nullptr;
1035}
1036
1037///////////////////////////////////////////////////////
1039 G4ParticleDefinition* theAdjPartDef)
1040{
1041 if(theAdjPartDef->GetParticleName() == "adj_e-")
1042 return G4Electron::Electron();
1043 else if(theAdjPartDef->GetParticleName() == "adj_gamma")
1044 return G4Gamma::Gamma();
1045 else if(theAdjPartDef->GetParticleName() == "adj_proton")
1046 return G4Proton::Proton();
1047 else if(theAdjPartDef == fAdjIon)
1048 return fFwdIon;
1049 return nullptr;
1050}
1051
1052///////////////////////////////////////////////////////
1053void G4AdjointCSManager::DefineCurrentMaterial(
1054 const G4MaterialCutsCouple* couple)
1055{
1056 if(couple != fCurrentCouple)
1057 {
1058 fCurrentCouple = const_cast<G4MaterialCutsCouple*>(couple);
1059 fCurrentMaterial = const_cast<G4Material*>(couple->GetMaterial());
1060 fCurrentMatIndex = couple->GetIndex();
1061 fLastCSCorrectionFactor = 1.;
1062 }
1063}
1064
1065///////////////////////////////////////////////////////
1066void G4AdjointCSManager::DefineCurrentParticle(
1067 const G4ParticleDefinition* aPartDef)
1068{
1069 static G4ParticleDefinition* currentParticleDef = nullptr;
1070
1071 if(aPartDef != currentParticleDef)
1072 {
1073 currentParticleDef = const_cast<G4ParticleDefinition*>(aPartDef);
1074 fMassRatio = 1.;
1075 if(aPartDef == fAdjIon)
1076 fMassRatio = proton_mass_c2 / aPartDef->GetPDGMass();
1077 fCurrentParticleIndex = 1000000;
1078 for(std::size_t i = 0; i < fAdjointParticlesInAction.size(); ++i)
1079 {
1080 if(aPartDef == fAdjointParticlesInAction[i])
1081 fCurrentParticleIndex = i;
1082 }
1083 }
1084}
1085
1086////////////////////////////////////////////////////////////////////////////////
1088 G4double aPrimEnergy, G4AdjointCSMatrix* anAdjointCSMatrix, G4double Tcut)
1089{
1090 std::vector<double>* theLogPrimEnergyVector =
1091 anAdjointCSMatrix->GetLogPrimEnergyVector();
1092 if(theLogPrimEnergyVector->empty())
1093 {
1094 G4cout << "No data are contained in the given AdjointCSMatrix!" << G4endl;
1095 return 0.;
1096 }
1097 G4double log_Tcut = std::log(Tcut);
1098 G4double log_E = std::log(aPrimEnergy);
1099
1100 if(aPrimEnergy <= Tcut || log_E > theLogPrimEnergyVector->back())
1101 return 0.;
1102
1104
1105 std::size_t ind =
1106 theInterpolator->FindPositionForLogVector(log_E, *theLogPrimEnergyVector);
1107 G4double aLogPrimEnergy1, aLogPrimEnergy2;
1108 G4double aLogCS1, aLogCS2;
1109 G4double log01, log02;
1110 std::vector<G4double>* aLogSecondEnergyVector1 = nullptr;
1111 std::vector<G4double>* aLogSecondEnergyVector2 = nullptr;
1112 std::vector<G4double>* aLogProbVector1 = nullptr;
1113 std::vector<G4double>* aLogProbVector2 = nullptr;
1114 std::vector<std::size_t>* aLogProbVectorIndex1 = nullptr;
1115 std::vector<std::size_t>* aLogProbVectorIndex2 = nullptr;
1116
1117 anAdjointCSMatrix->GetData((G4int)ind, aLogPrimEnergy1, aLogCS1, log01,
1118 aLogSecondEnergyVector1, aLogProbVector1,
1119 aLogProbVectorIndex1);
1120 anAdjointCSMatrix->GetData(G4int(ind + 1), aLogPrimEnergy2, aLogCS2, log02,
1121 aLogSecondEnergyVector2, aLogProbVector2,
1122 aLogProbVectorIndex2);
1123 if (! (aLogProbVector1 && aLogProbVector2 &&
1124 aLogSecondEnergyVector1 && aLogSecondEnergyVector2)){
1125 return 0.;
1126 }
1127
1128 if(anAdjointCSMatrix->IsScatProjToProj())
1129 { // case where the Tcut plays a role
1130 G4double log_minimum_prob1, log_minimum_prob2;
1131 log_minimum_prob1 = theInterpolator->InterpolateForLogVector(
1132 log_Tcut, *aLogSecondEnergyVector1, *aLogProbVector1);
1133 log_minimum_prob2 = theInterpolator->InterpolateForLogVector(
1134 log_Tcut, *aLogSecondEnergyVector2, *aLogProbVector2);
1135 aLogCS1 += log_minimum_prob1;
1136 aLogCS2 += log_minimum_prob2;
1137 }
1138
1139 G4double log_adjointCS = theInterpolator->LinearInterpolation(
1140 log_E, aLogPrimEnergy1, aLogPrimEnergy2, aLogCS1, aLogCS2);
1141 return std::exp(log_adjointCS);
1142}
std::vector< G4Element * > G4ElementTable
std::vector< G4Material * > G4MaterialTable
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
const G4double A[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
void RegisterAdjointParticle(G4ParticleDefinition *aPartDef)
G4ParticleDefinition * GetForwardParticleEquivalent(G4ParticleDefinition *theAdjPartDef)
void GetMaxAdjTotalCS(G4ParticleDefinition *aPartDef, const G4MaterialCutsCouple *aCouple, G4double &e_sigma_max, G4double &sigma_max)
G4double GetCrossSectionCorrection(G4ParticleDefinition *aPartDef, G4double PreStepEkin, const G4MaterialCutsCouple *aCouple, G4bool &fwd_is_used)
G4double GetTotalForwardCS(G4ParticleDefinition *aPartDef, G4double Ekin, const G4MaterialCutsCouple *aCouple)
G4double ComputeTotalAdjointCS(const G4MaterialCutsCouple *aMatCutCouple, G4ParticleDefinition *aPart, G4double PrimEnergy)
G4double ComputeAdjointCS(G4Material *aMaterial, G4VEmAdjointModel *aModel, G4double PrimEnergy, G4double Tcut, G4bool isScatProjToProj, std::vector< G4double > &AdjointCS_for_each_element)
G4ParticleDefinition * GetAdjointParticleEquivalent(G4ParticleDefinition *theFwdPartDef)
G4Element * SampleElementFromCSMatrices(G4Material *aMaterial, G4VEmAdjointModel *aModel, G4double PrimEnergy, G4double Tcut, G4bool isScatProjToProj)
G4double GetContinuousWeightCorrection(G4ParticleDefinition *aPartDef, G4double PreStepEkin, G4double AfterStepEkin, const G4MaterialCutsCouple *aCouple, G4double step_length)
G4double GetPostStepWeightCorrection()
void GetEminForTotalCS(G4ParticleDefinition *aPartDef, const G4MaterialCutsCouple *aCouple, G4double &emin_adj, G4double &emin_fwd)
static G4AdjointCSManager * GetAdjointCSManager()
G4double GetTotalAdjointCS(G4ParticleDefinition *aPartDef, G4double Ekin, const G4MaterialCutsCouple *aCouple)
G4double GetAdjointSigma(G4double Ekin_nuc, std::size_t index_model, G4bool is_scat_proj_to_proj, const G4MaterialCutsCouple *aCouple)
void RegisterEmProcess(G4VEmProcess *aProcess, G4ParticleDefinition *aPartDef)
std::size_t RegisterEmAdjointModel(G4VEmAdjointModel *)
void RegisterEnergyLossProcess(G4VEnergyLossProcess *aProcess, G4ParticleDefinition *aPartDef)
void GetMaxFwdTotalCS(G4ParticleDefinition *aPartDef, const G4MaterialCutsCouple *aCouple, G4double &e_sigma_max, G4double &sigma_max)
G4bool GetData(unsigned int i, G4double &aPrimEnergy, G4double &aCS, G4double &log0, std::vector< double > *&aLogSecondEnergyVector, std::vector< double > *&aLogProbVector, std::vector< size_t > *&aLogProbVectorIndex)
std::vector< double > * GetLogPrimEnergyVector()
void AddData(G4double aPrimEnergy, G4double aCS, std::vector< double > *aLogSecondEnergyVector, std::vector< double > *aLogProbVector, size_t n_pro_decade=0)
static G4AdjointElectron * AdjointElectron()
static G4AdjointGamma * AdjointGamma()
G4double LinearInterpolation(G4double &x, G4double &x1, G4double &x2, G4double &y1, G4double &y2)
static G4AdjointInterpolator * GetInstance()
size_t FindPositionForLogVector(G4double &x, std::vector< G4double > &x_vec)
G4double InterpolateForLogVector(G4double &x, std::vector< G4double > &x_vec, std::vector< G4double > &y_vec)
static G4AdjointProton * AdjointProton()
static G4Electron * Electron()
Definition: G4Electron.cc:93
static G4ElementTable * GetElementTable()
Definition: G4Element.cc:403
G4double GetZ() const
Definition: G4Element.hh:131
size_t GetIndex() const
Definition: G4Element.hh:182
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
const G4Material * GetMaterial() const
const G4Element * GetElement(G4int iel) const
Definition: G4Material.hh:197
size_t GetNumberOfElements() const
Definition: G4Material.hh:181
const G4double * GetVecNbOfAtomsPerVolume() const
Definition: G4Material.hh:201
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:677
size_t GetIndex() const
Definition: G4Material.hh:255
const G4String & GetParticleName() const
void PutValue(const std::size_t index, const G4double value)
G4double Energy(const std::size_t index) const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
static G4Proton * Proton()
Definition: G4Proton.cc:92
virtual G4double GetSecondAdjEnergyMaxForProdToProj(G4double primAdjEnergy)
G4bool GetSecondPartOfSameType()
G4bool GetUseOnlyOneMatrixForAllElements()
virtual G4double GetSecondAdjEnergyMinForScatProjToProj(G4double primAdjEnergy, G4double tcut=0.)
virtual G4double GetSecondAdjEnergyMaxForScatProjToProj(G4double primAdjEnergy)
std::vector< std::vector< double > * > ComputeAdjointCrossSectionVectorPerAtomForSecond(G4double kinEnergyProd, G4double Z, G4double A=0., G4int nbin_pro_decade=10)
G4ParticleDefinition * GetAdjointEquivalentOfDirectPrimaryParticleDefinition()
G4double GetLowEnergyLimit()
G4ParticleDefinition * GetAdjointEquivalentOfDirectSecondaryParticleDefinition()
virtual G4double AdjointCrossSection(const G4MaterialCutsCouple *aCouple, G4double primEnergy, G4bool isScatProjToProj)
std::vector< std::vector< double > * > ComputeAdjointCrossSectionVectorPerVolumeForSecond(G4Material *aMaterial, G4double kinEnergyProd, G4int nbin_pro_decade=10)
virtual G4double GetSecondAdjEnergyMinForProdToProj(G4double primAdjEnergy)
std::vector< std::vector< double > * > ComputeAdjointCrossSectionVectorPerVolumeForScatProj(G4Material *aMaterial, G4double kinEnergyProd, G4int nbin_pro_decade=10)
std::vector< std::vector< double > * > ComputeAdjointCrossSectionVectorPerAtomForScatProj(G4double kinEnergyProd, G4double Z, G4double A=0., G4int nbin_pro_decade=10)
G4double GetHighEnergyLimit()
virtual G4double GetChargeSquareRatio(const G4ParticleDefinition *, const G4Material *, G4double kineticEnergy)
Definition: G4VEmModel.cc:325
int G4lrint(double ad)
Definition: templates.hh:134
#define G4ThreadLocal
Definition: tls.hh:77