Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4FissionProductYieldDist.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 * File: G4FissionProductYieldDist.cc
28 * Author: B. Wendt ([email protected])
29 *
30 * Created on May 11, 2011, 12:04 PM
31 */
32
33/* * * * * * * * * * * * * * * * References * * * * * * * * * * * * * * * *
34 * *
35 * 1. "Systematics of fission fragment total kinetic energy release", *
36 * V. E. Viola, K. Kwiatkowski, and M. Walker, Physical Review C, 31.4, *
37 * April 1985 *
38 * 2. "Reactor Handbook", United States Atomic Energy Commission, *
39 * III.A:Physics, 1962 *
40 * 3. "Properties of the Alpha Particles Emitted in the Spontaneous Fission *
41 * of Cf252", Z. Fraenkel and S. G. Thompson, Physical Review Letters, *
42 * 13.14, October 1964 *
43 * *
44 * * * * * * * * * * * * * * * * References * * * * * * * * * * * * * * * */
45
46// #include <ios>
47// #include <iostream>
48
49#include "G4Alpha.hh"
50#include "G4Gamma.hh"
51#include "G4Ions.hh"
52#include "G4Neutron.hh"
53// #include "G4NeutronHPNames.hh"
54#include "G4ArrayOps.hh"
55#include "G4DynamicParticle.hh"
57#include "G4ENDFTapeRead.hh"
59#include "G4Exp.hh"
61#include "G4FFGDefaultValues.hh"
62#include "G4FFGEnumerations.hh"
63#include "G4FPYNubarValues.hh"
64#include "G4FPYSamplingOps.hh"
67#include "G4HadFinalState.hh"
68#include "G4NucleiProperties.hh"
69#include "G4ParticleTable.hh"
70#include "G4Pow.hh"
71#include "G4ReactionProduct.hh"
72#include "G4SystemOfUnits.hh"
73#include "G4ThreeVector.hh"
74#include "G4UImanager.hh"
75#include "Randomize.hh"
76#include "globals.hh"
77
78using CLHEP::pi;
79
80#ifdef G4MULTITHREADED
81# include "G4AutoLock.hh"
82G4Mutex G4FissionProductYieldDist::fissprodMutex = G4MUTEX_INITIALIZER;
83#endif
84
86 G4FFGEnumerations::MetaState WhichMetaState,
88 G4FFGEnumerations::YieldType WhichYieldType,
89 std::istringstream& dataStream)
90 : Isotope_(WhichIsotope),
91 MetaState_(WhichMetaState),
92 Cause_(WhichCause),
93 YieldType_(WhichYieldType),
94 Verbosity_(G4FFGDefaultValues::Verbosity)
95{
97
98 try {
99 // Initialize the class
100 Initialize(dataStream);
101 }
102 catch (std::exception& e) {
104 throw e;
105 }
106
108}
109
111 G4FFGEnumerations::MetaState WhichMetaState,
113 G4FFGEnumerations::YieldType WhichYieldType,
114 G4int Verbosity,
115 std::istringstream& dataStream)
116 : Isotope_(WhichIsotope),
117 MetaState_(WhichMetaState),
118 Cause_(WhichCause),
119 YieldType_(WhichYieldType),
120 Verbosity_(Verbosity)
121{
123
124 try {
125 // Initialize the class
126 Initialize(dataStream);
127 }
128 catch (std::exception& e) {
130 throw e;
131 }
132
134}
135
136void G4FissionProductYieldDist::Initialize(std::istringstream& dataStream)
137{
139
140 IncidentEnergy_ = 0.0;
143 SetNubar();
144
145 // Set miscellaneous variables
150
151 // Construct G4NeutronHPNames: provides access to the element names
153 // Get the pointer to G4ParticleTable: stores all G4Ions
155 // Construct the pointer to the random engine
156 // TODO Make G4FPSamplingOps a singleton so that only one instance is used across all classes
158
159 try {
160 // Read in and sort the probability data
162 // ENDFData_ = new G4ENDFTapeRead(MakeDirectoryName(),
163 // MakeFileName(Isotope_, MetaState_),
164 // YieldType_,
165 // Cause_);
171 MakeTrees();
173 }
174 catch (std::exception& e) {
175 delete ElementNames_;
176 delete RandomEngine_;
177
179 throw e;
180 }
181
183}
184
186{
188
189#ifdef G4MULTITHREADED
190 G4AutoLock lk(&G4FissionProductYieldDist::fissprodMutex);
191#endif
192
193 // Check to see if the user has set the alpha production to a somewhat
194 // reasonable level
196
197 // Generate the new G4DynamicParticle pointers to identify key locations in
198 // the G4DynamicParticle chain that will be passed to the G4FissionEvent
199 G4ReactionProduct* FirstDaughter = nullptr;
200 G4ReactionProduct* SecondDaughter = nullptr;
201 auto Alphas = new std::vector<G4ReactionProduct*>;
202 auto Neutrons = new std::vector<G4ReactionProduct*>;
203 auto Gammas = new std::vector<G4ReactionProduct*>;
204
205 // Generate all the nucleonic fission products
206 // How many nucleons do we have to work with?
207 // TK modified 131108
208 const G4int ParentA = (Isotope_ / 10) % 1000;
209 const G4int ParentZ = ((Isotope_ / 10) - ParentA) / 1000;
210 RemainingA_ = ParentA;
211 RemainingZ_ = ParentZ;
212
213 // Don't forget the extra nucleons depending on the fission cause
214 switch (Cause_) {
216 ++RemainingA_;
217 break;
218
220 ++RemainingZ_;
221 break;
222
225 default:
226 // Nothing to do here
227 break;
228 }
229
230 // Ternary fission can be set by the user. Thus, it is necessary to
231 // sample the alpha particle first and the first daughter product
232 // second. See the discussion in
233 // G4FissionProductYieldDist::G4GetFissionProduct() for more information
234 // as to why the fission events are sampled this way.
235 GenerateAlphas(Alphas);
236
237 // Generate the first daughter product
238 FirstDaughter = new G4ReactionProduct(GetFissionProduct());
239 RemainingA_ -= FirstDaughter->GetDefinition()->GetAtomicMass();
240 RemainingZ_ -= FirstDaughter->GetDefinition()->GetAtomicNumber();
244
245 G4cout << " -- First daughter product sampled" << G4endl;
247 G4cout << " Name: " << FirstDaughter->GetDefinition()->GetParticleName() << G4endl;
249 G4cout << " Z: " << FirstDaughter->GetDefinition()->GetAtomicNumber() << G4endl;
251 G4cout << " A: " << FirstDaughter->GetDefinition()->GetAtomicMass() << G4endl;
253 G4cout << " Meta State: " << (FirstDaughter->GetDefinition()->GetPDGEncoding() % 10) << G4endl;
254 }
255
256 GenerateNeutrons(Neutrons);
257
258 // Now that all the nucleonic particles have been generated, we can
259 // calculate the composition of the second daughter product.
260 G4int NewIsotope = RemainingZ_ * 1000 + RemainingA_;
261 SecondDaughter =
266
267 G4cout << " -- Second daughter product sampled" << G4endl;
269 G4cout << " Name: " << SecondDaughter->GetDefinition()->GetParticleName() << G4endl;
271 G4cout << " Z: " << SecondDaughter->GetDefinition()->GetAtomicNumber() << G4endl;
273 G4cout << " A: " << SecondDaughter->GetDefinition()->GetAtomicMass() << G4endl;
275 G4cout << " Meta State: " << (SecondDaughter->GetDefinition()->GetPDGEncoding() % 10)
276 << G4endl;
277 }
278
279 // Calculate how much kinetic energy will be available
280 // 195 to 205 MeV are available in a fission reaction, but about 20 MeV
281 // are from delayed sources. We are concerned only with prompt sources,
282 // so sample a Gaussian distribution about 20 MeV and subtract the
283 // result from the total available energy. Also, the energy of fission
284 // neutrinos is neglected. Fission neutrinos would add ~11 MeV
285 // additional energy to the fission. (Ref 2)
286 // Finally, add in the kinetic energy contribution of the fission
287 // inducing particle, if any.
288 const G4double TotalKE = RandomEngine_->G4SampleUniform(195.0, 205.0) * MeV
289 - RandomEngine_->G4SampleGaussian(20.0, 3.0) * MeV + IncidentEnergy_;
290 RemainingEnergy_ = TotalKE;
291
292 // Calculate the energies of the alpha particles and neutrons
293 // Once again, since the alpha particles are user defined, we must
294 // sample their kinetic energy first. SampleAlphaEnergies() returns the
295 // amount of energy consumed by the alpha particles, so remove the total
296 // energy alloted to the alpha particles from the available energy
297 SampleAlphaEnergies(Alphas);
298
299 // Second, the neutrons are sampled from the Watt fission spectrum.
300 SampleNeutronEnergies(Neutrons);
301
302 // Calculate the total energy available to the daughter products
303 // A Gaussian distribution about the average calculated energy with
304 // a standard deviation of 1.5 MeV (Ref. 2) is used. Since the energy
305 // distribution is dependant on the alpha particle generation and the
306 // Watt fission sampling for neutrons, we only have the left-over energy
307 // to work with for the fission daughter products.
308 G4double FragmentsKE = 0.;
309 G4int icounter = 0;
310 G4int icounter_max = 1024;
311 do {
312 icounter++;
313 if (icounter > icounter_max) {
314 G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of "
315 << __FILE__ << "." << G4endl;
316 break;
317 }
318 FragmentsKE = RandomEngine_->G4SampleGaussian(RemainingEnergy_, 1.5 * MeV);
319 } while (FragmentsKE > RemainingEnergy_); // Loop checking, 11.05.2015, T. Koi
320
321 // Make sure that we don't produce any sub-gamma photons
322 if ((RemainingEnergy_ - FragmentsKE) / (100 * keV) < 1.0) {
323 FragmentsKE = RemainingEnergy_;
324 }
325
326 // This energy has now been allotted to the fission fragments.
327 // Subtract FragmentsKE from the total available fission energy.
328 RemainingEnergy_ -= FragmentsKE;
329
330 // Sample the energies of the gamma rays
331 // Assign the remainder, if any, of the energy to the gamma rays
332 SampleGammaEnergies(Gammas);
333
334 // Prepare to balance the momenta of the system
335 // We will need these for sampling the angles and balancing the momenta
336 // of all the fission products
337 G4double NumeratorSqrt, NumeratorOther, Denominator;
338 G4double Theta, Phi, Magnitude;
339 G4ThreeVector Direction;
340 G4ParticleMomentum ResultantVector(0, 0, 0);
341
342 if (!Alphas->empty()) {
343 // Sample the angles of the alpha particles and neutrons, then calculate
344 // the total moment contribution to the system
345 // The average angle of the alpha particles with respect to the
346 // light fragment is dependent on the ratio of the kinetic energies.
347 // This equation was determined by performing a fit on data from
348 // Ref. 3 using the website:
349 // http://soft.arquimedex.com/linear_regression.php
350 //
351 // RatioOfKE Angle (rad) Angle (degrees)
352 // 1.05 1.257 72
353 // 1.155 1.361 78
354 // 1.28 1.414 81
355 // 1.5 1.518 87
356 // 1.75 1.606 92
357 // 1.9 1.623 93
358 // 2.2 1.728 99
359 // This equation generates the angle in radians. If the RatioOfKE is
360 // greater than 2.25 the angle defaults to 1.3963 rad (100 degrees)
361 G4double MassRatio =
362 FirstDaughter->GetDefinition()->GetPDGMass() / SecondDaughter->GetDefinition()->GetPDGMass();
363
364 // Invert the mass ratio if the first daughter product is the lighter fragment
365 if (MassRatio < 1) {
366 MassRatio = 1 / MassRatio;
367 }
368
369 // The empirical equation is valid for mass ratios up to 2.75
370 if (MassRatio > 2.75) {
371 MassRatio = 2.75;
372 }
373 const G4double MeanAlphaAngle = 0.3644 * MassRatio * MassRatio * MassRatio
374 - 1.9766 * MassRatio * MassRatio + 3.8207 * MassRatio - 0.9917;
375
376 // Sample the directions of the alpha particles with respect to the
377 // light fragment. For the moment we will assume that the light
378 // fragment is traveling along the z-axis in the positive direction.
379 const G4double MeanAlphaAngleStdDev = 0.0523598776;
380 G4double PlusMinus;
381
382 for (auto& Alpha : *Alphas) {
383 PlusMinus = std::acos(RandomEngine_->G4SampleGaussian(0, MeanAlphaAngleStdDev)) - (pi / 2);
384 Theta = MeanAlphaAngle + PlusMinus;
385 if (Theta < 0) {
386 Theta = 0.0 - Theta;
387 }
388 else if (Theta > pi) {
389 Theta = (2 * pi - Theta);
390 }
391 Phi = RandomEngine_->G4SampleUniform(-pi, pi);
392
393 Direction.setRThetaPhi(1.0, Theta, Phi);
394 Magnitude = std::sqrt(2 * Alpha->GetKineticEnergy() * Alpha->GetDefinition()->GetPDGMass());
395 Alpha->SetMomentum(Direction * Magnitude);
396 ResultantVector += Alpha->GetMomentum();
397 }
398 }
399
400 // Sample the directions of the neutrons.
401 if (!Neutrons->empty()) {
402 for (auto& Neutron : *Neutrons) {
403 Theta = std::acos(RandomEngine_->G4SampleUniform(-1, 1));
404 Phi = RandomEngine_->G4SampleUniform(-pi, pi);
405
406 Direction.setRThetaPhi(1.0, Theta, Phi);
407 Magnitude =
408 std::sqrt(2 * Neutron->GetKineticEnergy() * Neutron->GetDefinition()->GetPDGMass());
409 Neutron->SetMomentum(Direction * Magnitude);
410 ResultantVector += Neutron->GetMomentum();
411 }
412 }
413
414 // Sample the directions of the gamma rays
415 if (!Gammas->empty()) {
416 for (auto& Gamma : *Gammas) {
417 Theta = std::acos(RandomEngine_->G4SampleUniform(-1, 1));
418 Phi = RandomEngine_->G4SampleUniform(-pi, pi);
419
420 Direction.setRThetaPhi(1.0, Theta, Phi);
421 Magnitude = Gamma->GetKineticEnergy() / CLHEP::c_light;
422 Gamma->SetMomentum(Direction * Magnitude);
423 ResultantVector += Gamma->GetMomentum();
424 }
425 }
426
427 // Calculate the momenta of the two daughter products
428 G4ReactionProduct* LightFragment;
429 G4ReactionProduct* HeavyFragment;
430 G4ThreeVector LightFragmentDirection;
431 G4ThreeVector HeavyFragmentDirection;
432 G4double ResultantX, ResultantY, ResultantZ;
433 ResultantX = ResultantVector.getX();
434 ResultantY = ResultantVector.getY();
435 ResultantZ = ResultantVector.getZ();
436
437 if (FirstDaughter->GetDefinition()->GetPDGMass() < SecondDaughter->GetDefinition()->GetPDGMass())
438 {
439 LightFragment = FirstDaughter;
440 HeavyFragment = SecondDaughter;
441 }
442 else {
443 LightFragment = SecondDaughter;
444 HeavyFragment = FirstDaughter;
445 }
446 const G4double LightFragmentMass = LightFragment->GetDefinition()->GetPDGMass();
447 const G4double HeavyFragmentMass = HeavyFragment->GetDefinition()->GetPDGMass();
448
449 LightFragmentDirection.setRThetaPhi(1.0, 0, 0);
450
451 // Fit the momenta of the daughter products to the resultant vector of
452 // the remaining fission products. This will be done in the Cartesian
453 // coordinate system, not spherical. This is done using the following
454 // table listing the system momenta and the corresponding equations:
455 // X Y Z
456 //
457 // A 0 0 P
458 //
459 // B -R_x -R_y -P - R_z
460 //
461 // R R_x R_y R_z
462 //
463 // v = sqrt(2*m*k) -> k = v^2/(2*m)
464 // tk = k_A + k_B
465 // k_L = P^2/(2*m_L)
466 // k_H = ((-R_x)^2 + (-R_y)^2 + (-P - R_z)^2)/(2*m_H)
467 // where:
468 // P: momentum of the light daughter product
469 // R: the remaining fission products' resultant vector
470 // v: momentum
471 // m: mass
472 // k: kinetic energy
473 // tk: total kinetic energy available to the daughter products
474 //
475 // Below is the solved form for P, with the solution generated using
476 // the WolframAlpha website:
477 // http://www.wolframalpha.com/input/?i=
478 // solve+((-x)^2+%2B+(-y)^2+%2B+(-P-z)^2)%2F(2*B)+%2B+L^2%2F(2*A)+%3D+k+
479 // for+P
480 //
481 //
482 // nsqrt = sqrt(m_L*(m_L*(2*m_H*tk - R_x^2 - R_y^2) +
483 // m_H*(2*m_H*tk - R_x^2 - R_y^2 - R_z^2))
484 NumeratorSqrt = std::sqrt(
485 LightFragmentMass
486 * (LightFragmentMass
487 * (2 * HeavyFragmentMass * FragmentsKE - ResultantX * ResultantX - ResultantY * ResultantY)
488 + HeavyFragmentMass
489 * (2 * HeavyFragmentMass * FragmentsKE - ResultantX * ResultantX
490 - ResultantY * ResultantY - ResultantZ - ResultantZ)));
491
492 // nother = m_L*R_z
493 NumeratorOther = LightFragmentMass * ResultantZ;
494
495 // denom = m_L + m_H
496 Denominator = LightFragmentMass + HeavyFragmentMass;
497
498 // P = (nsqrt + nother) / denom
499 const G4double LightFragmentMomentum = (NumeratorSqrt + NumeratorOther) / Denominator;
500 const G4double HeavyFragmentMomentum =
501 std::sqrt(ResultantX * ResultantX + ResultantY * ResultantY
502 + G4Pow::GetInstance()->powN(LightFragmentMomentum + ResultantZ, 2));
503
504 // Finally! We now have everything we need for the daughter products
505 LightFragment->SetMomentum(LightFragmentDirection * LightFragmentMomentum);
506 HeavyFragmentDirection.setX(-ResultantX);
507 HeavyFragmentDirection.setY(-ResultantY);
508 HeavyFragmentDirection.setZ((-LightFragmentMomentum - ResultantZ));
509 // Don't forget to normalize the vector to the unit sphere
510 HeavyFragmentDirection.setR(1.0);
511 HeavyFragment->SetMomentum(HeavyFragmentDirection * HeavyFragmentMomentum);
512
516
517 G4cout << " -- Daugher product momenta finalized" << G4endl;
519 }
520
521 // Load all the particles into a contiguous set
522 // TK modifed 131108
523 // G4DynamicParticleVector* FissionProducts = new G4DynamicParticleVector(2 + Alphas->size() +
524 // Neutrons->size() + Gammas->size());
525 auto FissionProducts = new G4DynamicParticleVector();
526 // Load the fission fragments
527 FissionProducts->push_back(MakeG4DynamicParticle(LightFragment));
528 FissionProducts->push_back(MakeG4DynamicParticle(HeavyFragment));
529 // Load the neutrons
530 for (auto& Neutron : *Neutrons) {
531 FissionProducts->push_back(MakeG4DynamicParticle(Neutron));
532 }
533 // Load the gammas
534 for (auto& Gamma : *Gammas) {
535 FissionProducts->push_back(MakeG4DynamicParticle(Gamma));
536 }
537 // Load the alphas
538 for (auto& Alpha : *Alphas) {
539 FissionProducts->push_back(MakeG4DynamicParticle(Alpha));
540 }
541
542 // Rotate the system to a random location so that the light fission fragment
543 // is not always traveling along the positive z-axis
544 // Sample Theta and Phi.
545 G4ThreeVector RotationAxis;
546
547 Theta = std::acos(RandomEngine_->G4SampleUniform(-1, 1));
548 Phi = RandomEngine_->G4SampleUniform(-pi, pi);
549 RotationAxis.setRThetaPhi(1.0, Theta, Phi);
550
551 // We will also check the net momenta
552 ResultantVector.set(0.0, 0.0, 0.0);
553 for (auto& FissionProduct : *FissionProducts) {
554 Direction = FissionProduct->GetMomentumDirection();
555 Direction.rotateUz(RotationAxis);
556 FissionProduct->SetMomentumDirection(Direction);
557 ResultantVector += FissionProduct->GetMomentum();
558 }
559
560 // Warn if the sum momenta of the system is not within a reasonable
561 // tolerance
562 G4double PossibleImbalance = ResultantVector.mag();
563 if (PossibleImbalance > 0.01) {
564 std::ostringstream Temp;
565 Temp << "Momenta imbalance of ";
566 Temp << PossibleImbalance / (MeV / CLHEP::c_light);
567 Temp << " MeV/c in the system";
568 G4Exception("G4FissionProductYieldDist::G4GetFission()", Temp.str().c_str(), JustWarning,
569 "Results may not be valid");
570 }
571
572 // Clean up
573 delete FirstDaughter;
574 delete SecondDaughter;
578
580 return FissionProducts;
581}
582
592
594{
596
597 AlphaProduction_ = WhatAlphaProduction;
598
600}
601
603{
605
607 IncidentEnergy_ = WhatIncidentEnergy;
608 }
609 else {
610 IncidentEnergy_ = 0 * GeV;
611 }
612
614}
615
617{
619
620 TernaryProbability_ = WhatTernaryProbability;
621
623}
624
636
638{
640
641 // This provides comfortable breathing room at 16 MeV per alpha
642 if (AlphaProduction_ > 10) {
643 AlphaProduction_ = 10;
644 }
645 else if (AlphaProduction_ < -7) {
646 AlphaProduction_ = -7;
647 }
648
650}
651
653{
655
656 // Determine which energy group is currently in use
657 G4bool isExact = false;
658 G4bool lowerExists = false;
659 G4bool higherExists = false;
660 G4int energyGroup;
661 for (energyGroup = 0; energyGroup < YieldEnergyGroups_; energyGroup++) {
662 if (IncidentEnergy_ == YieldEnergies_[energyGroup]) {
663 isExact = true;
664 break;
665 }
666
667 if (energyGroup == 0 && IncidentEnergy_ < YieldEnergies_[energyGroup]) {
668 // Break if the energy is less than the lowest energy
669 higherExists = true;
670 break;
671 }
672 if (energyGroup == YieldEnergyGroups_ - 1) {
673 // The energy is greater than any values in the yield data.
674 lowerExists = true;
675 break;
676 }
677 // Break if the energy is less than the lowest energy
678 if (IncidentEnergy_ > YieldEnergies_[energyGroup]) {
679 energyGroup--;
680 lowerExists = true;
681 higherExists = true;
682 break;
683 }
684 }
685
686 // Determine which particle it is
687 G4Ions* FoundParticle = nullptr;
688 if (isExact || YieldEnergyGroups_ == 1) {
689 // Determine which tree contains the random value
690 G4int tree;
691 for (tree = 0; tree < TreeCount_; tree++) {
692 // Break if a tree is identified as containing the random particle
693 if (RandomParticle <= Trees_[tree].ProbabilityRangeEnd[energyGroup]) {
694 break;
695 }
696 }
697 ProbabilityBranch* Branch = Trees_[tree].Trunk;
698
699 // Iteratively traverse the tree until the particle addressed by the random
700 // variable is found
701 G4bool RangeIsSmaller;
702 G4bool RangeIsGreater;
703 while ((RangeIsSmaller = (RandomParticle < Branch->ProbabilityRangeBottom[energyGroup]))
704 || (RangeIsGreater = (RandomParticle > Branch->ProbabilityRangeTop[energyGroup])))
705 // Loop checking, 11.05.2015, T. Koi
706 {
707 if (RangeIsSmaller) {
708 Branch = Branch->Left;
709 }
710 else {
711 Branch = Branch->Right;
712 }
713 }
714
715 FoundParticle = Branch->Particle;
716 }
717 else if (lowerExists && higherExists) {
718 // We need to do some interpolation
719 FoundParticle = FindParticleInterpolation(RandomParticle, energyGroup);
720 }
721 else {
722 // We need to do some extrapolation
723 FoundParticle = FindParticleExtrapolation(RandomParticle, lowerExists);
724 }
725
726 // Return the particle
728 return FoundParticle;
729}
730
732 G4bool LowerEnergyGroupExists)
733{
735
736 G4Ions* FoundParticle = nullptr;
737 G4int NearestEnergy;
738 G4int NextNearestEnergy;
739
740 // Check to see if we are extrapolating above or below the data set
741 if (LowerEnergyGroupExists) {
742 NearestEnergy = YieldEnergyGroups_ - 1;
743 NextNearestEnergy = NearestEnergy - 1;
744 }
745 else {
746 NearestEnergy = 0;
747 NextNearestEnergy = 1;
748 }
749
750 for (G4int Tree = 0; Tree < TreeCount_ && FoundParticle == nullptr; Tree++) {
751 FoundParticle = FindParticleBranchSearch(Trees_[Tree].Trunk, RandomParticle, NearestEnergy,
752 NextNearestEnergy);
753 }
754
756 return FoundParticle;
757}
758
760 G4int LowerEnergyGroup)
761{
763
764 G4Ions* FoundParticle = nullptr;
765 G4int HigherEnergyGroup = LowerEnergyGroup + 1;
766
767 for (G4int Tree = 0; Tree < TreeCount_ && FoundParticle == nullptr; Tree++) {
768 FoundParticle = FindParticleBranchSearch(Trees_[Tree].Trunk, RandomParticle, LowerEnergyGroup,
769 HigherEnergyGroup);
770 }
771
773 return FoundParticle;
774}
775
777 G4double RandomParticle,
778 G4int EnergyGroup1, G4int EnergyGroup2)
779{
781
782 G4Ions* Particle;
783
784 // Verify that the branch exists
785 if (Branch == nullptr) {
786 Particle = nullptr;
787 }
788 else if (EnergyGroup1 >= Branch->IncidentEnergiesCount
789 || EnergyGroup2 >= Branch->IncidentEnergiesCount || EnergyGroup1 == EnergyGroup2
790 || Branch->IncidentEnergies[EnergyGroup1] == Branch->IncidentEnergies[EnergyGroup2])
791 {
792 // Set NULL if any invalid conditions exist
793 Particle = nullptr;
794 }
795 else {
796 // Everything check out - proceed
797 G4Ions* FoundParticle = nullptr;
798 G4double Intercept;
799 G4double Slope;
800 G4double RangeAtIncidentEnergy;
801 G4double Denominator =
802 Branch->IncidentEnergies[EnergyGroup1] - Branch->IncidentEnergies[EnergyGroup2];
803
804 // Calculate the lower probability bounds
805 Slope =
806 (Branch->ProbabilityRangeBottom[EnergyGroup1] - Branch->ProbabilityRangeBottom[EnergyGroup2])
807 / Denominator;
808 Intercept =
809 Branch->ProbabilityRangeBottom[EnergyGroup1] - Slope * Branch->IncidentEnergies[EnergyGroup1];
810 RangeAtIncidentEnergy = Slope * IncidentEnergy_ + Intercept;
811
812 // Go right if the particle is below the probability bounds
813 if (RandomParticle < RangeAtIncidentEnergy) {
814 FoundParticle =
815 FindParticleBranchSearch(Branch->Left, RandomParticle, EnergyGroup1, EnergyGroup2);
816 }
817 else {
818 // Calculate the upper probability bounds
819 Slope =
820 (Branch->ProbabilityRangeTop[EnergyGroup1] - Branch->ProbabilityRangeTop[EnergyGroup2])
821 / Denominator;
822 Intercept =
823 Branch->ProbabilityRangeTop[EnergyGroup1] - Slope * Branch->IncidentEnergies[EnergyGroup1];
824 RangeAtIncidentEnergy = Slope * IncidentEnergy_ + Intercept;
825
826 // Go left if the particle is above the probability bounds
827 if (RandomParticle > RangeAtIncidentEnergy) {
828 FoundParticle =
829 FindParticleBranchSearch(Branch->Right, RandomParticle, EnergyGroup1, EnergyGroup2);
830 }
831 else {
832 // If the particle is bounded then we found it!
833 FoundParticle = Branch->Particle;
834 }
835 }
836
837 Particle = FoundParticle;
838 }
839
841 return Particle;
842}
843
844void G4FissionProductYieldDist::GenerateAlphas(std::vector<G4ReactionProduct*>* Alphas)
845{
847
848 // Throw the dice to determine if ternary fission occurs
850 if (MakeAlphas) {
851 G4int NumberOfAlphasToProduce;
852
853 // Determine how many alpha particles to produce for the ternary fission
854 if (AlphaProduction_ < 0) {
855 NumberOfAlphasToProduce = RandomEngine_->G4SampleIntegerGaussian(AlphaProduction_ * -1, 1,
857 }
858 else {
859 NumberOfAlphasToProduce = (G4int)AlphaProduction_;
860 }
861
862 // TK modifed 131108
863 // Alphas->resize(NumberOfAlphasToProduce);
864 for (int i = 0; i < NumberOfAlphasToProduce; i++) {
865 // Set the G4Ions as an alpha particle
866 Alphas->push_back(new G4ReactionProduct(AlphaDefinition_));
867
868 // Remove 4 nucleons (2 protons and 2 neutrons) for each alpha added
869 RemainingZ_ -= 2;
870 RemainingA_ -= 4;
871 }
872 }
873
875}
876
877void G4FissionProductYieldDist::GenerateNeutrons(std::vector<G4ReactionProduct*>* Neutrons)
878{
880
881 G4int NeutronProduction;
882 NeutronProduction =
884
885 // TK modifed 131108
886 // Neutrons->resize(NeutronProduction);
887 for (int i = 0; i < NeutronProduction; i++) {
888 // Define the fragment as a neutron
889 Neutrons->push_back(new G4ReactionProduct(NeutronDefinition_));
890
891 // Remove 1 nucleon for each neutron added
892 RemainingA_--;
893 }
894
896}
897
899 // TK modified 131108
900 // G4FFGEnumerations::MetaState MetaState )
901 G4FFGEnumerations::MetaState /*MetaState*/)
902{
904
905 G4Ions* Temp;
906
907 // Break Product down into its A and Z components
908 G4int A = Product % 1000; // Extract A
909 G4int Z = (Product - A) / 1000; // Extract Z
910
911 // Check to see if the particle is registered using the PDG code
912 // TODO Add metastable state when supported by G4IonTable::GetIon()
913 Temp = static_cast<G4Ions*>(IonTable_->GetIon(Z, A));
914
915 // Removed in favor of the G4IonTable::GetIon() method
916 // // Register the particle if it does not exist
917 // if(Temp == NULL)
918 // {
919 // // Define the particle properties
920 // G4String Name = MakeIsotopeName(Product, MetaState);
921 // // Calculate the rest mass using a function already in Geant4
922 // G4double Mass = G4NucleiProperties::
923 // GetNuclearMass((double)A, (double)Z );
924 // G4double Charge = Z*eplus;
925 // G4int BaryonNum = A;
926 // G4bool Stable = TRUE;
927 //
928 // // I am unsure about the following properties:
929 // // 2*Spin, Parity, C-conjugation, 2*Isospin, 2*Isospin3, G-parity.
930 // // Perhaps is would be a good idea to have a physicist familiar with
931 // // Geant4 nomenclature to review and correct these properties.
932 // Temp = new G4Ions (
933 // // Name Mass Width Charge
934 // Name, Mass, 0.0, Charge,
935 //
936 // // 2*Spin Parity C-conjugation 2*Isospin
937 // 0, 1, 0, 0,
938 //
939 // // 2*Isospin3 G-parity Type Lepton number
940 // 0, 0, "nucleus", 0,
941 //
942 // // Baryon number PDG encoding Stable Lifetime
943 // BaryonNum, PDGCode, Stable, -1,
944 //
945 // // Decay table Shortlived SubType Anti_encoding
946 // NULL, FALSE, "generic", 0,
947 //
948 // // Excitation
949 // 0.0);
950 // Temp->SetPDGMagneticMoment(0.0);
951 //
952 // // Declare that there is no anti-particle
953 // Temp->SetAntiPDGEncoding(0);
954 //
955 // // Define the processes to use in transporting the particles
956 // std::ostringstream osAdd;
957 // osAdd << "/run/particle/addProcManager " << Name;
958 // G4String cmdAdd = osAdd.str();
959 //
960 // // set /control/verbose 0
961 // G4int tempVerboseLevel = G4UImanager::GetUIpointer()->GetVerboseLevel();
962 // G4UImanager::GetUIpointer()->SetVerboseLevel(0);
963 //
964 // // issue /run/particle/addProcManage
965 // G4UImanager::GetUIpointer()->ApplyCommand(cmdAdd);
966 //
967 // // retrieve /control/verbose
968 // G4UImanager::GetUIpointer()->SetVerboseLevel(tempVerboseLevel);
969 // }
970
972 return Temp;
973}
974
976{
978
979 // Generate the file location starting in the Geant4 data directory
980 std::ostringstream DirectoryName;
981 DirectoryName << G4FindDataDir("G4NEUTRONHPDATA") << G4FFGDefaultValues::ENDFFissionDataLocation;
982
983 // Return the directory structure
985 return DirectoryName.str();
986}
987
990{
992
993 // Create the unique identifying name for the particle
994 std::ostringstream FileName;
995
996 // Determine if a leading 0 is needed (ZZZAAA or 0ZZAAA)
997 if (Isotope < 100000) {
998 FileName << "0";
999 }
1000
1001 // Add the name of the element and the extension
1002 FileName << MakeIsotopeName(Isotope, MetaState) << ".fpy";
1003
1005 return FileName.str();
1006}
1007
1010{
1012
1013 auto DynamicParticle =
1014 new G4DynamicParticle(ReactionProduct->GetDefinition(), ReactionProduct->GetMomentum());
1015
1017 return DynamicParticle;
1018}
1019
1022{
1024
1025 // Break Product down into its A and Z components
1026 G4int A = Isotope % 1000;
1027 G4int Z = (Isotope - A) / 1000;
1028
1029 // Create the unique identifying name for the particle
1030 std::ostringstream IsotopeName;
1031
1032 IsotopeName << Z << "_" << A;
1033
1034 // If it is metastable then append "m" to the name
1035 if (MetaState != G4FFGEnumerations::GROUND_STATE) {
1036 IsotopeName << "m";
1037
1038 // If it is a second isomeric state then append "2" to the name
1039 if (MetaState == G4FFGEnumerations::META_2) {
1040 IsotopeName << "2";
1041 }
1042 }
1043 // Add the name of the element and the extension
1044 IsotopeName << "_" << ElementNames_->GetName(Z - 1);
1045
1047 return IsotopeName.str();
1048}
1049
1051{
1053
1054 // Allocate the space
1055 // We will make each tree a binary search
1056 // The maximum number of iterations required to find a single fission product
1057 // based on it's probability is defined by the following:
1058 // x = number of fission products
1059 // Trees = T(x) = ceil( ln(x) )
1060 // Rows/Tree = R(x) = ceil(( sqrt( (8 * x / T(x)) + 1) - 1) / 2)
1061 // Maximum = M(x) = T(x) + R(x)
1062 // Results: x => M(x)
1063 // 10 5
1064 // 100 10
1065 // 1000 25
1066 // 10000 54
1067 // 100000 140
1070
1071 // Initialize the range of each node
1072 for (G4int i = 0; i < TreeCount_; i++) {
1074 Trees_[i].Trunk = nullptr;
1075 Trees_[i].BranchCount = 0;
1076 Trees_[i].IsEnd = FALSE;
1077 }
1078 // Mark the last tree as the ending tree
1079 Trees_[TreeCount_ - 1].IsEnd = TRUE;
1080
1082}
1083
1085{
1087
1089 BranchCount_ = 0;
1091
1092 // Loop through all the products
1093 for (G4int i = 0; i < ProductCount; i++) {
1094 // Acquire the data and sort it
1096 }
1097
1098 // Generate the true normalization factor, since round-off errors may result
1099 // in non-singular normalization of the data files. Also, reset DataTotal_
1100 // since it is used by Renormalize() to set the probability segments.
1103
1104 // Go through all the trees one at a time
1105 for (G4int i = 0; i < TreeCount_; i++) {
1106 Renormalize(Trees_[i].Trunk);
1107 // Set the max range of the tree to DataTotal
1108 G4ArrayOps::Copy(YieldEnergyGroups_, Trees_[i].ProbabilityRangeEnd, DataTotal_);
1109 }
1110
1112}
1113
1115{
1117
1118 // Check to see if Branch exists. Branch will be a null pointer if it
1119 // doesn't exist
1120 if (Branch != nullptr) {
1121 // Call the lower branch to set the probability segment first, since it
1122 // supposed to have a lower probability segment that this node
1123 Renormalize(Branch->Left);
1124
1125 // Set this node as the next sequential probability segment
1130
1131 // Now call the upper branch to set those probability segments
1132 Renormalize(Branch->Right);
1133 }
1134
1136}
1137
1138void G4FissionProductYieldDist::SampleAlphaEnergies(std::vector<G4ReactionProduct*>* Alphas)
1139{
1141
1142 // The condition of sampling more energy from the fission products than is
1143 // alloted is statistically unfavorable, but it could still happen. The
1144 // do-while loop prevents such an occurrence from happening
1145 G4double MeanAlphaEnergy = 16.0;
1146 G4double TotalAlphaEnergy;
1147
1148 do {
1149 G4double AlphaEnergy;
1150 TotalAlphaEnergy = 0;
1151
1152 // Walk through the alpha particles one at a time and sample each's
1153 // energy
1154 for (auto& Alpha : *Alphas) {
1155 AlphaEnergy =
1156 RandomEngine_->G4SampleGaussian(MeanAlphaEnergy, 2.35, G4FFGEnumerations::POSITIVE) * MeV;
1157 // Assign the energy to the alpha particle
1158 Alpha->SetKineticEnergy(AlphaEnergy);
1159
1160 // Add up the total amount of kinetic energy consumed.
1161 TotalAlphaEnergy += AlphaEnergy;
1162 }
1163
1164 // If true, decrement the mean alpha energy by 0.1 and try again.
1165 MeanAlphaEnergy -= 0.1;
1166 } while (TotalAlphaEnergy >= RemainingEnergy_); // Loop checking, 11.05.2015, T. Koi
1167
1168 // Subtract the total amount of energy that was assigned.
1169 RemainingEnergy_ -= TotalAlphaEnergy;
1170
1172}
1173
1174void G4FissionProductYieldDist::SampleGammaEnergies(std::vector<G4ReactionProduct*>* Gammas)
1175{
1177
1178 // Make sure that there is energy to assign to the gamma rays
1179 if (RemainingEnergy_ != 0) {
1180 G4double SampleEnergy;
1181
1182 // Sample from RemainingEnergy until it is all gone. Also,
1183 // RemainingEnergy should not be smaller than
1184 // G4FFGDefaultValues::MeanGammaEnergy. This will prevent the
1185 // sampling of a fractional portion of the Gaussian distribution
1186 // in an attempt to find a new gamma ray energy.
1187 G4int icounter = 0;
1188 G4int icounter_max = 1024;
1189 while (RemainingEnergy_
1190 >= G4FFGDefaultValues::MeanGammaEnergy) // Loop checking, 11.05.2015, T. Koi
1191 {
1192 icounter++;
1193 if (icounter > icounter_max) {
1194 G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of "
1195 << __FILE__ << "." << G4endl;
1196 break;
1197 }
1198 SampleEnergy = RandomEngine_->G4SampleGaussian(G4FFGDefaultValues::MeanGammaEnergy, 1.0 * MeV,
1200 // Make sure that we didn't sample more energy than was available
1201 if (SampleEnergy <= RemainingEnergy_) {
1202 // If this energy assignment would leave less energy than the
1203 // 'intrinsic' minimal energy of a gamma ray then just assign
1204 // all of the remaining energy
1205 if (RemainingEnergy_ - SampleEnergy < 100 * keV) {
1206 SampleEnergy = RemainingEnergy_;
1207 }
1208
1209 // Create the new particle
1210 Gammas->push_back(new G4ReactionProduct());
1211
1212 // Set the properties
1213 Gammas->back()->SetDefinition(GammaDefinition_);
1214 Gammas->back()->SetTotalEnergy(SampleEnergy);
1215
1216 // Calculate how much is left
1217 RemainingEnergy_ -= SampleEnergy;
1218 }
1219 }
1220
1221 // If there is anything left over, the energy must be above 100 keV but
1222 // less than G4FFGDefaultValues::MeanGammaEnergy. Arbitrarily assign
1223 // RemainingEnergy to a new particle
1224 if (RemainingEnergy_ > 0) {
1225 SampleEnergy = RemainingEnergy_;
1226 Gammas->push_back(new G4ReactionProduct());
1227
1228 // Set the properties
1229 Gammas->back()->SetDefinition(GammaDefinition_);
1230 Gammas->back()->SetTotalEnergy(SampleEnergy);
1231
1232 // Calculate how much is left
1233 RemainingEnergy_ -= SampleEnergy;
1234 }
1235 }
1236
1238}
1239
1240void G4FissionProductYieldDist::SampleNeutronEnergies(std::vector<G4ReactionProduct*>* Neutrons)
1241{
1243
1244 // The condition of sampling more energy from the fission products than is
1245 // alloted is statistically unfavorable, but it could still happen. The
1246 // do-while loop prevents such an occurrence from happening
1247 G4double TotalNeutronEnergy = 0.;
1248 G4double NeutronEnergy = 0.;
1249
1250 // Make sure that we don't sample more energy than is available
1251 G4int icounter = 0;
1252 G4int icounter_max = 1024;
1253 do {
1254 icounter++;
1255 if (icounter > icounter_max) {
1256 G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of "
1257 << __FILE__ << "." << G4endl;
1258 break;
1259 }
1260 TotalNeutronEnergy = 0;
1261
1262 // Walk through the neutrons one at a time and sample the energies.
1263 // The gamma rays have not yet been sampled, so the last neutron will
1264 // have a NULL value for NextFragment
1265 for (auto& Neutron : *Neutrons) {
1266 // Assign the energy to the neutron
1268 Neutron->SetKineticEnergy(NeutronEnergy);
1269
1270 // Add up the total amount of kinetic energy consumed.
1271 TotalNeutronEnergy += NeutronEnergy;
1272 }
1273 } while (TotalNeutronEnergy > RemainingEnergy_); // Loop checking, 11.05.2015, T. Koi
1274
1275 // Subtract the total amount of energy that was assigned.
1276 RemainingEnergy_ -= TotalNeutronEnergy;
1277
1279}
1280
1282{
1284
1285 G4int* WhichNubar;
1286 G4int* NubarWidth;
1287 G4double XFactor, BFactor;
1288
1290 WhichNubar = const_cast<G4int*>(&SpontaneousNubar_[0][0]);
1291 NubarWidth = const_cast<G4int*>(&SpontaneousNubarWidth_[0][0]);
1292 }
1293 else {
1294 WhichNubar = const_cast<G4int*>(&NeutronInducedNubar_[0][0]);
1295 NubarWidth = const_cast<G4int*>(&NeutronInducedNubarWidth_[0][0]);
1296 }
1297
1298 XFactor = G4Pow::GetInstance()->powA(10.0, -13.0);
1299 BFactor = G4Pow::GetInstance()->powA(10.0, -4.0);
1300 Nubar_ = *(WhichNubar + 1) * IncidentEnergy_ * XFactor + *(WhichNubar + 2) * BFactor;
1301 while (*WhichNubar != -1) // Loop checking, 11.05.2015, T. Koi
1302 {
1303 if (*WhichNubar == Isotope_) {
1304 Nubar_ = *(WhichNubar + 1) * IncidentEnergy_ * XFactor + *(WhichNubar + 2) * BFactor;
1305
1306 break;
1307 }
1308 WhichNubar += 3;
1309 }
1310
1311 XFactor = G4Pow::GetInstance()->powN((G4double)10, -6);
1312 NubarWidth_ = *(NubarWidth + 1) * XFactor;
1313 while (*WhichNubar != -1) // Loop checking, 11.05.2015, T. Koi
1314 {
1315 if (*WhichNubar == Isotope_) {
1316 NubarWidth_ = *(NubarWidth + 1) * XFactor;
1317
1318 break;
1319 }
1320 WhichNubar += 2;
1321 }
1322
1324}
1325
1327{
1329
1330 // Initialize the new branch
1331 auto NewBranch = new ProbabilityBranch;
1333 NewBranch->Left = nullptr;
1334 NewBranch->Right = nullptr;
1335 NewBranch->Particle = GetParticleDefinition(YieldData->GetProduct(), YieldData->GetMetaState());
1336 NewBranch->IncidentEnergies = new G4double[YieldEnergyGroups_];
1337 NewBranch->ProbabilityRangeTop = new G4double[YieldEnergyGroups_];
1338 NewBranch->ProbabilityRangeBottom = new G4double[YieldEnergyGroups_];
1339 G4ArrayOps::Copy(YieldEnergyGroups_, NewBranch->ProbabilityRangeTop,
1340 YieldData->GetYieldProbability());
1341 G4ArrayOps::Copy(YieldEnergyGroups_, NewBranch->IncidentEnergies, YieldEnergies_);
1343
1344 // Check to see if the this is the smallest/largest particle. First, check
1345 // to see if this is the first particle in the system
1346 if (SmallestZ_ == nullptr) {
1347 SmallestZ_ = SmallestA_ = LargestZ_ = LargestA_ = NewBranch->Particle;
1348 }
1349 else {
1350 G4bool IsSmallerZ = NewBranch->Particle->GetAtomicNumber() < SmallestZ_->GetAtomicNumber();
1351 G4bool IsSmallerA = NewBranch->Particle->GetAtomicMass() < SmallestA_->GetAtomicMass();
1352 G4bool IsLargerZ = NewBranch->Particle->GetAtomicNumber() > LargestZ_->GetAtomicNumber();
1353 G4bool IsLargerA = NewBranch->Particle->GetAtomicMass() > LargestA_->GetAtomicMass();
1354
1355 if (IsSmallerZ) {
1356 SmallestZ_ = NewBranch->Particle;
1357 }
1358
1359 if (IsLargerZ) {
1360 LargestA_ = NewBranch->Particle;
1361 }
1362
1363 if (IsSmallerA) {
1364 SmallestA_ = NewBranch->Particle;
1365 }
1366
1367 if (IsLargerA) {
1368 LargestA_ = NewBranch->Particle;
1369 }
1370 }
1371
1372 // Place the new branch
1373 // Determine which tree the new branch goes into
1374 auto WhichTree = (G4int)floor((G4double)(BranchCount_ % TreeCount_));
1375 ProbabilityBranch** WhichBranch = &(Trees_[WhichTree].Trunk);
1376 Trees_[WhichTree].BranchCount++;
1377
1378 // Search for the position
1379 // Determine where the branch goes
1380 G4int BranchPosition = (G4int)floor((G4double)(BranchCount_ / TreeCount_)) + 1;
1381
1382 // Run through the tree until the end branch is reached
1383 while (BranchPosition > 1) // Loop checking, 11.05.2015, T. Koi
1384 {
1385 if ((BranchPosition & 1) != 0) {
1386 // If the 1's bit is on then move to the next 'right' branch
1387 WhichBranch = &((*WhichBranch)->Right);
1388 }
1389 else {
1390 // If the 1's bit is off then move to the next 'down' branch
1391 WhichBranch = &((*WhichBranch)->Left);
1392 }
1393
1394 BranchPosition >>= 1;
1395 }
1396
1397 *WhichBranch = NewBranch;
1398 BranchCount_++;
1399
1401}
1402
1404{
1406
1407 // Burn each tree, one by one
1408 G4int WhichTree = 0;
1409 while (static_cast<int>(Trees_[WhichTree].IsEnd) != TRUE) // Loop checking, 11.05.2015, T. Koi
1410 {
1411 BurnTree(Trees_[WhichTree].Trunk);
1412 delete Trees_[WhichTree].Trunk;
1413 delete[] Trees_[WhichTree].ProbabilityRangeEnd;
1414 WhichTree++;
1415 }
1416
1417 // Delete each dynamically allocated variable
1418 delete ENDFData_;
1419 delete[] Trees_;
1420 delete[] DataTotal_;
1421 delete[] MaintainNormalizedData_;
1422 delete ElementNames_;
1423 delete RandomEngine_;
1424
1426}
1427
1429{
1431
1432 // Check to see it Branch exists. Branch will be a null pointer if it
1433 // doesn't exist
1434 if (Branch != nullptr) {
1435 // Burn down before you burn up
1436 BurnTree(Branch->Left);
1437 delete Branch->Left;
1438 BurnTree(Branch->Right);
1439 delete Branch->Right;
1440
1441 delete[] Branch->IncidentEnergies;
1442 delete[] Branch->ProbabilityRangeTop;
1443 delete[] Branch->ProbabilityRangeBottom;
1444 }
1445
1447}
std::vector< G4DynamicParticle * > G4DynamicParticleVector
const char * G4FindDataDir(const char *)
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define G4FFG_DATA_FUNCTIONENTER__
#define G4FFG_DATA_FUNCTIONLEAVE__
#define G4FFG_FUNCTIONLEAVE__
#define G4FFG_FUNCTIONENTER__
#define G4FFG_RECURSIVE_FUNCTIONENTER__
#define G4FFG_RECURSIVE_FUNCTIONLEAVE__
#define G4FFG_LOCATION__
#define G4FFG_SPACING__
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
const G4double A[17]
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
double getZ() const
void setY(double)
void setRThetaPhi(double r, double theta, double phi)
void setR(double s)
void setZ(double)
double mag() const
void set(double x, double y, double z)
double getX() const
void setX(double)
Hep3Vector & rotateUz(const Hep3Vector &)
double getY() const
static G4Alpha * Definition()
Definition G4Alpha.cc:43
G4double * G4GetEnergyGroupValues()
G4int G4GetNumberOfEnergyGroups()
void G4SetVerbosity(G4int WhatVerbosity)
G4ENDFYieldDataContainer * G4GetYield(G4int WhichYield)
G4int G4GetNumberOfFissionProducts()
G4FFGEnumerations::MetaState GetMetaState()
G4double G4SampleWatt(G4int WhatIsotope, G4FFGEnumerations::FissionCause WhatCause, G4double WhatEnergy)
G4double G4SampleGaussian(G4double Mean, G4double StdDev)
G4int G4SampleIntegerGaussian(G4double Mean, G4double StdDev)
void G4SetVerbosity(G4int WhatVerbosity)
void Renormalize(ProbabilityBranch *Branch)
void BurnTree(ProbabilityBranch *Branch)
void G4SetEnergy(G4double WhatIncidentEnergy)
virtual G4Ions * GetFissionProduct()=0
void SampleAlphaEnergies(std::vector< G4ReactionProduct * > *Alphas)
void SampleNeutronEnergies(std::vector< G4ReactionProduct * > *Neutrons)
G4Ions * FindParticleBranchSearch(ProbabilityBranch *Branch, G4double RandomParticle, G4int EnergyGroup1, G4int EnergyGroup2)
G4FissionProductYieldDist(G4int WhichIsotope, G4FFGEnumerations::MetaState WhichMetaState, G4FFGEnumerations::FissionCause WhichCause, G4FFGEnumerations::YieldType WhichYieldType, std::istringstream &dataStream)
virtual void SortProbability(G4ENDFYieldDataContainer *YieldData)
G4String MakeFileName(G4int Isotope, G4FFGEnumerations::MetaState MetaState)
G4String MakeIsotopeName(G4int Isotope, G4FFGEnumerations::MetaState MetaState)
const G4FFGEnumerations::FissionCause Cause_
G4Ions * FindParticle(G4double RandomParticle)
G4Ions * FindParticleInterpolation(G4double RandomParticle, G4int LowerEnergyGroup)
virtual void GenerateNeutrons(std::vector< G4ReactionProduct * > *Neutrons)
G4Ions * GetParticleDefinition(G4int Product, G4FFGEnumerations::MetaState MetaState)
void G4SetAlphaProduction(G4double WhatAlphaProduction)
virtual void GenerateAlphas(std::vector< G4ReactionProduct * > *Alphas)
G4DynamicParticle * MakeG4DynamicParticle(G4ReactionProduct *)
void SampleGammaEnergies(std::vector< G4ReactionProduct * > *Gammas)
void G4SetVerbosity(G4int WhatVerbosity)
G4DynamicParticleVector * G4GetFission()
const G4FFGEnumerations::YieldType YieldType_
void G4SetTernaryProbability(G4double TernaryProbability)
G4Ions * FindParticleExtrapolation(G4double RandomParticle, G4bool LowerEnergyGroupExists)
static G4Gamma * Definition()
Definition G4Gamma.cc:43
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
static G4IonTable * GetIonTable()
static G4Neutron * Definition()
Definition G4Neutron.cc:50
G4int GetAtomicNumber() const
G4int GetAtomicMass() const
const G4String & GetParticleName() const
G4ParticleHPDataUsed GetName(G4int A, G4int Z, const G4String &base, const G4String &rest, G4bool &active)
static G4Pow * GetInstance()
Definition G4Pow.cc:41
G4double powN(G4double x, G4int n) const
Definition G4Pow.cc:162
G4double powA(G4double A, G4double y) const
Definition G4Pow.hh:230
void SetMomentum(const G4double x, const G4double y, const G4double z)
const G4ParticleDefinition * GetDefinition() const
G4ThreeVector GetMomentum() const
#define TRUE
Definition globals.hh:41
#define FALSE
Definition globals.hh:38
void Add(G4int Elements, T *To, T *A1, T *A2=nullptr)
Definition G4ArrayOps.hh:71
void Multiply(G4int Elements, T *To, T *M1, T *M2=nullptr)
void Divide(G4int Elements, T *To, T *Numerator, T *Denominator=NULL)
void DeleteVectorOfPointers(std::vector< T > &Vector)
void Copy(G4int Elements, T *To, T *From)
Definition G4ArrayOps.hh:60
void Set(G4int Elements, T *To, T Value)
Definition G4ArrayOps.hh:51
ProbabilityBranch * Left
ProbabilityBranch * Right
G4double * ProbabilityRangeBottom
G4double * ProbabilityRangeEnd
ProbabilityBranch * Trunk