Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4NeutronGeneralProcess.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//
29// GEANT4 Class file
30//
31//
32// File name: G4NeutronGeneralProcess
33//
34// Author: Vladimir Ivanchenko
35//
36// Creation date: 08.08.2022
37//
38// Modifications:
39//
40// Class Description:
41//
42
43// -------------------------------------------------------------------
44//
45//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
46//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
47
50#include "G4SystemOfUnits.hh"
51#include "G4HadronicProcess.hh"
54#include "G4Step.hh"
55#include "G4Track.hh"
57#include "G4PhysicsTable.hh"
58#include "G4PhysicsLogVector.hh"
59#include "G4VParticleChange.hh"
62#include "G4Material.hh"
63#include "G4MaterialTable.hh"
64#include "G4Element.hh"
65#include "G4Neutron.hh"
67#include "G4NeutronElasticXS.hh"
68#include "G4NeutronCaptureXS.hh"
69#include "G4Threading.hh"
70
71#include "G4Log.hh"
72#include <iostream>
73
74//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
75
76G4HadDataHandler* G4NeutronGeneralProcess::theHandler = nullptr;
77
78G4String G4NeutronGeneralProcess::nameT[nTables] = {"0","1","2","3","4"};
79
81: G4HadronicProcess(pname),
82 fMinEnergy(1*CLHEP::keV),
83 fMiddleEnergy(20*CLHEP::MeV),
84 fMaxEnergy(100*CLHEP::TeV),
85 fTimeLimit(10*CLHEP::microsecond)
86{
89
90 fNeutron = G4Neutron::Neutron();
91
93 isMaster = false;
94 }
95}
96
97//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
98
100{
101 if(isMaster) {
102 delete theHandler;
103 theHandler = nullptr;
104 }
105}
106
107//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
108
113
114//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
115
117{
118 fInelasticP = ptr;
119 fXSSInelastic = ptr->GetCrossSectionDataStore();
120 fInelasticXS = InitialisationXS(ptr);
121 if(nullptr == fInelasticXS) {
122 fInelasticXS = new G4NeutronInelasticXS();
123 ptr->AddDataSet(fInelasticXS);
124 }
125}
126
127//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
128
130{
131 fElasticP = ptr;
132 fXSSElastic = ptr->GetCrossSectionDataStore();
133 fElasticXS = InitialisationXS(ptr);
134 if(nullptr == fElasticXS) {
135 fElasticXS = new G4NeutronElasticXS();
136 ptr->AddDataSet(fElasticXS);
137 }
138}
139
140//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
141
143{
144 fCaptureP = ptr;
145 fXSSCapture = ptr->GetCrossSectionDataStore();
146 fCaptureXS = InitialisationXS(ptr);
147 if(nullptr == fCaptureXS) {
148 fCaptureXS = new G4NeutronCaptureXS();
149 ptr->AddDataSet(fCaptureXS);
150 }
151}
152
153//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
154
156G4NeutronGeneralProcess::InitialisationXS(G4HadronicProcess* proc)
157{
158 G4VCrossSectionDataSet* ptr = nullptr;
159 auto xsv = proc->GetCrossSectionDataStore()->GetDataSetList();
160 if(!xsv.empty()) {
161 ptr = xsv[0];
162 }
163 return ptr;
164}
165
166//....Ooooo0ooooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
167
169{
170 G4VCrossSectionDataSet* xs = nullptr;
172 if(type == fHadronElastic) { xs = fElasticXS; }
173 else if(type == fHadronInelastic) { xs = fInelasticXS; }
174 else if(type == fCapture) { xs = fCaptureXS; }
175 return xs;
176}
177
178//....Ooooo0ooooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
179
181{
182 G4HadronicProcess* ptr = nullptr;
184 if(type == fHadronElastic) { ptr = fElasticP; }
185 else if(type == fHadronInelastic) { ptr = fInelasticP; }
186 else if(type == fCapture) { ptr = fCaptureP; }
187 return ptr;
188}
189
190//....Ooooo0ooooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
191
193{
194 if(1 < verboseLevel) {
195 G4cout << "G4NeutronGeneralProcess::PreparePhysicsTable() for "
196 << GetProcessName()
197 << " and particle " << part.GetParticleName()
198 << " isMaster: " << isMaster << G4endl;
199 }
200 G4bool noEl = (nullptr == fElasticP);
201 G4bool noInel = (nullptr == fInelasticP);
202 G4bool noCap = (nullptr == fCaptureP);
203 if(noEl || noInel || noCap) {
205 ed << "Incomplete configuration of the neutron general process." << G4endl;
206 if(noEl) { ed << "Neutron elastic process is not defined" << G4endl; }
207 if(noInel) { ed << "Neutron inelastic process is not defined" << G4endl; }
208 if(noCap) { ed << "Neutron capture process is not defined" << G4endl; }
209 G4Exception ("G4NeutronGeneralProcess::PreparePhysicsTable(..)", "had001",
210 FatalException, ed, "");
211 return;
212 }
213
215
217 fMaxEnergy = std::max(100*MeV, param->GetMaxEnergy());
218 if(param->ApplyFactorXS()) {
219 fXSFactorEl = param->XSFactorNucleonElastic();
220 fXSFactorInel = param->XSFactorNucleonInelastic();
221 }
222
223 fElasticP->PreparePhysicsTable(part);
224 fInelasticP->PreparePhysicsTable(part);
225 fCaptureP->PreparePhysicsTable(part);
226
227 std::size_t nmat = G4Material::GetNumberOfMaterials();
229
230 std::size_t nmax = 0;
231 for(std::size_t i=0; i<nmat; ++i) {
232 std::size_t nelm = (*matTable)[i]->GetNumberOfElements();
233 nmax = std::max(nmax, nelm);
234 }
235 fXsec.resize(nmax);
236
237 if(isMaster) {
238 if(nullptr == theHandler) {
239 theHandler = new G4HadDataHandler(nTables);
240 }
241
242 fMaxEnergy = std::max(fMaxEnergy, param->GetMaxEnergy());
243 nLowE *= G4lrint(std::log10(fMiddleEnergy/fMinEnergy));
244 nHighE *= G4lrint(std::log10(fMaxEnergy/fMiddleEnergy));
245
246 G4PhysicsVector* vec = nullptr;
247 G4PhysicsLogVector aVector(fMinEnergy, fMiddleEnergy, nLowE, false);
248 G4PhysicsLogVector bVector(fMiddleEnergy, fMaxEnergy, nHighE, false);
249
250 for(std::size_t i=0; i<nTables; ++i) {
251 G4PhysicsTable* table = new G4PhysicsTable();
252 theHandler->UpdateTable(table, i);
253 table->resize(nmat);
254 for(std::size_t j=0; j<nmat; ++j) {
255 vec = (*table)[j];
256 if (nullptr == vec) {
257 if(i <= 2) {
258 vec = new G4PhysicsVector(aVector);
259 } else {
260 vec = new G4PhysicsVector(bVector);
261 }
263 }
264 }
265 }
266 }
267}
268
269//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
270
272{
273 if(1 < verboseLevel) {
274 G4cout << "### G4NeutronGeneralProcess::BuildPhysicsTable() for "
275 << GetProcessName()
276 << " and particle " << part.GetParticleName()
277 << G4endl;
278 }
279 fElasticP->BuildPhysicsTable(part);
280 fInelasticP->BuildPhysicsTable(part);
281 fCaptureP->BuildPhysicsTable(part);
282
283 if(isMaster) {
284 std::size_t nmat = G4Material::GetNumberOfMaterials();
286
287 auto tables = theHandler->GetTables();
288
289 G4double sigEl(0.), sigInel(0.), sigCap(0.), val(0.), sum(0.);
290
291 for(std::size_t i=0; i<nmat; ++i) {
292 const G4Material* mat = (*matTable)[i];
293
294 // energy interval 0
295 std::size_t nn = (*(tables[0]))[i]->GetVectorLength();
296 if(1 < verboseLevel) {
297 G4cout << "======= Zone 0 ======= N= " << nn
298 << " for " << mat->GetName() << G4endl;
299 }
300 for(std::size_t j=0; j<nn; ++j) {
301 G4double e = (*(tables[0]))[i]->Energy(j);
302 G4double loge = G4Log(e);
303 sigEl = fXSFactorEl*ComputeCrossSection(fElasticXS, mat, e, loge);
304 sigInel = fXSFactorInel*ComputeCrossSection(fInelasticXS, mat, e, loge);
305 sigCap = ComputeCrossSection(fCaptureXS, mat, e, loge);
306 sum = sigEl + sigInel + sigCap;
307 if(1 < verboseLevel) {
308 G4cout << j << ". E= " << e << " xs=" << sum << " sigEl=" << sigEl
309 << " sigInel=" << sigInel << " sigCap=" << sigCap << G4endl;
310 }
311 (*(tables[0]))[i]->PutValue(j, sum);
312 val = sigEl/sum;
313 (*(tables[1]))[i]->PutValue(j, val);
314 val = (sigEl + sigInel)/sum;
315 (*(tables[2]))[i]->PutValue(j, val);
316 }
317
318 // energy interval 1
319 nn = (*(tables[3]))[0]->GetVectorLength();
320 if(1 < verboseLevel) {
321 G4cout << "======= Zone 1 ======= N= " << nn << G4endl;
322 }
323 for(std::size_t j=0; j<nn; ++j) {
324 G4double e = (*(tables[3]))[i]->Energy(j);
325 G4double loge = G4Log(e);
326 sigEl = fXSFactorEl*ComputeCrossSection(fElasticXS, mat, e, loge);
327 sigInel = fXSFactorInel*ComputeCrossSection(fInelasticXS, mat, e, loge);
328 sum = sigEl + sigInel;
329 if(1 < verboseLevel) {
330 G4cout << j << ". E= " << e << " xs=" << sum << " sigEl=" << sigEl
331 << " sigInel=" << sigInel << " factInel=" << fXSFactorInel
332 << G4endl;
333 }
334 (*(tables[3]))[i]->PutValue(j, sum);
335 val = sigInel/sum;
336 (*(tables[4]))[i]->PutValue(j, val);
337 }
338 }
339 }
340 if(1 < verboseLevel) {
341 G4cout << "### G4VEmProcess::BuildPhysicsTable() done for "
342 << GetProcessName()
343 << " and particle " << part.GetParticleName()
344 << G4endl;
345 }
346}
347
348//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
349
351G4NeutronGeneralProcess::ComputeCrossSection(G4VCrossSectionDataSet* xs,
352 const G4Material* mat,
353 G4double e, G4double loge)
354{
355 const G4double* natom = mat->GetVecNbOfAtomsPerVolume();
356 G4int nelm = (G4int)mat->GetNumberOfElements();
357 G4double sig = 0.0;
358 for(G4int i=0; i<nelm; ++i) {
359 sig += natom[i]*xs->ComputeCrossSectionPerElement(e, loge, fNeutron,
360 mat->GetElement(i), mat);
361 }
362 return sig;
363}
364
365//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
366
368{
370 fCurrMat = nullptr;
371}
372
373//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
374
376 const G4Track& track,
377 G4double previousStepSize,
379{
381
382 // time limit
383 if(track.GetGlobalTime() >= fTimeLimit) {
384 fLambda = 0.0;
385 return 0.0;
386 }
387
388 // recompute total cross section if needed
389 CurrentCrossSection(track);
390
392
393 // beggining of tracking (or just after DoIt of this process)
396
397 } else {
398
400 previousStepSize/currentInteractionLength;
403 }
404
406 /*
407 G4cout << "PostStepGetPhysicalInteractionLength: e= " << energy
408 << " idxe= " << idxEnergy << " xs= " << fLambda
409 << " x= " << x << G4endl;
410 */
411 return x;
412}
413
414//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
415
417 const G4Step& step)
418{
419 fSelectedProc = this;
420 // time limit
421 if(0.0 == fLambda) {
424 return theTotalResult;
425 }
426 // In all cases clear number of interaction lengths
429 /*
430 G4cout << "PostStep: preStepLambda= " << fLambda << " idxE= " << idxEnergy
431 << " matIndex=" << matIndex << G4endl;
432 */
433 if (0 == idxEnergy) {
434 if(q <= GetProbability(1)) {
435 SelectedProcess(step, fElasticP, fXSSElastic);
436 } else if(q <= GetProbability(2)) {
437 SelectedProcess(step, fInelasticP, fXSSInelastic);
438 } else {
439 SelectedProcess(step, fCaptureP, fXSSCapture);
440 }
441 } else {
442 if(q <= GetProbability(4)) {
443 SelectedProcess(step, fInelasticP, fXSSInelastic);
444 } else {
445 SelectedProcess(step, fElasticP, fXSSElastic);
446 }
447 }
448 // total cross section is needed for selection of an element
449 if(fCurrMat->GetNumberOfElements() > 1) {
450 fCurrentXSS->ComputeCrossSection(track.GetDynamicParticle(), fCurrMat);
451 }
452 /*
453 G4cout << "## neutron E(MeV)=" << fCurrE << " inside " << fCurrMat->GetName()
454 << fSelectedProc->GetProcessName()
455 << " time(ns)=" << track.GetGlobalTime()/ns << G4endl;
456 */
457 // sample secondaries
458 return fSelectedProc->PostStepDoIt(track, step);
459}
460
461//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
462
463G4bool
465 const G4String& directory,
466 G4bool ascii)
467{
468 G4bool yes = true;
469 if(!isMaster) { return yes; }
470 for(std::size_t i=0; i<nTables; ++i) {
471 G4String nam = (0==i || 3==i)
472 ? "LambdaNeutronGeneral" + nameT[i] : "ProbNeutronGeneral" + nameT[i];
473 G4String fnam = GetPhysicsTableFileName(part, directory, nam, ascii);
474 auto table = theHandler->Table(i);
475 if(nullptr == table || !table->StorePhysicsTable(fnam, ascii)) {
476 yes = false;
477 }
478 }
479 return yes;
480}
481
482//....Ooooo0ooooo ........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
483
485 G4double,
487{
489 // recompute total cross section if needed
490 CurrentCrossSection(track);
492}
493
494//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
495
497{
498 fElasticP->ProcessDescription(out);
499 fInelasticP->ProcessDescription(out);
500 fCaptureP->ProcessDescription(out);
501}
502
503//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
504
506{
507 return (nullptr != fSelectedProc) ? fSelectedProc->GetProcessName()
509}
510
511//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
512
514{
515 return (nullptr != fSelectedProc) ? fSelectedProc->GetProcessSubType()
517}
518
519//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
520
522{
523 return fSelectedProc;
524}
525
526//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double condition(const G4ErrorSymMatrix &m)
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4ForceCondition
@ NotForced
G4HadronicProcessType
@ fNeutronGeneral
@ fHadronInelastic
G4double G4Log(G4double x)
Definition G4Log.hh:227
std::vector< G4Material * > G4MaterialTable
@ fStopAndKill
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
#define G4UniformRand()
Definition Randomize.hh:52
const std::vector< G4VCrossSectionDataSet * > & GetDataSetList() const
G4double ComputeCrossSection(const G4DynamicParticle *, const G4Material *)
G4PhysicsTable * Table(std::size_t idx) const
void UpdateTable(G4PhysicsTable *, std::size_t idx)
const std::vector< G4PhysicsTable * > & GetTables() const
static G4HadronicParameters * Instance()
G4double XSFactorNucleonElastic() const
G4double XSFactorNucleonInelastic() const
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
void ProcessDescription(std::ostream &outFile) const override
G4ParticleChange * theTotalResult
void AddDataSet(G4VCrossSectionDataSet *aDataSet)
void PreparePhysicsTable(const G4ParticleDefinition &) override
void BuildPhysicsTable(const G4ParticleDefinition &) override
G4CrossSectionDataStore * GetCrossSectionDataStore()
const G4Element * GetElement(G4int iel) const
static std::size_t GetNumberOfMaterials()
const G4double * GetVecNbOfAtomsPerVolume() const
static G4MaterialTable * GetMaterialTable()
std::size_t GetNumberOfElements() const
const G4String & GetName() const
void SetCaptureProcess(G4HadronicProcess *)
G4NeutronGeneralProcess(const G4String &pname="NeutronGeneralProc")
void StartTracking(G4Track *) override
void ProcessDescription(std::ostream &outFile) const override
G4VCrossSectionDataSet * GetXSection(G4int type)
void PreparePhysicsTable(const G4ParticleDefinition &) override
G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
void SelectedProcess(const G4Step &step, G4HadronicProcess *ptr, G4CrossSectionDataStore *)
G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &) override
void SetElasticProcess(G4HadronicProcess *)
G4double GetProbability(size_t idxt)
G4bool StorePhysicsTable(const G4ParticleDefinition *part, const G4String &directory, G4bool ascii) override
void BuildPhysicsTable(const G4ParticleDefinition &) override
const G4VProcess * GetCreatorProcess() const override
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
const G4String & GetSubProcessName() const
G4HadronicProcess * GetHadronicProcess(G4int type)
void SetInelasticProcess(G4HadronicProcess *)
G4bool IsApplicable(const G4ParticleDefinition &) override
static G4Neutron * Neutron()
Definition G4Neutron.cc:101
void Initialize(const G4Track &) override
const G4String & GetParticleName() const
static void SetPhysicsVector(G4PhysicsTable *physTable, std::size_t idx, G4PhysicsVector *vec)
void resize(std::size_t, G4PhysicsVector *vec=nullptr)
G4double GetGlobalTime() const
const G4DynamicParticle * GetDynamicParticle() const
virtual G4double ComputeCrossSectionPerElement(G4double kinEnergy, G4double loge, const G4ParticleDefinition *, const G4Element *, const G4Material *mat=nullptr)
void ProposeTrackStatus(G4TrackStatus status)
G4double currentInteractionLength
G4double theInitialNumberOfInteractionLength
void SetVerboseLevel(G4int value)
G4int verboseLevel
G4double theNumberOfInteractionLengthLeft
void SetProcessSubType(G4int)
G4int GetProcessSubType() const
const G4String & GetPhysicsTableFileName(const G4ParticleDefinition *, const G4String &directory, const G4String &tableName, G4bool ascii=false)
const G4String & GetProcessName() const
G4bool IsWorkerThread()
int G4lrint(double ad)
Definition templates.hh:134