ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4AdjointForcedInteractionForGamma.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4AdjointForcedInteractionForGamma.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
28 #include "G4SystemOfUnits.hh"
29 #include "G4AdjointCSManager.hh"
30 #include "G4AdjointCSMatrix.hh"
31 #include "G4VEmAdjointModel.hh"
32 #include "G4MaterialCutsCouple.hh"
33 #include "G4ParticleChange.hh"
34 #include "G4AdjointGamma.hh"
35 
36 
39  G4VContinuousDiscreteProcess(process_name),theAdjointComptonModel(0),theAdjointBremModel(0)
42  lastAdjCS=0.;
43  trackid = nstep = 0;
44  is_free_flight_gamma = false;
47 
50 
57 
58 
59 
60 }
62 //
65 { if (fParticleChange) delete fParticleChange;
66 }
68 //
70 {;
71 }
73 //
75 {
76  theAdjointCSManager->BuildCrossSectionMatrices(); //do not worry it will be done just once
78 }
79 //Note on weight correction for forced interaction
80 //For the forced interaction applied here we do use a truncated exponential law for the probability of survival
81 //over a fixed total length. This is done by using a linear transformation of the non biased probability survival
82 //In mathematic this writes
83 //P'(x)=C1P(x)+C2
84 //With P(x)=exp(-sum(sigma_ixi)) x and L can cross different volumes with different cross section sigma.
85 //For forced interaction we get the following limit conditions
86 //P'(L)=0 P'(0)=1 (L can be used over different volumes)
87 //From simple solving of linear equation we get
88 //C1=1/(1-P(L)) et C2=-P(L)/(1-P(L))
89 //P'(x)=(P(x)-P(L))/(1-P(L))
90 //For the probability over a step x1 to x2
91 //P'(x1->x2)=P'(x2)/P'(x1)
92 //The effective cross section is defined -d(P'(x))/dx/P'(x)
93 //We get therefore
94 //sigma_eff=C1sigmaP(x)/(C1P(x)+C2)=sigmaP(x)/(P(x)+C2/C1)=sigmaP(x)/(P(x)-P(L))=sigma/(1-P(L)/P(x))
96 //
98 { fParticleChange->Initialize(track);
99  //For the free flight gamma no interaction occur but a gamma with same property is
100  //produces for further forced interaction
101  //It is done at the very beginning of the track such that the weight can be the same
103  G4ThreeVector theGammaMomentum = track.GetMomentum();
107  }
108  else { //Occurrence of forced interaction
109 
110  //Selection of the model to be called
111  G4VEmAdjointModel* theSelectedModel =0;
112  G4bool is_scat_proj_to_proj_case=false;
114  if (!theAdjointComptonModel) {
115  theSelectedModel = theAdjointBremModel;
116  is_scat_proj_to_proj_case=false;
117  //This is needed because the results of it will be used in the post step do it weight correction inside the model
119  track.GetMaterialCutsCouple(),track.GetKineticEnergy(), false);
120 
121  }
122  else if (!theAdjointBremModel) {
123  theSelectedModel = theAdjointComptonModel;
124  is_scat_proj_to_proj_case=true;
125  }
126  else { //Choose the model according to cross sections
127 
129  track.GetMaterialCutsCouple(),track.GetKineticEnergy(), false);
130  if (G4UniformRand()*lastAdjCS<bremAdjCS) {
131  theSelectedModel = theAdjointBremModel;
132  is_scat_proj_to_proj_case=false;
133  }
134  else {
135  theSelectedModel = theAdjointComptonModel;
136  is_scat_proj_to_proj_case=true;
137  }
138  }
139 
140  //Compute the weight correction factor
141  G4double one_over_effectiveAdjointCS= (1.-std::exp(acc_nb_adj_interaction_length-total_acc_nb_adj_interaction_length))/lastAdjCS;
142  G4double weight_correction_factor = lastAdjCS*one_over_effectiveAdjointCS;
143  //G4cout<<"Weight correction factor start "<<weight_correction_factor<<std::endl;
144  //Call the selected model without correction of the weight in the model
145  theSelectedModel->SetCorrectWeightForPostStepInModel(false);
146  theSelectedModel->SetAdditionalWeightCorrectionFactorForPostStepOutsideModel(weight_correction_factor);
147  theSelectedModel->SampleSecondaries(track,is_scat_proj_to_proj_case,fParticleChange);
148  theSelectedModel->SetCorrectWeightForPostStepInModel(true);
149 
151  }
152  return fParticleChange;
153 }
155 //
157 { fParticleChange->Initialize(track);
158  //Compute nb of interactions length over step length
160  G4double stepLength = track.GetStep()->GetStepLength();
161  G4double ekin = track.GetKineticEnergy();
162  G4double nb_fwd_interaction_length_over_step=0.;
163  G4double nb_adj_interaction_length_over_step=0.;
166  ekin,track.GetMaterialCutsCouple());
167  nb_fwd_interaction_length_over_step = stepLength*lastFwdCS;
168  nb_adj_interaction_length_over_step = stepLength*lastAdjCS;
169  G4double fwd_survival_probability=std::exp(-nb_fwd_interaction_length_over_step);
170  G4double mc_induced_survival_probability=1.;
171 
172  if (is_free_flight_gamma) { //for free_flight survival probability stays 1
173  //Accumulate the number of interaction lengths during free flight of gamma
174  total_acc_nb_fwd_interaction_length+=nb_fwd_interaction_length_over_step;
175  total_acc_nb_adj_interaction_length+=nb_adj_interaction_length_over_step;
176  acc_track_length+=stepLength;
177  }
178  else {
179  G4double previous_acc_nb_adj_interaction_length =acc_nb_adj_interaction_length;
180  acc_nb_fwd_interaction_length+=nb_fwd_interaction_length_over_step;
181  acc_nb_adj_interaction_length+=nb_adj_interaction_length_over_step;
182  theNumberOfInteractionLengthLeft-=nb_adj_interaction_length_over_step;
183 
184  //Following condition to remove very rare FPE issue
185  //if (total_acc_nb_adj_interaction_length <= 1.e-50 && theNumberOfInteractionLengthLeft<=1.e-50) { //condition added to avoid FPE issue
186  // VI 06.11.2017 - new condition
187  if (std::abs(total_acc_nb_adj_interaction_length - previous_acc_nb_adj_interaction_length) <= 1.e-15) {
188  mc_induced_survival_probability = 1.e50;
189  /*
190  G4cout << "FPE protection: " << total_acc_nb_adj_interaction_length << " "
191  << previous_acc_nb_adj_interaction_length << " "
192  << acc_nb_fwd_interaction_length << " "
193  << acc_nb_adj_interaction_length << " "
194  << theNumberOfInteractionLengthLeft
195  << G4endl;
196  */
197  }
198  else {
199  mc_induced_survival_probability= std::exp(-acc_nb_adj_interaction_length)-std::exp(-total_acc_nb_adj_interaction_length);
200  mc_induced_survival_probability=mc_induced_survival_probability/(std::exp(-previous_acc_nb_adj_interaction_length)-std::exp(-total_acc_nb_adj_interaction_length));
201  }
202  }
203  G4double weight_correction = fwd_survival_probability/mc_induced_survival_probability;
204 
205  //weight_correction = 1.;
206  //Caution!!!
207  // It is important to select the weight of the post_step_point
208  // as the current weight and not the weight of the track, as t
209  // the weight of the track is changed after having applied all
210  // the along_step_do_it.
211  G4double new_weight=weight_correction*track.GetStep()->GetPostStepPoint()->GetWeight();
212 /*
213  G4cout<<"New weight "<<new_weight<<std::endl;
214  G4cout<<"Weight correction "<<weight_correction<<std::endl;
215  */
216 
220 
221  return fParticleChange;
222 }
224 //
226  const G4Track& track,
227  G4double ,
229 { G4int step_id = track.GetCurrentStepNumber();
230  *condition = NotForced;
232  G4int track_id=track.GetTrackID();
234  if (is_free_flight_gamma) {
235  if (step_id == 1 || continue_gamma_as_new_free_flight) {
236  *condition=Forced;
237  //A gamma with same conditions will be generate at next post_step do it for the forced interaction
239  last_free_flight_trackid = track_id;
240  acc_track_length=0.;
244  return 1.e-90;
245  }
246  else {
247  //Computation of accumulated length for
248  return DBL_MAX;
249  }
250  }
251  else { //compute the interaction length for forced interaction
252  if (step_id ==1) {
253  G4double min_val= std::exp(-total_acc_nb_adj_interaction_length);
254  theNumberOfInteractionLengthLeft = -std::log( min_val+G4UniformRand()*(1.-min_val));
258  }
259  G4VPhysicalVolume* thePostPhysVolume = track.GetStep()->GetPreStepPoint()->GetPhysicalVolume();
260  G4double ekin =track.GetKineticEnergy();
261  G4double postCS=0.;
262  if (thePostPhysVolume){
264  ekin,thePostPhysVolume->GetLogicalVolume()->GetMaterialCutsCouple());
265  }
266  if (postCS>0.) return theNumberOfInteractionLengthLeft/postCS;
267  else return DBL_MAX;
268  }
269 }
271 //
273  G4double ,
274  G4double ,
275  G4double& )
276 {return DBL_MAX;
277 }
279 //Not used in this process but should be implemented as virtual method
281  G4double ,
283 { return 0.;
284 }
285 
286