Changeset 962 for trunk/source/processes/hadronic/models/rpg
- Timestamp:
- Apr 6, 2009, 12:30:29 PM (17 years ago)
- Location:
- trunk/source/processes/hadronic/models/rpg
- Files:
-
- 60 edited
-
History (modified) (1 diff)
-
include/G4RPGAntiKZeroInelastic.hh (modified) (1 diff)
-
include/G4RPGAntiLambdaInelastic.hh (modified) (1 diff)
-
include/G4RPGAntiNeutronInelastic.hh (modified) (1 diff)
-
include/G4RPGAntiOmegaMinusInelastic.hh (modified) (1 diff)
-
include/G4RPGAntiProtonInelastic.hh (modified) (1 diff)
-
include/G4RPGAntiSigmaMinusInelastic.hh (modified) (1 diff)
-
include/G4RPGAntiSigmaPlusInelastic.hh (modified) (1 diff)
-
include/G4RPGAntiXiMinusInelastic.hh (modified) (1 diff)
-
include/G4RPGAntiXiZeroInelastic.hh (modified) (1 diff)
-
include/G4RPGFragmentation.hh (modified) (2 diffs)
-
include/G4RPGInelastic.hh (modified) (5 diffs)
-
include/G4RPGKLongInelastic.hh (modified) (1 diff)
-
include/G4RPGKMinusInelastic.hh (modified) (1 diff)
-
include/G4RPGKPlusInelastic.hh (modified) (1 diff)
-
include/G4RPGKShortInelastic.hh (modified) (1 diff)
-
include/G4RPGKZeroInelastic.hh (modified) (1 diff)
-
include/G4RPGLambdaInelastic.hh (modified) (1 diff)
-
include/G4RPGNeutronInelastic.hh (modified) (3 diffs)
-
include/G4RPGOmegaMinusInelastic.hh (modified) (1 diff)
-
include/G4RPGPiMinusInelastic.hh (modified) (1 diff)
-
include/G4RPGPiPlusInelastic.hh (modified) (2 diffs)
-
include/G4RPGPionSuppression.hh (modified) (1 diff)
-
include/G4RPGProtonInelastic.hh (modified) (2 diffs)
-
include/G4RPGReaction.hh (modified) (3 diffs)
-
include/G4RPGSigmaMinusInelastic.hh (modified) (1 diff)
-
include/G4RPGSigmaPlusInelastic.hh (modified) (1 diff)
-
include/G4RPGStrangeProduction.hh (modified) (1 diff)
-
include/G4RPGTwoBody.hh (modified) (1 diff)
-
include/G4RPGTwoCluster.hh (modified) (1 diff)
-
include/G4RPGXiMinusInelastic.hh (modified) (1 diff)
-
include/G4RPGXiZeroInelastic.hh (modified) (1 diff)
-
src/G4RPGAntiKZeroInelastic.cc (modified) (1 diff)
-
src/G4RPGAntiLambdaInelastic.cc (modified) (1 diff)
-
src/G4RPGAntiNeutronInelastic.cc (modified) (1 diff)
-
src/G4RPGAntiOmegaMinusInelastic.cc (modified) (1 diff)
-
src/G4RPGAntiProtonInelastic.cc (modified) (1 diff)
-
src/G4RPGAntiSigmaMinusInelastic.cc (modified) (1 diff)
-
src/G4RPGAntiSigmaPlusInelastic.cc (modified) (1 diff)
-
src/G4RPGAntiXiMinusInelastic.cc (modified) (1 diff)
-
src/G4RPGAntiXiZeroInelastic.cc (modified) (1 diff)
-
src/G4RPGFragmentation.cc (modified) (6 diffs)
-
src/G4RPGInelastic.cc (modified) (12 diffs)
-
src/G4RPGKMinusInelastic.cc (modified) (1 diff)
-
src/G4RPGKPlusInelastic.cc (modified) (1 diff)
-
src/G4RPGKZeroInelastic.cc (modified) (1 diff)
-
src/G4RPGLambdaInelastic.cc (modified) (1 diff)
-
src/G4RPGNeutronInelastic.cc (modified) (1 diff)
-
src/G4RPGOmegaMinusInelastic.cc (modified) (1 diff)
-
src/G4RPGPiMinusInelastic.cc (modified) (8 diffs)
-
src/G4RPGPiPlusInelastic.cc (modified) (4 diffs)
-
src/G4RPGPionSuppression.cc (modified) (1 diff)
-
src/G4RPGProtonInelastic.cc (modified) (10 diffs)
-
src/G4RPGReaction.cc (modified) (7 diffs)
-
src/G4RPGSigmaMinusInelastic.cc (modified) (1 diff)
-
src/G4RPGSigmaPlusInelastic.cc (modified) (1 diff)
-
src/G4RPGStrangeProduction.cc (modified) (1 diff)
-
src/G4RPGTwoBody.cc (modified) (4 diffs)
-
src/G4RPGTwoCluster.cc (modified) (8 diffs)
-
src/G4RPGXiMinusInelastic.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/hadronic/models/rpg/History
r819 r962 14 14 * Please list in reverse chronological order (last date on top) 15 15 --------------------------------------------------------------- 16 17 9 June 2008 - Dennis Wright (hadr-rpg-V09-01-03) 18 ------------------------------------------------- 19 Remove unused variable ekIncident in G4RPGFragmentation.cc and 20 G4RPGTwoCluster.cc 21 22 5 May 2008 - Dennis Wright (hadr-rpg-V09-01-02) 23 ------------------------------------------------ 24 Fixed gcc-4.3 compiler warnings for unused variables in 25 G4RPGNeutronInelastic.hh, cc 26 G4RPGPiMinusInelastic.hh, cc 27 G4RPGPiPlusInelastic.hh, cc 28 G4RPGProtonInelastic.hh, cc 29 G4RPGReaction.hh, cc 30 G4RPGFragmentation.cc 31 G4RPGTwoBody.cc 32 G4RPGTwoCluster.cc 33 34 21 March 2008 - Dennis Wright (hadr-rpg-V09-01-01) 35 -------------------------------------------------- 36 Fixed gcc-4.3 compiler warning in G4RPGInelastic.cc 37 38 21 February 2008 - Dennis Wright (hadr-rpg-V09-01-00) 39 ----------------------------------------------------- 40 G4RPGInelastic: remove Rotate method, fix K0 ID problem 41 G4RPGFragmentation: fix energy non-conservation 42 G4RPGReaction.cc: add GenerateNBodyEventT method, fix energy non-conservation 43 in AddBlackTrackParticles 44 G4RPGProtonInelastic.cc, G4RPGNeutronInelastic.cc, G4RPGPiPlusInelastic.cc, 45 G4RPGPiMinusInelastic.cc: remove quasi-elastic flag, remove MeV units 46 16 47 17 48 5 December 2007 - Dennis Wright (hadr-rpg-V09-00-02) -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiKZeroInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiKZeroInelastic.hh,v 1.1 2007/07/18 20:51:36 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiLambdaInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiLambdaInelastic.hh,v 1.1 2007/07/18 20:51:36 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiNeutronInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiNeutronInelastic.hh,v 1.1 2007/07/18 20:51:36 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiOmegaMinusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiOmegaMinusInelastic.hh,v 1.1 2007/07/18 20:51:36 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiProtonInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiProtonInelastic.hh,v 1.1 2007/07/18 20:51:36 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiSigmaMinusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiSigmaMinusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiSigmaPlusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiSigmaPlusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiXiMinusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiXiMinusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGAntiXiZeroInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiXiZeroInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // -
trunk/source/processes/hadronic/models/rpg/include/G4RPGFragmentation.hh
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGFragmentation.hh,v 1. 1 2007/07/18 20:51:37dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGFragmentation.hh,v 1.2 2008/02/22 22:02:13 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D.H. Wright … … 73 73 private: 74 74 75 void 76 ReduceEnergiesOfSecondaries(G4int /*startingIndex*/, 77 G4double& /*forwardKinetic*/, 78 G4double& /*backwardKinetic*/, 79 G4FastVector<G4ReactionProduct,256>& /*vec*/, 80 G4int& /*vecLen*/, 81 G4ReactionProduct& /*forwardPseudoParticle*/, 82 G4ReactionProduct& /*backwardPseudoParticle*/, 83 G4double& /*pt*/); 84 75 85 G4double dndl[20]; 76 86 }; -
trunk/source/processes/hadronic/models/rpg/include/G4RPGInelastic.hh
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGInelastic.hh,v 1. 1 2007/07/18 20:51:37dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGInelastic.hh,v 1.3 2008/02/22 22:17:25 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright … … 39 39 40 40 #include "globals.hh" 41 #include <vector> 41 42 #include "G4FastVector.hh" 42 43 #include "G4HadronicInteraction.hh" … … 76 77 G4int &vecLen); 77 78 78 void Rotate(G4FastVector<G4ReactionProduct,256> &vec, G4int &vecLen);79 // void Rotate(G4FastVector<G4ReactionProduct,256> &vec, G4int &vecLen); 79 80 80 81 void GetNormalizationConstant(const G4double availableEnergy, … … 110 111 G4RPGTwoBody twoBody; 111 112 113 std::pair<G4int, G4double> interpolateEnergy(G4double ke) const; 114 115 G4int sampleFlat(std::vector<G4double> sigma) const; 116 117 void CheckQnums(G4FastVector<G4ReactionProduct,256> &vec, 118 G4int &vecLen, 119 G4ReactionProduct ¤tParticle, 120 G4ReactionProduct &targetParticle, 121 G4double Q, G4double B, G4double S); 122 123 enum {pi0, pip, pim, kp, km, k0, k0b, pro, neu, 124 lam, sp, s0, sm, xi0, xim, om, ap, an}; 125 126 static G4ParticleDefinition* particleDef[18]; 127 112 128 private: 113 129 … … 115 131 G4ThreeVector what; 116 132 133 static const G4double energyScale[30]; 134 117 135 }; 118 136 119 137 #endif 120 -
trunk/source/processes/hadronic/models/rpg/include/G4RPGKLongInelastic.hh
r819 r962 26 26 // 27 27 // $Id: G4RPGKLongInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 28 // GEANT4 tag $Name: $28 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 29 29 // 30 30 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGKMinusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGKMinusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/include/G4RPGKPlusInelastic.hh
r819 r962 26 26 // 27 27 // $Id: G4RPGKPlusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 28 // GEANT4 tag $Name: $28 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 29 29 // 30 30 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGKShortInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGKShortInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGKZeroInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGKZeroInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGLambdaInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGLambdaInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGNeutronInelastic.hh
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGNeutronInelastic.hh,v 1. 1 2007/07/18 20:51:37dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGNeutronInelastic.hh,v 1.3 2008/05/05 21:21:54 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright 30 // Date: 18 June200730 // Date: 28 December 2007 31 31 // 32 32 33 33 // Class Description: 34 //35 34 // Final state production model for neutron inelastic scattering 36 // using the re-parameterized Gheisha model .35 // using the re-parameterized Gheisha model 37 36 38 37 #ifndef G4RPGNeutronInelastic_h … … 40 39 41 40 42 #include "G4RPG Inelastic.hh"41 #include "G4RPGNucleonInelastic.hh" 43 42 44 43 45 class G4RPGNeutronInelastic : public G4RPG Inelastic44 class G4RPGNeutronInelastic : public G4RPGNucleonInelastic 46 45 { 47 public: // with description46 public: 48 47 49 G4RPGNeutronInelastic() : G4RPGInelastic("G4RPGNeutronInelastic") 50 { 51 SetMinEnergy(0.0); 52 SetMaxEnergy(35.*GeV); 53 } 48 G4RPGNeutronInelastic() : G4RPGNucleonInelastic("RPGNeutronInelastic") 49 {} 54 50 55 51 ~G4RPGNeutronInelastic() 56 { }52 {} 57 53 58 54 G4HadFinalState* ApplyYourself(const G4HadProjectile& aTrack, … … 60 56 61 57 private: 62 63 void Cascade(64 G4FastVector<G4ReactionProduct, GHADLISTSIZE> &vec,58 59 void InitialCollision( 60 G4FastVector<G4ReactionProduct,256>& vec, 65 61 G4int& vecLen, 66 const G4HadProjectile* originalIncident,67 62 G4ReactionProduct& currentParticle, 68 63 G4ReactionProduct& targetParticle, 69 G4bool& incidentHasChanged, 70 G4bool& targetHasChanged, 71 G4bool& quasiElastic); 64 G4bool& incidentHasChanged, 65 G4bool& targetHasChanged); 72 66 73 67 void SlowNeutron( -
trunk/source/processes/hadronic/models/rpg/include/G4RPGOmegaMinusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGOmegaMinusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGPiMinusInelastic.hh
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGPiMinusInelastic.hh,v 1. 1 2007/07/18 20:51:37dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGPiMinusInelastic.hh,v 1.3 2008/05/05 21:21:54 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 // Author: D. H. Wright30 // Date: 2 6 May200729 // Author: D. H. Wright 30 // Date: 23 November 2007 31 31 // 32 32 33 33 #ifndef G4RPGPiMinusInelastic_h 34 34 #define G4RPGPiMinusInelastic_h 1 35 35 36 // Class Description 36 // Class Description: 37 37 // Final state production model for pi- inelastic scattering 38 // using the re-parameterized Gheisha model .38 // using the re-parameterized Gheisha model 39 39 40 #include "G4RPG Inelastic.hh"40 #include "G4RPGPionInelastic.hh" 41 41 42 class G4RPGPiMinusInelastic : public G4RPG Inelastic42 class G4RPGPiMinusInelastic : public G4RPGPionInelastic 43 43 { 44 44 public: 45 45 46 G4RPGPiMinusInelastic() : G4RPGInelastic("G4RPGPiMinusInelastic") 47 { 48 SetMinEnergy( 0.0 ); 49 SetMaxEnergy( 55.*GeV ); 50 } 46 G4RPGPiMinusInelastic() : G4RPGPionInelastic("RPGPiMinusInelastic") 47 {} 51 48 52 ~G4RPGPiMinusInelastic() { } 49 ~G4RPGPiMinusInelastic() 50 {} 53 51 54 G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack,55 G4Nucleus &targetNucleus);52 G4HadFinalState* ApplyYourself(const G4HadProjectile& aTrack, 53 G4Nucleus& targetNucleus); 56 54 57 55 private: 58 56 59 void Cascade( // derived from CASPIM 60 G4FastVector<G4ReactionProduct,256> &vec, 61 G4int &vecLen, 62 const G4HadProjectile *originalIncident, 63 G4ReactionProduct ¤tParticle, 64 G4ReactionProduct &targetParticle, 65 G4bool &incidentHasChanged, 66 G4bool &targetHasChanged, 67 G4bool &quasiElastic ); 68 57 void InitialCollision( 58 G4FastVector<G4ReactionProduct,256>& vec, 59 G4int& vecLen, 60 G4ReactionProduct& currentParticle, 61 G4ReactionProduct& targetParticle, 62 G4bool& incidentHasChanged, 63 G4bool& targetHasChanged); 64 69 65 }; 70 71 66 #endif 72 67 -
trunk/source/processes/hadronic/models/rpg/include/G4RPGPiPlusInelastic.hh
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGPiPlusInelastic.hh,v 1. 1 2007/07/18 20:51:37dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGPiPlusInelastic.hh,v 1.3 2008/05/05 21:21:54 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright … … 38 38 // using the re-parameterized Gheisha model 39 39 40 #include "G4RPG Inelastic.hh"40 #include "G4RPGPionInelastic.hh" 41 41 42 class G4RPGPiPlusInelastic : public G4RPG Inelastic42 class G4RPGPiPlusInelastic : public G4RPGPionInelastic 43 43 { 44 44 public: 45 45 46 G4RPGPiPlusInelastic() : G4RPGInelastic("G4RPGPiPlusInelastic") 47 { 48 SetMinEnergy( 0.0 ); 49 SetMaxEnergy( 55.*GeV ); 50 } 46 G4RPGPiPlusInelastic() : G4RPGPionInelastic("RPGPiPlusInelastic") 47 {} 51 48 52 ~G4RPGPiPlusInelastic() { } 49 ~G4RPGPiPlusInelastic() 50 {} 53 51 54 G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack,55 G4Nucleus &targetNucleus);52 G4HadFinalState* ApplyYourself(const G4HadProjectile& aTrack, 53 G4Nucleus& targetNucleus); 56 54 57 55 private: 58 56 59 void Cascade( // derived from CASPIP 60 G4FastVector<G4ReactionProduct,256> &vec, 61 G4int &vecLen, 62 const G4HadProjectile *originalIncident, 63 G4ReactionProduct ¤tParticle, 64 G4ReactionProduct &targetParticle, 65 G4bool &incidentHasChanged, 66 G4bool &targetHasChanged, 67 G4bool &quasiElastic ); 68 57 void InitialCollision( 58 G4FastVector<G4ReactionProduct,256>& vec, 59 G4int& vecLen, 60 G4ReactionProduct& currentParticle, 61 G4ReactionProduct& targetParticle, 62 G4bool& incidentHasChanged, 63 G4bool& targetHasChanged); 64 69 65 }; 70 66 #endif -
trunk/source/processes/hadronic/models/rpg/include/G4RPGPionSuppression.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGPionSuppression.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D.H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGProtonInelastic.hh
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGProtonInelastic.hh,v 1. 1 2007/07/18 20:51:37dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGProtonInelastic.hh,v 1.3 2008/05/05 21:21:54 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright 30 // Date: 2 6 May200730 // Date: 28 December 2007 31 31 // 32 32 33 33 // Class Description: 34 //35 34 // Final state production model for proton inelastic scattering 36 // using the re-parameterized Gheisha model .35 // using the re-parameterized Gheisha model 37 36 38 37 #ifndef G4RPGProtonInelastic_h … … 40 39 41 40 42 #include "G4RPG Inelastic.hh"41 #include "G4RPGNucleonInelastic.hh" 43 42 44 43 45 class G4RPGProtonInelastic : public G4RPG Inelastic44 class G4RPGProtonInelastic : public G4RPGNucleonInelastic 46 45 { 47 public: // with description46 public: 48 47 49 G4RPGProtonInelastic() : G4RPGInelastic("G4RPGProtonInelastic") 50 { 51 SetMinEnergy(0.0); 52 SetMaxEnergy(35.*GeV); 53 } 48 G4RPGProtonInelastic() : G4RPGNucleonInelastic("RPGProtonInelastic") 49 {} 54 50 55 51 ~G4RPGProtonInelastic() 56 { }52 {} 57 53 58 G4HadFinalState * ApplyYourself(const G4HadProjectile& aTrack,59 G4Nucleus& targetNucleus);54 G4HadFinalState* ApplyYourself(const G4HadProjectile& aTrack, 55 G4Nucleus& targetNucleus); 60 56 61 57 private: 62 58 63 void Cascade(G4FastVector<G4ReactionProduct,GHADLISTSIZE> &vec, 64 G4int& vecLen, 65 const G4HadProjectile* originalIncident, 66 G4ReactionProduct& currentParticle, 67 G4ReactionProduct& targetParticle, 68 G4bool& incidentHasChanged, 69 G4bool& targetHasChanged, 70 G4bool& quasiElastic); 59 void InitialCollision( 60 G4FastVector<G4ReactionProduct,256>& vec, 61 G4int& vecLen, 62 G4ReactionProduct& currentParticle, 63 G4ReactionProduct& targetParticle, 64 G4bool& incidentHasChanged, 65 G4bool& targetHasChanged); 71 66 72 67 void SlowProton(const G4HadProjectile* originalIncident, -
trunk/source/processes/hadronic/models/rpg/include/G4RPGReaction.hh
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGReaction.hh,v 1. 1 2007/07/18 20:51:37dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGReaction.hh,v 1.3 2008/05/05 21:21:54 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright … … 72 72 const G4double /*edta*/, 73 73 const G4int /*ndta*/, 74 const G4double /*sprob*/,75 const G4double /*kineticMinimum*/,76 const G4double /*kineticFactor*/,77 74 const G4ReactionProduct& /*modifiedOriginal*/, 78 75 G4int /*PinNucleus*/, … … 87 84 G4FastVector<G4ReactionProduct,256> &vec, 88 85 G4int& vecLen); 86 87 G4double GenerateNBodyEventT(const G4double totalEnergy, 88 const G4bool constantCrossSection, 89 std::vector<G4ReactionProduct*>& list); 89 90 90 91 void NuclearReaction(G4FastVector<G4ReactionProduct,4> &vec, -
trunk/source/processes/hadronic/models/rpg/include/G4RPGSigmaMinusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGSigmaMinusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGSigmaPlusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGSigmaPlusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGStrangeProduction.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGStrangeProduction.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D.H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGTwoBody.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGTwoBody.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D.H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGTwoCluster.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGTwoCluster.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D.H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGXiMinusInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGXiMinusInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // Author: D. H. Wright -
trunk/source/processes/hadronic/models/rpg/include/G4RPGXiZeroInelastic.hh
r819 r962 25 25 // 26 26 // $Id: G4RPGXiZeroInelastic.hh,v 1.1 2007/07/18 20:51:37 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiKZeroInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiKZeroInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiLambdaInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiLambdaInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiNeutronInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiNeutronInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiOmegaMinusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiOmegaMinusInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiProtonInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiProtonInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiSigmaMinusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiSigmaMinusInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiSigmaPlusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiSigmaPlusInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiXiMinusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiXiMinusInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // -
trunk/source/processes/hadronic/models/rpg/src/G4RPGAntiXiZeroInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGAntiXiZeroInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 // -
trunk/source/processes/hadronic/models/rpg/src/G4RPGFragmentation.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGFragmentation.cc,v 1. 3 2007/12/06 01:13:14dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGFragmentation.cc,v 1.6 2008/06/09 18:13:16 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 … … 76 76 { 77 77 // 78 // Derived fromH. Fesefeldt's original FORTRAN code GENXPT78 // Based on H. Fesefeldt's original FORTRAN code GENXPT 79 79 // 80 80 // Generation of x- and pT- values for incident, target, and all secondary … … 89 89 // two-body scattering 90 90 // 91 if(vecLen == 0) return false; 92 93 G4ParticleDefinition *aPiMinus = G4PionMinus::PionMinus(); 94 G4ParticleDefinition *aProton = G4Proton::Proton(); 95 G4ParticleDefinition *aNeutron = G4Neutron::Neutron(); 96 G4ParticleDefinition *aPiPlus = G4PionPlus::PionPlus(); 97 G4ParticleDefinition *aPiZero = G4PionZero::PionZero(); 98 99 G4int i, l; 100 G4bool veryForward = false; 101 102 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/GeV; 103 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/GeV; 104 const G4double mOriginal = modifiedOriginal.GetMass()/GeV; 105 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/GeV; 106 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/GeV; 107 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal + 108 targetMass*targetMass + 109 2.0*targetMass*etOriginal ); // GeV 110 G4double currentMass = currentParticle.GetMass()/GeV; 91 if (vecLen == 0) return false; 92 93 G4ParticleDefinition* aPiMinus = G4PionMinus::PionMinus(); 94 G4ParticleDefinition* aProton = G4Proton::Proton(); 95 G4ParticleDefinition* aNeutron = G4Neutron::Neutron(); 96 G4ParticleDefinition* aPiPlus = G4PionPlus::PionPlus(); 97 G4ParticleDefinition* aPiZero = G4PionZero::PionZero(); 98 99 G4int i, l; 100 G4bool veryForward = false; 101 102 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/GeV; 103 const G4double etOriginal = modifiedOriginal.GetTotalEnergy()/GeV; 104 const G4double mOriginal = modifiedOriginal.GetMass()/GeV; 105 const G4double pOriginal = modifiedOriginal.GetMomentum().mag()/GeV; 106 G4double targetMass = targetParticle.GetDefinition()->GetPDGMass()/GeV; 107 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal + 108 targetMass*targetMass + 109 2.0*targetMass*etOriginal ); // GeV 110 G4double currentMass = currentParticle.GetMass()/GeV; 111 targetMass = targetParticle.GetMass()/GeV; 112 113 // Randomize the order of the secondary particles. 114 // Note that the current and target particles are not affected. 115 116 for (i=0; i<vecLen; ++i) { 117 G4int itemp = G4int( G4UniformRand()*vecLen ); 118 G4ReactionProduct pTemp = *vec[itemp]; 119 *vec[itemp] = *vec[i]; 120 *vec[i] = pTemp; 121 } 122 123 if (currentMass == 0.0 && targetMass == 0.0) { 124 // Target and projectile have annihilated. Replace them with the first 125 // two secondaries in the list. Current particle KE is maintained. 126 127 G4double ek = currentParticle.GetKineticEnergy(); 128 G4ThreeVector m = currentParticle.GetMomentum(); 129 currentParticle = *vec[0]; 130 currentParticle.SetSide(1); 131 targetParticle = *vec[1]; 132 targetParticle.SetSide(-1); 133 for( i=0; i<(vecLen-2); ++i )*vec[i] = *vec[i+2]; 134 G4ReactionProduct *temp = vec[vecLen-1]; 135 delete temp; 136 temp = vec[vecLen-2]; 137 delete temp; 138 vecLen -= 2; 139 currentMass = currentParticle.GetMass()/GeV; 111 140 targetMass = targetParticle.GetMass()/GeV; 141 incidentHasChanged = true; 142 targetHasChanged = true; 143 currentParticle.SetKineticEnergy( ek ); 144 currentParticle.SetMomentum( m ); 145 veryForward = true; 146 } 147 const G4double atomicWeight = targetNucleus.GetN(); 148 const G4double atomicNumber = targetNucleus.GetZ(); 149 const G4double protonMass = aProton->GetPDGMass(); 150 151 if (originalIncident->GetDefinition()->GetParticleSubType() == "kaon" 152 && G4UniformRand() >= 0.7) { 153 G4ReactionProduct temp = currentParticle; 154 currentParticle = targetParticle; 155 targetParticle = temp; 156 incidentHasChanged = true; 157 targetHasChanged = true; 158 currentMass = currentParticle.GetMass()/GeV; 159 targetMass = targetParticle.GetMass()/GeV; 160 } 161 const G4double afc = std::min( 0.75, 162 0.312+0.200*std::log(std::log(centerofmassEnergy*centerofmassEnergy))+ 163 std::pow(centerofmassEnergy*centerofmassEnergy,1.5)/6000.0 ); 164 165 G4double freeEnergy = centerofmassEnergy-currentMass-targetMass; 166 G4double forwardEnergy = freeEnergy/2.; 167 G4int forwardCount = 1; // number of particles in forward hemisphere 168 169 G4double backwardEnergy = freeEnergy/2.; 170 G4int backwardCount = 1; // number of particles in backward hemisphere 171 172 if(veryForward) { 173 if(currentParticle.GetSide()==-1) 174 { 175 forwardEnergy += currentMass; 176 forwardCount --; 177 backwardEnergy -= currentMass; 178 backwardCount ++; 179 } 180 if(targetParticle.GetSide()!=-1) 181 { 182 backwardEnergy += targetMass; 183 backwardCount --; 184 forwardEnergy -= targetMass; 185 forwardCount ++; 186 } 187 } 188 189 for (i=0; i<vecLen; ++i) { 190 if( vec[i]->GetSide() == -1 ) 191 { 192 ++backwardCount; 193 backwardEnergy -= vec[i]->GetMass()/GeV; 194 } else { 195 ++forwardCount; 196 forwardEnergy -= vec[i]->GetMass()/GeV; 197 } 198 } 199 200 // Check that sum of forward particle masses does not exceed forwardEnergy, 201 // and similarly for backward particles. If so, move particles from one 202 // hemisphere to another. 203 204 if (backwardEnergy < 0.0) { 205 for (i = 0; i < vecLen; ++i) { 206 if (vec[i]->GetSide() == -1) { 207 backwardEnergy += vec[i]->GetMass()/GeV; 208 --backwardCount; 209 vec[i]->SetSide(1); 210 forwardEnergy -= vec[i]->GetMass()/GeV; 211 ++forwardCount; 212 if (backwardEnergy > 0.0) break; 213 } 214 } 215 } 216 217 if (forwardEnergy < 0.0) { 218 for (i = 0; i < vecLen; ++i) { 219 if (vec[i]->GetSide() == 1) { 220 forwardEnergy += vec[i]->GetMass()/GeV; 221 --forwardCount; 222 vec[i]->SetSide(-1); 223 backwardEnergy -= vec[i]->GetMass()/GeV; 224 ++backwardCount; 225 if (forwardEnergy > 0.0) break; 226 } 227 } 228 } 229 230 // Special cases for reactions near threshold 231 232 // 1. There is only one secondary 233 if (forwardEnergy > 0.0 && backwardEnergy < 0.0) { 234 forwardEnergy += backwardEnergy; 235 backwardEnergy = 0; 236 } 237 238 // 2. Nuclear binding energy is large 239 if (forwardEnergy + backwardEnergy < 0.0) return false; 240 241 242 // forwardEnergy now represents the total energy in the forward reaction 243 // hemisphere which is available for kinetic energy and particle creation. 244 // Similarly for backwardEnergy. 245 246 // Add particles from the intranuclear cascade. 247 // nuclearExcitationCount = number of new secondaries produced by nuclear 248 // excitation 249 // extraCount = number of nucleons within these new secondaries 250 // 251 // Note: eventually have to make sure that enough nucleons are available 252 // in the case of small target nuclei 253 254 G4double xtarg; 255 if( centerofmassEnergy < (2.0+G4UniformRand()) ) 256 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount+vecLen+2)/2.0; 257 else 258 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount); 259 if( xtarg <= 0.0 )xtarg = 0.01; 260 G4int nuclearExcitationCount = G4Poisson( xtarg ); 261 // To do: try reducing nuclearExcitationCount with increasing energy 262 // to simulate cut-off of cascade 263 if(atomicWeight<1.0001) nuclearExcitationCount = 0; 264 G4int extraNucleonCount = 0; 265 G4double extraNucleonMass = 0.0; 266 267 if (nuclearExcitationCount > 0) { 268 const G4double nucsup[] = { 1.00, 0.7, 0.5, 0.4, 0.35, 0.3 }; 269 const G4double psup[] = { 3., 6., 20., 50., 100., 1000. }; 270 G4int momentumBin = 0; 271 while( (momentumBin < 6) && 272 (modifiedOriginal.GetTotalMomentum()/GeV > psup[momentumBin]) ) 273 ++momentumBin; 274 momentumBin = std::min( 5, momentumBin ); 275 276 // NOTE: in GENXPT, these new particles were given negative codes 277 // here I use NewlyAdded = true instead 112 278 // 113 // randomize the order of the secondary particles 114 // note that the current and target particles are not affected 279 280 for (i = 0; i < nuclearExcitationCount; ++i) { 281 G4ReactionProduct * pVec = new G4ReactionProduct(); 282 if (G4UniformRand() < nucsup[momentumBin]) { 283 284 if (G4UniformRand() > 1.0-atomicNumber/atomicWeight) 285 pVec->SetDefinition( aProton ); 286 else 287 pVec->SetDefinition( aNeutron ); 288 289 // nucleon comes from nucleus - 290 // do not subtract its mass from backward energy 291 pVec->SetSide( -2 ); // -2 means backside nucleon 292 ++extraNucleonCount; 293 extraNucleonMass += pVec->GetMass()/GeV; 294 // To do: Remove chosen nucleon from target nucleus 295 pVec->SetNewlyAdded( true ); 296 vec.SetElement( vecLen++, pVec ); 297 ++backwardCount; 298 299 } else { 300 301 G4double ran = G4UniformRand(); 302 if( ran < 0.3181 ) 303 pVec->SetDefinition( aPiPlus ); 304 else if( ran < 0.6819 ) 305 pVec->SetDefinition( aPiZero ); 306 else 307 pVec->SetDefinition( aPiMinus ); 308 309 if (backwardEnergy > pVec->GetMass()/GeV) { 310 backwardEnergy -= pVec->GetMass()/GeV; // pion mass comes from free energy 311 ++backwardCount; 312 pVec->SetSide( -1 ); // backside particle, but not a nucleon 313 pVec->SetNewlyAdded( true ); 314 vec.SetElement( vecLen++, pVec ); 315 } 316 317 // To do: Change proton to neutron (or vice versa) in target nucleus depending 318 // on pion charge 319 } 320 } 321 } 322 323 // Define initial state vectors for Lorentz transformations 324 // The pseudoParticles have non-standard masses, hence the "pseudo" 325 326 G4ReactionProduct pseudoParticle[8]; 327 for (i = 0; i < 8; ++i) pseudoParticle[i].SetZero(); 328 329 pseudoParticle[0].SetMass( mOriginal*GeV ); 330 pseudoParticle[0].SetMomentum( 0.0, 0.0, pOriginal*GeV ); 331 pseudoParticle[0].SetTotalEnergy( 332 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV ); 333 334 pseudoParticle[1].SetMass(protonMass); // this could be targetMass 335 pseudoParticle[1].SetTotalEnergy(protonMass); 336 337 pseudoParticle[3].SetMass(protonMass*(1+extraNucleonCount) ); 338 pseudoParticle[3].SetTotalEnergy(protonMass*(1+extraNucleonCount) ); 339 340 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1]; 341 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0]; 342 343 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] ); 344 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] ); 345 346 // Main loop for 4-momentum generation 347 // See Pitha-report (Aachen) for a detailed description of the method 348 349 G4double aspar, pt, et, x, pp, pp1, wgt; 350 G4int innerCounter, outerCounter; 351 G4bool eliminateThisParticle, resetEnergies, constantCrossSection; 352 353 G4double forwardKinetic = 0.0; 354 G4double backwardKinetic = 0.0; 355 356 // Process the secondary particles in reverse order 357 // The incident particle is done after the secondaries 358 // Nucleons, including the target, in the backward hemisphere are also 359 // done later 360 361 G4int backwardNucleonCount = 0; // number of nucleons in backward hemisphere 362 G4double totalEnergy, kineticEnergy, vecMass; 363 G4double phi; 364 365 for (i = vecLen-1; i >= 0; --i) { 366 367 if (vec[i]->GetNewlyAdded()) { // added from intranuclear cascade 368 if (vec[i]->GetSide() == -2) { // its a nucleon 369 if (backwardNucleonCount < 18) { 370 if (vec[i]->GetDefinition()->GetParticleSubType() == "pi") { 371 for(G4int i=0; i<vecLen; i++) delete vec[i]; 372 vecLen = 0; 373 throw G4HadReentrentException(__FILE__, __LINE__, 374 "G4RPGFragmentation::ReactionStage : a pion has been counted as a backward nucleon"); 375 } 376 vec[i]->SetSide(-3); 377 ++backwardNucleonCount; 378 continue; // Don't generate momenta for the first 17 backward 379 // cascade nucleons. This gets done by the cluster 380 // model later on. 381 } 382 } 383 } 384 385 // Set pt and phi values, they are changed somewhat in the iteration loop 386 // Set mass parameter for lambda fragmentation model 387 388 vecMass = vec[i]->GetMass()/GeV; 389 G4double ran = -std::log(1.0-G4UniformRand())/3.5; 390 391 if (vec[i]->GetSide() == -2) { // backward nucleon 392 aspar = 0.20; 393 pt = std::sqrt( std::pow( ran, 1.2 ) ); 394 395 } else { // not a backward nucleon 396 if (vec[i]->GetDefinition()->GetParticleSubType() == "pi") { 397 aspar = 0.75; 398 pt = std::sqrt( std::pow( ran, 1.7 ) ); 399 } else if (vec[i]->GetDefinition()->GetParticleSubType() == "kaon") { 400 aspar = 0.70; 401 pt = std::sqrt( std::pow( ran, 1.7 ) ); 402 } else { // vec[i] must be a baryon or ion 403 aspar = 0.65; 404 pt = std::sqrt( std::pow( ran, 1.5 ) ); 405 } 406 } 407 408 pt = std::max( 0.001, pt ); 409 phi = G4UniformRand()*twopi; 410 vec[i]->SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV ); 411 if (vec[i]->GetSide() > 0) 412 et = pseudoParticle[0].GetTotalEnergy()/GeV; 413 else 414 et = pseudoParticle[1].GetTotalEnergy()/GeV; 415 115 416 // 116 for( i=0; i<vecLen; ++i ) 117 { 118 G4int itemp = G4int( G4UniformRand()*vecLen ); 119 G4ReactionProduct pTemp = *vec[itemp]; 120 *vec[itemp] = *vec[i]; 121 *vec[i] = pTemp; 122 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 123 } 124 125 if( currentMass == 0.0 && targetMass == 0.0 ) 126 { 127 // Target and projectile have annihilated. Replace them with the first 128 // two secondaries in the list. Current particle KE is maintained. 129 130 G4double ek = currentParticle.GetKineticEnergy(); 131 G4ThreeVector m = currentParticle.GetMomentum(); 132 currentParticle = *vec[0]; 133 targetParticle = *vec[1]; 134 for( i=0; i<(vecLen-2); ++i )*vec[i] = *vec[i+2]; 135 G4ReactionProduct *temp = vec[vecLen-1]; 136 delete temp; 137 temp = vec[vecLen-2]; 138 delete temp; 139 vecLen -= 2; 140 currentMass = currentParticle.GetMass()/GeV; 141 targetMass = targetParticle.GetMass()/GeV; 142 incidentHasChanged = true; 143 targetHasChanged = true; 144 currentParticle.SetKineticEnergy( ek ); 145 currentParticle.SetMomentum( m ); 146 veryForward = true; 147 } 148 const G4double atomicWeight = targetNucleus.GetN(); 149 const G4double atomicNumber = targetNucleus.GetZ(); 150 const G4double protonMass = aProton->GetPDGMass()/MeV; 151 152 if (originalIncident->GetDefinition()->GetParticleSubType() == "kaon" 153 && G4UniformRand() >= 0.7) { 154 G4ReactionProduct temp = currentParticle; 155 currentParticle = targetParticle; 156 targetParticle = temp; 157 incidentHasChanged = true; 158 targetHasChanged = true; 159 currentMass = currentParticle.GetMass()/GeV; 160 targetMass = targetParticle.GetMass()/GeV; 161 } 162 const G4double afc = std::min( 0.75, 163 0.312+0.200*std::log(std::log(centerofmassEnergy*centerofmassEnergy))+ 164 std::pow(centerofmassEnergy*centerofmassEnergy,1.5)/6000.0 ); 165 166 G4double freeEnergy = centerofmassEnergy-currentMass-targetMass; 167 G4double forwardEnergy = freeEnergy/2.; 168 G4int forwardCount = 1; // number of particles in forward hemisphere 169 170 G4double backwardEnergy = freeEnergy/2.; 171 G4int backwardCount = 1; // number of particles in backward hemisphere 172 173 if(veryForward) 174 { 175 if(currentParticle.GetSide()==-1) 176 { 177 forwardEnergy += currentMass; 178 forwardCount --; 179 backwardEnergy -= currentMass; 180 backwardCount ++; 181 } 182 if(targetParticle.GetSide()!=-1) 183 { 184 backwardEnergy += targetMass; 185 backwardCount --; 186 forwardEnergy -= targetMass; 187 forwardCount ++; 188 } 189 } 190 191 for( i=0; i<vecLen; ++i ) 192 { 193 if( vec[i]->GetSide() == -1 ) 194 { 195 ++backwardCount; 196 backwardEnergy -= vec[i]->GetMass()/GeV; 197 } else { 198 ++forwardCount; 199 forwardEnergy -= vec[i]->GetMass()/GeV; 200 } 201 } 417 // Start of outer iteration loop 202 418 // 203 // Add particles from intranuclear cascade. 204 // nuclearExcitationCount = number of new secondaries produced by nuclear excitation 205 // extraCount = number of nucleons within these new secondaries 206 // 207 G4double xtarg; 208 if( centerofmassEnergy < (2.0+G4UniformRand()) ) 209 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount+vecLen+2)/2.0; 210 else 211 xtarg = afc * (std::pow(atomicWeight,0.33)-1.0) * (2.0*backwardCount); 212 if( xtarg <= 0.0 )xtarg = 0.01; 213 G4int nuclearExcitationCount = G4Poisson( xtarg ); 214 if(atomicWeight<1.0001) nuclearExcitationCount = 0; 215 G4int extraNucleonCount = 0; 216 G4double extraNucleonMass = 0.0; 217 if( nuclearExcitationCount > 0 ) 218 { 219 const G4double nucsup[] = { 1.00, 0.7, 0.5, 0.4, 0.35, 0.3 }; 220 const G4double psup[] = { 3., 6., 20., 50., 100., 1000. }; 221 G4int momentumBin = 0; 222 while( (momentumBin < 6) && 223 (modifiedOriginal.GetTotalMomentum()/GeV > psup[momentumBin]) ) 224 ++momentumBin; 225 momentumBin = std::min( 5, momentumBin ); 226 // 227 // NOTE: in GENXPT, these new particles were given negative codes 228 // here I use NewlyAdded = true instead 229 // 230 231 for( i=0; i<nuclearExcitationCount; ++i ) 232 { 233 G4ReactionProduct * pVec = new G4ReactionProduct(); 234 if( G4UniformRand() < nucsup[momentumBin] ) 235 { 236 if( G4UniformRand() > 1.0-atomicNumber/atomicWeight ) 237 pVec->SetDefinition( aProton ); 238 else 239 pVec->SetDefinition( aNeutron ); 240 pVec->SetSide( -2 ); // -2 means backside nucleon 241 ++extraNucleonCount; 242 backwardEnergy += pVec->GetMass()/GeV; 243 extraNucleonMass += pVec->GetMass()/GeV; 244 } 245 else 246 { 247 G4double ran = G4UniformRand(); 248 if( ran < 0.3181 ) 249 pVec->SetDefinition( aPiPlus ); 250 else if( ran < 0.6819 ) 251 pVec->SetDefinition( aPiZero ); 252 else 253 pVec->SetDefinition( aPiMinus ); 254 pVec->SetSide( -1 ); // backside particle, but not a nucleon 255 } 256 pVec->SetNewlyAdded( true ); // true is the same as IPA(i)<0 257 vec.SetElement( vecLen++, pVec ); 258 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 259 backwardEnergy -= pVec->GetMass()/GeV; 260 ++backwardCount; 261 } 262 } 263 // 264 // assume conservation of kinetic energy in forward & backward hemispheres 265 // 266 G4int is, iskip; 267 while( forwardEnergy <= 0.0 ) // must eliminate a particle from the forward side 268 { 269 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 270 iskip = G4int(G4UniformRand()*forwardCount) + 1; // 1 <= iskip <= forwardCount 271 is = 0; 272 G4int forwardParticlesLeft = 0; 273 for( i=(vecLen-1); i>=0; --i ) 274 { 275 if( vec[i]->GetSide() == 1 && vec[i]->GetMayBeKilled()) 276 { 277 forwardParticlesLeft = 1; 278 if( ++is == iskip ) 279 { 280 forwardEnergy += vec[i]->GetMass()/GeV; 281 for( G4int j=i; j<(vecLen-1); j++ )*vec[j] = *vec[j+1]; // shift up 282 --forwardCount; 283 delete vec[vecLen-1]; 284 if( --vecLen == 0 )return false; // all the secondaries have been eliminated 285 break; // --+ 286 } // | 287 } // | 288 } // break goes down to here 289 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 290 if( forwardParticlesLeft == 0 ) 291 { 292 G4int iremove = -1; 293 for (G4int i = 0; i < vecLen; i++) { 294 if (vec[i]->GetDefinition()->GetParticleSubType() == "pi") { 295 iremove = i; 296 break; 419 outerCounter = 0; 420 eliminateThisParticle = true; 421 resetEnergies = true; 422 dndl[0] = 0.0; 423 424 while (++outerCounter < 3) { 425 426 FragmentationIntegral(pt, et, aspar, vecMass); 427 innerCounter = 0; 428 vec[i]->SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV ); 429 430 // Start of inner iteration loop 431 432 while (++innerCounter < 7) { 433 434 ran = G4UniformRand()*dndl[19]; 435 l = 1; 436 while( ( ran > dndl[l] ) && ( l < 19 ) ) l++; 437 x = (G4double(l-1) + G4UniformRand())/19.; 438 if (vec[i]->GetSide() < 0) x *= -1.; 439 vec[i]->SetMomentum( x*et*GeV ); // set the z-momentum 440 totalEnergy = std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass ); 441 vec[i]->SetTotalEnergy( totalEnergy*GeV ); 442 kineticEnergy = vec[i]->GetKineticEnergy()/GeV; 443 444 if (vec[i]->GetSide() > 0) { // forward side 445 if( (forwardKinetic+kineticEnergy) < 0.95*forwardEnergy ) { 446 // Leave at least 5% of the forward free energy for the projectile 447 448 pseudoParticle[4] = pseudoParticle[4] + (*vec[i]); 449 forwardKinetic += kineticEnergy; 450 outerCounter = 2; // leave outer loop 451 eliminateThisParticle = false; // don't eliminate this particle 452 resetEnergies = false; 453 break; // leave inner loop 454 } 455 if( innerCounter > 5 )break; // leave inner loop 456 if( backwardEnergy >= vecMass ) // switch sides 457 { 458 vec[i]->SetSide(-1); 459 forwardEnergy += vecMass; 460 backwardEnergy -= vecMass; 461 ++backwardCount; 462 } 463 } else { // backward side 464 // if (extraNucleonCount > 19) x = 0.999; 465 // G4double xxx = 0.95+0.05*extraNucleonCount/20.0; 466 // DHW: I think above lines were meant to be as follows: 467 G4double xxx = 0.999; 468 if (extraNucleonCount < 20) xxx = 0.95+0.05*extraNucleonCount/20.0; 469 470 if ((backwardKinetic+kineticEnergy) < xxx*backwardEnergy) { 471 pseudoParticle[5] = pseudoParticle[5] + (*vec[i]); 472 backwardKinetic += kineticEnergy; 473 outerCounter = 2; // leave outer loop 474 eliminateThisParticle = false; // don't eliminate this particle 475 resetEnergies = false; 476 break; // leave inner loop 477 } 478 if (innerCounter > 5) break; // leave inner loop 479 if (forwardEnergy >= vecMass) { // switch sides 480 vec[i]->SetSide(1); 481 forwardEnergy -= vecMass; 482 backwardEnergy += vecMass; 483 backwardCount--; 297 484 } 298 485 } 299 if (iremove == -1) { 300 for (G4int i = 0; i < vecLen; i++) { 301 if (vec[i]->GetDefinition()->GetParticleSubType() == "kaon") { 302 iremove = i; 303 break; 304 } 305 } 486 G4ThreeVector momentum = vec[i]->GetMomentum(); 487 vec[i]->SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 ); 488 pt *= 0.9; 489 dndl[19] *= 0.9; 490 } // closes inner loop 491 492 // If we get here, the inner loop has been done 6 times. 493 // If necessary, reduce energies of the previously done particles if 494 // they are lighter than protons or are in the forward hemisphere. 495 // Then continue with outer loop. 496 497 if (resetEnergies) 498 ReduceEnergiesOfSecondaries(i+1, forwardKinetic, backwardKinetic, 499 vec, vecLen, 500 pseudoParticle[4], pseudoParticle[5], 501 pt); 502 503 } // closes outer loop 504 505 if (eliminateThisParticle && vec[i]->GetMayBeKilled()) { 506 // not enough energy, eliminate this particle 507 508 if (vec[i]->GetSide() > 0) { 509 --forwardCount; 510 forwardEnergy += vecMass; 511 } else { 512 --backwardCount; 513 if (vec[i]->GetSide() == -2) { 514 --extraNucleonCount; 515 extraNucleonMass -= vecMass; 516 } else { 517 backwardEnergy += vecMass; 518 } 519 } 520 521 for( G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1]; // shift up 522 G4ReactionProduct* temp = vec[vecLen-1]; 523 delete temp; 524 // To do: modify target nucleus according to particle eliminated 525 526 if( --vecLen == 0 ){ 527 G4cout << " FALSE RETURN DUE TO ENERGY BALANCE " << G4endl; 528 return false; 529 } // all the secondaries have been eliminated 530 } 531 } // closes main loop over secondaries 532 533 // Re-balance forward and backward energy if possible and if necessary 534 535 G4double forwardKEDiff = forwardEnergy - forwardKinetic; 536 G4double backwardKEDiff = backwardEnergy - backwardKinetic; 537 538 if (forwardKEDiff < 0.0 || backwardKEDiff < 0.0) { 539 ReduceEnergiesOfSecondaries(0, forwardKinetic, backwardKinetic, 540 vec, vecLen, 541 pseudoParticle[4], pseudoParticle[5], 542 pt); 543 544 forwardKEDiff = forwardEnergy - forwardKinetic; 545 backwardKEDiff = backwardEnergy - backwardKinetic; 546 if (backwardKEDiff < 0.0) { 547 if (forwardKEDiff + backwardKEDiff > 0.0) { 548 backwardEnergy = backwardKinetic; 549 forwardEnergy += backwardKEDiff; 550 forwardKEDiff = forwardEnergy - forwardKinetic; 551 backwardKEDiff = 0.0; 552 } else { 553 G4cout << " False return due to insufficient backward energy " << G4endl; 554 return false; 555 } 556 } 557 558 if (forwardKEDiff < 0.0) { 559 if (forwardKEDiff + backwardKEDiff > 0.0) { 560 forwardEnergy = forwardKinetic; 561 backwardEnergy += forwardKEDiff; 562 backwardKEDiff = backwardEnergy - backwardKinetic; 563 forwardKEDiff = 0.0; 564 } else { 565 G4cout << " False return due to insufficient forward energy " << G4endl; 566 return false; 567 } 568 } 569 } 570 571 // Generate momentum for incident (current) particle, which was placed 572 // in the forward hemisphere. 573 // Set mass parameter for lambda fragmentation model. 574 // Set pt and phi values, which are changed somewhat in the iteration loop 575 576 G4double ran = -std::log(1.0-G4UniformRand()); 577 if (currentParticle.GetDefinition()->GetParticleSubType() == "pi") { 578 aspar = 0.60; 579 pt = std::sqrt( std::pow( ran/6.0, 1.7 ) ); 580 } else if (currentParticle.GetDefinition()->GetParticleSubType() == "kaon") { 581 aspar = 0.50; 582 pt = std::sqrt( std::pow( ran/5.0, 1.4 ) ); 583 } else { 584 aspar = 0.40; 585 pt = std::sqrt( std::pow( ran/4.0, 1.2 ) ); 586 } 587 588 phi = G4UniformRand()*twopi; 589 currentParticle.SetMomentum(pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV); 590 et = pseudoParticle[0].GetTotalEnergy()/GeV; 591 dndl[0] = 0.0; 592 vecMass = currentParticle.GetMass()/GeV; 593 594 FragmentationIntegral(pt, et, aspar, vecMass); 595 596 ran = G4UniformRand()*dndl[19]; 597 l = 1; 598 while( ( ran > dndl[l] ) && ( l < 19 ) ) l++; 599 x = (G4double(l-1) + G4UniformRand())/19.; 600 currentParticle.SetMomentum( x*et*GeV ); // set the z-momentum 601 602 if (forwardEnergy < forwardKinetic) { 603 totalEnergy = vecMass + 0.04*std::fabs(normal()); 604 G4cout << " Not enough forward energy: forwardEnergy = " 605 << forwardEnergy << " forwardKinetic = " 606 << forwardKinetic << " total energy left = " 607 << backwardKEDiff + forwardKEDiff << G4endl; 608 } else { 609 totalEnergy = vecMass + forwardEnergy - forwardKinetic; 610 forwardKinetic = forwardEnergy; 611 } 612 currentParticle.SetTotalEnergy( totalEnergy*GeV ); 613 pp = std::sqrt(std::abs( totalEnergy*totalEnergy - vecMass*vecMass) )*GeV; 614 pp1 = currentParticle.GetMomentum().mag(); 615 616 if (pp1 < 1.0e-6*GeV) { 617 G4ThreeVector iso = Isotropic(pp); 618 currentParticle.SetMomentum( iso.x(), iso.y(), iso.z() ); 619 } else { 620 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) ); 621 } 622 pseudoParticle[4] = pseudoParticle[4] + currentParticle; 623 624 // Current particle now finished 625 626 // Begin target particle 627 628 if (backwardNucleonCount < 18) { 629 targetParticle.SetSide(-3); 630 ++backwardNucleonCount; 631 632 } else { 633 // Set pt and phi values, they are changed somewhat in the iteration loop 634 // Set mass parameter for lambda fragmentation model 635 636 vecMass = targetParticle.GetMass()/GeV; 637 ran = -std::log(1.0-G4UniformRand()); 638 aspar = 0.40; 639 pt = std::max( 0.001, std::sqrt( std::pow( ran/4.0, 1.2 ) ) ); 640 phi = G4UniformRand()*twopi; 641 targetParticle.SetMomentum(pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV); 642 et = pseudoParticle[1].GetTotalEnergy()/GeV; 643 outerCounter = 0; 644 innerCounter = 0; 645 G4bool marginalEnergy = true; 646 dndl[0] = 0.0; 647 G4double xxx = 0.999; 648 if( extraNucleonCount < 20 ) xxx = 0.95+0.05*extraNucleonCount/20.0; 649 G4ThreeVector momentum; 650 651 while (++outerCounter < 4) { 652 FragmentationIntegral(pt, et, aspar, vecMass); 653 654 for (innerCounter = 0; innerCounter < 6; innerCounter++) { 655 ran = G4UniformRand()*dndl[19]; 656 l = 1; 657 while( ( ran > dndl[l] ) && ( l < 19 ) ) l++; 658 x = -(G4double(l-1) + G4UniformRand())/19.; 659 targetParticle.SetMomentum( x*et*GeV ); // set the z-momentum 660 totalEnergy = std::sqrt(x*et*x*et + pt*pt + vecMass*vecMass); 661 targetParticle.SetTotalEnergy( totalEnergy*GeV ); 662 663 if ((backwardKinetic+totalEnergy-vecMass) < xxx*backwardEnergy) { 664 pseudoParticle[5] = pseudoParticle[5] + targetParticle; 665 backwardKinetic += totalEnergy - vecMass; 666 outerCounter = 3; // leave outer loop 667 marginalEnergy = false; 668 break; // leave inner loop 306 669 } 307 if (iremove == -1) iremove = 0; 308 309 forwardEnergy += vec[iremove]->GetMass()/GeV; 310 if (vec[iremove]->GetSide() > 0) --forwardCount; 311 312 for (G4int i = iremove; i < vecLen-1; i++) *vec[i] = *vec[i+1]; 313 delete vec[vecLen-1]; 314 vecLen--; 315 if (vecLen == 0) return false; // all secondaries have been eliminated 316 break; 317 } 318 } // while 319 320 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 321 while( backwardEnergy <= 0.0 ) // must eliminate a particle from the backward side 670 momentum = targetParticle.GetMomentum(); 671 targetParticle.SetMomentum(momentum.x() * 0.9, momentum.y() * 0.9); 672 pt *= 0.9; 673 dndl[19] *= 0.9; 674 } 675 } 676 677 if (marginalEnergy) { 678 G4cout << " Extra backward kinetic energy = " 679 << 0.999*backwardEnergy - backwardKinetic << G4endl; 680 totalEnergy = vecMass + 0.999*backwardEnergy - backwardKinetic; 681 targetParticle.SetTotalEnergy(totalEnergy*GeV); 682 pp = std::sqrt(std::abs(totalEnergy*totalEnergy - vecMass*vecMass) )*GeV; 683 targetParticle.SetMomentum(momentum.x()/0.9, momentum.y()/0.9); 684 pp1 = targetParticle.GetMomentum().mag(); 685 targetParticle.SetMomentum(targetParticle.GetMomentum() * pp/pp1 ); 686 pseudoParticle[5] = pseudoParticle[5] + targetParticle; 687 backwardKinetic = 0.999*backwardEnergy; 688 } 689 690 } 691 692 if (backwardEnergy < backwardKinetic) 693 G4cout << " Backward Edif = " << backwardEnergy - backwardKinetic << G4endl; 694 if (forwardEnergy != forwardKinetic) 695 G4cout << " Forward Edif = " << forwardEnergy - forwardKinetic << G4endl; 696 697 // Target particle finished. 698 // Now produce backward nucleons with a cluster model 699 // ps[2] = CM frame of projectile + target 700 // ps[3] = sum of projectile + nucleon cluster in lab frame 701 // ps[6] = proj + cluster 4-vector boosted into CM frame of proj + targ 702 // with secondaries, current and target particles subtracted 703 // = total 4-momentum of backward nucleon cluster 704 705 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] ); 706 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4]; 707 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5]; 708 709 if (backwardNucleonCount == 1) { 710 // Target particle is the only backward nucleon. Give it the remainder 711 // of the backward kinetic energy. 712 713 G4double ekin = 714 std::min(backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/GeV); 715 716 if( ekin < 0.04 )ekin = 0.04 * std::fabs( normal() ); 717 vecMass = targetParticle.GetMass()/GeV; 718 totalEnergy = ekin + vecMass; 719 targetParticle.SetTotalEnergy( totalEnergy*GeV ); 720 pp = std::sqrt(std::abs(totalEnergy*totalEnergy - vecMass*vecMass) )*GeV; 721 pp1 = pseudoParticle[6].GetMomentum().mag(); 722 if (pp1 < 1.0e-6*GeV) { 723 G4ThreeVector iso = Isotropic(pp); 724 targetParticle.SetMomentum( iso.x(), iso.y(), iso.z() ); 725 } else { 726 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1)); 727 } 728 pseudoParticle[5] = pseudoParticle[5] + targetParticle; 729 730 } else if (backwardNucleonCount > 1) { 731 // Share remaining energy with up to 17 backward nucleons 732 733 G4int tempCount = 5; 734 if (backwardNucleonCount < 5) tempCount = backwardNucleonCount; 735 tempCount -= 2; 736 737 G4double clusterMass = 0.; 738 if (targetParticle.GetSide() == -3) 739 clusterMass = targetParticle.GetMass()/GeV; 740 for (i = 0; i < vecLen; ++i) 741 if (vec[i]->GetSide() == -3) clusterMass += vec[i]->GetMass()/GeV; 742 clusterMass += backwardEnergy - backwardKinetic; 743 744 totalEnergy = pseudoParticle[6].GetTotalEnergy()/GeV; 745 pseudoParticle[6].SetMass(clusterMass*GeV); 746 747 pp = std::sqrt(std::abs(totalEnergy*totalEnergy - 748 clusterMass*clusterMass) )*GeV; 749 pp1 = pseudoParticle[6].GetMomentum().mag(); 750 if (pp1 < 1.0e-6*GeV) { 751 G4ThreeVector iso = Isotropic(pp); 752 pseudoParticle[6].SetMomentum(iso.x(), iso.y(), iso.z()); 753 } else { 754 pseudoParticle[6].SetMomentum(pseudoParticle[6].GetMomentum() * (-pp/pp1)); 755 } 756 757 std::vector<G4ReactionProduct*> tempList; // ptrs to backward nucleons 758 if (targetParticle.GetSide() == -3) tempList.push_back(&targetParticle); 759 for (i = 0; i < vecLen; ++i) 760 if (vec[i]->GetSide() == -3) tempList.push_back(vec[i]); 761 762 constantCrossSection = true; 763 764 if (tempList.size() > 1) { 765 G4int n_entry = 0; 766 wgt = GenerateNBodyEventT(pseudoParticle[6].GetMass(), 767 constantCrossSection, tempList); 768 769 if (targetParticle.GetSide() == -3) { 770 targetParticle = *tempList[0]; 771 targetParticle.Lorentz(targetParticle, pseudoParticle[6]); 772 n_entry++; 773 } 774 775 for (i = 0; i < vecLen; ++i) { 776 if (vec[i]->GetSide() == -3) { 777 *vec[i] = *tempList[n_entry]; 778 vec[i]->Lorentz(*vec[i], pseudoParticle[6]); 779 n_entry++; 780 } 781 } 782 } 783 } else return false; 784 785 if (vecLen == 0) return false; // all the secondaries have been eliminated 786 787 // Lorentz transformation to lab frame 788 789 currentParticle.Lorentz( currentParticle, pseudoParticle[1] ); 790 targetParticle.Lorentz( targetParticle, pseudoParticle[1] ); 791 for (i = 0; i < vecLen; ++i) vec[i]->Lorentz(*vec[i], pseudoParticle[1]); 792 793 // Set leading strange particle flag. 794 // leadFlag will be true if original particle and incident particle are 795 // both strange, in which case the incident particle becomes the leading 796 // particle. 797 // leadFlag will also be true if the target particle is strange, but the 798 // incident particle is not, in which case the target particle becomes the 799 // leading particle. 800 801 G4bool leadingStrangeParticleHasChanged = true; 802 if (leadFlag) 803 { 804 if (currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition()) 805 leadingStrangeParticleHasChanged = false; 806 if (leadingStrangeParticleHasChanged && 807 (targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition()) ) 808 leadingStrangeParticleHasChanged = false; 809 if( leadingStrangeParticleHasChanged ) 322 810 { 323 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 324 iskip = G4int(G4UniformRand()*backwardCount) + 1; // 1 <= iskip <= backwardCount 325 is = 0; 326 G4int backwardParticlesLeft = 0; 327 for( i=(vecLen-1); i>=0; --i ) 811 for( i=0; i<vecLen; i++ ) 328 812 { 329 if( vec[i]->GetSide() < 0 && vec[i]->GetMayBeKilled()) 330 { 331 backwardParticlesLeft = 1; 332 if( ++is == iskip ) // eliminate the i'th particle 333 { 334 if( vec[i]->GetSide() == -2 ) 335 { 336 --extraNucleonCount; 337 extraNucleonMass -= vec[i]->GetMass()/GeV; 338 backwardEnergy -= vec[i]->GetTotalEnergy()/GeV; 339 } 340 backwardEnergy += vec[i]->GetTotalEnergy()/GeV; 341 for( G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1]; // shift up 342 --backwardCount; 343 delete vec[vecLen-1]; 344 if( --vecLen == 0 )return false; // all the secondaries have been eliminated 345 break; 346 } 813 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() ) 814 { 815 leadingStrangeParticleHasChanged = false; 816 break; 347 817 } 348 818 } 349 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 350 if( backwardParticlesLeft == 0 ) 819 } 820 if( leadingStrangeParticleHasChanged ) 821 { 822 G4bool leadTest = 823 (leadingStrangeParticle.GetDefinition()->GetParticleSubType() == "kaon" || 824 leadingStrangeParticle.GetDefinition()->GetParticleSubType() == "pi"); 825 G4bool targetTest = 826 (targetParticle.GetDefinition()->GetParticleSubType() == "kaon" || 827 targetParticle.GetDefinition()->GetParticleSubType() == "pi"); 828 829 // following modified by JLC 22-Oct-97 830 831 if( (leadTest&&targetTest) || !(leadTest||targetTest) ) // both true or both false 351 832 { 352 G4int iremove = -1; 353 for (G4int i = 0; i < vecLen; i++) { 354 if (vec[i]->GetDefinition()->GetParticleSubType() == "pi") { 355 iremove = i; 356 break; 357 } 358 } 359 if (iremove == -1) { 360 for (G4int i = 0; i < vecLen; i++) { 361 if (vec[i]->GetDefinition()->GetParticleSubType() == "kaon") { 362 iremove = i; 363 break; 364 } 365 } 366 } 367 if (iremove == -1) iremove = 0; 368 369 backwardEnergy += vec[iremove]->GetMass()/GeV; 370 if (vec[iremove]->GetSide() > 0) --backwardCount; 371 372 for (G4int i = iremove; i < vecLen-1; i++) *vec[i] = *vec[i+1]; 373 delete vec[vecLen-1]; 374 vecLen--; 375 if (vecLen == 0) return false; // all secondaries have been eliminated 376 break; 377 } 378 } // while 379 380 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 381 // 382 // define initial state vectors for Lorentz transformations 383 // the pseudoParticles have non-standard masses, hence the "pseudo" 384 // 385 G4ReactionProduct pseudoParticle[8]; 386 for( i=0; i<8; ++i )pseudoParticle[i].SetZero(); 387 388 pseudoParticle[0].SetMass( mOriginal*GeV ); 389 pseudoParticle[0].SetMomentum( 0.0, 0.0, pOriginal*GeV ); 390 pseudoParticle[0].SetTotalEnergy( 391 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV ); 392 393 pseudoParticle[1].SetMass( protonMass*MeV ); // this could be targetMass 394 pseudoParticle[1].SetTotalEnergy( protonMass*MeV ); 395 396 pseudoParticle[3].SetMass( protonMass*(1+extraNucleonCount)*MeV ); 397 pseudoParticle[3].SetTotalEnergy( protonMass*(1+extraNucleonCount)*MeV ); 398 399 pseudoParticle[2] = pseudoParticle[0] + pseudoParticle[1]; 400 pseudoParticle[3] = pseudoParticle[3] + pseudoParticle[0]; 401 402 pseudoParticle[0].Lorentz( pseudoParticle[0], pseudoParticle[2] ); 403 pseudoParticle[1].Lorentz( pseudoParticle[1], pseudoParticle[2] ); 404 405 // 406 // main loop for 4-momentum generation 407 // see Pitha-report (Aachen) for a detailed description of the method 408 // 409 G4double aspar, pt, et, x, pp, pp1, wgt; 410 G4int innerCounter, outerCounter; 411 G4bool eliminateThisParticle, resetEnergies, constantCrossSection; 412 413 G4double forwardKinetic = 0.0, backwardKinetic = 0.0; 414 // 415 // process the secondary particles in reverse order 416 // the incident particle is Done after the secondaries 417 // nucleons, including the target, in the backward hemisphere are also Done later 418 // 419 G4int backwardNucleonCount = 0; // number of nucleons in backward hemisphere 420 G4double totalEnergy, kineticEnergy, vecMass; 421 422 for( i=(vecLen-1); i>=0; --i ) 423 { 424 G4double phi = G4UniformRand()*twopi; 425 if( vec[i]->GetNewlyAdded() ) // added from intranuclear cascade 833 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() ); 834 targetHasChanged = true; 835 } 836 else 426 837 { 427 if( vec[i]->GetSide() == -2 ) // is a nucleon 428 { 429 if( backwardNucleonCount < 18 ) 430 { 431 if (vec[i]->GetDefinition()->GetParticleSubType() == "pi") { 432 for(G4int i=0; i<vecLen; i++) delete vec[i]; 433 vecLen = 0; 434 throw G4HadReentrentException(__FILE__, __LINE__, 435 "G4RPGFragmentation::ReactionStage : a pion has been counted as a backward nucleon"); 436 } 437 vec[i]->SetSide( -3 ); 438 ++backwardNucleonCount; 439 continue; 440 } 441 } 442 } 443 // 444 // set pt and phi values, they are changed somewhat in the iteration loop 445 // set mass parameter for lambda fragmentation model 446 // 447 vecMass = vec[i]->GetMass()/GeV; 448 G4double ran = -std::log(1.0-G4UniformRand())/3.5; 449 if( vec[i]->GetSide() == -2 ) // backward nucleon 450 { 451 if (vec[i]->GetDefinition()->GetParticleSubType() == "kaon" || 452 vec[i]->GetDefinition()->GetParticleSubType() == "pi") { 453 aspar = 0.75; 454 pt = std::sqrt( std::pow( ran, 1.7 ) ); 455 } else { // vec[i] must be a proton, neutron, 456 aspar = 0.20; // lambda, sigma, xsi, or ion 457 pt = std::sqrt( std::pow( ran, 1.2 ) ); 458 } 459 460 } else { // not a backward nucleon 461 462 if (vec[i]->GetDefinition()->GetParticleSubType() == "pi") { 463 aspar = 0.75; 464 pt = std::sqrt( std::pow( ran, 1.7 ) ); 465 } else if (vec[i]->GetDefinition()->GetParticleSubType() == "kaon") { 466 aspar = 0.70; 467 pt = std::sqrt( std::pow( ran, 1.7 ) ); 468 } else { // vec[i] must be a proton, neutron, 469 aspar = 0.65; // lambda, sigma, xsi, or ion 470 pt = std::sqrt( std::pow( ran, 1.5 ) ); 471 } 472 } 473 pt = std::max( 0.001, pt ); 474 vec[i]->SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV ); 475 if( vec[i]->GetSide() > 0 ) 476 et = pseudoParticle[0].GetTotalEnergy()/GeV; 477 else 478 et = pseudoParticle[1].GetTotalEnergy()/GeV; 479 480 // 481 // start of outer iteration loop 482 // 483 outerCounter = 0; 484 eliminateThisParticle = true; 485 resetEnergies = true; 486 dndl[0] = 0.0; 487 488 while( ++outerCounter < 3 ) 489 { 490 FragmentationIntegral(pt, et, aspar, vecMass); 491 492 innerCounter = 0; 493 vec[i]->SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV ); 494 // 495 // start of inner iteration loop 496 // 497 while( ++innerCounter < 7 ) 498 { 499 ran = G4UniformRand()*dndl[19]; 500 l = 1; 501 while( ( ran > dndl[l] ) && ( l < 19 ) ) l++; 502 x = (G4double(l-1) + G4UniformRand())/19.; 503 if( vec[i]->GetSide() < 0 )x *= -1.; 504 vec[i]->SetMomentum( x*et*GeV ); // set the z-momentum 505 totalEnergy = std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass ); 506 vec[i]->SetTotalEnergy( totalEnergy*GeV ); 507 kineticEnergy = vec[i]->GetKineticEnergy()/GeV; 508 if( vec[i]->GetSide() > 0 ) // forward side 509 { 510 if( (forwardKinetic+kineticEnergy) < 0.95*forwardEnergy ) 511 { 512 pseudoParticle[4] = pseudoParticle[4] + (*vec[i]); 513 forwardKinetic += kineticEnergy; 514 outerCounter = 2; // leave outer loop 515 eliminateThisParticle = false; // don't eliminate this particle 516 resetEnergies = false; 517 break; // leave inner loop 518 } 519 if( innerCounter > 5 )break; // leave inner loop 520 if( backwardEnergy >= vecMass ) // switch sides 521 { 522 vec[i]->SetSide( -1 ); 523 forwardEnergy += vecMass; 524 backwardEnergy -= vecMass; 525 ++backwardCount; 526 } 527 } else { // backward side 528 if( extraNucleonCount > 19 ) // commented out to duplicate ?bug? in GENXPT 529 x = 0.999; 530 G4double xxx = 0.95+0.05*extraNucleonCount/20.0; 531 if( (backwardKinetic+kineticEnergy) < xxx*backwardEnergy ) 532 { 533 pseudoParticle[5] = pseudoParticle[5] + (*vec[i]); 534 backwardKinetic += kineticEnergy; 535 outerCounter = 2; // leave outer loop 536 eliminateThisParticle = false; // don't eliminate this particle 537 resetEnergies = false; 538 break; // leave inner loop 539 } 540 if( innerCounter > 5 )break; // leave inner loop 541 if( forwardEnergy >= vecMass ) // switch sides 542 { 543 vec[i]->SetSide( 1 ); 544 forwardEnergy -= vecMass; 545 backwardEnergy += vecMass; 546 backwardCount--; 547 } 548 } 549 G4ThreeVector momentum = vec[i]->GetMomentum(); 550 vec[i]->SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 ); 551 pt *= 0.9; 552 dndl[19] *= 0.9; 553 } // closes inner loop 554 if( resetEnergies ) { 555 // If we get to here, the inner loop has been done 6 times. 556 // Reset the kinetic energies of previously done particles, if 557 // they are lighter than protons and in the forward hemisphere, 558 // then continue with outer loop. 559 // 560 forwardKinetic = 0.0; 561 backwardKinetic = 0.0; 562 pseudoParticle[4].SetZero(); 563 pseudoParticle[5].SetZero(); 564 for( l=i+1; l<vecLen; ++l ) { 565 if (vec[l]->GetSide() > 0 || 566 vec[l]->GetDefinition()->GetParticleSubType() == "kaon" || 567 vec[l]->GetDefinition()->GetParticleSubType() == "pi") { 568 569 G4double tempMass = vec[l]->GetMass()/MeV; 570 totalEnergy = 0.95*vec[l]->GetTotalEnergy()/MeV + 0.05*tempMass; 571 totalEnergy = std::max( tempMass, totalEnergy ); 572 vec[l]->SetTotalEnergy( totalEnergy*MeV ); 573 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - tempMass*tempMass ) ); 574 pp1 = vec[l]->GetMomentum().mag()/MeV; 575 if( pp1 < 1.0e-6*GeV ) { 576 G4ThreeVector iso = Isotropic(pp); 577 vec[l]->SetMomentum( iso.x(), iso.y(), iso.z() ); 578 } else { 579 vec[l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) ); 580 } 581 G4double px = vec[l]->GetMomentum().x()/MeV; 582 G4double py = vec[l]->GetMomentum().y()/MeV; 583 pt = std::max( 1.0, std::sqrt( px*px + py*py ) )/GeV; 584 if( vec[l]->GetSide() > 0 ) 585 { 586 forwardKinetic += vec[l]->GetKineticEnergy()/GeV; 587 pseudoParticle[4] = pseudoParticle[4] + (*vec[l]); 588 } else { 589 backwardKinetic += vec[l]->GetKineticEnergy()/GeV; 590 pseudoParticle[5] = pseudoParticle[5] + (*vec[l]); 591 } 592 } // if pi, K or forward 593 } // for l 594 } // if resetEnergies 595 } // closes outer loop 596 597 if( eliminateThisParticle && vec[i]->GetMayBeKilled()) // not enough energy, eliminate this particle 598 { 599 if( vec[i]->GetSide() > 0 ) 600 { 601 --forwardCount; 602 forwardEnergy += vecMass; 603 } else { 604 if( vec[i]->GetSide() == -2 ) 605 { 606 --extraNucleonCount; 607 extraNucleonMass -= vecMass; 608 backwardEnergy -= vecMass; 609 } 610 --backwardCount; 611 backwardEnergy += vecMass; 612 } 613 for( G4int j=i; j<(vecLen-1); ++j )*vec[j] = *vec[j+1]; // shift up 614 G4ReactionProduct *temp = vec[vecLen-1]; 615 delete temp; 616 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 617 if( --vecLen == 0 )return false; // all the secondaries have been eliminated 618 } 619 } // closes main for loop 620 621 // 622 // for the incident particle: it was placed in the forward hemisphere 623 // set pt and phi values, they are changed somewhat in the iteration loop 624 // set mass parameter for lambda fragmentation model 625 // 626 G4double phi = G4UniformRand()*twopi; 627 G4double ran = -std::log(1.0-G4UniformRand()); 628 if (currentParticle.GetDefinition()->GetParticleSubType() == "pi") { 629 aspar = 0.60; 630 pt = std::sqrt( std::pow( ran/6.0, 1.7 ) ); 631 } else if (currentParticle.GetDefinition()->GetParticleSubType() == "kaon") { 632 aspar = 0.50; 633 pt = std::sqrt( std::pow( ran/5.0, 1.4 ) ); 634 } else { 635 aspar = 0.40; 636 pt = std::sqrt( std::pow( ran/4.0, 1.2 ) ); 637 } 638 639 currentParticle.SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV ); 640 et = pseudoParticle[0].GetTotalEnergy()/GeV; 641 dndl[0] = 0.0; 642 vecMass = currentParticle.GetMass()/GeV; 643 644 FragmentationIntegral(pt, et, aspar, vecMass); 645 646 ran = G4UniformRand()*dndl[19]; 647 l = 1; 648 while( ( ran > dndl[l] ) && ( l < 19 ) ) l++; 649 x = (G4double(l-1) + G4UniformRand())/19.; 650 currentParticle.SetMomentum( x*et*GeV ); // set the z-momentum 651 if( forwardEnergy < forwardKinetic ) 652 totalEnergy = vecMass + 0.04*std::fabs(normal()); 653 else 654 totalEnergy = vecMass + forwardEnergy - forwardKinetic; 655 currentParticle.SetTotalEnergy( totalEnergy*GeV ); 656 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*GeV; 657 pp1 = currentParticle.GetMomentum().mag()/MeV; 658 659 if( pp1 < 1.0e-6*GeV ) { 660 G4ThreeVector iso = Isotropic(pp); 661 currentParticle.SetMomentum( iso.x(), iso.y(), iso.z() ); 662 } else { 663 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) ); 664 } 665 pseudoParticle[4] = pseudoParticle[4] + currentParticle; 666 667 // 668 // Current particle now finished 669 // 670 // Begin target particle 671 // 672 673 if( backwardNucleonCount < 18 ) 674 { 675 targetParticle.SetSide( -3 ); 676 ++backwardNucleonCount; 677 } 678 else 679 { 680 // set pt and phi values, they are changed somewhat in the iteration loop 681 // set mass parameter for lambda fragmentation model 682 // 683 vecMass = targetParticle.GetMass()/GeV; 684 ran = -std::log(1.0-G4UniformRand()); 685 aspar = 0.40; 686 pt = std::max( 0.001, std::sqrt( std::pow( ran/4.0, 1.2 ) ) ); 687 targetParticle.SetMomentum( pt*std::cos(phi)*GeV, pt*std::sin(phi)*GeV ); 688 et = pseudoParticle[1].GetTotalEnergy()/GeV; 689 outerCounter = 0; 690 eliminateThisParticle = true; // should never eliminate the target particle 691 resetEnergies = true; 692 dndl[0] = 0.0; 693 694 while( ++outerCounter < 3 ) // start of outer iteration loop 695 { 696 FragmentationIntegral(pt, et, aspar, vecMass); 697 698 innerCounter = 0; 699 while( ++innerCounter < 7 ) // start of inner iteration loop 700 { 701 ran = G4UniformRand()*dndl[19]; 702 l = 1; 703 while( ( ran > dndl[l] ) && ( l < 19 ) ) l++; 704 x = (G4double(l-1) + G4UniformRand())/19.; 705 if( targetParticle.GetSide() < 0 )x *= -1.; 706 targetParticle.SetMomentum( x*et*GeV ); // set the z-momentum 707 totalEnergy = std::sqrt( x*et*x*et + pt*pt + vecMass*vecMass ); 708 targetParticle.SetTotalEnergy( totalEnergy*GeV ); 709 if( targetParticle.GetSide() < 0 ) 710 { 711 if( extraNucleonCount > 19 )x=0.999; 712 G4double xxx = 0.95+0.05*extraNucleonCount/20.0; 713 if( (backwardKinetic+totalEnergy-vecMass) < xxx*backwardEnergy ) 714 { 715 pseudoParticle[5] = pseudoParticle[5] + targetParticle; 716 backwardKinetic += totalEnergy - vecMass; 717 // pseudoParticle[6] = pseudoParticle[4] + pseudoParticle[5]; 718 // pseudoParticle[6].SetMomentum( 0.0 ); // set z-momentum 719 outerCounter = 2; // leave outer loop 720 eliminateThisParticle = false; // don't eliminate this particle 721 resetEnergies = false; 722 break; // leave inner loop 723 } 724 if( innerCounter > 5 )break; // leave inner loop 725 if( forwardEnergy >= vecMass ) // switch sides 726 { 727 targetParticle.SetSide( 1 ); 728 forwardEnergy -= vecMass; 729 backwardEnergy += vecMass; 730 --backwardCount; 731 } 732 G4ThreeVector momentum = targetParticle.GetMomentum(); 733 targetParticle.SetMomentum( momentum.x() * 0.9, momentum.y() * 0.9 ); 734 pt *= 0.9; 735 dndl[19] *= 0.9; 736 } 737 else // target has gone to forward side 738 { 739 if( forwardEnergy < forwardKinetic ) 740 totalEnergy = vecMass + 0.04*std::fabs(normal()); 741 else 742 totalEnergy = vecMass + forwardEnergy - forwardKinetic; 743 targetParticle.SetTotalEnergy( totalEnergy*GeV ); 744 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*GeV; 745 pp1 = targetParticle.GetMomentum().mag()/MeV; 746 if( pp1 < 1.0e-6*GeV ) { 747 G4ThreeVector iso = Isotropic(pp); 748 targetParticle.SetMomentum( iso.x(), iso.y(), iso.z() ); 749 } else { 750 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) ); 751 } 752 753 pseudoParticle[4] = pseudoParticle[4] + targetParticle; 754 outerCounter = 2; // leave outer loop 755 eliminateThisParticle = false; // don't eliminate this particle 756 resetEnergies = false; 757 break; // leave inner loop 758 } 759 } // closes inner loop 760 761 if( resetEnergies ) { 762 // If we get to here, the inner loop has been done 6 times. 763 // Reset the kinetic energies of previously done particles, 764 // if they are lighter than protons and in the forward hemisphere, 765 // then continue with outer loop. 766 767 forwardKinetic = backwardKinetic = 0.0; 768 pseudoParticle[4].SetZero(); 769 pseudoParticle[5].SetZero(); 770 for( l=0; l<vecLen; ++l ) { 771 if (vec[l]->GetSide() > 0 || 772 vec[l]->GetDefinition()->GetParticleSubType() == "kaon" || 773 vec[l]->GetDefinition()->GetParticleSubType() == "pi") { 774 G4double tempMass = vec[l]->GetMass()/GeV; 775 totalEnergy = 776 std::max( tempMass, 0.95*vec[l]->GetTotalEnergy()/GeV + 0.05*tempMass ); 777 vec[l]->SetTotalEnergy( totalEnergy*GeV ); 778 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - tempMass*tempMass ) )*GeV; 779 pp1 = vec[l]->GetMomentum().mag()/MeV; 780 if( pp1 < 1.0e-6*GeV ) { 781 G4ThreeVector iso = Isotropic(pp); 782 vec[l]->SetMomentum( iso.x(), iso.y(), iso.z() ); 783 } else { 784 vec[l]->SetMomentum( vec[l]->GetMomentum() * (pp/pp1) ); 785 } 786 pt = std::max( 0.001*GeV, std::sqrt( sqr(vec[l]->GetMomentum().x()/MeV) + 787 sqr(vec[l]->GetMomentum().y()/MeV) ) )/GeV; 788 if( vec[l]->GetSide() > 0) 789 { 790 forwardKinetic += vec[l]->GetKineticEnergy()/GeV; 791 pseudoParticle[4] = pseudoParticle[4] + (*vec[l]); 792 } else { 793 backwardKinetic += vec[l]->GetKineticEnergy()/GeV; 794 pseudoParticle[5] = pseudoParticle[5] + (*vec[l]); 795 } 796 } // if pi, K or forward 797 } // for l 798 } // if (resetEnergies) 799 } // closes outer loop 800 801 // if( eliminateThisParticle ) // not enough energy, eliminate target 802 // { 803 // G4cerr << "Warning: eliminating target particle" << G4endl; 804 // exit( EXIT_FAILURE ); 805 // } 806 } 807 // 808 // Target particle finished. 809 // 810 // Now produce backward nucleons with a cluster model 811 // 812 pseudoParticle[6].Lorentz( pseudoParticle[3], pseudoParticle[2] ); 813 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[4]; 814 pseudoParticle[6] = pseudoParticle[6] - pseudoParticle[5]; 815 if( backwardNucleonCount == 1 ) // target particle is the only backward nucleon 816 { 817 G4double ekin = 818 std::min( backwardEnergy-backwardKinetic, centerofmassEnergy/2.0-protonMass/GeV ); 819 820 if( ekin < 0.04 )ekin = 0.04 * std::fabs( normal() ); 821 vecMass = targetParticle.GetMass()/GeV; 822 totalEnergy = ekin+vecMass; 823 targetParticle.SetTotalEnergy( totalEnergy*GeV ); 824 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*GeV; 825 pp1 = pseudoParticle[6].GetMomentum().mag()/MeV; 826 if( pp1 < 1.0e-6*GeV ) { 827 G4ThreeVector iso = Isotropic(pp); 828 targetParticle.SetMomentum( iso.x(), iso.y(), iso.z() ); 829 } else { 830 targetParticle.SetMomentum( pseudoParticle[6].GetMomentum() * (pp/pp1) ); 831 } 832 pseudoParticle[5] = pseudoParticle[5] + targetParticle; 833 } 834 else if (backwardNucleonCount > 1) 835 { 836 const G4double cpar[] = { 1.60, 1.35, 1.15, 1.10 }; 837 const G4double gpar[] = { 2.60, 1.80, 1.30, 1.20 }; 838 839 G4int tempCount = 5; 840 if (backwardNucleonCount < 5) tempCount = backwardNucleonCount; 841 tempCount -= 2; 842 843 G4double rmb = 0.; 844 if( targetParticle.GetSide() == -3 ) rmb += targetParticle.GetMass()/GeV; 845 for( i=0; i<vecLen; ++i ) 846 { 847 if( vec[i]->GetSide() == -3 ) rmb += vec[i]->GetMass()/GeV; 848 } 849 rmb += std::pow(-std::log(1.0-G4UniformRand()),1./cpar[tempCount]) / gpar[tempCount]; 850 totalEnergy = pseudoParticle[6].GetTotalEnergy()/GeV; 851 vecMass = std::min( rmb, totalEnergy ); 852 pseudoParticle[6].SetMass( vecMass*GeV ); 853 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - vecMass*vecMass ) )*GeV; 854 pp1 = pseudoParticle[6].GetMomentum().mag()/MeV; 855 if( pp1 < 1.0e-6*GeV ) { 856 G4ThreeVector iso = Isotropic(pp); 857 pseudoParticle[6].SetMomentum( iso.x(), iso.y(), iso.z() ); 858 } else { 859 pseudoParticle[6].SetMomentum( pseudoParticle[6].GetMomentum() * (-pp/pp1) ); 860 } 861 G4FastVector<G4ReactionProduct,256> tempV; // tempV contains the backward nucleons 862 tempV.Initialize( backwardNucleonCount ); 863 G4int tempLen = 0; 864 if( targetParticle.GetSide() == -3 )tempV.SetElement( tempLen++, &targetParticle ); 865 for( i=0; i<vecLen; ++i ) 866 { 867 if( vec[i]->GetSide() == -3 )tempV.SetElement( tempLen++, vec[i] ); 868 } 869 if( tempLen != backwardNucleonCount ) 870 { 871 G4cerr << "tempLen is not the same as backwardNucleonCount" << G4endl; 872 G4cerr << "tempLen = " << tempLen; 873 G4cerr << ", backwardNucleonCount = " << backwardNucleonCount << G4endl; 874 G4cerr << "targetParticle side = " << targetParticle.GetSide() << G4endl; 875 G4cerr << "currentParticle side = " << currentParticle.GetSide() << G4endl; 876 for( i=0; i<vecLen; ++i ) 877 G4cerr << "particle #" << i << " side = " << vec[i]->GetSide() << G4endl; 878 exit( EXIT_FAILURE ); 879 } 880 constantCrossSection = true; 881 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 882 if( tempLen >= 2 ) 883 { 884 wgt = GenerateNBodyEvent( 885 pseudoParticle[6].GetMass(), constantCrossSection, tempV, tempLen ); 886 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 887 if( targetParticle.GetSide() == -3 ) 888 { 889 targetParticle.Lorentz( targetParticle, pseudoParticle[6] ); 890 // tempV contains the real stuff 891 pseudoParticle[5] = pseudoParticle[5] + targetParticle; 892 } 893 for( i=0; i<vecLen; ++i ) 894 { 895 if( vec[i]->GetSide() == -3 ) 896 { 897 vec[i]->Lorentz( *vec[i], pseudoParticle[6] ); 898 pseudoParticle[5] = pseudoParticle[5] + (*vec[i]); 899 } 900 } 901 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 902 } 903 } 904 else return false; 905 906 // 907 // Lorentz transformation in lab system 908 // 909 if( vecLen == 0 )return false; // all the secondaries have been eliminated 910 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 911 912 currentParticle.Lorentz( currentParticle, pseudoParticle[1] ); 913 targetParticle.Lorentz( targetParticle, pseudoParticle[1] ); 914 for( i=0; i<vecLen; ++i ) vec[i]->Lorentz( *vec[i], pseudoParticle[1] ); 915 916 // leadFlag will be true if original particle and incident particle are 917 // both strange, in which case the incident particle becomes the leading 918 // particle. 919 // leadFlag will also be true if the target particle is strange, but the 920 // incident particle is not, in which case the target particle becomes the 921 // leading particle. 922 923 G4bool leadingStrangeParticleHasChanged = true; 924 if( leadFlag ) 925 { 926 if( currentParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() ) 927 leadingStrangeParticleHasChanged = false; 928 if( leadingStrangeParticleHasChanged && 929 ( targetParticle.GetDefinition() == leadingStrangeParticle.GetDefinition() ) ) 930 leadingStrangeParticleHasChanged = false; 931 if( leadingStrangeParticleHasChanged ) 932 { 933 for( i=0; i<vecLen; i++ ) 934 { 935 if( vec[i]->GetDefinition() == leadingStrangeParticle.GetDefinition() ) 936 { 937 leadingStrangeParticleHasChanged = false; 938 break; 939 } 940 } 941 } 942 if( leadingStrangeParticleHasChanged ) 943 { 944 G4bool leadTest = 945 (leadingStrangeParticle.GetDefinition()->GetParticleSubType() == "kaon" || 946 leadingStrangeParticle.GetDefinition()->GetParticleSubType() == "pi"); 947 G4bool targetTest = 948 (targetParticle.GetDefinition()->GetParticleSubType() == "kaon" || 949 targetParticle.GetDefinition()->GetParticleSubType() == "pi"); 950 951 // following modified by JLC 22-Oct-97 952 953 if( (leadTest&&targetTest) || !(leadTest||targetTest) ) // both true or both false 954 { 955 targetParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() ); 956 targetHasChanged = true; 957 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 958 } 959 else 960 { 961 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() ); 962 incidentHasChanged = false; 963 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 964 } 965 } 966 } // end of if( leadFlag ) 967 968 // Get number of final state nucleons and nucleons remaining in 969 // target nucleus 970 971 std::pair<G4int, G4int> finalStateNucleons = 972 GetFinalStateNucleons(originalTarget, vec, vecLen); 973 974 G4int protonsInFinalState = finalStateNucleons.first; 975 G4int neutronsInFinalState = finalStateNucleons.second; 976 977 G4int numberofFinalStateNucleons = 978 protonsInFinalState + neutronsInFinalState; 979 980 if (currentParticle.GetDefinition()->GetBaryonNumber() == 1 && 981 targetParticle.GetDefinition()->GetBaryonNumber() == 1 && 982 originalIncident->GetDefinition()->GetPDGMass() < 983 G4Lambda::Lambda()->GetPDGMass()) 984 numberofFinalStateNucleons++; 985 986 numberofFinalStateNucleons = std::max(1, numberofFinalStateNucleons); 987 988 G4int PinNucleus = std::max(0, 989 G4int(targetNucleus.GetZ()) - protonsInFinalState); 990 G4int NinNucleus = std::max(0, 991 G4int(targetNucleus.GetN()-targetNucleus.GetZ()) - neutronsInFinalState); 992 993 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*GeV ); 994 pseudoParticle[3].SetMass( mOriginal*GeV ); 995 pseudoParticle[3].SetTotalEnergy( 996 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV ); 997 998 G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition(); 999 G4int diff = 0; 1000 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1; 1001 if(numberofFinalStateNucleons == 1) diff = 0; 1002 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 ); 1003 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-diff)*MeV ); 1004 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff)*MeV ); 1005 1006 G4double theoreticalKinetic = 1007 pseudoParticle[3].GetTotalEnergy()/MeV + 1008 pseudoParticle[4].GetTotalEnergy()/MeV - 1009 currentParticle.GetMass()/MeV - 1010 targetParticle.GetMass()/MeV; 1011 1012 G4double simulatedKinetic = 1013 currentParticle.GetKineticEnergy()/MeV + targetParticle.GetKineticEnergy()/MeV; 1014 1015 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4]; 1016 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] ); 1017 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] ); 1018 1019 pseudoParticle[7].SetZero(); 1020 pseudoParticle[7] = pseudoParticle[7] + currentParticle; 1021 pseudoParticle[7] = pseudoParticle[7] + targetParticle; 1022 1023 for( i=0; i<vecLen; ++i ) 1024 { 1025 pseudoParticle[7] = pseudoParticle[7] + *vec[i]; 1026 simulatedKinetic += vec[i]->GetKineticEnergy()/MeV; 1027 theoreticalKinetic -= vec[i]->GetMass()/MeV; 1028 } 1029 838 currentParticle.SetDefinitionAndUpdateE( leadingStrangeParticle.GetDefinition() ); 839 incidentHasChanged = false; 840 } 841 } 842 } // end of if( leadFlag ) 843 844 // Get number of final state nucleons and nucleons remaining in 845 // target nucleus 846 847 std::pair<G4int, G4int> finalStateNucleons = 848 GetFinalStateNucleons(originalTarget, vec, vecLen); 849 850 G4int protonsInFinalState = finalStateNucleons.first; 851 G4int neutronsInFinalState = finalStateNucleons.second; 852 853 G4int numberofFinalStateNucleons = 854 protonsInFinalState + neutronsInFinalState; 855 856 if (currentParticle.GetDefinition()->GetBaryonNumber() == 1 && 857 targetParticle.GetDefinition()->GetBaryonNumber() == 1 && 858 originalIncident->GetDefinition()->GetPDGMass() < 859 G4Lambda::Lambda()->GetPDGMass()) 860 numberofFinalStateNucleons++; 861 862 numberofFinalStateNucleons = std::max(1, numberofFinalStateNucleons); 863 864 G4int PinNucleus = std::max(0, 865 G4int(targetNucleus.GetZ()) - protonsInFinalState); 866 G4int NinNucleus = std::max(0, 867 G4int(targetNucleus.GetN()-targetNucleus.GetZ()) - neutronsInFinalState); 868 869 pseudoParticle[3].SetMomentum( 0.0, 0.0, pOriginal*GeV ); 870 pseudoParticle[3].SetMass( mOriginal*GeV ); 871 pseudoParticle[3].SetTotalEnergy( 872 std::sqrt( pOriginal*pOriginal + mOriginal*mOriginal )*GeV ); 873 874 G4ParticleDefinition * aOrgDef = modifiedOriginal.GetDefinition(); 875 G4int diff = 0; 876 if(aOrgDef == G4Proton::Proton() || aOrgDef == G4Neutron::Neutron() ) diff = 1; 877 if(numberofFinalStateNucleons == 1) diff = 0; 878 pseudoParticle[4].SetMomentum( 0.0, 0.0, 0.0 ); 879 pseudoParticle[4].SetMass( protonMass*(numberofFinalStateNucleons-diff) ); 880 pseudoParticle[4].SetTotalEnergy( protonMass*(numberofFinalStateNucleons-diff) ); 881 882 G4double theoreticalKinetic = 883 pseudoParticle[3].GetTotalEnergy() + pseudoParticle[4].GetTotalEnergy() - 884 currentParticle.GetMass() - targetParticle.GetMass(); 885 for (i = 0; i < vecLen; ++i) theoreticalKinetic -= vec[i]->GetMass(); 886 887 G4double simulatedKinetic = 888 currentParticle.GetKineticEnergy() + targetParticle.GetKineticEnergy(); 889 for (i = 0; i < vecLen; ++i) 890 simulatedKinetic += vec[i]->GetKineticEnergy(); 891 892 pseudoParticle[5] = pseudoParticle[3] + pseudoParticle[4]; 893 pseudoParticle[3].Lorentz( pseudoParticle[3], pseudoParticle[5] ); 894 pseudoParticle[4].Lorentz( pseudoParticle[4], pseudoParticle[5] ); 895 896 pseudoParticle[7].SetZero(); 897 pseudoParticle[7] = pseudoParticle[7] + currentParticle; 898 pseudoParticle[7] = pseudoParticle[7] + targetParticle; 899 for (i = 0; i < vecLen; ++i) 900 pseudoParticle[7] = pseudoParticle[7] + *vec[i]; 901 902 /* 903 // This code does not appear to do anything to the energy or angle spectra 1030 904 if( vecLen <= 16 && vecLen > 0 ) 1031 905 { … … 1037 911 tempR[1] = targetParticle; 1038 912 for( i=0; i<vecLen; ++i )tempR[i+2] = *vec[i]; 1039 G4FastVector<G4ReactionProduct,256> tempV ;1040 tempV .Initialize( vecLen+2 );1041 G4int tempLen = 0;1042 for( i=0; i<vecLen+2; ++i )tempV .SetElement( tempLen++, &tempR[i] );913 G4FastVector<G4ReactionProduct,256> tempV1; 914 tempV1.Initialize( vecLen+2 ); 915 G4int tempLen1 = 0; 916 for( i=0; i<vecLen+2; ++i )tempV1.SetElement( tempLen1++, &tempR[i] ); 1043 917 constantCrossSection = true; 1044 918 1045 wgt = GenerateNBodyEvent( pseudoParticle[3].GetTotalEnergy()/MeV+1046 pseudoParticle[4].GetTotalEnergy()/MeV,1047 constantCrossSection, tempV, tempLen);919 wgt = GenerateNBodyEvent(pseudoParticle[3].GetTotalEnergy() + 920 pseudoParticle[4].GetTotalEnergy(), 921 constantCrossSection, tempV1, tempLen1); 1048 922 if (wgt == -1) { 1049 923 G4double Qvalue = 0; 1050 for (i = 0; i < tempLen ; i++) Qvalue += tempV[i]->GetMass();1051 wgt = GenerateNBodyEvent( Qvalue/MeV,1052 constantCrossSection, tempV, tempLen);924 for (i = 0; i < tempLen1; i++) Qvalue += tempV1[i]->GetMass(); 925 wgt = GenerateNBodyEvent(Qvalue, 926 constantCrossSection, tempV1, tempLen1); 1053 927 } 1054 928 if(wgt>-.5) 1055 929 { 1056 930 theoreticalKinetic = 0.0; 1057 for( i=0; i<tempLen ; ++i )931 for( i=0; i<tempLen1; ++i ) 1058 932 { 1059 pseudoParticle[6].Lorentz( *tempV [i], pseudoParticle[4] );1060 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy() /MeV;933 pseudoParticle[6].Lorentz( *tempV1[i], pseudoParticle[4] ); 934 theoreticalKinetic += pseudoParticle[6].GetKineticEnergy(); 1061 935 } 1062 936 } 1063 937 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 1064 938 } 1065 // 1066 // Make sure, that the kinetic energies are correct 1067 // 1068 if( simulatedKinetic != 0.0 ) 1069 { 1070 wgt = (theoreticalKinetic)/simulatedKinetic; 1071 theoreticalKinetic = currentParticle.GetKineticEnergy()/MeV * wgt; 1072 simulatedKinetic = theoreticalKinetic; 1073 currentParticle.SetKineticEnergy( theoreticalKinetic*MeV ); 1074 pp = currentParticle.GetTotalMomentum()/MeV; 1075 pp1 = currentParticle.GetMomentum().mag()/MeV; 939 */ 940 941 // 942 // Make sure that the kinetic energies are correct 943 // 944 945 if (simulatedKinetic != 0.0) { 946 wgt = theoreticalKinetic/simulatedKinetic; 947 theoreticalKinetic = currentParticle.GetKineticEnergy() * wgt; 948 simulatedKinetic = theoreticalKinetic; 949 currentParticle.SetKineticEnergy(theoreticalKinetic); 950 pp = currentParticle.GetTotalMomentum(); 951 pp1 = currentParticle.GetMomentum().mag(); 952 if (pp1 < 1.0e-6*GeV) { 953 G4ThreeVector iso = Isotropic(pp); 954 currentParticle.SetMomentum( iso.x(), iso.y(), iso.z() ); 955 } else { 956 currentParticle.SetMomentum(currentParticle.GetMomentum() * (pp/pp1)); 957 } 958 959 theoreticalKinetic = targetParticle.GetKineticEnergy() * wgt; 960 targetParticle.SetKineticEnergy(theoreticalKinetic); 961 simulatedKinetic += theoreticalKinetic; 962 pp = targetParticle.GetTotalMomentum(); 963 pp1 = targetParticle.GetMomentum().mag(); 964 965 if (pp1 < 1.0e-6*GeV) { 966 G4ThreeVector iso = Isotropic(pp); 967 targetParticle.SetMomentum(iso.x(), iso.y(), iso.z() ); 968 } else { 969 targetParticle.SetMomentum(targetParticle.GetMomentum() * (pp/pp1) ); 970 } 971 972 for (i = 0; i < vecLen; ++i ) { 973 theoreticalKinetic = vec[i]->GetKineticEnergy() * wgt; 974 simulatedKinetic += theoreticalKinetic; 975 vec[i]->SetKineticEnergy(theoreticalKinetic); 976 pp = vec[i]->GetTotalMomentum(); 977 pp1 = vec[i]->GetMomentum().mag(); 1076 978 if( pp1 < 1.0e-6*GeV ) { 1077 979 G4ThreeVector iso = Isotropic(pp); 1078 currentParticle.SetMomentum(iso.x(), iso.y(), iso.z() );980 vec[i]->SetMomentum(iso.x(), iso.y(), iso.z() ); 1079 981 } else { 1080 currentParticle.SetMomentum( currentParticle.GetMomentum() * (pp/pp1) ); 1081 } 1082 theoreticalKinetic = targetParticle.GetKineticEnergy()/MeV * wgt; 1083 targetParticle.SetKineticEnergy( theoreticalKinetic*MeV ); 1084 simulatedKinetic += theoreticalKinetic; 1085 pp = targetParticle.GetTotalMomentum()/MeV; 1086 pp1 = targetParticle.GetMomentum().mag()/MeV; 1087 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 1088 if( pp1 < 1.0e-6*GeV ) { 1089 G4ThreeVector iso = Isotropic(pp); 1090 targetParticle.SetMomentum( iso.x(), iso.y(), iso.z() ); 1091 } else { 1092 targetParticle.SetMomentum( targetParticle.GetMomentum() * (pp/pp1) ); 1093 } 1094 1095 for( i=0; i<vecLen; ++i ) { 1096 theoreticalKinetic = vec[i]->GetKineticEnergy()/MeV * wgt; 1097 simulatedKinetic += theoreticalKinetic; 1098 vec[i]->SetKineticEnergy( theoreticalKinetic*MeV ); 1099 pp = vec[i]->GetTotalMomentum()/MeV; 1100 pp1 = vec[i]->GetMomentum().mag()/MeV; 1101 if( pp1 < 1.0e-6*GeV ) { 1102 G4ThreeVector iso = Isotropic(pp); 1103 vec[i]->SetMomentum( iso.x(), iso.y(), iso.z() ); 1104 } else { 1105 vec[i]->SetMomentum( vec[i]->GetMomentum() * (pp/pp1) ); 1106 } 1107 } 1108 } 1109 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 1110 1111 Rotate( numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(), 1112 modifiedOriginal, originalIncident, targetNucleus, 1113 currentParticle, targetParticle, vec, vecLen ); 1114 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 1115 // 1116 // add black track particles 1117 // the total number of particles produced is restricted to 198 1118 // this may have influence on very high energies 1119 // 1120 if( atomicWeight >= 1.5 ) 982 vec[i]->SetMomentum(vec[i]->GetMomentum() * (pp/pp1) ); 983 } 984 } 985 } 986 987 // Rotate(numberofFinalStateNucleons, pseudoParticle[3].GetMomentum(), 988 // modifiedOriginal, originalIncident, targetNucleus, 989 // currentParticle, targetParticle, vec, vecLen ); 990 991 // Add black track particles 992 // the total number of particles produced is restricted to 198 993 // this may have influence on very high energies 994 995 if( atomicWeight >= 1.5 ) 996 { 997 // npnb is number of proton/neutron black track particles 998 // ndta is the number of deuterons, tritons, and alphas produced 999 // epnb is the kinetic energy available for proton/neutron black track 1000 // particles 1001 // edta is the kinetic energy available for deuteron/triton/alpha particles 1002 1003 G4int npnb = 0; 1004 G4int ndta = 0; 1005 1006 G4double epnb, edta; 1007 if (veryForward) { 1008 epnb = targetNucleus.GetAnnihilationPNBlackTrackEnergy(); 1009 edta = targetNucleus.GetAnnihilationDTABlackTrackEnergy(); 1010 } else { 1011 epnb = targetNucleus.GetPNBlackTrackEnergy(); 1012 edta = targetNucleus.GetDTABlackTrackEnergy(); 1013 } 1014 /* 1015 G4ReactionProduct* fudge = new G4ReactionProduct(); 1016 fudge->SetDefinition( aProton ); 1017 G4double TT = epnb + edta; 1018 G4double MM = fudge->GetMass()/GeV; 1019 fudge->SetTotalEnergy(MM*GeV + TT*GeV); 1020 G4double pzz = std::sqrt(TT*(TT + 2.*MM)); 1021 fudge->SetMomentum(0.0, 0.0, pzz*GeV); 1022 vec.SetElement(vecLen++, fudge); 1023 // G4cout << " Fudge = " << vec[vecLen-1]->GetKineticEnergy()/GeV 1024 << G4endl; 1025 */ 1026 1027 const G4double pnCutOff = 0.001; 1028 const G4double dtaCutOff = 0.001; 1029 // const G4double kineticMinimum = 1.e-6; 1030 // const G4double kineticFactor = -0.010; 1031 // G4double sprob = 0.0; // sprob = probability of self-absorption in 1032 // heavy molecules 1033 // Not currently used (DHW 9 June 2008) const G4double ekIncident = originalIncident->GetKineticEnergy()/GeV; 1034 // if (ekIncident >= 5.0) sprob = std::min(1.0, 0.6*std::log(ekIncident-4.0)); 1035 if (epnb > pnCutOff) 1121 1036 { 1122 // npnb is number of proton/neutron black track particles 1123 // ndta is the number of deuterons, tritons, and alphas produced 1124 // epnb is the kinetic energy available for proton/neutron black track particles 1125 // edta is the kinetic energy available for deuteron/triton/alpha particles 1126 // 1127 G4int npnb = 0; 1128 G4int ndta = 0; 1129 1130 G4double epnb, edta; 1131 if (veryForward) { 1132 epnb = targetNucleus.GetAnnihilationPNBlackTrackEnergy(); 1133 edta = targetNucleus.GetAnnihilationDTABlackTrackEnergy(); 1134 } else { 1135 epnb = targetNucleus.GetPNBlackTrackEnergy(); 1136 edta = targetNucleus.GetDTABlackTrackEnergy(); 1137 } 1138 1139 const G4double pnCutOff = 0.001; 1140 const G4double dtaCutOff = 0.001; 1141 const G4double kineticMinimum = 1.e-6; 1142 const G4double kineticFactor = -0.010; 1143 G4double sprob = 0.0; // sprob = probability of self-absorption in heavy molecules 1144 const G4double ekIncident = originalIncident->GetKineticEnergy()/GeV; 1145 if( ekIncident >= 5.0 )sprob = std::min( 1.0, 0.6*std::log(ekIncident-4.0) ); 1146 if( epnb >= pnCutOff ) 1147 { 1148 npnb = G4Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta)); 1149 if( numberofFinalStateNucleons + npnb > atomicWeight ) 1150 npnb = G4int(atomicWeight+0.00001 - numberofFinalStateNucleons); 1151 npnb = std::min( npnb, 127-vecLen ); 1152 } 1153 if( edta >= dtaCutOff ) 1154 { 1155 ndta = G4Poisson( (1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta) ); 1156 ndta = std::min( ndta, 127-vecLen ); 1157 } 1158 if (npnb == 0 && ndta == 0) npnb = 1; 1159 1160 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 1161 1162 AddBlackTrackParticles(epnb, npnb, edta, ndta, sprob, kineticMinimum, 1163 kineticFactor, modifiedOriginal, 1164 PinNucleus, NinNucleus, targetNucleus, 1165 vec, vecLen); 1166 } 1037 npnb = G4Poisson((1.5+1.25*numberofFinalStateNucleons)*epnb/(epnb+edta)); 1038 if (numberofFinalStateNucleons + npnb > atomicWeight) 1039 npnb = G4int(atomicWeight+0.00001 - numberofFinalStateNucleons); 1040 npnb = std::min( npnb, 127-vecLen ); 1041 } 1042 if( edta >= dtaCutOff ) 1043 { 1044 ndta = G4Poisson((1.5+1.25*numberofFinalStateNucleons)*edta/(epnb+edta)); 1045 ndta = std::min( ndta, 127-vecLen ); 1046 } 1047 if (npnb == 0 && ndta == 0) npnb = 1; 1048 1049 AddBlackTrackParticles(epnb, npnb, edta, ndta, modifiedOriginal, 1050 PinNucleus, NinNucleus, targetNucleus, 1051 vec, vecLen); 1052 } 1053 1167 1054 // if( centerofmassEnergy <= (4.0+G4UniformRand()) ) 1168 1055 // MomentumCheck( modifiedOriginal, currentParticle, targetParticle, … … 1171 1058 // calculate time delay for nuclear reactions 1172 1059 // 1060 1173 1061 if( (atomicWeight >= 1.5) && (atomicWeight <= 230.0) && (ekOriginal <= 0.2) ) 1174 1062 currentParticle.SetTOF( … … 1179 1067 1180 1068 } 1181 1069 1070 1071 void G4RPGFragmentation:: 1072 ReduceEnergiesOfSecondaries(G4int startingIndex, 1073 G4double& forwardKinetic, 1074 G4double& backwardKinetic, 1075 G4FastVector<G4ReactionProduct,256>& vec, 1076 G4int& vecLen, 1077 G4ReactionProduct& forwardPseudoParticle, 1078 G4ReactionProduct& backwardPseudoParticle, 1079 G4double& pt) 1080 { 1081 // Reduce energies and pt of secondaries in order to maintain 1082 // energy conservation 1083 1084 G4double totalEnergy; 1085 G4double pp; 1086 G4double pp1; 1087 G4double px; 1088 G4double py; 1089 G4double mass; 1090 G4ReactionProduct* pVec; 1091 G4int i; 1092 1093 forwardKinetic = 0.0; 1094 backwardKinetic = 0.0; 1095 forwardPseudoParticle.SetZero(); 1096 backwardPseudoParticle.SetZero(); 1097 1098 for (i = startingIndex; i < vecLen; i++) { 1099 pVec = vec[i]; 1100 if (pVec->GetSide() != -3) { 1101 mass = pVec->GetMass(); 1102 totalEnergy = 0.95*pVec->GetTotalEnergy() + 0.05*mass; 1103 pVec->SetTotalEnergy(totalEnergy); 1104 pp = std::sqrt( std::abs( totalEnergy*totalEnergy - mass*mass ) ); 1105 pp1 = pVec->GetMomentum().mag(); 1106 if (pp1 < 1.0e-6*GeV) { 1107 G4ThreeVector iso = Isotropic(pp); 1108 pVec->SetMomentum( iso.x(), iso.y(), iso.z() ); 1109 } else { 1110 pVec->SetMomentum(pVec->GetMomentum() * (pp/pp1) ); 1111 } 1112 1113 px = pVec->GetMomentum().x(); 1114 py = pVec->GetMomentum().y(); 1115 pt = std::max(1.0, std::sqrt( px*px + py*py ) )/GeV; 1116 if (pVec->GetSide() > 0) { 1117 forwardKinetic += pVec->GetKineticEnergy()/GeV; 1118 forwardPseudoParticle = forwardPseudoParticle + (*pVec); 1119 } else { 1120 backwardKinetic += pVec->GetKineticEnergy()/GeV; 1121 backwardPseudoParticle = backwardPseudoParticle + (*pVec); 1122 } 1123 } 1124 } 1125 } 1126 1182 1127 /* end of file */ -
trunk/source/processes/hadronic/models/rpg/src/G4RPGInelastic.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGInelastic.cc,v 1. 2 2007/08/15 20:38:25dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGInelastic.cc,v 1.6 2008/03/22 00:03:24 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 … … 168 168 } 169 169 170 void G4RPGInelastic::CalculateMomenta(171 G4FastVector<G4ReactionProduct,256> &vec,172 G4int &vecLen,173 const G4HadProjectile *originalIncident,174 const G4DynamicParticle *originalTarget,175 G4ReactionProduct &modifiedOriginal,176 G4Nucleus &targetNucleus,177 G4ReactionProduct ¤tParticle,178 G4ReactionProduct &targetParticle,179 G4bool &incidentHasChanged,180 G4bool &targetHasChanged,181 G4bool quasiElastic)170 void 171 G4RPGInelastic::CalculateMomenta(G4FastVector<G4ReactionProduct,256>& vec, 172 G4int& vecLen, 173 const G4HadProjectile* originalIncident, 174 const G4DynamicParticle* originalTarget, 175 G4ReactionProduct& modifiedOriginal, 176 G4Nucleus& targetNucleus, 177 G4ReactionProduct& currentParticle, 178 G4ReactionProduct& targetParticle, 179 G4bool& incidentHasChanged, 180 G4bool& targetHasChanged, 181 G4bool quasiElastic) 182 182 { 183 183 cache = 0; … … 186 186 G4ReactionProduct leadingStrangeParticle; 187 187 188 strangeProduction.ReactionStage(originalIncident, modifiedOriginal,189 incidentHasChanged, originalTarget,190 targetParticle, targetHasChanged,191 targetNucleus, currentParticle,192 vec, vecLen,193 false, leadingStrangeParticle);188 // strangeProduction.ReactionStage(originalIncident, modifiedOriginal, 189 // incidentHasChanged, originalTarget, 190 // targetParticle, targetHasChanged, 191 // targetNucleus, currentParticle, 192 // vec, vecLen, 193 // false, leadingStrangeParticle); 194 194 195 195 if( quasiElastic ) … … 266 266 for (G4int i = 0; i < vecLen; i++) savevec.push_back(*vec[i]); 267 267 268 if( annihilation || (vecLen >= 6) || 269 (modifiedOriginal.GetKineticEnergy()/GeV >= 1.0) && 268 // Call fragmentation code if 269 // 1) there is annihilation, or 270 // 2) there are more than 5 secondaries, or 271 // 3) incident KE is > 1 GeV AND 272 // ( incident is a kaon AND rand < 0.5 OR twsup ) 273 // 274 275 if( annihilation || vecLen > 5 || 276 ( modifiedOriginal.GetKineticEnergy()/GeV >= 1.0 && 277 270 278 (((originalIncident->GetDefinition() == G4KaonPlus::KaonPlus() || 271 279 originalIncident->GetDefinition() == G4KaonMinus::KaonMinus() || 272 280 originalIncident->GetDefinition() == G4KaonZeroLong::KaonZeroLong() || 273 281 originalIncident->GetDefinition() == G4KaonZeroShort::KaonZeroShort()) && 274 rand1 < 0.5) || rand2 > twsup[vecLen]) ) 282 rand1 < 0.5) 283 || rand2 > twsup[vecLen]) ) ) 275 284 276 285 finishedGenXPt = … … 282 291 leadFlag, leadingStrangeParticle); 283 292 284 if( finishedGenXPt ) 285 { 286 Rotate(vec, vecLen); 287 return; 288 } 293 if (finishedGenXPt) return; 289 294 290 295 G4bool finishedTwoClu = false; 291 if( modifiedOriginal.GetTotalMomentum()/MeV < 1.0 ) 292 {293 for (G4int i=0; i<vecLen; i++) delete vec[i];296 297 if (modifiedOriginal.GetTotalMomentum() < 1.0) { 298 for (G4int i = 0; i < vecLen; i++) delete vec[i]; 294 299 vecLen = 0; 295 } 296 else 297 { 300 301 } else { 298 302 // Occaisionally, GenerateXandPt will fail in the annihilation channel. 299 303 // Restore current, target and secondaries to pre-GenerateXandPt state … … 313 317 } 314 318 315 pionSuppression.ReactionStage(originalIncident, modifiedOriginal, 316 incidentHasChanged, originalTarget, 317 targetParticle, targetHasChanged, 318 targetNucleus, currentParticle, 319 vec, vecLen, 320 false, leadingStrangeParticle); 319 // Big violations of energy conservation in this method - don't use 320 // 321 // pionSuppression.ReactionStage(originalIncident, modifiedOriginal, 322 // incidentHasChanged, originalTarget, 323 // targetParticle, targetHasChanged, 324 // targetNucleus, currentParticle, 325 // vec, vecLen, 326 // false, leadingStrangeParticle); 321 327 322 328 try … … 337 343 } 338 344 339 if( finishedTwoClu ) 340 { 341 Rotate(vec, vecLen); 342 return; 343 } 345 if (finishedTwoClu) return; 344 346 345 347 twoBody.ReactionStage(originalIncident, modifiedOriginal, … … 351 353 } 352 354 353 355 /* 354 356 void G4RPGInelastic:: 355 357 Rotate(G4FastVector<G4ReactionProduct,256> &vec, G4int &vecLen) … … 365 367 } 366 368 } 369 */ 367 370 368 371 void 369 G4RPGInelastic::SetUpChange(G4FastVector<G4ReactionProduct,256> &vec,370 G4int &vecLen,371 G4ReactionProduct ¤tParticle,372 G4ReactionProduct &targetParticle,373 G4bool &incidentHasChanged )372 G4RPGInelastic::SetUpChange(G4FastVector<G4ReactionProduct,256>& vec, 373 G4int& vecLen, 374 G4ReactionProduct& currentParticle, 375 G4ReactionProduct& targetParticle, 376 G4bool& incidentHasChanged ) 374 377 { 375 378 theParticleChange.Clear(); 376 G4ParticleDefinition *aKaonZL = G4KaonZeroLong::KaonZeroLong();377 G4ParticleDefinition *aKaonZS = G4KaonZeroShort::KaonZeroShort();379 G4ParticleDefinition* aKaonZL = G4KaonZeroLong::KaonZeroLong(); 380 G4ParticleDefinition* aKaonZS = G4KaonZeroShort::KaonZeroShort(); 378 381 G4int i; 379 if( currentParticle.GetDefinition() == aKaonZL ) 380 { 381 if( G4UniformRand() <= 0.5 ) 382 { 383 currentParticle.SetDefinition( aKaonZS ); 382 383 if (currentParticle.GetDefinition() == particleDef[k0]) { 384 if (G4UniformRand() < 0.5) { 385 currentParticle.SetDefinitionAndUpdateE(aKaonZL); 384 386 incidentHasChanged = true; 385 } 386 } 387 else if( currentParticle.GetDefinition() == aKaonZS ) 388 { 389 if( G4UniformRand() > 0.5 ) 390 { 391 currentParticle.SetDefinition( aKaonZL ); 387 } else { 388 currentParticle.SetDefinitionAndUpdateE(aKaonZS); 389 } 390 } else if (currentParticle.GetDefinition() == particleDef[k0b]) { 391 if (G4UniformRand() < 0.5) { 392 currentParticle.SetDefinitionAndUpdateE(aKaonZL); 393 } else { 394 currentParticle.SetDefinitionAndUpdateE(aKaonZS); 392 395 incidentHasChanged = true; 393 396 } 394 397 } 395 398 396 if( targetParticle.GetDefinition() == aKaonZL ) 397 { 398 if( G4UniformRand() <= 0.5 )targetParticle.SetDefinition( aKaonZS ); 399 } 400 else if( targetParticle.GetDefinition() == aKaonZS ) 401 { 402 if( G4UniformRand() > 0.5 )targetParticle.SetDefinition( aKaonZL ); 403 } 404 for( i=0; i<vecLen; ++i ) 405 { 406 if( vec[i]->GetDefinition() == aKaonZL ) 407 { 408 if( G4UniformRand() <= 0.5 )vec[i]->SetDefinition( aKaonZS ); 409 } 410 else if( vec[i]->GetDefinition() == aKaonZS ) 411 { 412 if( G4UniformRand() > 0.5 )vec[i]->SetDefinition( aKaonZL ); 413 } 414 } 415 416 if( incidentHasChanged ) 417 { 399 if (targetParticle.GetDefinition() == particleDef[k0] || 400 targetParticle.GetDefinition() == particleDef[k0b] ) { 401 if (G4UniformRand() < 0.5) { 402 targetParticle.SetDefinitionAndUpdateE(aKaonZL); 403 } else { 404 targetParticle.SetDefinitionAndUpdateE(aKaonZS); 405 } 406 } 407 408 for (i = 0; i < vecLen; ++i) { 409 if (vec[i]->GetDefinition() == particleDef[k0] || 410 vec[i]->GetDefinition() == particleDef[k0b] ) { 411 if (G4UniformRand() < 0.5) { 412 vec[i]->SetDefinitionAndUpdateE(aKaonZL); 413 } else { 414 vec[i]->SetDefinitionAndUpdateE(aKaonZS); 415 } 416 } 417 } 418 419 if (incidentHasChanged) { 418 420 G4DynamicParticle* p0 = new G4DynamicParticle; 419 p0->SetDefinition( currentParticle.GetDefinition() );420 p0->SetMomentum( currentParticle.GetMomentum() );421 p0->SetDefinition(currentParticle.GetDefinition() ); 422 p0->SetMomentum(currentParticle.GetMomentum() ); 421 423 theParticleChange.AddSecondary( p0 ); 422 424 theParticleChange.SetStatusChange( stopAndKill ); 423 425 theParticleChange.SetEnergyChange( 0.0 ); 424 } 425 else 426 { 426 427 } else { 427 428 G4double p = currentParticle.GetMomentum().mag()/MeV; 428 429 G4ThreeVector m = currentParticle.GetMomentum(); 429 if ( p > DBL_MIN)430 if (p > DBL_MIN) 430 431 theParticleChange.SetMomentumChange( m.x()/p, m.y()/p, m.z()/p ); 431 432 else … … 437 438 } 438 439 439 if ( targetParticle.GetMass() > 0.0) // Tgt particle can be eliminated in TwoBody440 if (targetParticle.GetMass() > 0.0) // Tgt particle can be eliminated in TwoBody 440 441 { 441 442 G4ThreeVector momentum = targetParticle.GetMomentum(); … … 455 456 456 457 G4DynamicParticle* p; 457 for( i=0; i<vecLen; ++i ) 458 { 458 for (i = 0; i < vecLen; ++i) { 459 459 G4double secKE = vec[i]->GetKineticEnergy(); 460 460 G4ThreeVector momentum = vec[i]->GetMomentum(); … … 470 470 } 471 471 } 472 472 473 474 std::pair<G4int, G4double> 475 G4RPGInelastic::interpolateEnergy(G4double e) const 476 { 477 G4int index = 29; 478 G4double fraction = 0.0; 479 480 for (G4int i = 1; i < 30; i++) { 481 if (e < energyScale[i]) { 482 index = i-1; 483 fraction = (e - energyScale[index]) / (energyScale[i] - energyScale[index]); 484 break; 485 } 486 } 487 return std::pair<G4int, G4double>(index, fraction); 488 } 489 490 491 G4int 492 G4RPGInelastic::sampleFlat(std::vector<G4double> sigma) const 493 { 494 G4int i; 495 G4double sum(0.); 496 for (i = 0; i < G4int(sigma.size()); i++) sum += sigma[i]; 497 498 G4double fsum = sum*G4UniformRand(); 499 G4double partialSum = 0.0; 500 G4int channel = 0; 501 502 for (i = 0; i < G4int(sigma.size()); i++) { 503 partialSum += sigma[i]; 504 if (fsum < partialSum) { 505 channel = i; 506 break; 507 } 508 } 509 510 return channel; 511 } 512 513 514 void G4RPGInelastic::CheckQnums(G4FastVector<G4ReactionProduct,256> &vec, 515 G4int &vecLen, 516 G4ReactionProduct ¤tParticle, 517 G4ReactionProduct &targetParticle, 518 G4double Q, G4double B, G4double S) 519 { 520 G4ParticleDefinition* projDef = currentParticle.GetDefinition(); 521 G4ParticleDefinition* targDef = targetParticle.GetDefinition(); 522 G4double chargeSum = projDef->GetPDGCharge() + targDef->GetPDGCharge(); 523 G4double baryonSum = projDef->GetBaryonNumber() + targDef->GetBaryonNumber(); 524 G4double strangenessSum = projDef->GetQuarkContent(3) - 525 projDef->GetAntiQuarkContent(3) + 526 targDef->GetQuarkContent(3) - 527 targDef->GetAntiQuarkContent(3); 528 529 G4ParticleDefinition* secDef = 0; 530 for (G4int i = 0; i < vecLen; i++) { 531 secDef = vec[i]->GetDefinition(); 532 chargeSum += secDef->GetPDGCharge(); 533 baryonSum += secDef->GetBaryonNumber(); 534 strangenessSum += secDef->GetQuarkContent(3) 535 - secDef->GetAntiQuarkContent(3); 536 } 537 538 G4bool OK = true; 539 if (chargeSum != Q) { 540 G4cout << " Charge not conserved " << G4endl; 541 OK = false; 542 } 543 if (baryonSum != B) { 544 G4cout << " Baryon number not conserved " << G4endl; 545 OK = false; 546 } 547 if (strangenessSum != S) { 548 G4cout << " Strangeness not conserved " << G4endl; 549 OK = false; 550 } 551 552 if (!OK) { 553 G4cout << " projectile: " << projDef->GetParticleName() 554 << " target: " << targDef->GetParticleName() << G4endl; 555 for (G4int i = 0; i < vecLen; i++) { 556 secDef = vec[i]->GetDefinition(); 557 G4cout << secDef->GetParticleName() << " " ; 558 } 559 G4cout << G4endl; 560 } 561 562 } 563 564 565 const G4double G4RPGInelastic::energyScale[30] = { 566 0.0, 0.01, 0.013, 0.018, 0.024, 0.032, 0.042, 0.056, 0.075, 0.1, 567 0.13, 0.18, 0.24, 0.32, 0.42, 0.56, 0.75, 1.0, 1.3, 1.8, 568 2.4, 3.2, 4.2, 5.6, 7.5, 10.0, 13.0, 18.0, 24.0, 32.0 }; 569 570 G4ParticleDefinition* p0 = G4PionZero::PionZero(); 571 G4ParticleDefinition* p1 = G4PionPlus::PionPlus(); 572 G4ParticleDefinition* p2 = G4PionMinus::PionMinus(); 573 G4ParticleDefinition* p3 = G4KaonPlus::KaonPlus(); 574 G4ParticleDefinition* p4 = G4KaonMinus::KaonMinus(); 575 G4ParticleDefinition* p5 = G4KaonZero::KaonZero(); 576 G4ParticleDefinition* p6 = G4AntiKaonZero::AntiKaonZero(); 577 G4ParticleDefinition* p7 = G4Proton::Proton(); 578 G4ParticleDefinition* p8 = G4Neutron::Neutron(); 579 G4ParticleDefinition* p9 = G4Lambda::Lambda(); 580 G4ParticleDefinition* p10 = G4SigmaPlus::SigmaPlus(); 581 G4ParticleDefinition* p11 = G4SigmaZero::SigmaZero(); 582 G4ParticleDefinition* p12 = G4SigmaMinus::SigmaMinus(); 583 G4ParticleDefinition* p13 = G4XiZero::XiZero(); 584 G4ParticleDefinition* p14 = G4XiMinus::XiMinus(); 585 G4ParticleDefinition* p15 = G4OmegaMinus::OmegaMinus(); 586 G4ParticleDefinition* p16 = G4AntiProton::AntiProton(); 587 G4ParticleDefinition* p17 = G4AntiNeutron::AntiNeutron(); 588 589 G4ParticleDefinition* G4RPGInelastic::particleDef[18] = { 590 p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, 591 p15, p16, p17 }; 592 473 593 /* end of file */ -
trunk/source/processes/hadronic/models/rpg/src/G4RPGKMinusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGKMinusInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGKPlusInelastic.cc
r819 r962 26 26 // 27 27 // $Id: G4RPGKPlusInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 28 // GEANT4 tag $Name: $28 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 29 29 // 30 30 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGKZeroInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGKZeroInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGLambdaInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGLambdaInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGNeutronInelastic.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGNeutronInelastic.cc,v 1. 1 2007/07/18 21:04:20dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGNeutronInelastic.cc,v 1.4 2008/05/05 21:21:55 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 30 30 #include "G4RPGNeutronInelastic.hh" 31 31 #include "Randomize.hh" 32 #include "G4Electron.hh" 33 // #include "DumpFrame.hh" 34 35 G4HadFinalState * 36 G4RPGNeutronInelastic::ApplyYourself( const G4HadProjectile &aTrack, 37 G4Nucleus &targetNucleus ) 38 { 39 theParticleChange.Clear(); 40 const G4HadProjectile *originalIncident = &aTrack; 41 // 42 // create the target particle 43 // 44 G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle(); 45 46 if( verboseLevel > 1 ) 47 { 48 const G4Material *targetMaterial = aTrack.GetMaterial(); 49 G4cout << "G4RPGNeutronInelastic::ApplyYourself called" << G4endl; 50 G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy()/MeV << "MeV, "; 51 G4cout << "target material = " << targetMaterial->GetName() << ", "; 52 G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName() 53 << G4endl; 54 } 55 /* not true, for example for Fe56, etc.. 56 if( originalIncident->GetKineticEnergy()/MeV < 0.000001 ) 57 throw G4HadronicException(__FILE__, __LINE__, "G4RPGNeutronInelastic: should be capture process!"); 58 if( originalIncident->Get4Momentum().vect().mag()/MeV < 0.000001 ) 59 throw G4HadronicException(__FILE__, __LINE__, "G4RPGNeutronInelastic: should be capture process!"); 60 */ 61 62 G4ReactionProduct modifiedOriginal; 63 modifiedOriginal = *originalIncident; 64 G4ReactionProduct targetParticle; 65 targetParticle = *originalTarget; 66 if( originalIncident->GetKineticEnergy()/GeV < 0.01 + 2.*G4UniformRand()/9. ) 67 { 68 SlowNeutron( originalIncident, modifiedOriginal, targetParticle, targetNucleus ); 69 delete originalTarget; 70 return &theParticleChange; 71 } 72 // 73 // Fermi motion and evaporation 74 // As of Geant3, the Fermi energy calculation had not been Done 75 // 76 G4double ek = originalIncident->GetKineticEnergy()/MeV; 77 G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV; 78 79 G4double tkin = targetNucleus.Cinema( ek ); 80 ek += tkin; 81 modifiedOriginal.SetKineticEnergy( ek*MeV ); 82 G4double et = ek + amas; 83 G4double p = std::sqrt( std::abs((et-amas)*(et+amas)) ); 84 G4double pp = modifiedOriginal.GetMomentum().mag()/MeV; 85 if( pp > 0.0 ) 86 { 87 G4ThreeVector momentum = modifiedOriginal.GetMomentum(); 88 modifiedOriginal.SetMomentum( momentum * (p/pp) ); 89 } 90 // 91 // calculate black track energies 92 // 93 tkin = targetNucleus.EvaporationEffects( ek ); 94 ek -= tkin; 95 modifiedOriginal.SetKineticEnergy( ek*MeV ); 96 et = ek + amas; 97 p = std::sqrt( std::abs((et-amas)*(et+amas)) ); 98 pp = modifiedOriginal.GetMomentum().mag()/MeV; 99 if( pp > 0.0 ) 100 { 101 G4ThreeVector momentum = modifiedOriginal.GetMomentum(); 102 modifiedOriginal.SetMomentum( momentum * (p/pp) ); 103 } 104 const G4double cutOff = 0.1; 105 if( modifiedOriginal.GetKineticEnergy()/MeV <= cutOff ) 106 { 107 SlowNeutron( originalIncident, modifiedOriginal, targetParticle, targetNucleus ); 108 delete originalTarget; 109 return &theParticleChange; 110 } 111 G4ReactionProduct currentParticle = modifiedOriginal; 112 currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere 113 targetParticle.SetSide( -1 ); // target always goes in backward hemisphere 114 G4bool incidentHasChanged = false; 115 G4bool targetHasChanged = false; 116 G4bool quasiElastic = false; 117 G4FastVector<G4ReactionProduct,256> vec; // vec will contain the secondary particles 118 G4int vecLen = 0; 119 vec.Initialize( 0 ); 120 121 Cascade( vec, vecLen, 122 originalIncident, currentParticle, targetParticle, 123 incidentHasChanged, targetHasChanged, quasiElastic ); 124 125 CalculateMomenta( vec, vecLen, 126 originalIncident, originalTarget, modifiedOriginal, 127 targetNucleus, currentParticle, targetParticle, 128 incidentHasChanged, targetHasChanged, quasiElastic ); 129 130 SetUpChange( vec, vecLen, 131 currentParticle, targetParticle, 132 incidentHasChanged ); 133 32 33 34 G4HadFinalState* 35 G4RPGNeutronInelastic::ApplyYourself(const G4HadProjectile& aTrack, 36 G4Nucleus& targetNucleus) 37 { 38 theParticleChange.Clear(); 39 const G4HadProjectile* originalIncident = &aTrack; 40 41 // 42 // create the target particle 43 // 44 G4DynamicParticle* originalTarget = targetNucleus.ReturnTargetParticle(); 45 46 G4ReactionProduct modifiedOriginal; 47 modifiedOriginal = *originalIncident; 48 G4ReactionProduct targetParticle; 49 targetParticle = *originalTarget; 50 if( originalIncident->GetKineticEnergy()/GeV < 0.01 + 2.*G4UniformRand()/9. ) 51 { 52 SlowNeutron(originalIncident,modifiedOriginal,targetParticle,targetNucleus ); 134 53 delete originalTarget; 135 54 return &theParticleChange; 136 55 } 137 138 void 139 G4RPGNeutronInelastic::SlowNeutron( 140 const G4HadProjectile *originalIncident, 141 G4ReactionProduct &modifiedOriginal, 142 G4ReactionProduct &targetParticle, 143 G4Nucleus &targetNucleus ) 144 { 145 const G4double A = targetNucleus.GetN(); // atomic weight 146 const G4double Z = targetNucleus.GetZ(); // atomic number 147 148 G4double currentKinetic = modifiedOriginal.GetKineticEnergy()/MeV; 149 G4double currentMass = modifiedOriginal.GetMass()/MeV; 150 if( A < 1.5 ) // Hydrogen 56 57 // 58 // Fermi motion and evaporation 59 // As of Geant3, the Fermi energy calculation had not been Done 60 // 61 G4double ek = originalIncident->GetKineticEnergy()/MeV; 62 G4double amas = originalIncident->GetDefinition()->GetPDGMass()/MeV; 63 64 G4double tkin = targetNucleus.Cinema( ek ); 65 ek += tkin; 66 modifiedOriginal.SetKineticEnergy( ek*MeV ); 67 G4double et = ek + amas; 68 G4double p = std::sqrt( std::abs((et-amas)*(et+amas)) ); 69 G4double pp = modifiedOriginal.GetMomentum().mag()/MeV; 70 if( pp > 0.0 ) 71 { 72 G4ThreeVector momentum = modifiedOriginal.GetMomentum(); 73 modifiedOriginal.SetMomentum( momentum * (p/pp) ); 74 } 75 // 76 // calculate black track energies 77 // 78 tkin = targetNucleus.EvaporationEffects( ek ); 79 ek -= tkin; 80 modifiedOriginal.SetKineticEnergy(ek); 81 et = ek + amas; 82 p = std::sqrt( std::abs((et-amas)*(et+amas)) ); 83 pp = modifiedOriginal.GetMomentum().mag(); 84 if( pp > 0.0 ) 85 { 86 G4ThreeVector momentum = modifiedOriginal.GetMomentum(); 87 modifiedOriginal.SetMomentum( momentum * (p/pp) ); 88 } 89 const G4double cutOff = 0.1; 90 if( modifiedOriginal.GetKineticEnergy()/MeV <= cutOff ) 91 { 92 SlowNeutron( originalIncident, modifiedOriginal, targetParticle, targetNucleus ); 93 delete originalTarget; 94 return &theParticleChange; 95 } 96 97 G4ReactionProduct currentParticle = modifiedOriginal; 98 currentParticle.SetSide( 1 ); // incident always goes in forward hemisphere 99 targetParticle.SetSide( -1 ); // target always goes in backward hemisphere 100 G4bool incidentHasChanged = false; 101 G4bool targetHasChanged = false; 102 G4bool quasiElastic = false; 103 G4FastVector<G4ReactionProduct,256> vec; // vec will contain sec. particles 104 G4int vecLen = 0; 105 vec.Initialize( 0 ); 106 107 InitialCollision(vec, vecLen, currentParticle, targetParticle, 108 incidentHasChanged, targetHasChanged); 109 110 CalculateMomenta(vec, vecLen, 111 originalIncident, originalTarget, modifiedOriginal, 112 targetNucleus, currentParticle, targetParticle, 113 incidentHasChanged, targetHasChanged, quasiElastic); 114 115 SetUpChange(vec, vecLen, 116 currentParticle, targetParticle, 117 incidentHasChanged); 118 119 delete originalTarget; 120 return &theParticleChange; 121 } 122 123 void 124 G4RPGNeutronInelastic::SlowNeutron(const G4HadProjectile* originalIncident, 125 G4ReactionProduct& modifiedOriginal, 126 G4ReactionProduct& targetParticle, 127 G4Nucleus& targetNucleus) 128 { 129 const G4double A = targetNucleus.GetN(); // atomic weight 130 const G4double Z = targetNucleus.GetZ(); // atomic number 131 132 G4double currentKinetic = modifiedOriginal.GetKineticEnergy()/MeV; 133 G4double currentMass = modifiedOriginal.GetMass()/MeV; 134 if( A < 1.5 ) // Hydrogen 135 { 136 // 137 // very simple simulation of scattering angle and energy 138 // nonrelativistic approximation with isotropic angular 139 // distribution in the cms system 140 // 141 G4double cost1, eka = 0.0; 142 while (eka <= 0.0) 151 143 { 152 // 153 // very simple simulation of scattering angle and energy 154 // nonrelativistic approximation with isotropic angular 155 // distribution in the cms system 156 // 157 G4double cost1, eka = 0.0; 158 while (eka <= 0.0) 159 { 160 cost1 = -1.0 + 2.0*G4UniformRand(); 161 eka = 1.0 + 2.0*cost1*A + A*A; 144 cost1 = -1.0 + 2.0*G4UniformRand(); 145 eka = 1.0 + 2.0*cost1*A + A*A; 146 } 147 G4double cost = std::min( 1.0, std::max( -1.0, (A*cost1+1.0)/std::sqrt(eka) ) ); 148 eka /= (1.0+A)*(1.0+A); 149 G4double ek = currentKinetic*MeV/GeV; 150 G4double amas = currentMass*MeV/GeV; 151 ek *= eka; 152 G4double en = ek + amas; 153 G4double p = std::sqrt(std::abs(en*en-amas*amas)); 154 G4double sint = std::sqrt(std::abs(1.0-cost*cost)); 155 G4double phi = G4UniformRand()*twopi; 156 G4double px = sint*std::sin(phi); 157 G4double py = sint*std::cos(phi); 158 G4double pz = cost; 159 targetParticle.SetMomentum( px*GeV, py*GeV, pz*GeV ); 160 G4double pxO = originalIncident->Get4Momentum().x()/GeV; 161 G4double pyO = originalIncident->Get4Momentum().y()/GeV; 162 G4double pzO = originalIncident->Get4Momentum().z()/GeV; 163 G4double ptO = pxO*pxO + pyO+pyO; 164 if( ptO > 0.0 ) 165 { 166 G4double pO = std::sqrt(pxO*pxO+pyO*pyO+pzO*pzO); 167 cost = pzO/pO; 168 sint = 0.5*(std::sqrt(std::abs((1.0-cost)*(1.0+cost)))+std::sqrt(ptO)/pO); 169 G4double ph = pi/2.0; 170 if( pyO < 0.0 )ph = ph*1.5; 171 if( std::abs(pxO) > 0.000001 )ph = std::atan2(pyO,pxO); 172 G4double cosp = std::cos(ph); 173 G4double sinp = std::sin(ph); 174 px = cost*cosp*px - sinp*py+sint*cosp*pz; 175 py = cost*sinp*px + cosp*py+sint*sinp*pz; 176 pz = -sint*px + cost*pz; 177 } 178 else 179 { 180 if( pz < 0.0 )pz *= -1.0; 181 } 182 G4double pu = std::sqrt(px*px+py*py+pz*pz); 183 modifiedOriginal.SetMomentum( targetParticle.GetMomentum() * (p/pu) ); 184 modifiedOriginal.SetKineticEnergy( ek*GeV ); 185 186 targetParticle.SetMomentum( 187 originalIncident->Get4Momentum().vect() - modifiedOriginal.GetMomentum() ); 188 G4double pp = targetParticle.GetMomentum().mag(); 189 G4double tarmas = targetParticle.GetMass(); 190 targetParticle.SetTotalEnergy( std::sqrt( pp*pp + tarmas*tarmas ) ); 191 192 theParticleChange.SetEnergyChange( modifiedOriginal.GetKineticEnergy() ); 193 G4DynamicParticle *pd = new G4DynamicParticle; 194 pd->SetDefinition( targetParticle.GetDefinition() ); 195 pd->SetMomentum( targetParticle.GetMomentum() ); 196 theParticleChange.AddSecondary( pd ); 197 return; 198 } 199 200 G4FastVector<G4ReactionProduct,4> vec; // vec will contain the secondary particles 201 G4int vecLen = 0; 202 vec.Initialize( 0 ); 203 204 G4double theAtomicMass = targetNucleus.AtomicMass( A, Z ); 205 G4double massVec[9]; 206 massVec[0] = targetNucleus.AtomicMass( A+1.0, Z ); 207 massVec[1] = theAtomicMass; 208 massVec[2] = 0.; 209 if (Z > 1.0) massVec[2] = targetNucleus.AtomicMass(A, Z-1.0); 210 massVec[3] = 0.; 211 if (Z > 1.0 && A > 1.0) massVec[3] = targetNucleus.AtomicMass(A-1.0, Z-1.0 ); 212 massVec[4] = 0.; 213 if (Z > 1.0 && A > 2.0 && A-2.0 > Z-1.0) 214 massVec[4] = targetNucleus.AtomicMass( A-2.0, Z-1.0 ); 215 massVec[5] = 0.; 216 if (Z > 2.0 && A > 3.0 && A-3.0 > Z-2.0) 217 massVec[5] = targetNucleus.AtomicMass( A-3.0, Z-2.0 ); 218 massVec[6] = 0.; 219 if (A > 1.0 && A-1.0 > Z) massVec[6] = targetNucleus.AtomicMass(A-1.0, Z); 220 massVec[7] = massVec[3]; 221 massVec[8] = 0.; 222 if (Z > 2.0 && A > 1.0) massVec[8] = targetNucleus.AtomicMass( A-1.0,Z-2.0 ); 223 224 twoBody.NuclearReaction(vec, vecLen, originalIncident, 225 targetNucleus, theAtomicMass, massVec ); 226 227 theParticleChange.SetStatusChange( stopAndKill ); 228 theParticleChange.SetEnergyChange( 0.0 ); 229 230 G4DynamicParticle* pd; 231 for( G4int i=0; i<vecLen; ++i ) { 232 pd = new G4DynamicParticle(); 233 pd->SetDefinition( vec[i]->GetDefinition() ); 234 pd->SetMomentum( vec[i]->GetMomentum() ); 235 theParticleChange.AddSecondary( pd ); 236 delete vec[i]; 237 } 238 } 239 240 241 // Initial Collision 242 // selects the particle types arising from the initial collision of 243 // the neutron and target nucleon. Secondaries are assigned to 244 // forward and backward reaction hemispheres, but final state energies 245 // and momenta are not calculated here. 246 247 void 248 G4RPGNeutronInelastic::InitialCollision(G4FastVector<G4ReactionProduct,256>& vec, 249 G4int& vecLen, 250 G4ReactionProduct& currentParticle, 251 G4ReactionProduct& targetParticle, 252 G4bool& incidentHasChanged, 253 G4bool& targetHasChanged) 254 { 255 G4double KE = currentParticle.GetKineticEnergy()/GeV; 256 257 G4int mult; 258 G4int partType; 259 std::vector<G4int> fsTypes; 260 G4int part1; 261 G4int part2; 262 263 G4double testCharge; 264 G4double testBaryon; 265 G4double testStrange; 266 267 // Get particle types according to incident and target types 268 269 if (targetParticle.GetDefinition() == particleDef[neu]) { 270 mult = GetMultiplicityT1(KE); 271 fsTypes = GetFSPartTypesForNN(mult, KE); 272 273 part1 = fsTypes[0]; 274 part2 = fsTypes[1]; 275 currentParticle.SetDefinition(particleDef[part1]); 276 targetParticle.SetDefinition(particleDef[part2]); 277 if (part1 == pro) { 278 if (part2 == neu) { 279 if (G4UniformRand() > 0.5) { 280 incidentHasChanged = true; 281 } else { 282 targetHasChanged = true; 283 currentParticle.SetDefinition(particleDef[part2]); 284 targetParticle.SetDefinition(particleDef[part1]); 285 } 286 } else { 287 targetHasChanged = true; 288 incidentHasChanged = true; 162 289 } 163 G4double cost = std::min( 1.0, std::max( -1.0, (A*cost1+1.0)/std::sqrt(eka) ) ); 164 eka /= (1.0+A)*(1.0+A); 165 G4double ek = currentKinetic*MeV/GeV; 166 G4double amas = currentMass*MeV/GeV; 167 ek *= eka; 168 G4double en = ek + amas; 169 G4double p = std::sqrt(std::abs(en*en-amas*amas)); 170 G4double sint = std::sqrt(std::abs(1.0-cost*cost)); 171 G4double phi = G4UniformRand()*twopi; 172 G4double px = sint*std::sin(phi); 173 G4double py = sint*std::cos(phi); 174 G4double pz = cost; 175 targetParticle.SetMomentum( px*GeV, py*GeV, pz*GeV ); 176 G4double pxO = originalIncident->Get4Momentum().x()/GeV; 177 G4double pyO = originalIncident->Get4Momentum().y()/GeV; 178 G4double pzO = originalIncident->Get4Momentum().z()/GeV; 179 G4double ptO = pxO*pxO + pyO+pyO; 180 if( ptO > 0.0 ) 181 { 182 G4double pO = std::sqrt(pxO*pxO+pyO*pyO+pzO*pzO); 183 cost = pzO/pO; 184 sint = 0.5*(std::sqrt(std::abs((1.0-cost)*(1.0+cost)))+std::sqrt(ptO)/pO); 185 G4double ph = pi/2.0; 186 if( pyO < 0.0 )ph = ph*1.5; 187 if( std::abs(pxO) > 0.000001 )ph = std::atan2(pyO,pxO); 188 G4double cosp = std::cos(ph); 189 G4double sinp = std::sin(ph); 190 px = cost*cosp*px - sinp*py+sint*cosp*pz; 191 py = cost*sinp*px + cosp*py+sint*sinp*pz; 192 pz = -sint*px + cost*pz; 290 291 } else { // neutron 292 if (part2 > neu && part2 < xi0) targetHasChanged = true; 293 } 294 295 testCharge = 0.0; 296 testBaryon = 2.0; 297 testStrange = 0.0; 298 299 } else { // target was a proton 300 mult = GetMultiplicityT0(KE); 301 fsTypes = GetFSPartTypesForNP(mult, KE); 302 303 part1 = fsTypes[0]; 304 part2 = fsTypes[1]; 305 currentParticle.SetDefinition(particleDef[part1]); 306 targetParticle.SetDefinition(particleDef[part2]); 307 if (part1 == pro) { 308 if (part2 == pro) { 309 incidentHasChanged = true; 310 } else if (part2 == neu) { 311 if (G4UniformRand() > 0.5) { 312 incidentHasChanged = true; 313 targetHasChanged = true; 314 } else { 315 currentParticle.SetDefinition(particleDef[part2]); 316 targetParticle.SetDefinition(particleDef[part1]); 317 } 318 319 } else if (part2 > neu && part2 < xi0) { 320 incidentHasChanged = true; 321 targetHasChanged = true; 193 322 } 194 else 195 { 196 if( pz < 0.0 )pz *= -1.0; 197 } 198 G4double pu = std::sqrt(px*px+py*py+pz*pz); 199 modifiedOriginal.SetMomentum( targetParticle.GetMomentum() * (p/pu) ); 200 modifiedOriginal.SetKineticEnergy( ek*GeV ); 201 202 targetParticle.SetMomentum( 203 originalIncident->Get4Momentum().vect() - modifiedOriginal.GetMomentum() ); 204 G4double pp = targetParticle.GetMomentum().mag(); 205 G4double tarmas = targetParticle.GetMass(); 206 targetParticle.SetTotalEnergy( std::sqrt( pp*pp + tarmas*tarmas ) ); 207 208 theParticleChange.SetEnergyChange( modifiedOriginal.GetKineticEnergy() ); 209 G4DynamicParticle *pd = new G4DynamicParticle; 210 pd->SetDefinition( targetParticle.GetDefinition() ); 211 pd->SetMomentum( targetParticle.GetMomentum() ); 212 theParticleChange.AddSecondary( pd ); 213 return; 214 } 215 G4FastVector<G4ReactionProduct,4> vec; // vec will contain the secondary particles 216 G4int vecLen = 0; 217 vec.Initialize( 0 ); 218 219 G4double theAtomicMass = targetNucleus.AtomicMass( A, Z ); 220 G4double massVec[9]; 221 massVec[0] = targetNucleus.AtomicMass( A+1.0, Z ); 222 massVec[1] = theAtomicMass; 223 massVec[2] = 0.; 224 if (Z > 1.0) 225 massVec[2] = targetNucleus.AtomicMass( A , Z-1.0 ); 226 massVec[3] = 0.; 227 if (Z > 1.0 && A > 1.0) 228 massVec[3] = targetNucleus.AtomicMass( A-1.0, Z-1.0 ); 229 massVec[4] = 0.; 230 if (Z > 1.0 && A > 2.0 && A-2.0 > Z-1.0) 231 massVec[4] = targetNucleus.AtomicMass( A-2.0, Z-1.0 ); 232 massVec[5] = 0.; 233 if (Z > 2.0 && A > 3.0 && A-3.0 > Z-2.0) 234 massVec[5] = targetNucleus.AtomicMass( A-3.0, Z-2.0 ); 235 massVec[6] = 0.; 236 if (A > 1.0 && A-1.0 > Z) 237 massVec[6] = targetNucleus.AtomicMass( A-1.0, Z ); 238 massVec[7] = massVec[3]; 239 massVec[8] = 0.; 240 if (Z > 2.0 && A > 1.0) 241 massVec[8] = targetNucleus.AtomicMass( A-1.0, Z-2.0 ); 242 243 twoBody.NuclearReaction(vec, vecLen, originalIncident, 244 targetNucleus, theAtomicMass, massVec ); 245 246 theParticleChange.SetStatusChange( stopAndKill ); 247 theParticleChange.SetEnergyChange( 0.0 ); 248 249 G4DynamicParticle * pd; 250 for( G4int i=0; i<vecLen; ++i ) 251 { 252 pd = new G4DynamicParticle(); 253 pd->SetDefinition( vec[i]->GetDefinition() ); 254 pd->SetMomentum( vec[i]->GetMomentum() ); 255 theParticleChange.AddSecondary( pd ); 256 delete vec[i]; 257 } 258 } 259 260 void 261 G4RPGNeutronInelastic::Cascade( 262 G4FastVector<G4ReactionProduct,256> &vec, 263 G4int& vecLen, 264 const G4HadProjectile *originalIncident, 265 G4ReactionProduct ¤tParticle, 266 G4ReactionProduct &targetParticle, 267 G4bool &incidentHasChanged, 268 G4bool &targetHasChanged, 269 G4bool &quasiElastic ) 270 { 271 // derived from original FORTRAN code CASN by H. Fesefeldt (13-Sep-1987) 272 // 273 // Neutron undergoes interaction with nucleon within a nucleus. Check if it is 274 // energetically possible to produce pions/kaons. In not, assume nuclear excitation 275 // occurs and input particle is degraded in energy. No other particles are produced. 276 // If reaction is possible, find the correct number of pions/protons/neutrons 277 // produced using an interpolation to multiplicity data. Replace some pions or 278 // protons/neutrons by kaons or strange baryons according to the average 279 // multiplicity per Inelastic reaction. 280 // 281 const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV; 282 const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV; 283 const G4double targetMass = targetParticle.GetMass()/MeV; 284 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal + 285 targetMass*targetMass + 286 2.0*targetMass*etOriginal ); 287 G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal); 288 if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV ) 289 { 290 quasiElastic = true; 291 return; 292 } 293 static G4bool first = true; 294 const G4int numMul = 1200; 295 const G4int numSec = 60; 296 static G4double protmul[numMul], protnorm[numSec]; // proton constants 297 static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants 298 // np = number of pi+, nm = number of pi-, nz = number of pi0 299 G4int counter, nt=0, np=0, nm=0, nz=0; 300 const G4double c = 1.25; 301 const G4double b[] = { 0.35, 0.0 }; 302 if( first ) // compute normalization constants, this will only be Done once 303 { 304 first = false; 305 G4int i; 306 for( i=0; i<numMul; ++i )protmul[i] = 0.0; 307 for( i=0; i<numSec; ++i )protnorm[i] = 0.0; 308 counter = -1; 309 for( np=0; np<numSec/3; ++np ) 310 { 311 for( nm=std::max(0,np-1); nm<=(np+1); ++nm ) 312 { 313 for( nz=0; nz<numSec/3; ++nz ) 314 { 315 if( ++counter < numMul ) 316 { 317 nt = np+nm+nz; 318 if( nt > 0 ) 319 { 320 protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c) / 321 (Factorial(1-np+nm)*Factorial(1+np-nm) ); 322 protnorm[nt-1] += protmul[counter]; 323 } 324 } 325 } 326 } 327 } 328 for( i=0; i<numMul; ++i )neutmul[i] = 0.0; 329 for( i=0; i<numSec; ++i )neutnorm[i] = 0.0; 330 counter = -1; 331 for( np=0; np<(numSec/3); ++np ) 332 { 333 for( nm=np; nm<=(np+2); ++nm ) 334 { 335 for( nz=0; nz<numSec/3; ++nz ) 336 { 337 if( ++counter < numMul ) 338 { 339 nt = np+nm+nz; 340 if( (nt>0) && (nt<=numSec) ) 341 { 342 neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c) / 343 (Factorial(nm-np)*Factorial(2-nm+np) ); 344 neutnorm[nt-1] += neutmul[counter]; 345 } 346 } 347 } 348 } 349 } 350 for( i=0; i<numSec; ++i ) 351 { 352 if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i]; 353 if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i]; 354 } 355 } // end of initialization 356 357 const G4double expxu = 82.; // upper bound for arg. of exp 358 const G4double expxl = -expxu; // lower bound for arg. of exp 359 G4ParticleDefinition *aNeutron = G4Neutron::Neutron(); 360 G4ParticleDefinition *aProton = G4Proton::Proton(); 361 G4int ieab = static_cast<G4int>(availableEnergy*5.0/GeV); 362 const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98}; 363 G4double test, w0, wp, wt, wm; 364 if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) ) 365 { 366 // suppress high multiplicity events at low momentum 367 // only one pion will be produced 368 369 nm = np = nz = 0; 370 if( targetParticle.GetDefinition() == aNeutron ) 371 { 372 test = std::exp( std::min( expxu, std::max( expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) ); 373 w0 = test/2.0; 374 wm = test; 375 if( G4UniformRand() < w0/(w0+wm) ) 376 nz = 1; 377 else 378 nm = 1; 379 } else { // target is a proton 380 test = std::exp( std::min( expxu, std::max( expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) ); 381 w0 = test; 382 wp = test/2.0; 383 test = std::exp( std::min( expxu, std::max( expxl, -(-1.0+b[0])*(-1.0+b[0])/(2.0*c*c) ) ) ); 384 wm = test/2.0; 385 wt = w0+wp+wm; 386 wp += w0; 387 G4double ran = G4UniformRand(); 388 if( ran < w0/wt ) 389 nz = 1; 390 else if( ran < wp/wt ) 391 np = 1; 392 else 393 nm = 1; 394 } 395 } else { // (availableEnergy >= 2.0*GeV) || (random number < supp[ieab]) 396 G4double n, anpn; 397 GetNormalizationConstant( availableEnergy, n, anpn ); 398 G4double ran = G4UniformRand(); 399 G4double dum, excs = 0.0; 400 if( targetParticle.GetDefinition() == aProton ) 401 { 402 counter = -1; 403 for( np=0; np<numSec/3 && ran>=excs; ++np ) 404 { 405 for( nm=std::max(0,np-1); nm<=(np+1) && ran>=excs; ++nm ) 406 { 407 for( nz=0; nz<numSec/3 && ran>=excs; ++nz ) 408 { 409 if( ++counter < numMul ) 410 { 411 nt = np+nm+nz; 412 if( nt > 0 ) 413 { 414 test = std::exp( std::min( expxu, std::max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) ); 415 dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n); 416 if( std::fabs(dum) < 1.0 ) { 417 if( test >= 1.0e-10 )excs += dum*test; 418 } else { 419 excs += dum*test; 420 } 421 } 422 } 423 } 424 } 425 } 426 if( ran >= excs ) // 3 previous loops continued to the end 427 { 428 quasiElastic = true; 429 return; 430 } 431 np--; nm--; nz--; 432 } else { // target must be a neutron 433 counter = -1; 434 for( np=0; np<numSec/3 && ran>=excs; ++np ) 435 { 436 for( nm=np; nm<=(np+2) && ran>=excs; ++nm ) 437 { 438 for( nz=0; nz<numSec/3 && ran>=excs; ++nz ) 439 { 440 if( ++counter < numMul ) 441 { 442 nt = np+nm+nz; 443 if( (nt>=1) && (nt<=numSec) ) 444 { 445 test = std::exp( std::min( expxu, std::max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) ); 446 dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n); 447 if( std::fabs(dum) < 1.0 ) { 448 if( test >= 1.0e-10 )excs += dum*test; 449 } else { 450 excs += dum*test; 451 } 452 } 453 } 454 } 455 } 456 } 457 if( ran >= excs ) // 3 previous loops continued to the end 458 { 459 quasiElastic = true; 460 return; 461 } 462 np--; nm--; nz--; 463 } 464 } 465 if( targetParticle.GetDefinition() == aProton ) 466 { 467 switch( np-nm ) 468 { 469 case 0: 470 if( G4UniformRand() < 0.33 ) 471 { 472 currentParticle.SetDefinitionAndUpdateE( aProton ); 473 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 474 incidentHasChanged = true; 475 targetHasChanged = true; 476 } 477 break; 478 case 1: 479 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 480 targetHasChanged = true; 481 break; 482 default: 483 currentParticle.SetDefinitionAndUpdateE( aProton ); 484 incidentHasChanged = true; 485 break; 486 } 487 } else { // target must be a neutron 488 switch( np-nm ) 489 { 490 case -1: // changed from +1 by JLC, 7Jul97 491 if( G4UniformRand() < 0.5 ) 492 { 493 currentParticle.SetDefinitionAndUpdateE( aProton ); 494 incidentHasChanged = true; 495 } else { 496 targetParticle.SetDefinitionAndUpdateE( aProton ); 497 targetHasChanged = true; 498 } 499 break; 500 case 0: 501 break; 502 default: 503 currentParticle.SetDefinitionAndUpdateE( aProton ); 504 targetParticle.SetDefinitionAndUpdateE( aProton ); 505 incidentHasChanged = true; 506 targetHasChanged = true; 507 break; 508 } 509 } 510 SetUpPions( np, nm, nz, vec, vecLen ); 511 // DEBUG --> DumpFrames::DumpFrame(vec, vecLen); 512 return; 513 } 514 515 /* end of file */ 516 323 324 } else { // neutron 325 targetHasChanged = true; 326 } 327 328 testCharge = 1.0; 329 testBaryon = 2.0; 330 testStrange = 0.0; 331 } 332 333 // if (mult == 2 && !incidentHasChanged && !targetHasChanged) 334 // quasiElastic = true; 335 336 // Remove incident and target from fsTypes 337 338 fsTypes.erase(fsTypes.begin()); 339 fsTypes.erase(fsTypes.begin()); 340 341 // Remaining particles are secondaries. Put them into vec. 342 343 G4ReactionProduct* rp(0); 344 for(G4int i=0; i < mult-2; ++i ) { 345 partType = fsTypes[i]; 346 rp = new G4ReactionProduct(); 347 rp->SetDefinition(particleDef[partType]); 348 (G4UniformRand() < 0.5) ? rp->SetSide(-1) : rp->SetSide(1); 349 vec.SetElement(vecLen++, rp); 350 } 351 352 // Check conservation of charge, strangeness, baryon number 353 354 CheckQnums(vec, vecLen, currentParticle, targetParticle, 355 testCharge, testBaryon, testStrange); 356 357 return; 358 } -
trunk/source/processes/hadronic/models/rpg/src/G4RPGOmegaMinusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGOmegaMinusInelastic.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGPiMinusInelastic.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGPiMinusInelastic.cc,v 1. 1 2007/07/18 21:04:20dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGPiMinusInelastic.cc,v 1.4 2008/05/05 21:21:55 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 … … 31 31 #include "Randomize.hh" 32 32 33 34 33 G4HadFinalState* 35 34 G4RPGPiMinusInelastic::ApplyYourself(const G4HadProjectile& aTrack, 36 G4Nucleus& targetNucleus)35 G4Nucleus& targetNucleus) 37 36 { 38 37 const G4HadProjectile* originalIncident = &aTrack; 39 if (originalIncident->GetKineticEnergy() <= 0.1*MeV) 40 {38 39 if (originalIncident->GetKineticEnergy()<= 0.1) { 41 40 theParticleChange.SetStatusChange(isAlive); 42 41 theParticleChange.SetEnergyChange(aTrack.GetKineticEnergy()); … … 50 49 G4ReactionProduct targetParticle( originalTarget->GetDefinition() ); 51 50 52 if( verboseLevel > 1 )53 {54 const G4Material *targetMaterial = aTrack.GetMaterial();55 G4cout << "G4PionMinusInelastic::ApplyYourself called" << G4endl;56 G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy() << "MeV, ";57 G4cout << "target material = " << targetMaterial->GetName() << ", ";58 G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()59 << G4endl;60 }61 62 51 G4ReactionProduct currentParticle( 63 const_cast<G4ParticleDefinition *>(originalIncident->GetDefinition() ) );52 const_cast<G4ParticleDefinition *>(originalIncident->GetDefinition() ) ); 64 53 currentParticle.SetMomentum( originalIncident->Get4Momentum().vect() ); 65 54 currentParticle.SetKineticEnergy( originalIncident->GetKineticEnergy() ); … … 77 66 G4double p = std::sqrt( std::abs((et-amas)*(et+amas)) ); 78 67 G4double pp = currentParticle.GetMomentum().mag(); 79 if( pp > 0.0 ) 80 { 68 if( pp > 0.0 ) { 81 69 G4ThreeVector momentum = currentParticle.GetMomentum(); 82 70 currentParticle.SetMomentum( momentum * (p/pp) ); … … 91 79 p = std::sqrt( std::abs((et-amas)*(et+amas)) ); 92 80 pp = currentParticle.GetMomentum().mag(); 93 if( pp > 0.0 ) 94 { 81 if( pp > 0.0 ) { 95 82 G4ThreeVector momentum = currentParticle.GetMomentum(); 96 83 currentParticle.SetMomentum( momentum * (p/pp) ); … … 104 91 G4bool targetHasChanged = false; 105 92 G4bool quasiElastic = false; 106 G4FastVector<G4ReactionProduct,256> vec; 93 G4FastVector<G4ReactionProduct,256> vec; // vec will contain the secondary particles 107 94 G4int vecLen = 0; 108 95 vec.Initialize( 0 ); 109 96 110 const G4double cutOff = 0.1 *MeV;97 const G4double cutOff = 0.1; 111 98 if( currentParticle.GetKineticEnergy() > cutOff ) 112 Cascade(vec, vecLen, 113 originalIncident, currentParticle, targetParticle, 114 incidentHasChanged, targetHasChanged, quasiElastic); 99 InitialCollision(vec, vecLen, currentParticle, targetParticle, 100 incidentHasChanged, targetHasChanged); 115 101 116 102 CalculateMomenta(vec, vecLen, … … 119 105 incidentHasChanged, targetHasChanged, quasiElastic); 120 106 121 SetUpChange(vec, vecLen, currentParticle, targetParticle, 107 SetUpChange(vec, vecLen, 108 currentParticle, targetParticle, 122 109 incidentHasChanged); 123 110 … … 125 112 return &theParticleChange; 126 113 } 114 115 116 // Initial Collision 117 // selects the particle types arising from the initial collision of 118 // the projectile and target nucleon. Secondaries are assigned to 119 // forward and backward reaction hemispheres, but final state energies 120 // and momenta are not calculated here. 127 121 128 void G4RPGPiMinusInelastic::Cascade( 129 G4FastVector<G4ReactionProduct,256> &vec, 130 G4int& vecLen, 131 const G4HadProjectile *originalIncident, 132 G4ReactionProduct ¤tParticle, 133 G4ReactionProduct &targetParticle, 134 G4bool &incidentHasChanged, 135 G4bool &targetHasChanged, 136 G4bool &quasiElastic) 122 void 123 G4RPGPiMinusInelastic::InitialCollision(G4FastVector<G4ReactionProduct,256>& vec, 124 G4int& vecLen, 125 G4ReactionProduct& currentParticle, 126 G4ReactionProduct& targetParticle, 127 G4bool& incidentHasChanged, 128 G4bool& targetHasChanged) 137 129 { 138 // Derived from H. Fesefeldt's original FORTRAN code CASPIM 139 // 140 // pi- undergoes interaction with nucleon within nucleus. 141 // Check if energetically possible to produce pions/kaons. 142 // If not assume nuclear excitation occurs and input particle 143 // is degraded in energy. No other particles produced. 144 // If reaction is possible find correct number of pions/protons/neutrons 145 // produced using an interpolation to multiplicity data. 146 // Replace some pions or protons/neutrons by kaons or strange baryons 147 // according to average multiplicity per inelastic reactions. 148 // 149 const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass(); 150 const G4double etOriginal = originalIncident->GetTotalEnergy(); 151 const G4double pOriginal = originalIncident->GetTotalMomentum(); 152 const G4double targetMass = targetParticle.GetMass(); 153 G4double centerofmassEnergy = std::sqrt(mOriginal*mOriginal + 154 targetMass*targetMass + 155 2.0*targetMass*etOriginal); 156 G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal); 157 static G4bool first = true; 158 const G4int numMul = 1200; 159 const G4int numSec = 60; 160 static G4double protmul[numMul], protnorm[numSec]; // proton constants 161 static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants 162 // np = number of pi+, nm = number of pi-, nz = number of pi0 163 G4int counter, nt=0, np=0, nm=0, nz=0; 164 const G4double c = 1.25; 165 const G4double b[] = { 0.70, 0.70 }; 166 if( first ) // compute normalization constants, this will only be Done once 167 { 168 first = false; 169 G4int i; 170 for( i=0; i<numMul; ++i )protmul[i] = 0.0; 171 for( i=0; i<numSec; ++i )protnorm[i] = 0.0; 172 counter = -1; 173 for( np=0; np<(numSec/3); ++np ) 174 { 175 for( nm=std::max(0,np-1); nm<=(np+1); ++nm ) 176 { 177 for( nz=0; nz<numSec/3; ++nz ) 178 { 179 if( ++counter < numMul ) 180 { 181 nt = np+nm+nz; 182 if( nt > 0 ) 183 { 184 protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c); 185 protnorm[nt-1] += protmul[counter]; 186 } 187 } 188 } 189 } 190 } 191 for( i=0; i<numMul; ++i )neutmul[i] = 0.0; 192 for( i=0; i<numSec; ++i )neutnorm[i] = 0.0; 193 counter = -1; 194 for( np=0; np<numSec/3; ++np ) 195 { 196 for( nm=np; nm<=(np+2); ++nm ) 197 { 198 for( nz=0; nz<numSec/3; ++nz ) 199 { 200 if( ++counter < numMul ) 201 { 202 nt = np+nm+nz; 203 if( (nt>0) && (nt<=numSec) ) 204 { 205 neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c); 206 neutnorm[nt-1] += neutmul[counter]; 207 } 208 } 209 } 210 } 211 } 212 for( i=0; i<numSec; ++i ) { 213 if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i]; 214 if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i]; 130 G4double KE = currentParticle.GetKineticEnergy()/GeV; 131 132 G4int mult; 133 G4int partType; 134 std::vector<G4int> fsTypes; 135 136 G4double testCharge; 137 G4double testBaryon; 138 G4double testStrange; 139 140 // Get particle types according to incident and target types 141 142 if (targetParticle.GetDefinition() == particleDef[pro]) { 143 mult = GetMultiplicityT12(KE); 144 fsTypes = GetFSPartTypesForPimP(mult, KE); 145 partType = fsTypes[0]; 146 if (partType != pro) { 147 targetHasChanged = true; 148 targetParticle.SetDefinition(particleDef[partType]); 215 149 } 216 } // end of initialization 217 218 const G4double expxu = 82.; // upper bound for arg. of exp 219 const G4double expxl = -expxu; // lower bound for arg. of exp 220 G4ParticleDefinition *aNeutron = G4Neutron::Neutron(); 221 G4ParticleDefinition *aProton = G4Proton::Proton(); 222 G4ParticleDefinition *aPiZero = G4PionZero::PionZero(); 223 G4int ieab = G4int(availableEnergy*5.0/GeV); 224 const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98}; 225 G4double test, w0, wp, wt, wm; 226 if( (availableEnergy<2.0*GeV) && (G4UniformRand()>=supp[ieab]) ) 227 { 228 // suppress high multiplicity events at low momentum 229 // only one pion will be produced 230 231 // charge exchange reaction is included in inelastic cross section 232 233 const G4double cech[] = {1.,0.95,0.79,0.32,0.19,0.16,0.14,0.12,0.10,0.08}; 234 G4int iplab = G4int(std::min( 9.0, pOriginal/GeV*5.0 )); 235 if( G4UniformRand() <= cech[iplab] ) 236 { 237 if( targetParticle.GetDefinition() == aProton ) 238 { 239 currentParticle.SetDefinitionAndUpdateE( aPiZero ); // charge exchange 240 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 241 incidentHasChanged = true; 242 targetHasChanged = true; 243 } 150 151 testCharge = 0.0; 152 testBaryon = 1.0; 153 testStrange = 0.0; 154 155 } else { // target was a neutron 156 mult = GetMultiplicityT32(KE); 157 fsTypes = GetFSPartTypesForPimN(mult, KE); 158 partType = fsTypes[0]; 159 if (partType != neu) { 160 targetHasChanged = true; 161 targetParticle.SetDefinition(particleDef[partType]); 244 162 } 245 246 if( availableEnergy <= G4PionMinus::PionMinus()->GetPDGMass() ) 247 { 248 quasiElastic = true; 249 return; 163 164 testCharge = -1.0; 165 testBaryon = 1.0; 166 testStrange = 0.0; 167 } 168 169 // Remove target particle from list 170 171 fsTypes.erase(fsTypes.begin()); 172 173 // See if the incident particle changed type 174 175 G4int choose = -1; 176 for(G4int i=0; i < mult-1; ++i ) { 177 partType = fsTypes[i]; 178 if (partType == pim) { 179 choose = i; 180 break; 250 181 } 251 252 nm = np = nz = 0; 253 if( targetParticle.GetDefinition() == aProton ) 254 { 255 test = std::exp( std::min( expxu, std::max( expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) ); 256 w0 = test; 257 wp = 10.0*test; 258 test = std::exp( std::min( expxu, std::max( expxl, -(-1.0+b[0])*(-1.0+b[0])/(2.0*c*c) ) ) ); 259 wm = test; 260 wt = w0+wp+wm; 261 wp += w0; 262 G4double ran = G4UniformRand(); 263 if( ran < w0/wt ) 264 nz = 1; 265 else if( ran < wp/wt ) 266 np = 1; 267 else 268 nm = 1; 269 } 270 else // target is a neutron 271 { 272 test = std::exp( std::min( expxu, std::max( expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) ); 273 w0 = test; 274 test = std::exp( std::min( expxu, std::max( expxl, -(-1.0+b[1])*(-1.0+b[1])/(2.0*c*c) ) ) ); 275 wm = test; 276 G4double ran = G4UniformRand(); 277 if( ran < w0/(w0+wm) ) 278 nz = 1; 279 else 280 nm = 1; 281 } 282 } 283 else 284 { 285 if( availableEnergy <= G4PionMinus::PionMinus()->GetPDGMass() ) 286 { 287 quasiElastic = true; 288 return; 289 } 290 G4double n, anpn; 291 GetNormalizationConstant( availableEnergy, n, anpn ); 292 G4double ran = G4UniformRand(); 293 G4double dum, excs = 0.0; 294 if( targetParticle.GetDefinition() == aProton ) 295 { 296 counter = -1; 297 for( np=0; (np<numSec/3) && (ran>=excs); ++np ) 298 { 299 for( nm=std::max(0,np-1); (nm<=(np+1)) && (ran>=excs); ++nm ) 300 { 301 for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz ) 302 { 303 if( ++counter < numMul ) 304 { 305 nt = np+nm+nz; 306 if( nt > 0 ) 307 { 308 test = std::exp( std::min( expxu, std::max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) ); 309 dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n); 310 if( std::fabs(dum) < 1.0 ) 311 { 312 if( test >= 1.0e-10 )excs += dum*test; 313 } 314 else 315 excs += dum*test; 316 } 317 } 318 } 319 } 320 } 321 if( ran >= excs ) // 3 previous loops continued to the end 322 { 323 quasiElastic = true; 324 return; 325 } 326 np--; nm--; nz--; 327 } 328 else // target must be a neutron 329 { 330 counter = -1; 331 for( np=0; (np<numSec/3) && (ran>=excs); ++np ) 332 { 333 for( nm=np; (nm<=(np+2)) && (ran>=excs); ++nm ) 334 { 335 for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz ) 336 { 337 if( ++counter < numMul ) 338 { 339 nt = np+nm+nz; 340 if( (nt>=1) && (nt<=numSec) ) 341 { 342 test = std::exp( std::min( expxu, std::max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) ); 343 dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n); 344 if( std::fabs(dum) < 1.0 ) 345 { 346 if( test >= 1.0e-10 )excs += dum*test; 347 } 348 else 349 excs += dum*test; 350 } 351 } 352 } 353 } 354 } 355 if( ran >= excs ) // 3 previous loops continued to the end 356 { 357 quasiElastic = true; 358 return; 359 } 360 np--; nm--; nz--; 361 } 362 } 363 if( targetParticle.GetDefinition() == aProton ) 364 { 365 switch( np-nm ) 366 { 367 case 0: 368 if( G4UniformRand() >= 0.75 ) 369 { 370 currentParticle.SetDefinitionAndUpdateE( aPiZero ); 371 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 372 incidentHasChanged = true; 373 targetHasChanged = true; 374 } 375 break; 376 case 1: 377 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 378 targetHasChanged = true; 379 break; 380 default: 381 currentParticle.SetDefinitionAndUpdateE( aPiZero ); 382 incidentHasChanged = true; 383 break; 384 } 385 } 386 else 387 { 388 switch( np-nm ) 389 { 390 case -1: 391 if( G4UniformRand() < 0.5 ) 392 { 393 targetParticle.SetDefinitionAndUpdateE( aProton ); 394 targetHasChanged = true; 395 } else { 396 currentParticle.SetDefinitionAndUpdateE( aPiZero ); 397 incidentHasChanged = true; 398 } 399 break; 400 case 0: 401 break; 402 default: 403 currentParticle.SetDefinitionAndUpdateE( aPiZero ); 404 incidentHasChanged = true; 405 break; 406 } 407 } 408 409 SetUpPions( np, nm, nz, vec, vecLen ); 182 } 183 if (choose == -1) { 184 incidentHasChanged = true; 185 choose = G4int(G4UniformRand()*(mult-1) ); 186 partType = fsTypes[choose]; 187 currentParticle.SetDefinition(particleDef[partType]); 188 } 189 190 fsTypes.erase(fsTypes.begin()+choose); 191 192 // Remaining particles are secondaries. Put them into vec. 193 194 G4ReactionProduct* rp(0); 195 for(G4int i=0; i < mult-2; ++i ) { 196 partType = fsTypes[i]; 197 rp = new G4ReactionProduct(); 198 rp->SetDefinition(particleDef[partType]); 199 (G4UniformRand() < 0.5) ? rp->SetSide(-1) : rp->SetSide(1); 200 if (partType > pim && partType < pro) rp->SetMayBeKilled(false); // kaons 201 vec.SetElement(vecLen++, rp); 202 } 203 204 // if (mult == 2 && !incidentHasChanged && !targetHasChanged) 205 // quasiElastic = true; 206 207 // Check conservation of charge, strangeness, baryon number 208 209 CheckQnums(vec, vecLen, currentParticle, targetParticle, 210 testCharge, testBaryon, testStrange); 211 410 212 return; 411 213 } 412 413 /* end of file */414 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGPiPlusInelastic.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGPiPlusInelastic.cc,v 1. 1 2007/07/18 21:04:20dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGPiPlusInelastic.cc,v 1.4 2008/05/05 21:21:55 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 … … 31 31 #include "Randomize.hh" 32 32 33 G4HadFinalState * 34 G4RPGPiPlusInelastic::ApplyYourself( const G4HadProjectile &aTrack, 35 G4Nucleus &targetNucleus ) 36 { 37 const G4HadProjectile *originalIncident = &aTrack; 38 if (originalIncident->GetKineticEnergy()<= 0.1*MeV) 39 { 40 theParticleChange.SetStatusChange(isAlive); 41 theParticleChange.SetEnergyChange(aTrack.GetKineticEnergy()); 42 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 43 return &theParticleChange; 44 } 33 G4HadFinalState* 34 G4RPGPiPlusInelastic::ApplyYourself(const G4HadProjectile& aTrack, 35 G4Nucleus& targetNucleus) 36 { 37 const G4HadProjectile *originalIncident = &aTrack; 38 if (originalIncident->GetKineticEnergy()<= 0.1) { 39 theParticleChange.SetStatusChange(isAlive); 40 theParticleChange.SetEnergyChange(aTrack.GetKineticEnergy()); 41 theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); 42 return &theParticleChange; 43 } 45 44 46 45 // create the target particle 47 46 48 47 G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle(); 49 // G4double targetMass = originalTarget->GetDefinition()->GetPDGMass();50 48 G4ReactionProduct targetParticle( originalTarget->GetDefinition() ); 51 49 52 if( verboseLevel > 1 )53 {54 const G4Material *targetMaterial = aTrack.GetMaterial();55 G4cout << "G4RPGPiPlusInelastic::ApplyYourself called" << G4endl;56 G4cout << "kinetic energy = " << originalIncident->GetKineticEnergy() << "MeV, ";57 G4cout << "target material = " << targetMaterial->GetName() << ", ";58 G4cout << "target particle = " << originalTarget->GetDefinition()->GetParticleName()59 << G4endl;60 }61 50 G4ReactionProduct currentParticle( 62 51 const_cast<G4ParticleDefinition *>(originalIncident->GetDefinition() ) ); … … 107 96 vec.Initialize( 0 ); 108 97 109 const G4double cutOff = 0.1 *MeV;98 const G4double cutOff = 0.1; 110 99 if( currentParticle.GetKineticEnergy() > cutOff ) 111 Cascade( vec, vecLen, 112 originalIncident, currentParticle, targetParticle, 113 incidentHasChanged, targetHasChanged, quasiElastic ); 100 InitialCollision(vec, vecLen, currentParticle, targetParticle, 101 incidentHasChanged, targetHasChanged); 114 102 115 103 CalculateMomenta( vec, vecLen, … … 124 112 delete originalTarget; 125 113 return &theParticleChange; 126 } 114 } 115 116 117 // Initial Collision 118 // selects the particle types arising from the initial collision of 119 // the projectile and target nucleon. Secondaries are assigned to 120 // forward and backward reaction hemispheres, but final state energies 121 // and momenta are not calculated here. 127 122 128 void 129 G4RPGPiPlusInelastic::Cascade( 130 G4FastVector<G4ReactionProduct,256> &vec, 131 G4int& vecLen, 132 const G4HadProjectile *originalIncident, 133 G4ReactionProduct ¤tParticle, 134 G4ReactionProduct &targetParticle, 135 G4bool &incidentHasChanged, 136 G4bool &targetHasChanged, 137 G4bool &quasiElastic ) 138 { 139 // derived from original FORTRAN code CASPIP by H. Fesefeldt (18-Sep-1987) 140 // 141 // pi+ undergoes interaction with nucleon within nucleus. 142 // Check if energetically possible to produce pions/kaons. 143 // If not assume nuclear excitation occurs and input particle 144 // is degraded in energy. No other particles produced. 145 // If reaction is possible find correct number of pions/protons/neutrons 146 // produced using an interpolation to multiplicity data. 147 // Replace some pions or protons/neutrons by kaons or strange baryons 148 // according to average multiplicity per inelastic reactions. 149 // 150 const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass(); 151 const G4double etOriginal = originalIncident->GetTotalEnergy(); 152 const G4double pOriginal = originalIncident->GetTotalMomentum(); 153 const G4double targetMass = targetParticle.GetMass(); 154 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal + 155 targetMass*targetMass + 156 2.0*targetMass*etOriginal ); 157 G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal); 158 static G4bool first = true; 159 const G4int numMul = 1200; 160 const G4int numSec = 60; 161 static G4double protmul[numMul], protnorm[numSec]; // proton constants 162 static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants 163 // np = number of pi+, nm = number of pi-, nz = number of pi0 164 G4int counter, nt=0, np=0, nm=0, nz=0; 165 const G4double c = 1.25; 166 const G4double b[] = { 0.70, 0.70 }; 167 if( first ) { // compute normalization constants, this will only be Done once 168 first = false; 169 G4int i; 170 for( i=0; i<numMul; ++i )protmul[i] = 0.0; 171 for( i=0; i<numSec; ++i )protnorm[i] = 0.0; 172 counter = -1; 173 for( np=0; np<(numSec/3); ++np ) { 174 for( nm=std::max(0,np-2); nm<=np; ++nm ) { 175 for( nz=0; nz<numSec/3; ++nz ) { 176 if( ++counter < numMul ) { 177 nt = np+nm+nz; 178 if( nt > 0 ) { 179 protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c); 180 protnorm[nt-1] += protmul[counter]; 181 } 182 } 183 } 184 } 185 } 186 for( i=0; i<numMul; ++i )neutmul[i] = 0.0; 187 for( i=0; i<numSec; ++i )neutnorm[i] = 0.0; 188 counter = -1; 189 for( np=0; np<numSec/3; ++np ) { 190 for( nm=std::max(0,np-1); nm<=(np+1); ++nm ) { 191 for( nz=0; nz<numSec/3; ++nz ) { 192 if( ++counter < numMul ) { 193 nt = np+nm+nz; 194 if( (nt>0) && (nt<=numSec) ) { 195 neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c); 196 neutnorm[nt-1] += neutmul[counter]; 197 } 198 } 199 } 200 } 201 } 202 for( i=0; i<numSec; ++i ) { 203 if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i]; 204 if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i]; 205 } 206 } // end of initialization 207 208 const G4double expxu = 82.; // upper bound for arg. of exp 209 const G4double expxl = -expxu; // lower bound for arg. of exp 210 G4ParticleDefinition *aNeutron = G4Neutron::Neutron(); 211 G4ParticleDefinition *aProton = G4Proton::Proton(); 212 G4ParticleDefinition *aPiZero = G4PionZero::PionZero(); 213 G4int ieab = static_cast<G4int>(availableEnergy*5.0/GeV); 214 const G4double supp[] = {0.,0.2,0.45,0.55,0.65,0.75,0.85,0.90,0.94,0.98}; 215 G4double test, w0, wp, wt, wm; 216 if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) ) 217 { 218 // suppress high multiplicity events at low momentum 219 // only one pion will be produced 220 // charge exchange reaction is included in inelastic cross section 221 222 const G4double cech[] = {1.,0.95,0.79,0.32,0.19,0.16,0.14,0.12,0.10,0.08}; 223 G4int iplab = G4int(std::min( 9.0, pOriginal/GeV*5.0 )); 224 if( G4UniformRand() <= cech[iplab] ) 225 { 226 if( targetParticle.GetDefinition() == aNeutron ) 227 { 228 currentParticle.SetDefinitionAndUpdateE( aPiZero ); // charge exchange 229 targetParticle.SetDefinitionAndUpdateE( aProton ); 230 incidentHasChanged = true; 231 targetHasChanged = true; 232 } 233 } 234 235 if( availableEnergy <= G4PionMinus::PionMinus()->GetPDGMass() ) 236 { 237 quasiElastic = true; 238 return; 239 } 240 241 nm = np = nz = 0; 242 if( targetParticle.GetDefinition() == aProton ) { 243 test = std::exp( std::min( expxu, std::max( expxl, -sqr(1.0+b[0])/(2.0*c*c) ) ) ); 244 w0 = test; 245 wp = test; 246 if( G4UniformRand() < w0/(w0+wp) ) 247 nz =1; 248 else 249 np = 1; 250 } else { // target is a neutron 251 test = std::exp( std::min( expxu, std::max( expxl, -sqr(1.0+b[1])/(2.0*c*c) ) ) ); 252 w0 = test; 253 wp = test; 254 test = std::exp( std::min( expxu, std::max( expxl, -sqr(-1.0+b[1])/(2.0*c*c) ) ) ); 255 wm = test; 256 wt = w0+wp+wm; 257 wp = w0+wp; 258 G4double ran = G4UniformRand(); 259 if( ran < w0/wt ) 260 nz = 1; 261 else if( ran < wp/wt ) 262 np = 1; 263 else 264 nm = 1; 265 } 266 } else { 267 if( availableEnergy <= G4PionMinus::PionMinus()->GetPDGMass() ) 268 { 269 quasiElastic = true; 270 return; 271 } 272 G4double n, anpn; 273 GetNormalizationConstant( availableEnergy, n, anpn ); 274 G4double ran = G4UniformRand(); 275 G4double dum, excs = 0.0; 276 if( targetParticle.GetDefinition() == aProton ) { 277 counter = -1; 278 for( np=0; (np<numSec/3) && (ran>=excs); ++np ) { 279 for( nm=std::max(0,np-2); (nm<=np) && (ran>=excs); ++nm ) { 280 for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz ) { 281 if( ++counter < numMul ) { 282 nt = np+nm+nz; 283 if( nt > 0 ) { 284 test = std::exp( std::min( expxu, std::max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) ); 285 dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n); 286 if( std::fabs(dum) < 1.0 ) { 287 if( test >= 1.0e-10 )excs += dum*test; 288 } else { 289 excs += dum*test; 290 } 291 } 292 } 293 } 294 } 295 } 296 if( ran >= excs ) 297 { 298 quasiElastic = true; 299 return; // 3 previous loops continued to the end 300 } 301 np--; nm--; nz--; 302 } else { // target must be a neutron 303 counter = -1; 304 for( np=0; (np<numSec/3) && (ran>=excs); ++np ) { 305 for( nm=std::max(0,np-1); (nm<=(np+1)) && (ran>=excs); ++nm ) { 306 for( nz=0; (nz<numSec/3) && (ran>=excs); ++nz ) { 307 if( ++counter < numMul ) { 308 nt = np+nm+nz; 309 if( (nt>=1) && (nt<=numSec) ) { 310 test = std::exp( std::min( expxu, std::max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) ); 311 dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n); 312 if( std::fabs(dum) < 1.0 ) { 313 if( test >= 1.0e-10 )excs += dum*test; 314 } else { 315 excs += dum*test; 316 } 317 } 318 } 319 } 320 } 321 } 322 if( ran >= excs ) // 3 previous loops continued to the end 323 { 324 quasiElastic = true; 325 return; // 3 previous loops continued to the end 326 } 327 np--; nm--; nz--; 328 } 329 } 330 if( targetParticle.GetDefinition() == aProton ) { 331 switch( np-nm ) { 332 case 1: 333 if( G4UniformRand() < 0.5 ) { 334 currentParticle.SetDefinitionAndUpdateE( aPiZero ); 335 incidentHasChanged = true; 336 } else { 337 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 338 targetHasChanged = true; 339 } 340 break; 341 case 2: 342 currentParticle.SetDefinitionAndUpdateE( aPiZero ); 343 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 344 incidentHasChanged = true; 345 targetHasChanged = true; 346 break; 347 default: 348 break; 349 } 350 } else { 351 switch( np-nm ) { 352 case 0: 353 if( G4UniformRand() < 0.25 ) { 354 currentParticle.SetDefinitionAndUpdateE( aPiZero ); 355 targetParticle.SetDefinitionAndUpdateE( aProton ); 356 incidentHasChanged = true; 357 targetHasChanged = true; 358 } 359 break; 360 case 1: 361 currentParticle.SetDefinitionAndUpdateE( aPiZero ); 362 incidentHasChanged = true; 363 break; 364 default: 365 targetParticle.SetDefinitionAndUpdateE( aProton ); 366 targetHasChanged = true; 367 break; 368 } 369 } 370 SetUpPions( np, nm, nz, vec, vecLen ); 371 return; 372 } 373 374 /* end of file */ 123 void 124 G4RPGPiPlusInelastic::InitialCollision(G4FastVector<G4ReactionProduct,256>& vec, 125 G4int& vecLen, 126 G4ReactionProduct& currentParticle, 127 G4ReactionProduct& targetParticle, 128 G4bool& incidentHasChanged, 129 G4bool& targetHasChanged) 130 { 131 G4double KE = currentParticle.GetKineticEnergy()/GeV; 132 133 G4int mult; 134 G4int partType; 135 std::vector<G4int> fsTypes; 136 137 G4double testCharge; 138 G4double testBaryon; 139 G4double testStrange; 140 141 // Get particle types according to incident and target types 142 143 if (targetParticle.GetDefinition() == particleDef[pro]) { 144 mult = GetMultiplicityT32(KE); 145 fsTypes = GetFSPartTypesForPipP(mult, KE); 146 partType = fsTypes[0]; 147 if (partType != pro) { 148 targetHasChanged = true; 149 targetParticle.SetDefinition(particleDef[partType]); 150 } 151 152 testCharge = 2.0; 153 testBaryon = 1.0; 154 testStrange = 0.0; 155 156 } else { // target was a neutron 157 mult = GetMultiplicityT12(KE); 158 fsTypes = GetFSPartTypesForPipN(mult, KE); 159 partType = fsTypes[0]; 160 if (partType != neu) { 161 targetHasChanged = true; 162 targetParticle.SetDefinition(particleDef[partType]); 163 } 164 165 testCharge = 1.0; 166 testBaryon = 1.0; 167 testStrange = 0.0; 168 } 169 170 // Remove target particle from list 171 172 fsTypes.erase(fsTypes.begin()); 173 174 // See if the incident particle changed type 175 176 G4int choose = -1; 177 for(G4int i=0; i < mult-1; ++i ) { 178 partType = fsTypes[i]; 179 if (partType == pip) { 180 choose = i; 181 break; 182 } 183 } 184 if (choose == -1) { 185 incidentHasChanged = true; 186 choose = G4int(G4UniformRand()*(mult-1) ); 187 partType = fsTypes[choose]; 188 currentParticle.SetDefinition(particleDef[partType]); 189 } 190 fsTypes.erase(fsTypes.begin()+choose); 191 192 // Remaining particles are secondaries. Put them into vec. 193 // Improve this by randomizing secondary order, then alternate 194 // which secondary is put into forward or backward hemisphere 195 196 G4ReactionProduct* rp(0); 197 for(G4int i=0; i < mult-2; ++i ) { 198 partType = fsTypes[i]; 199 rp = new G4ReactionProduct(); 200 rp->SetDefinition(particleDef[partType]); 201 (G4UniformRand() < 0.5) ? rp->SetSide(-1) : rp->SetSide(1); 202 if (partType > pim && partType < pro) rp->SetMayBeKilled(false); // kaons 203 vec.SetElement(vecLen++, rp); 204 } 375 205 206 // if (mult == 2 && !incidentHasChanged && !targetHasChanged) 207 // quasiElastic = true; 208 209 // Check conservation of charge, strangeness, baryon number 210 211 CheckQnums(vec, vecLen, currentParticle, targetParticle, 212 testCharge, testBaryon, testStrange); 213 214 return; 215 } -
trunk/source/processes/hadronic/models/rpg/src/G4RPGPionSuppression.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGPionSuppression.cc,v 1.1 2007/07/18 21:04:20 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGProtonInelastic.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGProtonInelastic.cc,v 1. 1 2007/07/18 21:04:20dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGProtonInelastic.cc,v 1.4 2008/05/05 21:21:55 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 … … 32 32 33 33 G4HadFinalState* 34 G4RPGProtonInelastic::ApplyYourself( const G4HadProjectile &aTrack,35 G4Nucleus &targetNucleus )34 G4RPGProtonInelastic::ApplyYourself(const G4HadProjectile& aTrack, 35 G4Nucleus& targetNucleus ) 36 36 { 37 37 theParticleChange.Clear(); 38 38 const G4HadProjectile *originalIncident = &aTrack; 39 if (originalIncident->GetKineticEnergy()<= 0.1 *MeV)39 if (originalIncident->GetKineticEnergy()<= 0.1) 40 40 { 41 41 theParticleChange.SetStatusChange(isAlive); … … 49 49 // 50 50 G4DynamicParticle *originalTarget = targetNucleus.ReturnTargetParticle(); 51 if( verboseLevel > 1 ) 52 { 53 const G4Material *targetMaterial = aTrack.GetMaterial(); 54 G4cout << "G4RPGProtonInelastic::ApplyYourself called" << G4endl; 55 G4cout << "kinetic energy = " 56 << originalIncident->GetKineticEnergy()/MeV << "MeV, "; 57 G4cout << "target material = " 58 << targetMaterial->GetName() << ", "; 59 G4cout << "target particle = " 60 << originalTarget->GetDefinition()->GetParticleName() 61 << G4endl; 62 } 63 64 if( originalIncident->GetKineticEnergy()/GeV < 0.01+2.*G4UniformRand()/9. ) 51 52 if (originalIncident->GetKineticEnergy()/GeV < 0.01+2.*G4UniformRand()/9. ) 65 53 { 66 54 SlowProton( originalIncident, targetNucleus ); … … 69 57 } 70 58 71 //72 59 // Fermi motion and evaporation 73 60 // As of Geant3, the Fermi energy calculation had not been Done 74 // 75 G4double ek = originalIncident->GetKineticEnergy() /MeV;76 G4double amas = originalIncident->GetDefinition()->GetPDGMass() /MeV;61 62 G4double ek = originalIncident->GetKineticEnergy(); 63 G4double amas = originalIncident->GetDefinition()->GetPDGMass(); 77 64 G4ReactionProduct modifiedOriginal; 78 65 modifiedOriginal = *originalIncident; … … 80 67 G4double tkin = targetNucleus.Cinema( ek ); 81 68 ek += tkin; 82 modifiedOriginal.SetKineticEnergy( ek*MeV);69 modifiedOriginal.SetKineticEnergy(ek); 83 70 G4double et = ek + amas; 84 71 G4double p = std::sqrt( std::abs((et-amas)*(et+amas)) ); 85 G4double pp = modifiedOriginal.GetMomentum().mag()/MeV; 86 if( pp > 0.0 ) 87 { 72 G4double pp = modifiedOriginal.GetMomentum().mag(); 73 if (pp > 0.0) { 88 74 G4ThreeVector momentum = modifiedOriginal.GetMomentum(); 89 75 modifiedOriginal.SetMomentum( momentum * (p/pp) ); … … 92 78 // calculate black track energies 93 79 // 94 tkin = targetNucleus.EvaporationEffects( ek);80 tkin = targetNucleus.EvaporationEffects(ek); 95 81 ek -= tkin; 96 modifiedOriginal.SetKineticEnergy( ek*MeV);82 modifiedOriginal.SetKineticEnergy(ek); 97 83 et = ek + amas; 98 84 p = std::sqrt( std::abs((et-amas)*(et+amas)) ); 99 pp = modifiedOriginal.GetMomentum().mag()/MeV; 100 if( pp > 0.0 ) 101 { 85 pp = modifiedOriginal.GetMomentum().mag(); 86 if (pp > 0.0) { 102 87 G4ThreeVector momentum = modifiedOriginal.GetMomentum(); 103 88 modifiedOriginal.SetMomentum( momentum * (p/pp) ); 104 89 } 105 90 const G4double cutOff = 0.1; 106 if( modifiedOriginal.GetKineticEnergy()/MeV <= cutOff ) 107 { 91 if (modifiedOriginal.GetKineticEnergy() < cutOff) { 108 92 SlowProton( originalIncident, targetNucleus ); 109 93 delete originalTarget; … … 123 107 vec.Initialize( 0 ); 124 108 125 Cascade( vec, vecLen, 126 originalIncident, currentParticle, targetParticle, 127 incidentHasChanged, targetHasChanged, quasiElastic ); 128 129 CalculateMomenta( vec, vecLen, 130 originalIncident, originalTarget, modifiedOriginal, 131 targetNucleus, currentParticle, targetParticle, 132 incidentHasChanged, targetHasChanged, quasiElastic ); 109 InitialCollision(vec, vecLen, currentParticle, targetParticle, 110 incidentHasChanged, targetHasChanged); 111 112 CalculateMomenta(vec, vecLen, 113 originalIncident, originalTarget, modifiedOriginal, 114 targetNucleus, currentParticle, targetParticle, 115 incidentHasChanged, targetHasChanged, quasiElastic); 133 116 134 117 SetUpChange( vec, vecLen, … … 139 122 return &theParticleChange; 140 123 } 124 141 125 142 126 void … … 146 130 const G4double A = targetNucleus.GetN(); // atomic weight 147 131 const G4double Z = targetNucleus.GetZ(); // atomic number 148 // G4double currentKinetic = originalIncident->GetKineticEnergy() /MeV;132 // G4double currentKinetic = originalIncident->GetKineticEnergy(); 149 133 // 150 134 // calculate Q-value of reactions … … 194 178 } 195 179 } 196 197 void G4RPGProtonInelastic::Cascade( 198 G4FastVector<G4ReactionProduct,256> &vec, 199 G4int &vecLen, 200 const G4HadProjectile *originalIncident, 201 G4ReactionProduct ¤tParticle, 202 G4ReactionProduct &targetParticle, 203 G4bool &incidentHasChanged, 204 G4bool &targetHasChanged, 205 G4bool &quasiElastic ) 180 181 182 // Initial Collision 183 // selects the particle types arising from the initial collision of 184 // the proton and target nucleon. Secondaries are assigned to forward 185 // and backward reaction hemispheres, but final state energies and 186 // momenta are not calculated here. 187 188 void 189 G4RPGProtonInelastic::InitialCollision(G4FastVector<G4ReactionProduct,256>& vec, 190 G4int& vecLen, 191 G4ReactionProduct& currentParticle, 192 G4ReactionProduct& targetParticle, 193 G4bool& incidentHasChanged, 194 G4bool& targetHasChanged) 206 195 { 207 // Derived from H. Fesefeldt's original FORTRAN code CASP 208 // 209 // Proton undergoes interaction with nucleon within a nucleus. Check if 210 // it is energetically possible to produce pions/kaons. In not, assume 211 // nuclear excitation occurs and input particle is degraded in energy. No 212 // other particles are produced. 213 // If reaction is possible, find the correct number of 214 // pions/protons/neutrons produced using an interpolation to multiplicity 215 // data. Replace some pions or protons/neutrons by kaons or strange 216 // baryons according to the average multiplicity per Inelastic reaction. 217 // 218 // The center of mass energy is based on the initial energy, before 219 // Fermi motion and evaporation effects are taken into account 220 // 221 const G4double mOriginal = originalIncident->GetDefinition()->GetPDGMass()/MeV; 222 const G4double etOriginal = originalIncident->GetTotalEnergy()/MeV; 223 const G4double targetMass = targetParticle.GetMass()/MeV; 224 G4double centerofmassEnergy = std::sqrt( mOriginal*mOriginal + 225 targetMass*targetMass + 226 2.0*targetMass*etOriginal ); 227 G4double availableEnergy = centerofmassEnergy-(targetMass+mOriginal); 228 if( availableEnergy <= G4PionPlus::PionPlus()->GetPDGMass()/MeV ) 229 { // not energetically possible to produce pion(s) 230 quasiElastic = true; 231 return; 232 } 233 static G4bool first = true; 234 const G4int numMul = 1200; 235 const G4int numSec = 60; 236 static G4double protmul[numMul], protnorm[numSec]; // proton constants 237 static G4double neutmul[numMul], neutnorm[numSec]; // neutron constants 238 // np = number of pi+, nm = number of pi-, nz = number of pi0 239 G4int counter, nt=0, np=0, nm=0, nz=0; 240 const G4double c = 1.25; 241 const G4double b[] = { 0.70, 0.35 }; 242 if( first ) // compute normalization constants, this will only be Done once 243 { 244 first = false; 245 G4int i; 246 for( i=0; i<numMul; ++i )protmul[i] = 0.0; 247 for( i=0; i<numSec; ++i )protnorm[i] = 0.0; 248 counter = -1; 249 for( np=0; np<(numSec/3); ++np ) 250 { 251 for( nm=std::max(0,np-2); nm<=np; ++nm ) 252 { 253 for( nz=0; nz<numSec/3; ++nz ) 254 { 255 if( ++counter < numMul ) 256 { 257 nt = np+nm+nz; 258 if( nt>0 && nt<=numSec ) 259 { 260 protmul[counter] = Pmltpc(np,nm,nz,nt,b[0],c) / 261 (Factorial(2-np+nm)*Factorial(np-nm) ); 262 protnorm[nt-1] += protmul[counter]; 263 } 264 } 265 } 196 G4double KE = currentParticle.GetKineticEnergy()/GeV; 197 198 G4int mult; 199 G4int partType; 200 std::vector<G4int> fsTypes; 201 G4int part1; 202 G4int part2; 203 204 G4double testCharge; 205 G4double testBaryon; 206 G4double testStrange; 207 208 // Get particle types according to incident and target types 209 210 if (targetParticle.GetDefinition() == particleDef[pro]) { 211 mult = GetMultiplicityT1(KE); 212 fsTypes = GetFSPartTypesForPP(mult, KE); 213 214 part1 = fsTypes[0]; 215 part2 = fsTypes[1]; 216 currentParticle.SetDefinition(particleDef[part1]); 217 targetParticle.SetDefinition(particleDef[part2]); 218 if (part1 == pro) { 219 if (part2 == neu) { 220 if (G4UniformRand() > 0.5) { 221 incidentHasChanged = true; 222 targetParticle.SetDefinition(particleDef[part1]); 223 currentParticle.SetDefinition(particleDef[part2]); 224 } else { 225 targetHasChanged = true; 226 } 227 } else if (part2 > neu && part2 < xi0) { 228 targetHasChanged = true; 266 229 } 230 231 } else { // neutron 232 targetHasChanged = true; 233 incidentHasChanged = true; 267 234 } 268 for( i=0; i<numMul; ++i )neutmul[i] = 0.0; 269 for( i=0; i<numSec; ++i )neutnorm[i] = 0.0; 270 counter = -1; 271 for( np=0; np<numSec/3; ++np ) 272 { 273 for( nm=std::max(0,np-1); nm<=(np+1); ++nm ) 274 { 275 for( nz=0; nz<numSec/3; ++nz ) 276 { 277 if( ++counter < numMul ) 278 { 279 nt = np+nm+nz; 280 if( nt>0 && nt<=numSec ) 281 { 282 neutmul[counter] = Pmltpc(np,nm,nz,nt,b[1],c) / 283 (Factorial(1-np+nm)*Factorial(1+np-nm) ); 284 neutnorm[nt-1] += neutmul[counter]; 285 } 286 } 287 } 235 236 testCharge = 2.0; 237 testBaryon = 2.0; 238 testStrange = 0.0; 239 240 } else { // target was a neutron 241 mult = GetMultiplicityT0(KE); 242 fsTypes = GetFSPartTypesForPN(mult, KE); 243 244 part1 = fsTypes[0]; 245 part2 = fsTypes[1]; 246 currentParticle.SetDefinition(particleDef[part1]); 247 targetParticle.SetDefinition(particleDef[part2]); 248 if (part1 == pro) { 249 if (part2 == pro) { 250 targetHasChanged = true; 251 } else if (part2 == neu) { 252 if (G4UniformRand() > 0.5) { 253 incidentHasChanged = true; 254 targetHasChanged = true; 255 targetParticle.SetDefinition(particleDef[part1]); 256 currentParticle.SetDefinition(particleDef[part2]); 257 } 258 } else { // hyperon 259 targetHasChanged = true; 288 260 } 261 262 } else { // neutron 263 incidentHasChanged = true; 264 if (part2 > neu && part2 < xi0) targetHasChanged = true; 289 265 } 290 for( i=0; i<numSec; ++i ) 291 { 292 if( protnorm[i] > 0.0 )protnorm[i] = 1.0/protnorm[i]; 293 if( neutnorm[i] > 0.0 )neutnorm[i] = 1.0/neutnorm[i]; 294 } 295 } // end of initialization 296 297 const G4double expxu = 82.; // upper bound for arg. of exp 298 const G4double expxl = -expxu; // lower bound for arg. of exp 299 G4ParticleDefinition *aNeutron = G4Neutron::Neutron(); 300 G4ParticleDefinition *aProton = G4Proton::Proton(); 301 G4int ieab = static_cast<G4int>(availableEnergy*5.0/GeV); 302 const G4double supp[] = {0.,0.4,0.55,0.65,0.75,0.82,0.86,0.90,0.94,0.98}; 303 G4double test, w0, wp, wt, wm; 304 if( (availableEnergy < 2.0*GeV) && (G4UniformRand() >= supp[ieab]) ) 305 { 306 // suppress high multiplicity events at low momentum 307 // only one pion will be produced 308 309 np = nm = nz = 0; 310 if( targetParticle.GetDefinition() == aProton ) 311 { 312 test = std::exp( std::min( expxu, std::max( 313 expxl, -(1.0+b[0])*(1.0+b[0])/(2.0*c*c) ) ) ); 314 w0 = test/2.0; 315 wp = test; 316 if( G4UniformRand() < w0/(w0+wp) ) 317 nz = 1; 318 else 319 np = 1; 320 } 321 else // target is a neutron 322 { 323 test = std::exp( std::min( expxu, std::max( 324 expxl, -(1.0+b[1])*(1.0+b[1])/(2.0*c*c) ) ) ); 325 w0 = test; 326 wp = test/2.0; 327 test = std::exp( std::min( expxu, std::max( 328 expxl, -(-1.0+b[1])*(-1.0+b[1])/(2.0*c*c) ) ) ); 329 wm = test/2.0; 330 wt = w0+wp+wm; 331 wp += w0; 332 G4double ran = G4UniformRand(); 333 if( ran < w0/wt ) 334 nz = 1; 335 else if( ran < wp/wt ) 336 np = 1; 337 else 338 nm = 1; 339 } 340 } 341 else // (availableEnergy >= 2.0*GeV) || (random number < supp[ieab]) 342 { 343 G4double n, anpn; 344 GetNormalizationConstant( availableEnergy, n, anpn ); 345 G4double ran = G4UniformRand(); 346 G4double dum, excs = 0.0; 347 if( targetParticle.GetDefinition() == aProton ) 348 { 349 counter = -1; 350 for( np=0; np<numSec/3 && ran>=excs; ++np ) 351 { 352 for( nm=std::max(0,np-2); nm<=np && ran>=excs; ++nm ) 353 { 354 for( nz=0; nz<numSec/3 && ran>=excs; ++nz ) 355 { 356 if( ++counter < numMul ) 357 { 358 nt = np+nm+nz; 359 if( nt>0 && nt<=numSec ) 360 { 361 test = std::exp( std::min( expxu, std::max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) ); 362 dum = (pi/anpn)*nt*protmul[counter]*protnorm[nt-1]/(2.0*n*n); 363 if( std::fabs(dum) < 1.0 ) 364 { 365 if( test >= 1.0e-10 )excs += dum*test; 366 } else { 367 excs += dum*test; 368 } 369 } 370 } 371 } 372 } 373 } 374 if( ran >= excs ) // 3 previous loops continued to the end 375 { 376 quasiElastic = true; 377 return; 378 } 379 } 380 else // target must be a neutron 381 { 382 counter = -1; 383 for( np=0; np<numSec/3 && ran>=excs; ++np ) 384 { 385 for( nm=std::max(0,np-1); nm<=(np+1) && ran>=excs; ++nm ) 386 { 387 for( nz=0; nz<numSec/3 && ran>=excs; ++nz ) 388 { 389 if( ++counter < numMul ) 390 { 391 nt = np+nm+nz; 392 if( nt>0 && nt<=numSec ) 393 { 394 test = std::exp( std::min( expxu, std::max( expxl, -(pi/4.0)*(nt*nt)/(n*n) ) ) ); 395 dum = (pi/anpn)*nt*neutmul[counter]*neutnorm[nt-1]/(2.0*n*n); 396 if( std::fabs(dum) < 1.0 ) 397 { 398 if( test >= 1.0e-10 )excs += dum*test; 399 } else { 400 excs += dum*test; 401 } 402 } 403 } 404 } 405 } 406 } 407 if( ran >= excs ) // 3 previous loops continued to the end 408 { 409 quasiElastic = true; 410 return; 411 } 412 } 413 np--; nm--; nz--; 414 } 415 if( targetParticle.GetDefinition() == aProton ) 416 { 417 switch( np-nm ) 418 { 419 case 1: 420 if( G4UniformRand() < 0.5 ) 421 { 422 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 423 targetHasChanged = true; 424 } else { 425 currentParticle.SetDefinitionAndUpdateE( aNeutron ); 426 incidentHasChanged = true; 427 } 428 break; 429 case 2: 430 currentParticle.SetDefinitionAndUpdateE( aNeutron ); 431 targetParticle.SetDefinitionAndUpdateE( aNeutron ); 432 incidentHasChanged = true; 433 targetHasChanged = true; 434 break; 435 default: 436 break; 437 } 438 } 439 else // target is a neutron 440 { 441 switch( np-nm ) 442 { 443 case 0: 444 if( G4UniformRand() < 0.333333 ) 445 { 446 currentParticle.SetDefinitionAndUpdateE( aNeutron ); 447 targetParticle.SetDefinitionAndUpdateE( aProton ); 448 incidentHasChanged = true; 449 targetHasChanged = true; 450 } 451 break; 452 case 1: 453 currentParticle.SetDefinitionAndUpdateE( aNeutron ); 454 incidentHasChanged = true; 455 break; 456 default: 457 targetParticle.SetDefinitionAndUpdateE( aProton ); 458 targetHasChanged = true; 459 break; 460 } 461 } 462 SetUpPions( np, nm, nz, vec, vecLen ); 463 return; 464 } 465 466 /* end of file */ 467 266 267 testCharge = 1.0; 268 testBaryon = 2.0; 269 testStrange = 0.0; 270 } 271 272 // Remove incident and target from fsTypes 273 274 fsTypes.erase(fsTypes.begin()); 275 fsTypes.erase(fsTypes.begin()); 276 277 // Remaining particles are secondaries. Put them into vec. 278 279 G4ReactionProduct* rp(0); 280 for(G4int i=0; i < mult-2; ++i ) { 281 partType = fsTypes[i]; 282 rp = new G4ReactionProduct(); 283 rp->SetDefinition(particleDef[partType]); 284 (G4UniformRand() < 0.5) ? rp->SetSide(-1) : rp->SetSide(1); 285 vec.SetElement(vecLen++, rp); 286 } 287 288 // Check conservation of charge, strangeness, baryon number 289 290 CheckQnums(vec, vecLen, currentParticle, targetParticle, 291 testCharge, testBaryon, testStrange); 292 293 return; 294 } -
trunk/source/processes/hadronic/models/rpg/src/G4RPGReaction.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGReaction.cc,v 1. 1 2007/07/18 21:04:21dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGReaction.cc,v 1.4 2008/05/05 21:21:55 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 … … 58 58 const G4double edta, // GeV 59 59 const G4int ndta, 60 const G4double sprob, 61 const G4double kineticMinimum, // GeV 62 const G4double kineticFactor, // GeV 63 const G4ReactionProduct &modifiedOriginal, 60 const G4ReactionProduct& modifiedOriginal, 64 61 G4int PinNucleus, 65 62 G4int NinNucleus, 66 const G4Nucleus &targetNucleus,67 G4FastVector<G4ReactionProduct,256> &vec,68 G4int &vecLen)63 const G4Nucleus& targetNucleus, 64 G4FastVector<G4ReactionProduct,256>& vec, 65 G4int& vecLen) 69 66 { 70 67 // derived from original FORTRAN code in GENXPT and TWOCLU by H. Fesefeldt … … 74 71 // epnb is the kinetic energy available for proton/neutron black track particles 75 72 // edta is the kinetic energy available for deuteron/triton/alpha particles 76 // 77 78 G4ParticleDefinition *aProton = G4Proton::Proton(); 79 G4ParticleDefinition *aNeutron = G4Neutron::Neutron(); 80 G4ParticleDefinition *aDeuteron = G4Deuteron::Deuteron(); 81 G4ParticleDefinition *aTriton = G4Triton::Triton(); 82 G4ParticleDefinition *anAlpha = G4Alpha::Alpha(); 83 84 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/MeV; 85 const G4double atomicWeight = targetNucleus.GetN(); 86 const G4double atomicNumber = targetNucleus.GetZ(); 87 88 const G4double ika1 = 3.6; 89 const G4double ika2 = 35.56; 90 const G4double ika3 = 6.45; 91 92 G4int i; 93 G4double pp; 94 G4double kinCreated = 0; 95 G4double cfa = 0.025*((atomicWeight-1.0)/120.0) * std::exp(-(atomicWeight-1.0)/120.0); 96 97 // First add protons and neutrons to final state 98 99 if (npnb > 0) 100 { 101 G4double backwardKinetic = 0.0; 102 G4int local_npnb = npnb; 103 for( i=0; i<npnb; ++i ) if( G4UniformRand() < sprob ) local_npnb--; 104 G4double local_epnb = epnb; 105 if (ndta == 0) local_epnb += edta; // Retrieve unused kinetic energy 106 G4double ekin = local_epnb/std::max(1,local_npnb); 107 108 for( i=0; i<local_npnb; ++i ) 109 { 110 G4ReactionProduct * p1 = new G4ReactionProduct(); 111 if( backwardKinetic > local_epnb ) 112 { 113 delete p1; 114 break; 115 } 116 G4double ran = G4UniformRand(); 117 G4double kinetic = -ekin*std::log(ran) - cfa*(1.0+0.5*normal()); 118 if( kinetic < 0.0 )kinetic = -0.010*std::log(ran); 119 backwardKinetic += kinetic; 120 if( backwardKinetic > local_epnb ) 121 kinetic = std::max( kineticMinimum, local_epnb-(backwardKinetic-kinetic) ); 122 123 if (G4UniformRand() > (1.0-atomicNumber/atomicWeight)) { 124 125 // Boil off a proton if there are any left, otherwise a neutron 126 127 if (PinNucleus > 0) { 128 p1->SetDefinition( aProton ); 129 PinNucleus--; 130 } else if (NinNucleus > 0) { 131 p1->SetDefinition( aNeutron ); 132 NinNucleus--; 133 } else { 134 delete p1; 135 break; // no nucleons left in nucleus 136 } 73 74 G4ParticleDefinition* aProton = G4Proton::Proton(); 75 G4ParticleDefinition* aNeutron = G4Neutron::Neutron(); 76 G4ParticleDefinition* aDeuteron = G4Deuteron::Deuteron(); 77 G4ParticleDefinition* aTriton = G4Triton::Triton(); 78 G4ParticleDefinition* anAlpha = G4Alpha::Alpha(); 79 80 const G4double ekOriginal = modifiedOriginal.GetKineticEnergy()/MeV; 81 const G4double atomicWeight = targetNucleus.GetN(); 82 const G4double atomicNumber = targetNucleus.GetZ(); 83 84 const G4double ika1 = 3.6; 85 const G4double ika2 = 35.56; 86 const G4double ika3 = 6.45; 87 88 G4int i; 89 G4double pp; 90 G4double kinetic = 0; 91 G4double kinCreated = 0; 92 // G4double cfa = 0.025*((atomicWeight-1.0)/120.0) * std::exp(-(atomicWeight-1.0)/120.0); 93 G4double remainingE = 0; 94 95 // First add protons and neutrons to final state 96 if (npnb > 0) { 97 // G4double backwardKinetic = 0.0; 98 G4int local_npnb = npnb; 99 // DHW: does not conserve energy for (i = 0; i < npnb; ++i) if (G4UniformRand() < sprob) local_npnb--; 100 local_npnb = std::min(PinNucleus + NinNucleus , local_npnb); 101 G4double local_epnb = epnb; 102 if (ndta == 0) local_epnb += edta; // Retrieve unused kinetic energy 103 // G4double ekin = local_epnb/std::max(1,local_npnb); 104 105 remainingE = local_epnb; 106 for (i = 0; i < local_npnb; ++i) 107 { 108 G4ReactionProduct* p1 = new G4ReactionProduct(); 109 // if( backwardKinetic > local_epnb ) { 110 // delete p1; 111 // break; 112 // } 113 114 // G4double ran = G4UniformRand(); 115 // G4double kinetic = -ekin*std::log(ran) - cfa*(1.0+0.5*normal()); 116 // if( kinetic < 0.0 )kinetic = -0.010*std::log(ran); 117 // backwardKinetic += kinetic; 118 // if( backwardKinetic > local_epnb ) 119 // kinetic = std::max( kineticMinimum, local_epnb-(backwardKinetic-kinetic) ); 120 121 if (G4UniformRand() > (1.0-atomicNumber/atomicWeight)) { 122 123 // Boil off a proton if there are any left, otherwise a neutron 124 125 if (PinNucleus > 0) { 126 p1->SetDefinition( aProton ); 127 PinNucleus--; 137 128 } else { 138 139 // Boil off a neutron if there are any left, otherwise a proton 140 141 if (NinNucleus > 0) { 142 p1->SetDefinition( aNeutron ); 143 NinNucleus--; 144 } else if (PinNucleus > 0) { 145 p1->SetDefinition( aProton ); 146 PinNucleus--; 147 } else { 148 delete p1; 149 break; // no nucleons left in nucleus 150 } 151 } 152 153 vec.SetElement( vecLen, p1 ); 154 G4double cost = G4UniformRand() * 2.0 - 1.0; 155 G4double sint = std::sqrt(std::fabs(1.0-cost*cost)); 156 G4double phi = twopi * G4UniformRand(); 157 vec[vecLen]->SetNewlyAdded( true ); 158 vec[vecLen]->SetKineticEnergy( kinetic*GeV ); 159 kinCreated+=kinetic; 160 pp = vec[vecLen]->GetTotalMomentum()/MeV; 161 vec[vecLen]->SetMomentum( pp*sint*std::sin(phi)*MeV, 162 pp*sint*std::cos(phi)*MeV, 163 pp*cost*MeV ); 164 vecLen++; 165 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 166 } 167 168 if (NinNucleus > 0) { 169 if( (atomicWeight >= 10.0) && (ekOriginal <= 2.0*GeV) ) 129 p1->SetDefinition( aNeutron ); 130 NinNucleus--; 131 // } else { 132 // delete p1; 133 // break; // no nucleons left in nucleus 134 } 135 } else { 136 137 // Boil off a neutron if there are any left, otherwise a proton 138 139 if (NinNucleus > 0) { 140 p1->SetDefinition( aNeutron ); 141 NinNucleus--; 142 } else { 143 p1->SetDefinition( aProton ); 144 PinNucleus--; 145 // } else { 146 // delete p1; 147 // break; // no nucleons left in nucleus 148 } 149 } 150 151 if (i < local_npnb - 1) { 152 kinetic = remainingE*G4UniformRand(); 153 remainingE -= kinetic; 154 } else { 155 kinetic = remainingE; 156 } 157 158 vec.SetElement( vecLen, p1 ); 159 G4double cost = G4UniformRand() * 2.0 - 1.0; 160 G4double sint = std::sqrt(std::fabs(1.0-cost*cost)); 161 G4double phi = twopi * G4UniformRand(); 162 vec[vecLen]->SetNewlyAdded( true ); 163 vec[vecLen]->SetKineticEnergy( kinetic*GeV ); 164 kinCreated+=kinetic; 165 pp = vec[vecLen]->GetTotalMomentum(); 166 vec[vecLen]->SetMomentum(pp*sint*std::sin(phi), 167 pp*sint*std::cos(phi), 168 pp*cost ); 169 vecLen++; 170 } 171 172 if (NinNucleus > 0) { 173 if( (atomicWeight >= 10.0) && (ekOriginal <= 2.0*GeV) ) 174 { 175 G4double ekw = ekOriginal/GeV; 176 G4int ika, kk = 0; 177 if( ekw > 1.0 )ekw *= ekw; 178 ekw = std::max( 0.1, ekw ); 179 ika = G4int(ika1*std::exp((atomicNumber*atomicNumber/ 180 atomicWeight-ika2)/ika3)/ekw); 181 if( ika > 0 ) 170 182 { 171 G4double ekw = ekOriginal/GeV; 172 G4int ika, kk = 0; 173 if( ekw > 1.0 )ekw *= ekw; 174 ekw = std::max( 0.1, ekw ); 175 ika = G4int(ika1*std::exp((atomicNumber*atomicNumber/ 176 atomicWeight-ika2)/ika3)/ekw); 177 if( ika > 0 ) 183 for( i=(vecLen-1); i>=0; --i ) 178 184 { 179 for( i=(vecLen-1); i>=0; --i)185 if( (vec[i]->GetDefinition() == aProton) && vec[i]->GetNewlyAdded() ) 180 186 { 181 if( (vec[i]->GetDefinition() == aProton) && vec[i]->GetNewlyAdded() ) 182 { 183 vec[i]->SetDefinitionAndUpdateE( aNeutron ); // modified 22-Oct-97 184 PinNucleus++; 185 NinNucleus--; 186 if( ++kk > ika )break; 187 } 187 vec[i]->SetDefinitionAndUpdateE( aNeutron ); // modified 22-Oct-97 188 PinNucleus++; 189 NinNucleus--; 190 if( ++kk > ika )break; 188 191 } 189 192 } 190 193 } 191 } // if (NinNucleus >0) 192 } // if (npnb > 0) 193 194 // Next try to add deuterons, tritons and alphas to final state 195 196 if (ndta > 0) 197 { 198 G4double backwardKinetic = 0.0; 199 G4int local_ndta=ndta; 200 // DHW for( i=0; i<ndta; ++i )if( G4UniformRand() < sprob )local_ndta--; 201 G4double local_edta = edta; 202 if (npnb == 0) local_edta += epnb; // Retrieve unused kinetic energy 203 G4double ekin = local_edta/std::max(1,local_ndta); 204 205 for( i=0; i<local_ndta; ++i ) 206 { 207 G4ReactionProduct *p2 = new G4ReactionProduct(); 208 if( backwardKinetic > local_edta ) 209 { 194 } 195 } // if (NinNucleus >0) 196 } // if (npnb > 0) 197 198 // Next try to add deuterons, tritons and alphas to final state 199 200 G4double ran = 0; 201 if (ndta > 0) { 202 // G4double backwardKinetic = 0.0; 203 G4int local_ndta=ndta; 204 // DHW: does not conserve energy for (i = 0; i < ndta; ++i) if (G4UniformRand() < sprob) local_ndta--; 205 G4double local_edta = edta; 206 if (npnb == 0) local_edta += epnb; // Retrieve unused kinetic energy 207 // G4double ekin = local_edta/std::max(1,local_ndta); 208 209 remainingE = local_edta; 210 for (i = 0; i < local_ndta; ++i) { 211 G4ReactionProduct* p2 = new G4ReactionProduct(); 212 // if( backwardKinetic > local_edta ) { 213 // delete p2; 214 // break; 215 // } 216 217 // G4double ran = G4UniformRand(); 218 // G4double kinetic = -ekin*std::log(ran)-cfa*(1.+0.5*normal()); 219 // if( kinetic < 0.0 )kinetic = kineticFactor*std::log(ran); 220 // backwardKinetic += kinetic; 221 // if( backwardKinetic > local_edta )kinetic = local_edta-(backwardKinetic-kinetic); 222 // if( kinetic < 0.0 )kinetic = kineticMinimum; 223 224 ran = G4UniformRand(); 225 if (ran < 0.60) { 226 if (PinNucleus > 0 && NinNucleus > 0) { 227 p2->SetDefinition( aDeuteron ); 228 PinNucleus--; 229 NinNucleus--; 230 } else if (NinNucleus > 0) { 231 p2->SetDefinition( aNeutron ); 232 NinNucleus--; 233 } else if (PinNucleus > 0) { 234 p2->SetDefinition( aProton ); 235 PinNucleus--; 236 } else { 210 237 delete p2; 211 238 break; 212 239 } 213 G4double ran = G4UniformRand(); 214 G4double kinetic = -ekin*std::log(ran)-cfa*(1.+0.5*normal()); 215 if( kinetic < 0.0 )kinetic = kineticFactor*std::log(ran); 216 backwardKinetic += kinetic; 217 if( backwardKinetic > local_edta )kinetic = local_edta-(backwardKinetic-kinetic); 218 if( kinetic < 0.0 )kinetic = kineticMinimum; 219 G4double cost = 2.0*G4UniformRand() - 1.0; 220 G4double sint = std::sqrt(std::max(0.0,(1.0-cost*cost))); 221 G4double phi = twopi*G4UniformRand(); 222 ran = G4UniformRand(); 223 if (ran < 0.60) { 224 if (PinNucleus > 0 && NinNucleus > 0) { 225 p2->SetDefinition( aDeuteron ); 226 PinNucleus--; 227 NinNucleus--; 228 } else if (NinNucleus > 0) { 229 p2->SetDefinition( aNeutron ); 230 NinNucleus--; 231 } else if (PinNucleus > 0) { 232 p2->SetDefinition( aProton ); 233 PinNucleus--; 234 } else { 235 delete p2; 236 break; 237 } 238 } else if (ran < 0.90) { 239 if (PinNucleus > 0 && NinNucleus > 1) { 240 p2->SetDefinition( aTriton ); 241 PinNucleus--; 242 NinNucleus -= 2; 243 } else if (PinNucleus > 0 && NinNucleus > 0) { 244 p2->SetDefinition( aDeuteron ); 245 PinNucleus--; 246 NinNucleus--; 247 } else if (NinNucleus > 0) { 248 p2->SetDefinition( aNeutron ); 249 NinNucleus--; 250 } else if (PinNucleus > 0) { 251 p2->SetDefinition( aProton ); 252 PinNucleus--; 253 } else { 254 delete p2; 255 break; 256 } 257 } else { 258 if (PinNucleus > 1 && NinNucleus > 1) { 259 p2->SetDefinition( anAlpha ); 260 PinNucleus -= 2; 261 NinNucleus -= 2; 262 } else if (PinNucleus > 0 && NinNucleus > 1) { 263 p2->SetDefinition( aTriton ); 264 PinNucleus--; 265 NinNucleus -= 2; 266 } else if (PinNucleus > 0 && NinNucleus > 0) { 267 p2->SetDefinition( aDeuteron ); 268 PinNucleus--; 269 NinNucleus--; 270 } else if (NinNucleus > 0) { 271 p2->SetDefinition( aNeutron ); 272 NinNucleus--; 273 } else if (PinNucleus > 0) { 274 p2->SetDefinition( aProton ); 275 PinNucleus--; 276 } else { 277 delete p2; 278 break; 279 } 280 } 281 282 vec.SetElement( vecLen, p2 ); 283 vec[vecLen]->SetNewlyAdded( true ); 284 vec[vecLen]->SetKineticEnergy( kinetic*GeV ); 285 kinCreated+=kinetic; 286 pp = vec[vecLen]->GetTotalMomentum()/MeV; 287 vec[vecLen++]->SetMomentum( pp*sint*std::sin(phi)*MeV, 288 pp*sint*std::cos(phi)*MeV, 289 pp*cost*MeV ); 290 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 291 } 292 } // if (ndta > 0) 293 294 // G4double delta = epnb+edta - kinCreated; 240 } else if (ran < 0.90) { 241 if (PinNucleus > 0 && NinNucleus > 1) { 242 p2->SetDefinition( aTriton ); 243 PinNucleus--; 244 NinNucleus -= 2; 245 } else if (PinNucleus > 0 && NinNucleus > 0) { 246 p2->SetDefinition( aDeuteron ); 247 PinNucleus--; 248 NinNucleus--; 249 } else if (NinNucleus > 0) { 250 p2->SetDefinition( aNeutron ); 251 NinNucleus--; 252 } else if (PinNucleus > 0) { 253 p2->SetDefinition( aProton ); 254 PinNucleus--; 255 } else { 256 delete p2; 257 break; 258 } 259 } else { 260 if (PinNucleus > 1 && NinNucleus > 1) { 261 p2->SetDefinition( anAlpha ); 262 PinNucleus -= 2; 263 NinNucleus -= 2; 264 } else if (PinNucleus > 0 && NinNucleus > 1) { 265 p2->SetDefinition( aTriton ); 266 PinNucleus--; 267 NinNucleus -= 2; 268 } else if (PinNucleus > 0 && NinNucleus > 0) { 269 p2->SetDefinition( aDeuteron ); 270 PinNucleus--; 271 NinNucleus--; 272 } else if (NinNucleus > 0) { 273 p2->SetDefinition( aNeutron ); 274 NinNucleus--; 275 } else if (PinNucleus > 0) { 276 p2->SetDefinition( aProton ); 277 PinNucleus--; 278 } else { 279 delete p2; 280 break; 281 } 282 } 283 284 if (i < local_ndta - 1) { 285 kinetic = remainingE*G4UniformRand(); 286 remainingE -= kinetic; 287 } else { 288 kinetic = remainingE; 289 } 290 291 vec.SetElement( vecLen, p2 ); 292 G4double cost = 2.0*G4UniformRand() - 1.0; 293 G4double sint = std::sqrt(std::max(0.0,(1.0-cost*cost))); 294 G4double phi = twopi*G4UniformRand(); 295 vec[vecLen]->SetNewlyAdded( true ); 296 vec[vecLen]->SetKineticEnergy( kinetic*GeV ); 297 kinCreated+=kinetic; 298 299 pp = vec[vecLen]->GetTotalMomentum(); 300 vec[vecLen]->SetMomentum( pp*sint*std::sin(phi), 301 pp*sint*std::cos(phi), 302 pp*cost ); 303 vecLen++; 304 } 305 } // if (ndta > 0) 295 306 } 296 307 297 308 298 G4double G4RPGReaction::GenerateNBodyEvent(299 const G4double totalEnergy,// MeV300 const G4bool constantCrossSection,301 G4FastVector<G4ReactionProduct,256> &vec,302 G4int &vecLen)309 G4double 310 G4RPGReaction::GenerateNBodyEvent(const G4double totalEnergy, // MeV 311 const G4bool constantCrossSection, 312 G4FastVector<G4ReactionProduct,256>& vec, 313 G4int &vecLen) 303 314 { 304 G4int i; 305 const G4double expxu = 82.; // upper bound for arg. of exp 306 const G4double expxl = -expxu; // lower bound for arg. of exp 307 if( vecLen < 2 ) 308 { 309 G4cerr << "*** Error in G4RPGReaction::GenerateNBodyEvent" << G4endl; 310 G4cerr << " number of particles < 2" << G4endl; 311 G4cerr << "totalEnergy = " << totalEnergy << "MeV, vecLen = " << vecLen << G4endl; 312 return -1.0; 313 } 314 G4double mass[18]; // mass of each particle 315 G4double energy[18]; // total energy of each particle 316 G4double pcm[3][18]; // pcm is an array with 3 rows and vecLen columns 317 318 G4double totalMass = 0.0; 319 G4double extraMass = 0; 320 G4double sm[18]; 321 322 for( i=0; i<vecLen; ++i ) 323 { 324 mass[i] = vec[i]->GetMass()/GeV; 325 if(vec[i]->GetSide() == -2) extraMass+=vec[i]->GetMass()/GeV; 326 vec[i]->SetMomentum( 0.0, 0.0, 0.0 ); 327 pcm[0][i] = 0.0; // x-momentum of i-th particle 328 pcm[1][i] = 0.0; // y-momentum of i-th particle 329 pcm[2][i] = 0.0; // z-momentum of i-th particle 330 energy[i] = mass[i]; // total energy of i-th particle 331 totalMass += mass[i]; 332 sm[i] = totalMass; 333 } 334 G4double totalE = totalEnergy/GeV; 335 if( totalMass > totalE ) 336 { 337 //G4cerr << "*** Error in G4RPGReaction::GenerateNBodyEvent" << G4endl; 338 //G4cerr << " total mass (" << totalMass*GeV << "MeV) > total energy (" 339 // << totalEnergy << "MeV)" << G4endl; 340 totalE = totalMass; 341 return -1.0; 342 } 343 G4double kineticEnergy = totalE - totalMass; 344 G4double emm[18]; 345 //G4double *emm = new G4double [vecLen]; 346 emm[0] = mass[0]; 347 emm[vecLen-1] = totalE; 348 if( vecLen > 2 ) // the random numbers are sorted 349 { 350 G4double ran[18]; 351 for( i=0; i<vecLen; ++i )ran[i] = G4UniformRand(); 352 for( i=0; i<vecLen-2; ++i ) 353 { 354 for( G4int j=vecLen-2; j>i; --j ) 355 { 356 if( ran[i] > ran[j] ) 357 { 358 G4double temp = ran[i]; 359 ran[i] = ran[j]; 360 ran[j] = temp; 361 } 362 } 363 } 364 for( i=1; i<vecLen-1; ++i )emm[i] = ran[i-1]*kineticEnergy + sm[i]; 365 } 366 // Weight is the sum of logarithms of terms instead of the product of terms 367 G4bool lzero = true; 368 G4double wtmax = 0.0; 369 if( constantCrossSection ) // this is KGENEV=1 in PHASP 370 { 371 G4double emmax = kineticEnergy + mass[0]; 372 G4double emmin = 0.0; 315 G4int i; 316 const G4double expxu = 82.; // upper bound for arg. of exp 317 const G4double expxl = -expxu; // lower bound for arg. of exp 318 319 if (vecLen < 2) { 320 G4cerr << "*** Error in G4RPGReaction::GenerateNBodyEvent" << G4endl; 321 G4cerr << " number of particles < 2" << G4endl; 322 G4cerr << "totalEnergy = " << totalEnergy << "MeV, vecLen = " << vecLen << G4endl; 323 return -1.0; 324 } 325 326 G4double mass[18]; // mass of each particle 327 G4double energy[18]; // total energy of each particle 328 G4double pcm[3][18]; // pcm is an array with 3 rows and vecLen columns 329 330 G4double totalMass = 0.0; 331 G4double extraMass = 0; 332 G4double sm[18]; 333 334 for (i=0; i<vecLen; ++i) { 335 mass[i] = vec[i]->GetMass()/GeV; 336 if(vec[i]->GetSide() == -2) extraMass+=vec[i]->GetMass()/GeV; 337 vec[i]->SetMomentum( 0.0, 0.0, 0.0 ); 338 pcm[0][i] = 0.0; // x-momentum of i-th particle 339 pcm[1][i] = 0.0; // y-momentum of i-th particle 340 pcm[2][i] = 0.0; // z-momentum of i-th particle 341 energy[i] = mass[i]; // total energy of i-th particle 342 totalMass += mass[i]; 343 sm[i] = totalMass; 344 } 345 346 G4double totalE = totalEnergy/GeV; 347 if (totalMass > totalE) { 348 //G4cerr << "*** Error in G4RPGReaction::GenerateNBodyEvent" << G4endl; 349 //G4cerr << " total mass (" << totalMass*GeV << "MeV) > total energy (" 350 // << totalEnergy << "MeV)" << G4endl; 351 totalE = totalMass; 352 return -1.0; 353 } 354 355 G4double kineticEnergy = totalE - totalMass; 356 G4double emm[18]; 357 emm[0] = mass[0]; 358 emm[vecLen-1] = totalE; 359 360 if (vecLen > 2) { // the random numbers are sorted 361 G4double ran[18]; 362 for( i=0; i<vecLen; ++i )ran[i] = G4UniformRand(); 363 for (i=0; i<vecLen-2; ++i) { 364 for (G4int j=vecLen-2; j>i; --j) { 365 if (ran[i] > ran[j]) { 366 G4double temp = ran[i]; 367 ran[i] = ran[j]; 368 ran[j] = temp; 369 } 370 } 371 } 372 for( i=1; i<vecLen-1; ++i )emm[i] = ran[i-1]*kineticEnergy + sm[i]; 373 } 374 375 // Weight is the sum of logarithms of terms instead of the product of terms 376 377 G4bool lzero = true; 378 G4double wtmax = 0.0; 379 if (constantCrossSection) { 380 G4double emmax = kineticEnergy + mass[0]; 381 G4double emmin = 0.0; 373 382 for( i=1; i<vecLen; ++i ) 374 383 { … … 394 403 else 395 404 wtmax = expxu; 396 } 397 else 398 { 405 } else { 399 406 // ffq(n) = pi*(2*pi)^(n-2)/(n-2)! 400 407 const G4double ffq[18] = { 0., 3.141592, 19.73921, 62.01255, 129.8788, 204.0131, … … 403 410 12.0006, 5.3858, 2.2560, 0.8859 }; 404 411 wtmax = std::log( std::pow( kineticEnergy, vecLen-2 ) * ffq[vecLen-1] / totalE ); 405 } 406 lzero = true; 407 G4double pd[50]; 408 //G4double *pd = new G4double [vecLen-1]; 412 } 413 414 // Calculate momenta for secondaries 415 416 lzero = true; 417 G4double pd[50]; 418 409 419 for( i=0; i<vecLen-1; ++i ) 410 420 { … … 475 485 } 476 486 } 477 for( i=0; i<vecLen; ++i ) 478 {479 vec[i]->SetMomentum( pcm[0][i]*GeV, pcm[1][i]*GeV, pcm[2][i]*GeV );480 vec[i]->SetTotalEnergy( energy[i]*GeV );481 }482 483 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen);484 return weight; 485 } 487 488 for (i=0; i<vecLen; ++i) { 489 vec[i]->SetMomentum( pcm[0][i]*GeV, pcm[1][i]*GeV, pcm[2][i]*GeV ); 490 vec[i]->SetTotalEnergy( energy[i]*GeV ); 491 } 492 493 return weight; 494 } 495 486 496 497 G4double 498 G4RPGReaction::GenerateNBodyEventT(const G4double totalEnergy, 499 const G4bool constantCrossSection, 500 std::vector<G4ReactionProduct*>& tempList) 501 { 502 G4int i; 503 const G4double expxu = 82.; // upper bound for arg. of exp 504 const G4double expxl = -expxu; // lower bound for arg. of exp 505 G4int listLen = tempList.size(); 506 507 if (listLen < 2) { 508 G4cerr << "*** Error in G4RPGReaction::GenerateNBodyEvent" << G4endl; 509 G4cerr << " number of particles < 2" << G4endl; 510 G4cerr << "totalEnergy = " << totalEnergy << "MeV, listLen = " << listLen << G4endl; 511 return -1.0; 512 } 513 514 G4double mass[18]; // mass of each particle 515 G4double energy[18]; // total energy of each particle 516 G4double pcm[3][18]; // pcm is an array with 3 rows and listLen columns 517 518 G4double totalMass = 0.0; 519 G4double extraMass = 0; 520 G4double sm[18]; 521 522 for (i=0; i<listLen; ++i) { 523 mass[i] = tempList[i]->GetMass()/GeV; 524 if(tempList[i]->GetSide() == -2) extraMass+=tempList[i]->GetMass()/GeV; 525 tempList[i]->SetMomentum( 0.0, 0.0, 0.0 ); 526 pcm[0][i] = 0.0; // x-momentum of i-th particle 527 pcm[1][i] = 0.0; // y-momentum of i-th particle 528 pcm[2][i] = 0.0; // z-momentum of i-th particle 529 energy[i] = mass[i]; // total energy of i-th particle 530 totalMass += mass[i]; 531 sm[i] = totalMass; 532 } 533 534 G4double totalE = totalEnergy/GeV; 535 if (totalMass > totalE) { 536 totalE = totalMass; 537 return -1.0; 538 } 539 540 G4double kineticEnergy = totalE - totalMass; 541 G4double emm[18]; 542 emm[0] = mass[0]; 543 emm[listLen-1] = totalE; 544 545 if (listLen > 2) { // the random numbers are sorted 546 G4double ran[18]; 547 for( i=0; i<listLen; ++i )ran[i] = G4UniformRand(); 548 for (i=0; i<listLen-2; ++i) { 549 for (G4int j=listLen-2; j>i; --j) { 550 if (ran[i] > ran[j]) { 551 G4double temp = ran[i]; 552 ran[i] = ran[j]; 553 ran[j] = temp; 554 } 555 } 556 } 557 for( i=1; i<listLen-1; ++i )emm[i] = ran[i-1]*kineticEnergy + sm[i]; 558 } 559 560 // Weight is the sum of logarithms of terms instead of the product of terms 561 562 G4bool lzero = true; 563 G4double wtmax = 0.0; 564 if (constantCrossSection) { 565 G4double emmax = kineticEnergy + mass[0]; 566 G4double emmin = 0.0; 567 for( i=1; i<listLen; ++i ) 568 { 569 emmin += mass[i-1]; 570 emmax += mass[i]; 571 G4double wtfc = 0.0; 572 if( emmax*emmax > 0.0 ) 573 { 574 G4double arg = emmax*emmax 575 + (emmin*emmin-mass[i]*mass[i])*(emmin*emmin-mass[i]*mass[i])/(emmax*emmax) 576 - 2.0*(emmin*emmin+mass[i]*mass[i]); 577 if( arg > 0.0 )wtfc = 0.5*std::sqrt( arg ); 578 } 579 if( wtfc == 0.0 ) 580 { 581 lzero = false; 582 break; 583 } 584 wtmax += std::log( wtfc ); 585 } 586 if( lzero ) 587 wtmax = -wtmax; 588 else 589 wtmax = expxu; 590 } else { 591 // ffq(n) = pi*(2*pi)^(n-2)/(n-2)! 592 const G4double ffq[18] = { 0., 3.141592, 19.73921, 62.01255, 129.8788, 204.0131, 593 256.3704, 268.4705, 240.9780, 189.2637, 594 132.1308, 83.0202, 47.4210, 24.8295, 595 12.0006, 5.3858, 2.2560, 0.8859 }; 596 wtmax = std::log( std::pow( kineticEnergy, listLen-2 ) * ffq[listLen-1] / totalE ); 597 } 598 599 // Calculate momenta for secondaries 600 601 lzero = true; 602 G4double pd[50]; 603 604 for( i=0; i<listLen-1; ++i ) 605 { 606 pd[i] = 0.0; 607 if( emm[i+1]*emm[i+1] > 0.0 ) 608 { 609 G4double arg = emm[i+1]*emm[i+1] 610 + (emm[i]*emm[i]-mass[i+1]*mass[i+1])*(emm[i]*emm[i]-mass[i+1]*mass[i+1]) 611 /(emm[i+1]*emm[i+1]) 612 - 2.0*(emm[i]*emm[i]+mass[i+1]*mass[i+1]); 613 if( arg > 0.0 )pd[i] = 0.5*std::sqrt( arg ); 614 } 615 if( pd[i] <= 0.0 ) // changed from == on 02 April 98 616 lzero = false; 617 else 618 wtmax += std::log( pd[i] ); 619 } 620 G4double weight = 0.0; // weight is returned by GenerateNBodyEvent 621 if( lzero )weight = std::exp( std::max(std::min(wtmax,expxu),expxl) ); 622 623 G4double bang, cb, sb, s0, s1, s2, c, s, esys, a, b, gama, beta; 624 pcm[0][0] = 0.0; 625 pcm[1][0] = pd[0]; 626 pcm[2][0] = 0.0; 627 for( i=1; i<listLen; ++i ) 628 { 629 pcm[0][i] = 0.0; 630 pcm[1][i] = -pd[i-1]; 631 pcm[2][i] = 0.0; 632 bang = twopi*G4UniformRand(); 633 cb = std::cos(bang); 634 sb = std::sin(bang); 635 c = 2.0*G4UniformRand() - 1.0; 636 s = std::sqrt( std::fabs( 1.0-c*c ) ); 637 if( i < listLen-1 ) 638 { 639 esys = std::sqrt(pd[i]*pd[i] + emm[i]*emm[i]); 640 beta = pd[i]/esys; 641 gama = esys/emm[i]; 642 for( G4int j=0; j<=i; ++j ) 643 { 644 s0 = pcm[0][j]; 645 s1 = pcm[1][j]; 646 s2 = pcm[2][j]; 647 energy[j] = std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[j]*mass[j] ); 648 a = s0*c - s1*s; // rotation 649 pcm[1][j] = s0*s + s1*c; 650 b = pcm[2][j]; 651 pcm[0][j] = a*cb - b*sb; 652 pcm[2][j] = a*sb + b*cb; 653 pcm[1][j] = gama*(pcm[1][j] + beta*energy[j]); 654 } 655 } 656 else 657 { 658 for( G4int j=0; j<=i; ++j ) 659 { 660 s0 = pcm[0][j]; 661 s1 = pcm[1][j]; 662 s2 = pcm[2][j]; 663 energy[j] = std::sqrt( s0*s0 + s1*s1 + s2*s2 + mass[j]*mass[j] ); 664 a = s0*c - s1*s; // rotation 665 pcm[1][j] = s0*s + s1*c; 666 b = pcm[2][j]; 667 pcm[0][j] = a*cb - b*sb; 668 pcm[2][j] = a*sb + b*cb; 669 } 670 } 671 } 672 673 for (i=0; i<listLen; ++i) { 674 tempList[i]->SetMomentum(pcm[0][i]*GeV, pcm[1][i]*GeV, pcm[2][i]*GeV); 675 tempList[i]->SetTotalEnergy(energy[i]*GeV); 676 } 677 678 return weight; 679 } 680 681 487 682 G4double G4RPGReaction::normal() 488 683 { … … 493 688 494 689 495 /* 496 G4int G4RPGReaction::Poisson( G4double x ) 690 void G4RPGReaction::Defs1(const G4ReactionProduct& modifiedOriginal, 691 G4ReactionProduct& currentParticle, 692 G4ReactionProduct& targetParticle, 693 G4FastVector<G4ReactionProduct,256>& vec, 694 G4int& vecLen) 497 695 { 498 G4int iran; 499 G4double ran; 500 501 if( x > 9.9 ) // use normal distribution with sigma^2 = <x> 502 iran = static_cast<G4int>(std::max( 0.0, x+normal()*std::sqrt(x) ) ); 503 else { 504 G4int mm = G4int(5.0*x); 505 if( mm <= 0 ) // for very small x try iran=1,2,3 506 { 507 G4double p1 = x*std::exp(-x); 508 G4double p2 = x*p1/2.0; 509 G4double p3 = x*p2/3.0; 510 ran = G4UniformRand(); 511 if( ran < p3 ) 512 iran = 3; 513 else if( ran < p2 ) // this is original Geisha, it should be ran < p2+p3 514 iran = 2; 515 else if( ran < p1 ) // should be ran < p1+p2+p3 516 iran = 1; 517 else 518 iran = 0; 519 } 696 // Rotate final state particle momenta by initial particle direction 697 698 const G4double pjx = modifiedOriginal.GetMomentum().x()/MeV; 699 const G4double pjy = modifiedOriginal.GetMomentum().y()/MeV; 700 const G4double pjz = modifiedOriginal.GetMomentum().z()/MeV; 701 const G4double p = modifiedOriginal.GetMomentum().mag()/MeV; 702 703 if (pjx*pjx+pjy*pjy > 0.0) { 704 G4double cost, sint, ph, cosp, sinp, pix, piy, piz; 705 cost = pjz/p; 706 sint = std::sqrt(std::abs((1.0-cost)*(1.0+cost))); 707 if( pjy < 0.0 ) 708 ph = 3*halfpi; 520 709 else 521 { 522 iran = 0; 523 G4double r = std::exp(-x); 524 ran = G4UniformRand(); 525 if( ran > r ) 526 { 527 G4double rrr; 528 G4double rr = r; 529 for( G4int i=1; i<=mm; ++i ) 530 { 531 iran++; 532 if( i > 5 ) // Stirling's formula for large numbers 533 rrr = std::exp(i*std::log(x)-(i+0.5)*std::log((G4double)i)+i-0.9189385); 534 else 535 rrr = std::pow(x,i)/Factorial(i); 536 rr += r*rrr; 537 if( ran <= rr )break; 538 } 539 } 540 } 541 } 542 return iran; 710 ph = halfpi; 711 if( std::abs( pjx ) > 0.001*MeV )ph = std::atan2(pjy,pjx); 712 cosp = std::cos(ph); 713 sinp = std::sin(ph); 714 pix = currentParticle.GetMomentum().x()/MeV; 715 piy = currentParticle.GetMomentum().y()/MeV; 716 piz = currentParticle.GetMomentum().z()/MeV; 717 currentParticle.SetMomentum((cost*cosp*pix - sinp*piy + sint*cosp*piz)*MeV, 718 (cost*sinp*pix + cosp*piy + sint*sinp*piz)*MeV, 719 (-sint*pix + cost*piz)*MeV); 720 pix = targetParticle.GetMomentum().x()/MeV; 721 piy = targetParticle.GetMomentum().y()/MeV; 722 piz = targetParticle.GetMomentum().z()/MeV; 723 targetParticle.SetMomentum((cost*cosp*pix - sinp*piy + sint*cosp*piz)*MeV, 724 (cost*sinp*pix + cosp*piy + sint*sinp*piz)*MeV, 725 (-sint*pix + cost*piz)*MeV); 726 727 for (G4int i=0; i<vecLen; ++i) { 728 pix = vec[i]->GetMomentum().x()/MeV; 729 piy = vec[i]->GetMomentum().y()/MeV; 730 piz = vec[i]->GetMomentum().z()/MeV; 731 vec[i]->SetMomentum((cost*cosp*pix - sinp*piy + sint*cosp*piz)*MeV, 732 (cost*sinp*pix + cosp*piy + sint*sinp*piz)*MeV, 733 (-sint*pix + cost*piz)*MeV); 734 } 735 736 } else { 737 if (pjz < 0.0) { 738 currentParticle.SetMomentum( -currentParticle.GetMomentum().z() ); 739 targetParticle.SetMomentum( -targetParticle.GetMomentum().z() ); 740 for (G4int i=0; i<vecLen; ++i) vec[i]->SetMomentum( -vec[i]->GetMomentum().z() ); 741 } 742 } 543 743 } 544 */ 545 546 // G4int G4RPGReaction::Factorial( G4int n ) 547 // { 548 // G4int m = std::min(n,10); 549 // G4int result = 1; 550 // if( m <= 1 )return result; 551 // for( G4int i=2; i<=m; ++i )result *= i; 552 // return result; 553 // } 554 555 556 void G4RPGReaction::Defs1( 557 const G4ReactionProduct &modifiedOriginal, 558 G4ReactionProduct ¤tParticle, 559 G4ReactionProduct &targetParticle, 560 G4FastVector<G4ReactionProduct,256> &vec, 561 G4int &vecLen ) 562 { 563 // Rotate final state particle momenta by initial particle direction 564 565 const G4double pjx = modifiedOriginal.GetMomentum().x()/MeV; 566 const G4double pjy = modifiedOriginal.GetMomentum().y()/MeV; 567 const G4double pjz = modifiedOriginal.GetMomentum().z()/MeV; 568 const G4double p = modifiedOriginal.GetMomentum().mag()/MeV; 569 if( pjx*pjx+pjy*pjy > 0.0 ) 570 { 571 G4double cost, sint, ph, cosp, sinp, pix, piy, piz; 572 cost = pjz/p; 573 sint = std::sqrt(std::abs((1.0-cost)*(1.0+cost))); 574 if( pjy < 0.0 ) 575 ph = 3*halfpi; 576 else 577 ph = halfpi; 578 if( std::abs( pjx ) > 0.001*MeV )ph = std::atan2(pjy,pjx); 579 cosp = std::cos(ph); 580 sinp = std::sin(ph); 581 pix = currentParticle.GetMomentum().x()/MeV; 582 piy = currentParticle.GetMomentum().y()/MeV; 583 piz = currentParticle.GetMomentum().z()/MeV; 584 currentParticle.SetMomentum((cost*cosp*pix - sinp*piy + sint*cosp*piz)*MeV, 585 (cost*sinp*pix + cosp*piy + sint*sinp*piz)*MeV, 586 (-sint*pix + cost*piz)*MeV); 587 pix = targetParticle.GetMomentum().x()/MeV; 588 piy = targetParticle.GetMomentum().y()/MeV; 589 piz = targetParticle.GetMomentum().z()/MeV; 590 targetParticle.SetMomentum((cost*cosp*pix - sinp*piy + sint*cosp*piz)*MeV, 591 (cost*sinp*pix + cosp*piy + sint*sinp*piz)*MeV, 592 (-sint*pix + cost*piz)*MeV); 593 for( G4int i=0; i<vecLen; ++i ) 594 { 595 pix = vec[i]->GetMomentum().x()/MeV; 596 piy = vec[i]->GetMomentum().y()/MeV; 597 piz = vec[i]->GetMomentum().z()/MeV; 598 vec[i]->SetMomentum((cost*cosp*pix - sinp*piy + sint*cosp*piz)*MeV, 599 (cost*sinp*pix + cosp*piy + sint*sinp*piz)*MeV, 600 (-sint*pix + cost*piz)*MeV); 601 } 602 } 603 else 604 { 605 if( pjz < 0.0 ) 606 { 607 currentParticle.SetMomentum( -currentParticle.GetMomentum().z() ); 608 targetParticle.SetMomentum( -targetParticle.GetMomentum().z() ); 609 for( G4int i=0; i<vecLen; ++i ) 610 vec[i]->SetMomentum( -vec[i]->GetMomentum().z() ); 611 } 612 } 613 } 614 744 745 615 746 void G4RPGReaction::Rotate( 616 747 const G4double numberofFinalStateNucleons, -
trunk/source/processes/hadronic/models/rpg/src/G4RPGSigmaMinusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGSigmaMinusInelastic.cc,v 1.1 2007/07/18 21:04:21 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGSigmaPlusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGSigmaPlusInelastic.cc,v 1.1 2007/07/18 21:04:21 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGStrangeProduction.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGStrangeProduction.cc,v 1.1 2007/07/18 21:04:21 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 -
trunk/source/processes/hadronic/models/rpg/src/G4RPGTwoBody.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGTwoBody.cc,v 1. 2 2007/08/15 20:38:37dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGTwoBody.cc,v 1.4 2008/05/05 21:21:55 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 … … 81 81 2.0*targetMass*etCurrent ); // in GeV 82 82 83 if( (pCurrent < 0.1) || (cmEnergy < 0.01) ) // 2-body scattering not possible 84 { 83 if (cmEnergy < 0.01) { // 2-body scattering not possible 85 84 targetParticle.SetMass( 0.0 ); // flag that the target particle doesn't exist 86 } 87 else 88 { 85 86 } else { 89 87 // Projectile momentum in cm 90 88 … … 231 229 const G4double pnCutOff = 0.0001; // GeV 232 230 const G4double dtaCutOff = 0.0001; // GeV 233 const G4double kineticMinimum = 0.0001;234 const G4double kineticFactor = -0.010;235 G4double sprob = 0.0; // sprob = probability of self-absorption in heavy molecules231 // const G4double kineticMinimum = 0.0001; 232 // const G4double kineticFactor = -0.010; 233 // G4double sprob = 0.0; // sprob = probability of self-absorption in heavy molecules 236 234 if( epnb >= pnCutOff ) 237 235 { … … 249 247 if (npnb == 0 && ndta == 0) npnb = 1; 250 248 251 AddBlackTrackParticles(epnb, npnb, edta, ndta, sprob, kineticMinimum, 252 kineticFactor, modifiedOriginal, 249 AddBlackTrackParticles(epnb, npnb, edta, ndta, modifiedOriginal, 253 250 PinNucleus, NinNucleus, targetNucleus, 254 251 vec, vecLen); -
trunk/source/processes/hadronic/models/rpg/src/G4RPGTwoCluster.cc
r819 r962 24 24 // ******************************************************************** 25 25 // 26 // $Id: G4RPGTwoCluster.cc,v 1. 2 2007/08/15 20:38:48dennis Exp $27 // GEANT4 tag $Name: geant4-09-0 1-patch-02 $26 // $Id: G4RPGTwoCluster.cc,v 1.5 2008/06/09 18:13:35 dennis Exp $ 27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29 … … 128 128 G4double bMass = backwardMass; 129 129 130 G4int backwardNucleonCount = 1; // number of nucleons in backward hemisphere130 // G4int backwardNucleonCount = 1; // number of nucleons in backward hemisphere 131 131 132 132 for( i=0; i<vecLen; ++i ) … … 163 163 164 164 if(atomicWeight<1.0001) nuclearExcitationCount = 0; 165 G4int extraNucleonCount = 0;166 G4double extraMass = 0.0;167 G4double extraNucleonMass = 0.0;165 // G4int extraNucleonCount = 0; 166 // G4double extraMass = 0.0; 167 // G4double extraNucleonMass = 0.0; 168 168 if( nuclearExcitationCount > 0 ) 169 169 { … … 183 183 else 184 184 pVec->SetDefinition( aNeutron ); 185 ++backwardNucleonCount;186 ++extraNucleonCount;187 extraNucleonMass += pVec->GetMass()/GeV;185 // Not used ++backwardNucleonCount; 186 // Not used ++extraNucleonCount; 187 // Not used extraNucleonMass += pVec->GetMass()/GeV; 188 188 } 189 189 else … … 196 196 else 197 197 pVec->SetDefinition( aPiMinus ); 198 199 // DHW: add following two lines to correct energy balance 200 // ++backwardCount; 201 // backwardMass += pVec->GetMass()/GeV; 198 202 } 199 203 pVec->SetSide( -2 ); // backside particle 200 extraMass += pVec->GetMass()/GeV;204 // Not used extraMass += pVec->GetMass()/GeV; 201 205 pVec->SetNewlyAdded( true ); 202 206 vec.SetElement( vecLen++, pVec ); … … 204 208 } 205 209 206 // Masses of particles added from cascade not included in energy balance 210 // Masses of particles added from cascade not included in energy balance. 211 // That's correct for nucleons from the intra-nuclear cascade but not for 212 // pions from the cascade. 213 207 214 G4double forwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +cMass - forwardMass; 208 215 G4double backwardEnergy = (centerofmassEnergy-cMass-bMass)/2.0 +bMass - backwardMass; … … 779 786 const G4double pnCutOff = 0.001; // GeV 780 787 const G4double dtaCutOff = 0.001; // GeV 781 const G4double kineticMinimum = 1.e-6;782 const G4double kineticFactor = -0.005;788 // const G4double kineticMinimum = 1.e-6; 789 // const G4double kineticFactor = -0.005; 783 790 784 G4double sprob = 0.0; // sprob = probability of self-absorption in791 // G4double sprob = 0.0; // sprob = probability of self-absorption in 785 792 // heavy molecules 786 const G4double ekIncident = originalIncident->GetKineticEnergy()/GeV;787 if( ekIncident >= 5.0 )sprob = std::min( 1.0, 0.6*std::log(ekIncident-4.0) );793 // Not currently used (DHW 9 June 2008) const G4double ekIncident = originalIncident->GetKineticEnergy()/GeV; 794 // if( ekIncident >= 5.0 )sprob = std::min( 1.0, 0.6*std::log(ekIncident-4.0) ); 788 795 789 796 if( epnb >= pnCutOff ) … … 803 810 // DEBUGGING --> DumpFrames::DumpFrame(vec, vecLen); 804 811 805 AddBlackTrackParticles(epnb, npnb, edta, ndta, sprob, kineticMinimum, 806 kineticFactor, modifiedOriginal, 812 AddBlackTrackParticles(epnb, npnb, edta, ndta, modifiedOriginal, 807 813 PinNucleus, NinNucleus, targetNucleus, 808 814 vec, vecLen ); -
trunk/source/processes/hadronic/models/rpg/src/G4RPGXiMinusInelastic.cc
r819 r962 25 25 // 26 26 // $Id: G4RPGXiMinusInelastic.cc,v 1.1 2007/07/18 21:04:21 dennis Exp $ 27 // GEANT4 tag $Name: $27 // GEANT4 tag $Name: geant4-09-02-ref-02 $ 28 28 // 29 29
Note:
See TracChangeset
for help on using the changeset viewer.
