Geant4 Cross Reference |
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 * ============================================================================ 28 * 29 * Filename: CexmcHadronicProcess.cc 30 * 31 * Description: hadronic process with production model 32 * 33 * Version: 1.0 34 * Created: 31.10.2009 23:54:38 35 * Revision: none 36 * Compiler: gcc 37 * 38 * Author: Alexey Radkov (), 39 * Company: PNPI 40 * 41 * ============================================================================ 42 */ 43 44 #include <G4ParticleChange.hh> 45 #include <G4ParticleDefinition.hh> 46 #include <G4HadronicInteraction.hh> 47 #include <G4Track.hh> 48 #include <G4Step.hh> 49 #include <G4Element.hh> 50 #include <G4StableIsotopes.hh> 51 #include <G4TrackStatus.hh> 52 #include "CexmcHadronicProcess.hh" 53 #include "CexmcProductionModel.hh" 54 #include "CexmcIncidentParticleTrackInfo.hh" 55 #include "CexmcException.hh" 56 57 58 CexmcHadronicProcess::CexmcHadronicProcess( const G4String & name ) : 59 G4HadronicProcess( name ), productionModel( NULL ), interaction( NULL ), 60 theTotalResult( NULL ), isInitialized( false ) 61 { 62 theTotalResult = new G4ParticleChange(); 63 SetIntegral(false); 64 } 65 66 67 CexmcHadronicProcess::~CexmcHadronicProcess() 68 { 69 delete theTotalResult; 70 } 71 72 73 void CexmcHadronicProcess::RegisterProductionModel( 74 CexmcProductionModel * model ) 75 { 76 productionModel = model; 77 78 interaction = dynamic_cast< G4HadronicInteraction * >( productionModel ); 79 80 if ( ! interaction ) 81 throw CexmcException( CexmcIncompatibleProductionModel ); 82 83 G4HadronicProcess::RegisterMe( interaction ); 84 } 85 86 87 void CexmcHadronicProcess::CalculateTargetNucleus( 88 const G4Material * material ) 89 { 90 G4int numberOfElements( material->GetNumberOfElements() ); 91 if ( numberOfElements > 1 ) 92 { 93 G4cout << CEXMC_LINE_START "WARNING: Number of elements in target " 94 "material is more than 1.\n Only the first " 95 "element will be chosen for target nucleus" << G4endl; 96 } 97 98 const G4Element * element( material->GetElement( 0 ) ); 99 G4double ZZ( element->GetZ() ); 100 G4int Z( G4int( ZZ + 0.5 ) ); 101 102 G4StableIsotopes stableIsotopes; 103 G4int index( stableIsotopes.GetFirstIsotope( Z ) ); 104 G4double AA( stableIsotopes.GetIsotopeNucleonCount( index ) ); 105 106 targetNucleus.SetParameters( AA, ZZ ); 107 } 108 109 110 void CexmcHadronicProcess::FillTotalResult( G4HadFinalState * hadFinalState, 111 const G4Track & track ) 112 { 113 G4int numberOfSecondaries( hadFinalState->GetNumberOfSecondaries() ); 114 115 theTotalResult->Clear(); 116 theTotalResult->Initialize( track ); 117 theTotalResult->SetSecondaryWeightByProcess( true ); 118 theTotalResult->ProposeLocalEnergyDeposit( 119 hadFinalState->GetLocalEnergyDeposit() ); 120 theTotalResult->SetNumberOfSecondaries( numberOfSecondaries ); 121 theTotalResult->ProposeEnergy( hadFinalState->GetEnergyChange() ); 122 theTotalResult->ProposeTrackStatus( fAlive ); 123 if ( hadFinalState->GetStatusChange() == stopAndKill ) 124 theTotalResult->ProposeTrackStatus( fStopAndKill ); 125 126 for ( G4int i( 0 ); i < numberOfSecondaries; ++i ) 127 { 128 G4double time( hadFinalState->GetSecondary( i )->GetTime() ); 129 if ( time < 0 ) 130 time = track.GetGlobalTime(); 131 132 G4Track * newTrack( new G4Track( 133 hadFinalState->GetSecondary( i )->GetParticle(), 134 time, track.GetPosition() ) ); 135 136 G4double newWeight( track.GetWeight() * 137 hadFinalState->GetSecondary( i )->GetWeight() ); 138 newTrack->SetWeight( newWeight ); 139 newTrack->SetTouchableHandle( track.GetTouchableHandle() ); 140 theTotalResult->AddSecondary( newTrack ); 141 } 142 143 hadFinalState->Clear(); 144 } 145 146 147 G4VParticleChange * CexmcHadronicProcess::PostStepDoIt( const G4Track & track, 148 const G4Step & ) 149 { 150 G4TrackStatus trackStatus( track.GetTrackStatus() ); 151 152 if ( trackStatus != fAlive && trackStatus != fSuspend ) 153 { 154 theTotalResult->Clear(); 155 theTotalResult->Initialize( track ); 156 157 return theTotalResult; 158 } 159 160 /* NB: the target nucleus is chosen only once, it means that it will always 161 * have same Z and A, practically the first stable isotope of the first 162 * element in elements vector will be chosen. This simplification prompts 163 * the user to choose simple single-element material for the target, for 164 * example liquid hydrogen. On the other hand target nucleus is supposedly 165 * only needed if user decides to turn Fermi motion on, so this 166 * simplification should not be very harmful */ 167 if ( ! isInitialized ) 168 { 169 CalculateTargetNucleus( track.GetMaterial() ); 170 isInitialized = true; 171 } 172 173 G4HadProjectile projectile( track ); 174 G4HadFinalState * result( interaction->ApplyYourself( projectile, 175 targetNucleus ) ); 176 FillTotalResult( result, track ); 177 178 if ( theTotalResult->GetTrackStatus() != fStopAndKill ) 179 { 180 CexmcTrackInfo * trackInfo( static_cast< CexmcTrackInfo * >( 181 track.GetUserInformation() ) ); 182 183 if ( trackInfo && 184 trackInfo->GetTypeInfo() == CexmcIncidentParticleTrackType ) 185 { 186 CexmcIncidentParticleTrackInfo * theTrackInfo( 187 static_cast< CexmcIncidentParticleTrackInfo * >( trackInfo ) ); 188 theTrackInfo->SetNeedsTrackLengthResampling(); 189 } 190 } 191 192 return theTotalResult; 193 } 194 195 196 G4bool CexmcHadronicProcess::IsApplicable( 197 const G4ParticleDefinition & particle ) 198 { 199 if ( ! productionModel ) 200 return false; 201 202 G4ParticleDefinition * incidentParticle( 203 productionModel->GetIncidentParticle() ); 204 205 if ( ! incidentParticle ) 206 return false; 207 208 return particle == *incidentParticle; 209 } 210 211