// // ******************************************************************** // * 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. * // * * // * Parts of this code which have been developed by QinetiQ Ltd * // * under contract to the European Space Agency (ESA) are the * // * intellectual property of ESA. Rights to use, copy, modify and * // * redistribute this software for general public use are granted * // * in compliance with any licensing, distribution and development * // * policy adopted by the Geant4 Collaboration. This code has been * // * written by QinetiQ Ltd for the European Space Agency, under ESA * // * contract 19770/06/NL/JD (Technology Research Programme). * // * * // * 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. * // ******************************************************************** // /// \file hadronic/Hadr02/src/G4DPMJET2_5CrossSection.cc /// \brief Implementation of the G4DPMJET2_5CrossSection class // // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // // MODULE: G4DPMJET2_5CrossSection.cc // // Version: 0.A // Date: 02/04/08 // Author: P R Truscott // Organisation: QinetiQ Ltd, UK // Customer: ESA/ESTEC, NOORDWIJK // Contract: 19770/06/NL/JD // // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /////////////////////////////////////////////////////////////////////////////// // #ifdef G4_USE_DPMJET #include "G4DPMJET2_5CrossSection.hh" #include "G4ParticleTable.hh" #include "G4DynamicParticle.hh" #include "G4IonTable.hh" #include "G4HadronicException.hh" #include "G4StableIsotopes.hh" #include "G4HadTmpUtil.hh" #include "globals.hh" #include #include #include #include "G4DynamicParticle.hh" using namespace std; /////////////////////////////////////////////////////////////////////////////// // G4DPMJET2_5CrossSection::G4DPMJET2_5CrossSection (): upperLimit ( 1000.0 * TeV ), lowerLimit ( 5.0 * GeV ), maxA(240) { theCrossSectionIndex.clear(); Initialise(); // // // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // This next bit is provisional, stating that this cross-section estimator // is applicable to hydrogen targets. However, the cross-section will be // set to zero. // ATmin = 1; // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // } /////////////////////////////////////////////////////////////////////////////// // G4DPMJET2_5CrossSection::~G4DPMJET2_5CrossSection () { // // Go through the list of cross-section fit parameters and delete the arrays. // G4cout << "G4DPMJET2_5CrossSection::~G4DPMJET2_5CrossSection" << G4endl; G4cout << "Size: " << theCrossSectionIndex.size() << G4endl; /* if(theCrossSectionIndex.size() > 0) { G4DPMJET2_5CrossSectionIndex::iterator it; for (it=theCrossSectionIndex.begin(); it!=theCrossSectionIndex.end(); ++it) { G4DPMJET2_5CrossSectionParamSet *ptr = it->second; for (G4DPMJET2_5CrossSectionParamSet *ptr1=ptr; ptr1GetNumberOfIsotopes(); G4bool result = true; if (nIso) { // // // Determine whether we have the necessary data loaded for the user-defined // cross-section. // G4IsotopeVector* isoVector = theTarget->GetIsotopeVector(); G4double ZZ = 0.0; G4double AA = 0.0; G4int i = 0; do { ZZ = G4double( (*isoVector)[i]->GetZ() ); AA = G4double( (*isoVector)[i]->GetN() ); result = IsZAApplicable(theProjectile, ZZ, AA); } while (result && ++i < nIso); } else { // // // Determine whether we have the necessary data loaded for the natural // abundance composition of the element. // G4int ZZ = G4lrint(theTarget->GetZ()); nIso = theDefaultIsotopes.GetNumberOfIsotopes(ZZ); G4int index = theDefaultIsotopes.GetFirstIsotope(ZZ); G4double AA = 0.0; G4int i = 0; do { AA = G4double( theDefaultIsotopes.GetIsotopeNucleonCount(index+i) ); result = IsZAApplicable(theProjectile, G4double(ZZ), AA); } while (result && ++i < nIso); } G4cout << "G4DPMJET2_5CrossSection::IsApplicable E(GeV)= " << theProjectile->GetKineticEnergy()/GeV << " off " << theTarget->GetName() << " - " << result << G4endl; return result; } /////////////////////////////////////////////////////////////////////////////// // G4bool G4DPMJET2_5CrossSection::IsZAApplicable (const G4DynamicParticle* theProjectile, G4double , G4double AA) { const G4int AT = G4lrint(AA); const G4int AP = G4lrint(theProjectile->GetDefinition()->GetBaryonNumber()); G4double EPN = theProjectile->GetKineticEnergy()/ theProjectile->GetDefinition()->GetBaryonNumber(); G4bool result = EPN >= lowerLimit && EPN <= upperLimit && AT >= ATmin && AT <= ATmax && AP >= APmin && AP <= APmax; return result; } /////////////////////////////////////////////////////////////////////////////// // G4double G4DPMJET2_5CrossSection::GetIsoZACrossSection (const G4DynamicParticle* theProjectile, G4double ZZ, G4double AA, G4double /*theTemperature*/) { // // Initialise the result. G4double result = 0.0; // // // Get details of the projectile and target (nucleon number, atomic number, // kinetic enery and energy/nucleon. // const G4int AT = G4lrint(AA); G4int AP = G4lrint(theProjectile->GetDefinition()->GetBaryonNumber()); const G4double TP = theProjectile->GetKineticEnergy(); G4double EPN = TP / AP; if (AT < ATmin || AT > ATmax || AP < APmin || AP > APmax || EPN < lowerLimit || EPN > upperLimit) { G4cout <GetIonTable() ->GetIonMass(static_cast(ZZ), static_cast(AT)); G4double EP = theProjectile->GetTotalEnergy(); G4double mP = EP - TP; G4double lnECM = std::log(std::sqrt(mP*mP + mT*mT + 2.0*mT*EP)); G4DPMJET2_5CrossSectionIndex::iterator it = theCrossSectionIndex.find(AT); if (it != theCrossSectionIndex.end()) { G4DPMJET2_5CrossSectionParamSet *ptr = (it->second) + AP; G4double cc0 = (*ptr)[0]; G4double cc1 = (*ptr)[1]; G4double cc2 = (*ptr)[2]; sigma = cc0 + cc1*lnECM + cc2*lnECM*lnECM; sigma = sigma * millibarn; if (verboseLevel >= 2) { G4cout <<"***************************************************************" <>APmin >>APmax >>ATmin >>ATmax; // // // Determine the list of targets based on the G4ElementList. The list of // target nucleon numbers is stored as a ket to the map theCrossSectionIndex. // G4double[240][3] array objects are created to allow storage of the // cross-section fit parameters. // const G4ElementTable *theElementTable = G4Element::GetElementTable(); G4ElementTable::const_iterator it; for (it=theElementTable->begin(); it!=theElementTable->end(); it++) { G4int nIso = (*it)->GetNumberOfIsotopes(); if (nIso) { // // // The user has defined her own isotopes associated with this element. Read // the nucleon numbers. // G4IsotopeVector* isoVector = (*it)->GetIsotopeVector(); for (G4int i = 0; i < nIso; i++) { G4int AA = (*isoVector)[i]->GetN(); if (theCrossSectionIndex.count(AA) == 0 && AA >= ATmin && AA <= ATmax) { // // // Whilst the use of std::map should eliminate duplication of keys, we need to // know whether isotope's with the same nucleon number have been declared before // creating the large arrays, hence the use of the "count" member function. // G4DPMJET2_5CrossSectionParamSet *a = new G4DPMJET2_5CrossSectionParamSet[maxA]; theCrossSectionIndex.insert( G4DPMJET2_5CrossSectionIndex::value_type(AA,a)); } } } else { // // // Determine the natural isotopic abundances for this element. // G4int ZZ = G4lrint((*it)->GetZ()); nIso = theDefaultIsotopes.GetNumberOfIsotopes(ZZ); G4int index = theDefaultIsotopes.GetFirstIsotope(ZZ); G4int AA = 0; for (G4int i = 0; i < nIso; i++) { AA = theDefaultIsotopes.GetIsotopeNucleonCount(index+i); if (theCrossSectionIndex.count(AA) == 0 && AA >= ATmin && AA <= ATmax) { G4DPMJET2_5CrossSectionParamSet *a = new G4DPMJET2_5CrossSectionParamSet[maxA]; theCrossSectionIndex.insert( G4DPMJET2_5CrossSectionIndex::value_type(AA,a)); } } } } // // // Now proceed to read in the remainder of the GlauberCrossSection.dat file, // loading into theCrossSectionIndex any relevant fitting parameters to the // target nuclei. // char inputChars[80]={' '}; G4String inputLine; while (-glauberXSFile.getline(inputChars, 80).eof() != EOF) { inputLine = inputChars; if (inputLine.length() != 0) { std::istringstream tmpStream(inputLine); G4int AP, AT; G4double cc0, cc1, cc2; tmpStream >>AP >>AT >>cc0 >>cc1 >>cc2; G4DPMJET2_5CrossSectionIndex::iterator it = theCrossSectionIndex.find(AT); if (it != theCrossSectionIndex.end()) { G4DPMJET2_5CrossSectionParamSet *ptr = (it->second) + AP; *ptr = G4DPMJET2_5CrossSectionParamSet(cc0,cc1,cc2); } } } glauberXSFile.close(); G4cout << "G4DPMJET2_5CrossSection::Initialise () done!" << G4endl; } else { G4cout <<"GlauberCrossSections.dat DOES NOT EXIST" <first; G4cout.unsetf(std::ios::fixed); G4cout.setf(std::ios::scientific|std::ios::right|std::ios::adjustfield); G4cout.precision(7); G4DPMJET2_5CrossSectionParamSet *ptr = (it->second) + AP; G4cout <