Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // ABLAXX statistical de-excitation model 26 // ABLAXX statistical de-excitation model 27 // Jose Luis Rodriguez, UDC (translation from << 27 // Jose Luis Rodriguez, GSI (translation from ABLA07 and contact person) 28 // Pekka Kaitaniemi, HIP (initial translation 28 // Pekka Kaitaniemi, HIP (initial translation of ablav3p) 29 // Aleksandra Kelic, GSI (ABLA07 code) 29 // Aleksandra Kelic, GSI (ABLA07 code) 30 // Davide Mancusi, CEA (contact person INCL) 30 // Davide Mancusi, CEA (contact person INCL) 31 // Aatos Heikkinen, HIP (project coordination) 31 // Aatos Heikkinen, HIP (project coordination) 32 // 32 // 33 33 34 #include "globals.hh" 34 #include "globals.hh" 35 #include <cmath> << 36 #include <iostream> 35 #include <iostream> >> 36 #include <cmath> 37 37 38 #include "G4AblaInterface.hh" 38 #include "G4AblaInterface.hh" 39 #include "G4DoubleHyperDoubleNeutron.hh" << 39 #include "G4ParticleDefinition.hh" 40 #include "G4DoubleHyperH4.hh" << 40 #include "G4ReactionProductVector.hh" >> 41 #include "G4ReactionProduct.hh" 41 #include "G4DynamicParticle.hh" 42 #include "G4DynamicParticle.hh" 42 #include "G4ExcitationHandler.hh" << 43 #include "G4HyperAlpha.hh" << 44 #include "G4HyperH4.hh" << 45 #include "G4HyperHe5.hh" << 46 #include "G4HyperTriton.hh" << 47 #include "G4IonTable.hh" 43 #include "G4IonTable.hh" 48 #include "G4ParticleDefinition.hh" << 44 #include "G4SystemOfUnits.hh" 49 #include "G4PhysicalConstants.hh" 45 #include "G4PhysicalConstants.hh" 50 #include "G4PhysicsModelCatalog.hh" 46 #include "G4PhysicsModelCatalog.hh" 51 #include "G4ReactionProduct.hh" << 47 #include "G4ExcitationHandler.hh" 52 #include "G4ReactionProductVector.hh" << 48 #include "G4HyperTriton.hh" 53 #include "G4SystemOfUnits.hh" << 49 #include "G4HyperH4.hh" >> 50 #include "G4HyperAlpha.hh" >> 51 #include "G4DoubleHyperH4.hh" >> 52 #include "G4DoubleHyperDoubleNeutron.hh" >> 53 #include "G4HyperHe5.hh" 54 54 55 G4AblaInterface::G4AblaInterface(G4ExcitationH << 55 G4AblaInterface::G4AblaInterface(G4ExcitationHandler* ptr) : 56 : G4VPreCompoundModel(ptr, "ABLAXX") << 56 G4VPreCompoundModel(ptr, "ABLAXX"), 57 , ablaResult(new G4VarNtp) << 57 ablaResult(new G4VarNtp), 58 , theABLAModel(new G4Abla(ablaResult)) << 58 volant(new G4Volant), 59 , eventNumber(0) << 59 theABLAModel(new G4Abla(volant, ablaResult)), 60 , secID(-1) << 60 eventNumber(0), 61 , isInitialised(false) << 61 secID(-1), 62 { << 62 isInitialised(false) 63 secID = G4PhysicsModelCatalog::GetModelID( << 63 { 64 // G4cout << "### NEW PrecompoundModel " < << 64 secID = G4PhysicsModelCatalog::GetModelID("model_" + GetModelName()); 65 if (!ptr) << 65 // G4cout << "### NEW PrecompoundModel " << this << G4endl; 66 SetExcitationHandler(new G4ExcitationH << 66 if (!ptr) SetExcitationHandler(new G4ExcitationHandler); 67 InitialiseModel(); << 67 InitialiseModel(); 68 G4cout << G4endl << "G4AblaInterface::Init << 68 G4cout << G4endl << "G4AblaInterface::InitialiseModel() was right." << G4endl; 69 } 69 } 70 70 71 G4AblaInterface::~G4AblaInterface() 71 G4AblaInterface::~G4AblaInterface() 72 { 72 { 73 applyYourselfResult.Clear(); << 73 applyYourselfResult.Clear(); 74 delete ablaResult; << 74 delete volant; 75 delete theABLAModel; << 75 delete ablaResult; 76 delete GetExcitationHandler(); << 76 delete theABLAModel; >> 77 delete GetExcitationHandler(); 77 } 78 } 78 79 79 void G4AblaInterface::BuildPhysicsTable(const << 80 void G4AblaInterface::BuildPhysicsTable(const G4ParticleDefinition&) 80 << 81 void G4AblaInterface::InitialiseModel() << 82 { 81 { 83 if (isInitialised) << 82 InitialiseModel(); 84 return; << 85 isInitialised = true; << 86 theABLAModel->initEvapora(); << 87 theABLAModel->SetParameters(); << 88 GetExcitationHandler()->Initialise(); << 89 } 83 } 90 84 91 G4HadFinalState* G4AblaInterface::ApplyYoursel << 85 void G4AblaInterface::InitialiseModel() 92 { 86 { 93 // This method is adapted from G4PreCompo << 87 if (isInitialised) return; 94 // and it is used only by Binary Cascade ( << 88 isInitialised = true; 95 // Abla for nuclear de-excitation. This me << 89 theABLAModel->initEvapora(); 96 // for proton and neutron projectile with << 90 theABLAModel->SetParameters(); 97 // creating a "compound" nucleus made by t << 91 GetExcitationHandler()->Initialise(); 98 // projectile", before calling the DeExcit << 92 } 99 const G4ParticleDefinition* primary = theP << 93 100 if (primary != G4Neutron::Definition() && << 94 101 { << 95 G4HadFinalState* G4AblaInterface::ApplyYourself(const G4HadProjectile & thePrimary, 102 G4ExceptionDescription ed; << 96 G4Nucleus & theNucleus) 103 ed << "G4AblaModel is used for "; << 97 { 104 if (primary) << 98 // This method is adapted from G4PreCompoundModel::ApplyYourself, 105 ed << primary->GetParticleName(); << 99 // and it is used only by Binary Cascade (BIC) when the latter is coupled with Abla 106 G4Exception("G4AblaInterface::ApplyYou << 100 // for nuclear de-excitation. 107 return nullptr; << 101 // This method allows BIC+ABLA to be used also for proton and neutron projectile 108 } << 102 // with kinetic energies below 45 MeV, by creating a "compound" nucleus made 109 << 103 // by the system "target nucleus + projectile", before calling the DeExcite 110 G4int Zp = 0; << 104 // method. 111 G4int Ap = 1; << 105 const G4ParticleDefinition* primary = thePrimary.GetDefinition(); 112 if (primary == G4Proton::Definition()) << 106 if ( primary != G4Neutron::Definition() && primary != G4Proton::Definition() ) { 113 Zp = 1; << 107 G4ExceptionDescription ed; 114 G4double timePrimary = thePrimary.GetGloba << 108 ed << "G4AblaModel is used for "; 115 G4int A = theNucleus.GetA_asInt(); << 109 if ( primary ) ed << primary->GetParticleName(); 116 G4int Z = theNucleus.GetZ_asInt(); << 110 G4Exception( "G4AblaInterface::ApplyYourself()", "had040", FatalException, ed, "" ); 117 G4LorentzVector p = thePrimary.Get4Momentu << 111 return nullptr; 118 G4double mass = G4NucleiProperties::GetNuc << 112 } 119 p += G4LorentzVector(0.0, 0.0, 0.0, mass); << 113 120 << 114 G4int Zp = 0; 121 G4Fragment anInitialState(A + Ap, Z + Zp, << 115 G4int Ap = 1; 122 anInitialState.SetNumberOfExcitedParticle( << 116 if ( primary == G4Proton::Definition() ) Zp = 1; 123 anInitialState.SetNumberOfHoles(1, Zp); << 117 G4double timePrimary = thePrimary.GetGlobalTime(); 124 anInitialState.SetCreationTime(thePrimary. << 118 G4int A = theNucleus.GetA_asInt(); 125 anInitialState.SetCreatorModelID(secID); << 119 G4int Z = theNucleus.GetZ_asInt(); 126 << 120 G4LorentzVector p = thePrimary.Get4Momentum(); 127 G4ReactionProductVector* deExciteResult = << 121 G4double mass = G4NucleiProperties::GetNuclearMass(A, Z); 128 << 122 p += G4LorentzVector( 0.0, 0.0, 0.0, mass ); 129 applyYourselfResult.Clear(); << 123 130 applyYourselfResult.SetStatusChange(stopAn << 124 G4Fragment anInitialState(A + Ap, Z + Zp, p); 131 for (auto const& prod : *deExciteResult) << 125 anInitialState.SetNumberOfExcitedParticle(1, Zp); >> 126 anInitialState.SetNumberOfHoles(1, Zp); >> 127 anInitialState.SetCreationTime( thePrimary.GetGlobalTime() ); >> 128 anInitialState.SetCreatorModelID( secID ); >> 129 >> 130 G4ReactionProductVector* deExciteResult = DeExcite( anInitialState ); >> 131 >> 132 applyYourselfResult.Clear(); >> 133 applyYourselfResult.SetStatusChange( stopAndKill ); >> 134 for ( auto const & prod : *deExciteResult ) { >> 135 G4DynamicParticle * aNewDP = >> 136 new G4DynamicParticle( prod->GetDefinition(), prod->GetTotalEnergy(), prod->GetMomentum() ); >> 137 G4HadSecondary aNew = G4HadSecondary( aNewDP ); >> 138 G4double time = std::max( prod->GetFormationTime(), 0.0 ); >> 139 aNew.SetTime( timePrimary + time ); >> 140 aNew.SetCreatorModelID( prod->GetCreatorModelID() ); >> 141 delete prod; >> 142 applyYourselfResult.AddSecondary( aNew ); >> 143 } >> 144 delete deExciteResult; >> 145 return &applyYourselfResult; >> 146 } >> 147 >> 148 >> 149 G4ReactionProductVector *G4AblaInterface::DeExcite(G4Fragment& aFragment) { >> 150 if (!isInitialised) InitialiseModel(); >> 151 >> 152 volant->clear(); >> 153 ablaResult->clear(); >> 154 >> 155 const G4int ARem = aFragment.GetA_asInt(); >> 156 const G4int ZRem = aFragment.GetZ_asInt(); >> 157 const G4int SRem = -aFragment.GetNumberOfLambdas(); // Strangeness = - (Number of lambdas) >> 158 const G4double eStarRem = aFragment.GetExcitationEnergy() / MeV; >> 159 const G4double jRem = aFragment.GetAngularMomentum().mag() / hbar_Planck; >> 160 const G4LorentzVector& pRem = aFragment.GetMomentum(); >> 161 const G4double pxRem = pRem.x() / MeV; >> 162 const G4double pyRem = pRem.y() / MeV; >> 163 const G4double pzRem = pRem.z() / MeV; >> 164 >> 165 ++eventNumber; >> 166 >> 167 theABLAModel->DeexcitationAblaxx(ARem, ZRem, eStarRem, jRem, pxRem, pyRem, >> 168 pzRem, (G4int)eventNumber, SRem); >> 169 >> 170 G4ReactionProductVector* result = new G4ReactionProductVector; >> 171 >> 172 for(G4int j = 0; j < ablaResult->ntrack; ++j) >> 173 { // Copy ABLA result to the EventInfo >> 174 G4ReactionProduct* product = >> 175 toG4Particle(ablaResult->avv[j], ablaResult->zvv[j], ablaResult->svv[j], >> 176 ablaResult->enerj[j], ablaResult->pxlab[j], >> 177 ablaResult->pylab[j], ablaResult->pzlab[j]); >> 178 if(product) 132 { 179 { 133 G4DynamicParticle* aNewDP = << 180 product->SetCreatorModelID(secID); 134 new G4DynamicParticle(prod->GetDef << 181 result->push_back(product); 135 G4HadSecondary aNew = G4HadSecondary(a << 136 G4double time = std::max(prod->GetForm << 137 aNew.SetTime(timePrimary + time); << 138 aNew.SetCreatorModelID(prod->GetCreato << 139 delete prod; << 140 applyYourselfResult.AddSecondary(aNew) << 141 } 182 } 142 delete deExciteResult; << 183 } 143 return &applyYourselfResult; << 184 return result; 144 } 185 } 145 186 146 G4ReactionProductVector* G4AblaInterface::DeEx << 187 G4ParticleDefinition *G4AblaInterface::toG4ParticleDefinition(G4int A, G4int Z, G4int S) const { 147 { << 188 if (A == 1 && Z == 1 && S == 0 ) return G4Proton::Proton(); 148 if (!isInitialised) << 189 else if(A == 1 && Z == 0 && S == 0 ) return G4Neutron::Neutron(); 149 InitialiseModel(); << 190 else if(A == 1 && Z == 0 && S == -1) return G4Lambda::Lambda(); 150 << 191 else if(A == -1 && Z == 1 && S == 0 ) return G4PionPlus::PionPlus(); 151 ablaResult->clear(); << 192 else if(A == -1 && Z == -1 && S == 0 ) return G4PionMinus::PionMinus(); 152 << 193 else if(A == -1 && Z == 0 && S == 0 ) return G4PionZero::PionZero(); 153 const G4int ARem = aFragment.GetA_asInt(); << 194 else if(A == 0 && Z == 0 && S == 0 ) return G4Gamma::Gamma(); 154 const G4int ZRem = aFragment.GetZ_asInt(); << 195 else if(A == 2 && Z == 1 && S == 0 ) return G4Deuteron::Deuteron(); 155 const G4int SRem = -aFragment.GetNumberOfL << 196 else if(A == 3 && Z == 1 && S == 0 ) return G4Triton::Triton(); 156 const G4double eStarRem = aFragment.GetExc << 197 else if(A == 3 && Z == 2 && S == 0 ) return G4He3::He3(); 157 const G4double jRem = aFragment.GetAngular << 198 else if(A == 3 && Z == 1 && S == -1) return G4HyperTriton::Definition(); 158 const G4LorentzVector& pRem = aFragment.Ge << 199 else if(A == 4 && Z == 2 && S == 0 ) return G4Alpha::Alpha(); 159 const G4double pxRem = pRem.x() / MeV; << 200 else if(A == 4 && Z == 1 && S == -1) return G4HyperH4::Definition(); 160 const G4double pyRem = pRem.y() / MeV; << 201 else if(A == 4 && Z == 2 && S == -1) return G4HyperAlpha::Definition(); 161 const G4double pzRem = pRem.z() / MeV; << 202 else if(A == 4 && Z == 1 && S == -2) return G4DoubleHyperH4::Definition(); 162 << 203 else if(A == 4 && Z == 0 && S == -2) return G4DoubleHyperDoubleNeutron::Definition(); 163 ++eventNumber; << 204 else if(A == 5 && Z == 2 && S == -1) return G4HyperHe5::Definition(); 164 << 205 else if(A > 0 && Z > 0 && A > Z ) 165 theABLAModel->DeexcitationAblaxx(ARem, ZRe << 206 { // Returns ground state ion definition. 166 << 207 auto ionfromtable = G4IonTable::GetIonTable()->GetIon(Z, A, std::abs(S), 0); // S is the number of lambdas 167 G4ReactionProductVector* result = new G4Re << 208 if(ionfromtable) 168 << 209 return ionfromtable; 169 for (G4int j = 0; j < ablaResult->ntrack; << 170 { // Copy ABLA result to the EventInfo << 171 G4ReactionProduct* product = toG4Parti << 172 << 173 << 174 << 175 << 176 << 177 << 178 if (product) << 179 { << 180 product->SetCreatorModelID(secID); << 181 result->push_back(product); << 182 } << 183 } << 184 return result; << 185 } << 186 << 187 G4ParticleDefinition* G4AblaInterface::toG4Par << 188 { << 189 if (A == 1 && Z == 1 && S == 0) << 190 return G4Proton::Proton(); << 191 else if (A == 1 && Z == 0 && S == 0) << 192 return G4Neutron::Neutron(); << 193 else if (A == 1 && Z == 0 && S == -1) << 194 return G4Lambda::Lambda(); << 195 else if (A == -1 && Z == 1 && S == 0) << 196 return G4PionPlus::PionPlus(); << 197 else if (A == -1 && Z == -1 && S == 0) << 198 return G4PionMinus::PionMinus(); << 199 else if (A == -1 && Z == 0 && S == 0) << 200 return G4PionZero::PionZero(); << 201 else if (A == 0 && Z == 0 && S == 0) << 202 return G4Gamma::Gamma(); << 203 else if (A == 2 && Z == 1 && S == 0) << 204 return G4Deuteron::Deuteron(); << 205 else if (A == 3 && Z == 1 && S == 0) << 206 return G4Triton::Triton(); << 207 else if (A == 3 && Z == 2 && S == 0) << 208 return G4He3::He3(); << 209 else if (A == 3 && Z == 1 && S == -1) << 210 return G4HyperTriton::Definition(); << 211 else if (A == 4 && Z == 2 && S == 0) << 212 return G4Alpha::Alpha(); << 213 else if (A == 4 && Z == 1 && S == -1) << 214 return G4HyperH4::Definition(); << 215 else if (A == 4 && Z == 2 && S == -1) << 216 return G4HyperAlpha::Definition(); << 217 else if (A == 4 && Z == 1 && S == -2) << 218 return G4DoubleHyperH4::Definition(); << 219 else if (A == 4 && Z == 0 && S == -2) << 220 return G4DoubleHyperDoubleNeutron::Def << 221 else if (A == 5 && Z == 2 && S == -1) << 222 return G4HyperHe5::Definition(); << 223 else if (A > 0 && Z > 0 && A > Z) << 224 { // Returns ground state ion definition. << 225 auto ionfromtable = G4IonTable::GetIon << 226 if (ionfromtable) << 227 return ionfromtable; << 228 else << 229 { << 230 G4cout << "Can't convert particle << 231 << " to G4ParticleDefinitio << 232 return 0; << 233 } << 234 } << 235 else 210 else 236 { // Error, unrecognized particle << 211 { 237 G4cout << "Can't convert particle with << 212 G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S 238 << " to G4ParticleDefinition, t << 213 << " to G4ParticleDefinition, trouble ahead" << G4endl; 239 return 0; << 214 return 0; 240 } << 215 } 241 } << 216 } 242 << 217 else 243 G4ReactionProduct* << 218 { // Error, unrecognized particle 244 G4AblaInterface::toG4Particle(G4int A, G4i << 219 G4cout << "Can't convert particle with A=" << A << ", Z=" << Z << ", S=" << S 245 { << 220 << " to G4ParticleDefinition, trouble ahead" << G4endl; 246 G4ParticleDefinition* def = toG4ParticleDe << 221 return 0; 247 if (def == 0) << 222 } 248 { // Check if we have a valid particle def << 223 } 249 return 0; << 224 250 } << 225 G4ReactionProduct* G4AblaInterface::toG4Particle(G4int A, G4int Z, G4int S, 251 << 226 G4double kinE, G4double px, 252 const G4double energy = kinE * MeV; << 227 G4double py, G4double pz) const { 253 const G4ThreeVector momentum(px, py, pz); << 228 G4ParticleDefinition* def = toG4ParticleDefinition(A, Z, S); 254 const G4ThreeVector momentumDirection = mo << 229 if(def == 0) 255 G4DynamicParticle p(def, momentumDirection << 230 { // Check if we have a valid particle definition 256 G4ReactionProduct* r = new G4ReactionProdu << 231 return 0; 257 (*r) = p; << 232 } 258 return r; << 233 >> 234 const G4double energy = kinE * MeV; >> 235 const G4ThreeVector momentum(px, py, pz); >> 236 const G4ThreeVector momentumDirection = momentum.unit(); >> 237 G4DynamicParticle p(def, momentumDirection, energy); >> 238 G4ReactionProduct* r = new G4ReactionProduct(def); >> 239 (*r) = p; >> 240 return r; 259 } 241 } 260 242 261 void G4AblaInterface::ModelDescription(std::os 243 void G4AblaInterface::ModelDescription(std::ostream& outFile) const 262 { 244 { 263 outFile << "ABLA++ does not provide an imp << 245 outFile << "ABLA++ does not provide an implementation of the ApplyYourself method!\n\n"; 264 "method!\n\n"; << 265 } 246 } 266 247 267 void G4AblaInterface::DeExciteModelDescription 248 void G4AblaInterface::DeExciteModelDescription(std::ostream& outFile) const 268 { 249 { 269 outFile << "ABLA++ is a statistical model << 250 outFile 270 << "the gamma emission and the eva << 251 << "ABLA++ is a statistical model for nuclear de-excitation. It simulates\n" 271 << "particles and IMFs, as well as << 252 << "the gamma emission and the evaporation of neutrons, light charged\n" 272 << "included in Geant4 is a C++ tr << 253 << "particles and IMFs, as well as fission where applicable. The code\n" 273 << "code ABLA07. Although the mode << 254 << "included in Geant4 is a C++ translation of the original Fortran\n" 274 << "hypernuclei by including the e << 255 << "code ABLA07. Although the model has been recently extended to\n" 275 << "More details about the physics << 256 << "hypernuclei by including the evaporation of lambda particles.\n" 276 << "Physics Reference Manual and i << 257 << "More details about the physics are available in the Geant4\n" 277 << "References:\n" << 258 << "Physics Reference Manual and in the reference articles.\n\n" 278 << "(1) A. Kelic, M. V. Ricciardi, << 259 << "References:\n" 279 << "ICTP-IAEA Advanced Workshop on << 260 << "(1) A. Kelic, M. V. Ricciardi, and K. H. Schmidt, in Proceedings of " 280 << "ICTP Trieste, Italy, 4–8 Feb << 261 "Joint\n" 281 "Leray, Y. Yariv, A. Mengoni, A << 262 << "ICTP-IAEA Advanced Workshop on Model Codes for Spallation Reactions,\n" 282 "INDC(NDS)-530, Vienna, 2008), << 263 << "ICTP Trieste, Italy, 4–8 February 2008, edited by D. Filges, S. Leray, " 283 << "(2) J.L. Rodriguez-Sanchez, J. << 264 "Y. Yariv,\n" 284 << "(3) J.L. Rodriguez-Sanchez et << 265 << "A. Mengoni, A. Stanculescu, and G. Mank (IAEA INDC(NDS)-530, Vienna, " 285 << "(4) J.L. Rodriguez-Sanchez et << 266 "2008), pp. 181–221.\n\n" >> 267 << "(2) J.L. Rodriguez-Sanchez, J.-C. David et al., Phys. Rev. C 98, " >> 268 "021602 (2018)\n\n"; 286 } 269 } >> 270 287 271