Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4NeutronHPCaptureData.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// neutron_hp -- source file
27// J.P. Wellisch, Nov-1996
28// A prototype of the low energy neutron transport model.
29//
30// 070523 add neglecting doppler broadening on the fly. T. Koi
31// 070613 fix memory leaking by T. Koi
32// 071002 enable cross section dump by T. Koi
33// 080428 change checking point of "neglecting doppler broadening" flag
34// from GetCrossSection to BuildPhysicsTable by T. Koi
35// 081024 G4NucleiPropertiesTable:: to G4NucleiProperties::
36//
37// P. Arce, June-2014 Conversion neutron_hp to particle_hp
38// V. Ivanchenko July-2023 converted back
39//
41
42#include "G4ElementTable.hh"
44#include "G4Neutron.hh"
45#include "G4NucleiProperties.hh"
46#include "G4ParticleHPData.hh"
48#include "G4Element.hh"
49#include "G4Material.hh"
51#include "G4PhysicsTable.hh"
53#include "G4Pow.hh"
54#include "G4SystemOfUnits.hh"
55#include "G4AutoLock.hh"
56
57G4bool G4NeutronHPCaptureData::fLock = true;
58G4PhysicsTable* G4NeutronHPCaptureData::theCrossSections = nullptr;
59
60namespace
61{
62 G4Mutex theHPCaptureData = G4MUTEX_INITIALIZER;
63}
64
66 : G4VCrossSectionDataSet("NeutronHPCaptureXS")
67{
68 emax = 20.*CLHEP::MeV;
70}
71
73{
74 if (isFirst) {
75 if (nullptr != theCrossSections)
76 theCrossSections->clearAndDestroy();
77 delete theCrossSections;
78 theCrossSections = nullptr;
79 }
80}
81
83 G4int, G4int,
84 const G4Element*,
85 const G4Material*)
86{
87 return true;
88}
89
91 G4int /*Z*/, G4int /*A*/,
92 const G4Isotope* /*iso*/,
93 const G4Element* element,
94 const G4Material* material)
95{
96 if (dp->GetKineticEnergy() == ke_cache && element == element_cache &&
97 material == material_cache)
98 return xs_cache;
99
100 ke_cache = dp->GetKineticEnergy();
101 element_cache = element;
102 material_cache = material;
103 G4double xs = GetCrossSection(dp, element, material->GetTemperature());
104 xs_cache = xs;
105 return xs;
106}
107
109{
110 // the choice of the first instance
111 if (fLock) {
112 G4AutoLock l(&theHPCaptureData);
113 if (fLock) {
114 isFirst = true;
115 fLock = false;
116 }
117 l.unlock();
118 }
119 if (!isFirst) { return; }
120 if (p.GetParticleName() != "neutron") {
122 ed << p.GetParticleName() << " is a wrong particle type -"
123 << " only neutron is allowed";
124 G4Exception("G4NeutronHPCaptureData::BuildPhysicsTable(..)","had012",
125 FatalException, ed, "");
126 return;
127 }
128
129 // initialisation for the first instance, others are locked
130 G4AutoLock l(&theHPCaptureData);
131 if (theCrossSections != nullptr) {
132 theCrossSections->clearAndDestroy();
133 delete theCrossSections;
134 }
135 std::size_t numberOfElements = G4Element::GetNumberOfElements();
136 theCrossSections = new G4PhysicsTable(numberOfElements);
137
138 // make a PhysicsVector for each element
139 auto theElementTable = G4Element::GetElementTable();
140 for (std::size_t i = 0; i < numberOfElements; ++i) {
141 auto elm = (*theElementTable)[i];
142#ifdef G4VERBOSE
143 if (fManager->GetDEBUG()) {
144 G4cout << "ElementIndex " << elm->GetIndex() << " "
145 << elm->GetName() << G4endl;
146 }
147#endif
148 G4PhysicsVector* physVec =
150 theCrossSections->push_back(physVec);
151 }
152 fManager->RegisterCaptureCrossSections(theCrossSections);
153 l.unlock();
154}
155
157{
158#ifdef G4VERBOSE
159 if (fManager->GetVerboseLevel() == 0) return;
160
161 //
162 // Dump element based cross section
163 // range 10e-5 eV to 20 MeV
164 // 10 point per decade
165 // in barn
166 //
167
168 G4cout << G4endl;
169 G4cout << G4endl;
170 G4cout << "Capture Cross Section of Neutron HP" << G4endl;
171 G4cout << "(Pointwise cross-section at 0 Kelvin.)" << G4endl;
172 G4cout << G4endl;
173 G4cout << "Name of Element" << G4endl;
174 G4cout << "Energy[eV] XS[barn]" << G4endl;
175 G4cout << G4endl;
176
177 std::size_t numberOfElements = G4Element::GetNumberOfElements();
178 auto theElementTable = G4Element::GetElementTable();
179
180 for (std::size_t i = 0; i < numberOfElements; ++i) {
181 G4cout << (*theElementTable)[i]->GetName() << G4endl;
182 G4cout << *((*theCrossSections)(i)) << G4endl;
183 }
184#endif
185}
186
188 const G4Element* anE,
189 G4double aT)
190{
191 G4double result = 0;
192 auto idx = (G4int)anE->GetIndex();
193
194 // prepare neutron
195 G4double eKinetic = aP->GetKineticEnergy();
196 if (eKinetic >= emax) { return 0.0; }
197
198 // NEGLECT_DOPPLER
199 if (fManager->GetNeglectDoppler()) {
200 return (*((*theCrossSections)(idx))).Value(eKinetic);
201 }
202
203 G4ReactionProduct theNeutron(aP->GetDefinition());
204 theNeutron.SetMomentum(aP->GetMomentum());
205 theNeutron.SetKineticEnergy(eKinetic);
206
207 // prepare thermal nucleus
208 G4Nucleus aNuc;
209 G4int theA = anE->GetN();
210 G4int theZ = anE->GetZasInt();
211 G4double eleMass = G4NucleiProperties::GetNuclearMass(theA, theZ)
212 / CLHEP::neutron_mass_c2;
213
214 G4ReactionProduct boosted;
215 G4double aXsection;
216
217 // MC integration loop
218 G4int counter = 0;
219 G4double buffer = 0;
220 G4int size = G4int(std::max(10., aT / 60 * kelvin));
221 G4ThreeVector neutronVelocity =
222 1. / G4Neutron::Neutron()->GetPDGMass() * theNeutron.GetMomentum();
223 G4double neutronVMag = neutronVelocity.mag();
224
225 while (counter == 0 ||
226 std::abs(buffer - result / std::max(1, counter)) > 0.03 * buffer)
227 // Loop checking, 11.05.2015, T. Koi
228 {
229 if (counter != 0) buffer = result / counter;
230 while (counter < size) // Loop checking, 11.05.2015, T. Koi
231 {
232 ++counter;
233 G4ReactionProduct aThermalNuc = aNuc.GetThermalNucleus(eleMass, aT);
234 boosted.Lorentz(theNeutron, aThermalNuc);
235 G4double theEkin = boosted.GetKineticEnergy();
236 aXsection = (*((*theCrossSections)(idx))).Value(theEkin);
237 // velocity correction, or luminosity factor...
238 G4ThreeVector targetVelocity = 1. / aThermalNuc.GetMass() * aThermalNuc.GetMomentum();
239 aXsection *= (targetVelocity - neutronVelocity).mag() / neutronVMag;
240 result += aXsection;
241 }
242 size += size;
243 }
244 result /= counter;
245 /*
246 // Checking impact of G4NEUTRONHP_NEGLECT_DOPPLER
247 G4cout << " result " << result << " "
248 << (*((*theCrossSections)(index))).Value(eKinetic) << " "
249 << (*((*theCrossSections)(index))).Value(eKinetic) /result << G4endl;
250 */
251 return result;
252}
253
255{
256 outF << "High Precision cross data based on Evaluated Nuclear Data Files"
257 << " (ENDF) for radiative capture reaction of neutrons below 20 MeV";
258}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#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
double mag() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
G4ThreeVector GetMomentum() const
static G4ElementTable * GetElementTable()
Definition G4Element.cc:389
static size_t GetNumberOfElements()
Definition G4Element.cc:393
size_t GetIndex() const
Definition G4Element.hh:159
G4int GetZasInt() const
Definition G4Element.hh:120
G4double GetN() const
Definition G4Element.hh:123
G4double GetTemperature() const
G4bool IsIsoApplicable(const G4DynamicParticle *, G4int Z, G4int A, const G4Element *, const G4Material *) override
G4double GetCrossSection(const G4DynamicParticle *, const G4Element *, G4double aT)
void DumpPhysicsTable(const G4ParticleDefinition &) override
G4double GetIsoCrossSection(const G4DynamicParticle *, G4int Z, G4int A, const G4Isotope *, const G4Element *, const G4Material *) override
void BuildPhysicsTable(const G4ParticleDefinition &) override
void CrossSectionDescription(std::ostream &) const override
static G4Neutron * Neutron()
Definition G4Neutron.cc:101
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4ReactionProduct GetThermalNucleus(G4double aMass, G4double temp=-1) const
Definition G4Nucleus.cc:248
const G4String & GetParticleName() const
G4PhysicsVector * MakePhysicsVector(const G4Element *thE, G4ParticleHPFissionData *theP)
static G4ParticleHPData * Instance(G4ParticleDefinition *projectile)
void RegisterCaptureCrossSections(G4PhysicsTable *val)
static G4ParticleHPManager * GetInstance()
G4bool GetNeglectDoppler() const
void push_back(G4PhysicsVector *)
void clearAndDestroy()
void SetMomentum(const G4double x, const G4double y, const G4double z)
G4double GetKineticEnergy() const
G4ThreeVector GetMomentum() const
void Lorentz(const G4ReactionProduct &p1, const G4ReactionProduct &p2)
void SetKineticEnergy(const G4double en)
G4double GetMass() const