Files
geant4/source/processes/hadronic/models/cascade/cascade/include/G4NucleiModel.hh
T
2024-06-28 13:08:51 +02:00

335 lines
13 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// 20100319 M. Kelsey -- Remove "using" directory and unnecessary #includes,
// move ctor to .cc file
// 20100407 M. Kelsey -- Create "partners thePartners" data member to act
// as buffer between ::generateInteractionPartners() and
// ::generateParticleFate(), and make "outgoing_cparticles" a
// data member returned from the latter by const-ref. Replace
// return-by-value of initializeCascad() with an input buffer.
// 20100409 M. Kelsey -- Add function to sort list of partnerts by pathlen,
// move non-inlinable code to .cc.
// 20100421 M. Kelsey -- Move getFermiKinetic() to .cc, no hardwired masses.
// 20100517 M. Kelsey -- Change cross-section tables to static arrays. Move
// absorptionCrossSection() from SpecialFunc.
// 20100520 M. Kelsey -- Add function to separate momentum from nucleon
// 20100617 M. Kelsey -- Add setVerboseLevel() function, add generateModel()
// with particle input, and ctor with A/Z input.
// 20100715 M. Kelsey -- Add G4InuclNuclei object for use with balance checks
// 20100723 M. Kelsey -- Move G4CollisionOutput buffer, along with all
// std::vector<> buffers, here for reuse
// 20100914 M. Kelsey -- Migrate to integer A and Z
// 20101004 M. Kelsey -- Rename and create functions used to generate model
// 20101019 M. Kelsey -- CoVerity report: dtor leak; move dtor to .cc file
// 20110223 M. Kelsey -- Add static parameters for radius and cross-section
// scaling factors.
// 20110303 M. Kelsey -- Add accessors for model parameters and units
// 20110304 M. Kelsey -- Extend reset() to fill neutron and proton counts
// 20110324 D. Wright -- Add list of nucleon interaction points, and nucleon
// effective radius, for trailing effect.
// 20110324 M. Kelsey -- Extend reset() to pass list of points; move
// implementation to .cc file.
// 20110405 M. Kelsey -- Add "passTrailing()" to encapsulate trailing effect
// 20110808 M. Kelsey -- Pass buffer into generateParticleFate instead of
// returning a vector to be copied.
// 20110823 M. Kelsey -- Remove local cross-section tables entirely
// 20120125 M. Kelsey -- Add special case for photons to have zero potential.
// 20120307 M. Kelsey -- Add zone volume array for use with quasideuteron
// density, functions to identify projectile, compute interaction
// distance.
// 20130129 M. Kelsey -- Add static objects for gamma-quasideuteron scattering
// 20130221 M. Kelsey -- Add function to emplant particle along trajectory
// 20130226 M. Kelsey -- Allow forcing zone selection in MFP calculation.
// 20130302 M. Kelsey -- Add forceFirst() wrapper function (allows configuring)
// 20130628 M. Kelsey -- Extend useQuasiDeuteron() to check good absorption,
// fix spelling of "Deutron" -> "Deuteron"
// 20130808 M. Kelsey -- To avoid thread collisions, move static neutronEP
// and protonEP objects to const data members.
// 20131001 M. Kelsey -- Move QDinterp object to data member, thread local
// 20140116 M. Kelsey -- Move statics to const data members to avoid weird
// interactions with MT.
#ifndef G4NUCLEI_MODEL_HH
#define G4NUCLEI_MODEL_HH
#include <algorithm>
#include <vector>
#include "G4InuclElementaryParticle.hh"
#include "G4CascadParticle.hh"
#include "G4CascadeInterpolator.hh"
#include "G4CollisionOutput.hh"
#include "G4LorentzConvertor.hh"
class G4InuclNuclei;
class G4ElementaryParticleCollider;
class G4NucleiModel {
public:
G4NucleiModel();
G4NucleiModel(G4int a, G4int z);
explicit G4NucleiModel(G4InuclNuclei* nuclei);
virtual ~G4NucleiModel();
void setVerboseLevel(G4int verbose) { verboseLevel = verbose; }
void generateModel(G4InuclNuclei* nuclei);
void generateModel(G4int a, G4int z);
// Arguments here are used for rescattering (::Propagate)
void reset(G4int nHitNeutrons=0, G4int nHitProtons=0,
const std::vector<G4ThreeVector>* hitPoints=0);
void printModel() const;
G4double getDensity(G4int ip, G4int izone) const {
return nucleon_densities[ip - 1][izone];
}
G4double getFermiMomentum(G4int ip, G4int izone) const {
return fermi_momenta[ip - 1][izone];
}
G4double getFermiKinetic(G4int ip, G4int izone) const;
G4double getPotential(G4int ip, G4int izone) const {
if (ip == 9 || ip < 0) return 0.0; // Photons and leptons
G4int ip0 = ip < 3 ? ip - 1 : 2;
if (ip > 10 && ip < 18) ip0 = 3;
if (ip > 20) ip0 = 4;
return izone < number_of_zones ? zone_potentials[ip0][izone] : 0.0;
}
// Factor to convert GEANT4 lengths to internal units
G4double getRadiusUnits() const { return radiusUnits*CLHEP::fermi; }
G4double getRadius() const { return nuclei_radius; }
G4double getRadius(G4int izone) const {
return ( (izone<0) ? 0.
: (izone<number_of_zones) ? zone_radii[izone] : nuclei_radius);
}
G4double getVolume(G4int izone) const {
return ( (izone<0) ? 0.
: (izone<number_of_zones) ? zone_volumes[izone] : nuclei_volume);
}
G4int getNumberOfZones() const { return number_of_zones; }
G4int getZone(G4double r) const {
for (G4int iz=0; iz<number_of_zones; iz++) if (r<zone_radii[iz]) return iz;
return number_of_zones;
}
G4int getNumberOfNeutrons() const { return neutronNumberCurrent; }
G4int getNumberOfProtons() const { return protonNumberCurrent; }
G4bool empty() const {
return neutronNumberCurrent < 1 && protonNumberCurrent < 1;
}
G4bool stillInside(const G4CascadParticle& cparticle) {
return cparticle.getCurrentZone() < number_of_zones;
}
G4CascadParticle initializeCascad(G4InuclElementaryParticle* particle);
typedef std::pair<std::vector<G4CascadParticle>, std::vector<G4InuclElementaryParticle> > modelLists;
void initializeCascad(G4InuclNuclei* bullet, G4InuclNuclei* target,
modelLists& output);
std::pair<G4int, G4int> getTypesOfNucleonsInvolved() const {
return std::pair<G4int, G4int>(current_nucl1, current_nucl2);
}
void generateParticleFate(G4CascadParticle& cparticle,
G4ElementaryParticleCollider* theEPCollider,
std::vector<G4CascadParticle>& cascade);
G4bool forceFirst(const G4CascadParticle& cparticle) const;
G4bool isProjectile(const G4CascadParticle& cparticle) const;
G4bool worthToPropagate(const G4CascadParticle& cparticle) const;
G4InuclElementaryParticle generateNucleon(G4int type, G4int zone) const;
G4LorentzVector generateNucleonMomentum(G4int type, G4int zone) const;
G4double absorptionCrossSection(G4double e, G4int type) const;
G4double totalCrossSection(G4double ke, G4int rtype) const;
// Identify whether given particle can interact with dibaryons
static G4bool useQuasiDeuteron(G4int ptype, G4int qdtype=0);
protected:
G4bool passFermi(const std::vector<G4InuclElementaryParticle>& particles,
G4int zone);
G4bool passTrailing(const G4ThreeVector& hit_position);
void boundaryTransition(G4CascadParticle& cparticle);
void choosePointAlongTraj(G4CascadParticle& cparticle);
G4InuclElementaryParticle generateQuasiDeuteron(G4int type1,
G4int type2,
G4int zone) const;
typedef std::pair<G4InuclElementaryParticle, G4double> partner;
std::vector<partner> thePartners; // Buffer for output below
void generateInteractionPartners(G4CascadParticle& cparticle);
// Function for std::sort() to use in organizing partners by path length
static G4bool sortPartners(const partner& p1, const partner& p2) {
return (p2.second > p1.second);
}
// Functions used to generate model nuclear structure
void fillBindingEnergies();
void fillZoneRadii(G4double nuclearRadius);
G4double fillZoneVolumes(G4double nuclearRadius);
void fillPotentials(G4int type, G4double tot_vol);
G4double zoneIntegralWoodsSaxon(G4double ur1, G4double ur2,
G4double nuclearRadius) const;
G4double zoneIntegralGaussian(G4double ur1, G4double ur2,
G4double nuclearRadius) const;
G4double getRatio(G4int ip) const; // Fraction of nucleons still available
// Scale nuclear density with interactions so far
G4double getCurrentDensity(G4int ip, G4int izone) const;
// Average path length for any interaction of projectile and target
// = 1. / (density * cross-section)
G4double inverseMeanFreePath(const G4CascadParticle& cparticle,
const G4InuclElementaryParticle& target,
G4int zone = -1); // Override zone value
// NOTE: Function is non-const in order to use dummy_converter
// Use path-length and MFP (above) to throw random distance to collision
G4double generateInteractionLength(const G4CascadParticle& cparticle,
G4double path, G4double invmfp) const;
// Set scaling factor for effective number of di-nucleons in nucleus
void setDinucleonDensityScale();
private:
G4int verboseLevel;
// Buffers for processing interactions on each cycle
G4LorentzConvertor dummy_convertor; // For getting collision frame
G4CollisionOutput EPCoutput; // For N-body inelastic collisions
std::vector<G4InuclElementaryParticle> qdeutrons; // For h+(NN) trials
std::vector<G4double> acsecs;
std::vector<G4ThreeVector> coordinates; // for initializeCascad()
std::vector<G4LorentzVector> momentums;
std::vector<G4InuclElementaryParticle> raw_particles;
std::vector<G4ThreeVector> collisionPts;
// Temporary buffers for computing nuclear model
G4double ur[7]; // Number of skin depths for each zone
G4double v[6]; // Density integrals by zone
G4double v1[6]; // Pseudo-volume (delta r^3) by zone
std::vector<G4double> rod; // Nucleon density
std::vector<G4double> pf; // Fermi momentum
std::vector<G4double> vz; // Nucleon potential
// Nuclear model configuration
std::vector<std::vector<G4double> > nucleon_densities;
std::vector<std::vector<G4double> > zone_potentials;
std::vector<std::vector<G4double> > fermi_momenta;
std::vector<G4double> zone_radii;
std::vector<G4double> zone_volumes;
std::vector<G4double> binding_energies;
G4double nuclei_radius;
G4double nuclei_volume;
G4int number_of_zones;
G4int A;
G4int Z;
G4InuclNuclei* theNucleus;
G4int neutronNumber;
G4int protonNumber;
G4int neutronNumberCurrent;
G4int protonNumberCurrent;
G4int current_nucl1;
G4int current_nucl2;
G4double dinucleonDensityScale;
// Ratio of naive to effective number of di-nucleons as predicted in
// local density approximation
// O. Benhar et al., arXiv:nucl-th/0301091v1. (2003)
G4CascadeInterpolator<30> gammaQDinterp; // quasideuteron interpolator
// Symbolic names for nuclear potentials
enum PotentialType { WoodsSaxon=0, Gaussian=1 };
// Parameters for nuclear structure
const G4double crossSectionUnits; // Scale from internal to natural units
const G4double radiusUnits;
const G4double skinDepth; // Fraction of radius for outer skin
const G4double radiusScale; // Coefficients for two-parameter fit
const G4double radiusScale2; // R = 1.16*cbrt(A) - 1.3456/cbrt(A)
const G4double radiusForSmall; // Average radius of light A<5 nuclei
const G4double radScaleAlpha; // Scaling factor R_alpha/R_small
const G4double fermiMomentum;
const G4double R_nucleon;
const G4double gammaQDscale; // Gamma/cluster scattering rescaling
const G4double potentialThickness; // Defaulted to 1.0
// Cutoffs for extreme values
static const G4double small;
static const G4double large;
static const G4double piTimes4thirds; // FIXME: We should not be using this!
static const G4double alfa3[3], alfa6[6]; // Zone boundaries in radii
static const G4double pion_vp; // Flat potentials for pi, K, Y
static const G4double pion_vp_small;
static const G4double kaon_vp;
static const G4double hyperon_vp;
// Neutrons and protons, for computing trajectory placements
const G4InuclElementaryParticle neutronEP;
const G4InuclElementaryParticle protonEP;
};
#endif // G4NUCLEI_MODEL_HH