Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/solidstate/channeling/src/G4Channeling.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 
 27 #include "G4Channeling.hh"
 28 
 29 #include "Randomize.hh"
 30 
 31 #include "G4ChannelingTrackData.hh"
 32 #include "G4TouchableHistory.hh"
 33 #include "G4SystemOfUnits.hh"
 34 #include "G4LambdacPlus.hh"
 35 #include "G4PhysicsModelCatalog.hh"
 36 
 37 G4Channeling::G4Channeling():
 38 G4VDiscreteProcess("channeling"),
 39 fChannelingID(G4PhysicsModelCatalog::GetModelID("model_channeling")),
 40 fTimeStepMin(0.),
 41 fTimeStepMax(0.),
 42 fTransverseVariationMax(2.E-2 * CLHEP::angstrom),
 43 k010(G4ThreeVector(0.,1.,0.)),
 44 fSpin(G4ThreeVector(0.,0.,0.))
 45 {}
 46 
 47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 48 
 49 G4Channeling::~G4Channeling(){;}
 50 
 51 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 52 
 53 G4ChannelingTrackData* G4Channeling::GetTrackData(const G4Track& aTrack){
 54     G4ChannelingTrackData* trackdata =
 55         (G4ChannelingTrackData*)(aTrack.GetAuxiliaryTrackInformation(fChannelingID));
 56     if(trackdata == nullptr){
 57         trackdata = new G4ChannelingTrackData();
 58         aTrack.SetAuxiliaryTrackInformation(fChannelingID,trackdata);
 59     }
 60     return trackdata;
 61 }
 62 
 63 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 64 
 65 void G4Channeling::GetEF(const G4Track& aTrack,
 66                          G4ThreeVector& pos,
 67                          G4ThreeVector& out){
 68     out = G4ThreeVector((GetMatData(aTrack)->GetEFX()->GetEC(pos)),
 69                         (GetMatData(aTrack)->GetEFY()->GetEC(pos)),
 70                         0.);
 71 }
 72 
 73 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 74 
 75 void G4Channeling::PosToLattice(G4StepPoint* step,G4ThreeVector& pos){
 76     G4TouchableHistory* theTouchable = (G4TouchableHistory*)(step->GetTouchable());
 77 
 78     pos -= theTouchable->GetTranslation();
 79     pos = ((*theTouchable->GetRotation()).inverse())(pos);
 80 }
 81 
 82 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 83 
 84 G4bool G4Channeling::UpdateParameters(const G4Track& aTrack){
 85 
 86     G4LogicalCrystalVolume* aLCV = (G4LogicalCrystalVolume*)(aTrack.GetVolume()->GetLogicalVolume());
 87     
 88     G4StepPoint* postStepPoint = aTrack.GetStep()->GetPostStepPoint();
 89     G4StepPoint* preStepPoint = aTrack.GetStep()->GetPreStepPoint();
 90 
 91     G4ThreeVector posPost = postStepPoint->GetPosition();
 92     aLCV->RotateToLattice(posPost);
 93     G4ThreeVector posPre = preStepPoint->GetPosition();
 94     aLCV->RotateToLattice(posPre);
 95     
 96     G4double integrationLimit = std::fabs(posPost.z() - posPre.z());
 97     
 98     if(integrationLimit > 0.){
 99         //----------------------------------------
100         // Check if the crystal is bent
101         //----------------------------------------
102         G4bool isBent = GetMatData(aTrack)->IsBent();
103 
104         //----------------------------------------
105         // Get the momentum in the world reference
106         // frame and rotate to the solid reference frame
107         //----------------------------------------
108         G4TouchableHistory* theTouchable = (G4TouchableHistory*)(preStepPoint->GetTouchable());
109         G4ThreeVector momWorld = aTrack.GetStep()->GetPreStepPoint()->GetMomentum();
110         G4ThreeVector mom = (*theTouchable->GetRotation())(momWorld);
111         
112         //----------------------------------------
113         // Get the momentum in the solid reference
114         // frame and rotate to the crystal reference frame
115         //----------------------------------------
116         aLCV->RotateToLattice(mom);
117 
118         //----------------------------------------
119         // Get the momentum in the crystal reference
120         // frame and rotate to the reference frame
121         // solidal to the bent planes
122         //----------------------------------------
123         if(isBent){
124             PosToLattice(preStepPoint,posPre);
125             G4ThreeVector axis010 = (*theTouchable->GetRotation())(k010);
126             mom.rotate(axis010,-posPre.z()/GetMatData(aTrack)->GetBR(posPre).x());
127         }
128 
129         //----------------------------------------
130         // Take the position stored in the track data.
131         // If the particle enters the crystal,
132         // the position in the channel is randomly
133         // generated using a uniform distribution
134         //----------------------------------------
135         G4ThreeVector pos;
136         if(GetTrackData(aTrack)->GetPosCh().x() == DBL_MAX){
137             G4double posX = G4UniformRand() * GetMatData(aTrack)->GetPot()->GetIntSp(0);
138             G4double posY = G4UniformRand() * GetMatData(aTrack)->GetPot()->GetIntSp(1);
139             pos = G4ThreeVector(posX,posY,0.);
140         }
141         else{
142             pos = GetTrackData(aTrack)->GetPosCh();
143         }
144 
145         G4double step=0., stepTot=0.;
146         G4double nud =0., eld    =0.;
147         G4double efx =0., efy    =0.;
148         G4double nud_temp =0., eld_temp    =0.;
149 
150         G4double beta = aTrack.GetVelocity()/CLHEP::c_light;
151         G4double Z = GetParticleDefinition(aTrack)->GetPDGCharge();
152         
153         const G4double oneSixth = 1./6.;
154         G4ThreeVector posk1,posk2,posk3,posk4,posk5,posk6;
155         G4ThreeVector momk1,momk2,momk3,momk4,momk5,momk6;
156         G4ThreeVector pos_temp, efxy;
157 
158         do{
159             //----------------------------------------
160             // Limit the variable step length for the
161             // integration via the selected algorithm
162             // and update variables for the integration
163             //----------------------------------------
164 
165             UpdateIntegrationStep(aTrack,mom,step);
166             if(step + stepTot > integrationLimit){
167                 step = integrationLimit - stepTot;
168             }
169 
170             //----------------------------------------
171             // Function integration algorithm
172             // 4th Order Runge-Kutta
173             //----------------------------------------
174             
175             GetEF(aTrack,pos,efxy);
176             posk1 = step / mom.z() * mom;
177             momk1 = step / beta * Z * efxy;
178             if(isBent) momk1.setX(momk1.x() - step * mom.z() * beta / (GetMatData(aTrack)->GetBR(pos)).x());
179             
180             GetEF(aTrack,pos_temp = pos + posk1 * 0.5,efxy);
181             posk2 = step / mom.z() * (mom + momk1 * 0.5);
182             momk2 = step / beta * Z * efxy;
183             if(isBent) momk2.setX(momk2.x() - step * mom.z() * beta / (GetMatData(aTrack)->GetBR(pos_temp)).x());
184 
185             GetEF(aTrack,pos_temp = pos + posk2 * 0.5,efxy);
186             posk3 = step / mom.z() * (mom + momk2 * 0.5);
187             momk3 = step / beta * Z * efxy;
188             if(isBent) momk3.setX(momk3.x() - step * mom.z() * beta / (GetMatData(aTrack)->GetBR(pos_temp)).x());
189             
190             GetEF(aTrack,pos_temp = pos + posk3,efxy);
191             posk4 = step / mom.z() * (mom + momk3);
192             momk4 = step / beta * Z * efxy;
193             if(isBent) momk4.setX(momk4.x() - step * mom.z() * beta / (GetMatData(aTrack)->GetBR(pos_temp)).x());
194 
195             pos = pos + oneSixth * (posk1 + 2.*posk2 + 2.*posk3 + posk4);
196             mom = mom + oneSixth * (momk1 + 2.*momk2 + 2.*momk3 + momk4);
197             
198             //----------------------------------------
199             // Function integration algorithm
200             // 2th Order Velocity-Verlet
201             //----------------------------------------
202            
203             /*
204             GetEF(aTrack,pos,efxy);
205             posk1 = pos + (step * 0.5 / mom.z()) * mom;
206             //momk1 = mom + step * 0.5 / betaZ * efxy;
207             momk1 = mom;
208             if(isBent) momk1.setX(momk1.x() - step * 0.5 * mom.z() * beta / (GetMatData(aTrack)->GetBR(pos)).x());
209             
210             GetEF(aTrack,posk1,efxy);
211             pos = pos + (step / momk1.z()) * momk1;
212             //mom = mom + step / betaZ * efxy;
213             mom = mom;
214             if(isBent) mom.setX(mom.x() - step * mom.z() * beta / (GetMatData(aTrack)->GetBR(posk1)).x());
215             */
216 
217             //----------------------------------------
218             // Update the total step and the electron
219             // and nuclei density experienced by
220             // the particle during its motion
221             //----------------------------------------
222 
223             stepTot += step;
224 
225             nud_temp = GetMatData(aTrack)->GetNuD()->GetEC(pos);
226             eld_temp = GetMatData(aTrack)->GetElD()->GetEC(pos);
227             
228             if(nud_temp < 0.) {nud_temp = 0.;}
229             if(eld_temp < 0.) {eld_temp = 0.;}
230 
231             nud += (step * nud_temp);
232             eld += (step * eld_temp);
233 
234             efx += (step * GetMatData(aTrack)->GetEFX()->GetEC(pos));
235             efy += (step * GetMatData(aTrack)->GetEFY()->GetEC(pos));
236 
237         } while(stepTot<integrationLimit);
238         
239         nud /= stepTot;
240         eld /= stepTot;
241 
242         if(nud < 1.E-10) {nud = 1.E-10;}
243         if(eld < 1.E-10) {eld = 1.E-10;}
244         
245         GetTrackData(aTrack)->SetNuD(nud);
246         GetTrackData(aTrack)->SetElD(eld);
247 
248         GetTrackData(aTrack)->SetEFX(efx);
249         GetTrackData(aTrack)->SetEFY(efy);
250         
251         GetTrackData(aTrack)->SetMomCh(mom);
252         GetTrackData(aTrack)->SetPosCh(pos);
253         return true;
254     }
255     else{
256         return false;
257     }
258     
259     return false;
260 }
261 
262 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
263 
264 G4bool G4Channeling::
265 UpdateIntegrationStep(const G4Track& aTrack,
266                       G4ThreeVector& mom,
267                       G4double& step){
268     
269     if(mom.x() != 0.0 || mom.y() != 0.0){
270         double xy2 = mom.x() * mom.x() + mom.y()*mom.y();
271         
272         if(xy2!=0.){
273             step = std::fabs(fTransverseVariationMax * GetPre(aTrack)->GetKineticEnergy() / std::pow(xy2,0.5));
274             if(step < fTimeStepMin) step = fTimeStepMin;
275             else{
276                 fTimeStepMax = std::sqrt( fTransverseVariationMax * GetPre(aTrack)->GetKineticEnergy()
277                                     / std::fabs(GetMatData(aTrack)->GetEFX()->GetMax()));
278                 
279                 if(step > fTimeStepMax) step = fTimeStepMax;
280             }
281         }
282         else{
283             step = fTimeStepMin;
284         }
285         
286         return true;
287     }
288     else{
289         step = fTimeStepMin;
290     }
291     return false;
292 }
293 
294 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
295 
296 G4double G4Channeling::
297 GetMeanFreePath(const G4Track& aTrack,
298                 G4double, // previousStepSize
299                 G4ForceCondition* condition){
300     
301     //----------------------------------------
302     // the condition is forced to check if
303     // the volume has a lattice at each step.
304     // if it hasn't, return DBL_MAX
305     //----------------------------------------
306     
307     *condition = Forced;
308     
309     G4LogicalVolume* aLV = aTrack.GetVolume()->GetLogicalVolume();
310     G4LogicalVolume* aNLV = aTrack.GetNextVolume()->GetLogicalVolume();
311     
312     if(G4LogicalCrystalVolume::IsLattice(aLV) == true &&
313        G4LogicalCrystalVolume::IsLattice(aNLV) == true){
314         G4double osc_per = GetOscillationPeriod(aTrack);
315         fTimeStepMin = osc_per * 2.E-4;
316         return osc_per * 0.01;
317     }
318     else{
319         GetTrackData(aTrack)->Reset();
320         return DBL_MAX;
321     }
322 }
323 
324 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
325 
326 G4VParticleChange* G4Channeling::
327 PostStepDoIt(const G4Track& aTrack,
328              const G4Step&){
329     
330     //----------------------------------------
331     // check if the volume has a lattice
332     // and if the particle is in channeling.
333     // If it is so, the particle is forced
334     // to follow the channeling plane
335     // direction. If the particle has
336     // dechanneled or exited the crystal,
337     // the outgoing angle is evaluated
338     //----------------------------------------
339     
340     aParticleChange.Initialize(aTrack);
341     G4LogicalVolume* aLV = aTrack.GetVolume()->GetLogicalVolume();
342     G4LogicalVolume* aNLV = aTrack.GetNextVolume()->GetLogicalVolume();
343     
344     
345     if(G4LogicalCrystalVolume::IsLattice(aLV) == true &&
346        G4LogicalCrystalVolume::IsLattice(aNLV) == true){
347 
348         G4bool bModifiedTraj = UpdateParameters(aTrack);
349 
350         if(bModifiedTraj==true){
351             //----------------------------------------
352             // Get the momentum in the reference frame
353             // solidal to the bent planes and rotate
354             // to the reference frame
355             //----------------------------------------
356             G4LogicalCrystalVolume* aLCV = (G4LogicalCrystalVolume*)(aTrack.GetVolume()->GetLogicalVolume());
357             G4ThreeVector momCh = GetTrackData(aTrack)->GetMomCh();
358 
359             G4StepPoint* postStepPoint = aTrack.GetStep()->GetPostStepPoint();
360             G4TouchableHistory* theTouchable = (G4TouchableHistory*)(postStepPoint->GetTouchable());
361 
362             if(GetMatData(aTrack)->IsBent()){
363                 G4ThreeVector posPost = postStepPoint->GetPosition();
364                 PosToLattice(postStepPoint,posPost);
365                 G4ThreeVector axis010 = (*theTouchable->GetRotation())(k010);
366                 momCh.rotate(axis010,posPost.z()/GetMatData(aTrack)->GetBR(posPost).x());
367             }
368             
369             //----------------------------------------
370             // Get the momentum in the crystal reference
371             // frame and rotate to the solid reference frame
372             //----------------------------------------
373 
374             aLCV->RotateToSolid(momCh);
375             
376             //----------------------------------------
377             // Get the momentum in the solid reference
378             // frame and rotate to the world reference frame
379             //----------------------------------------
380             G4ThreeVector mom = ((*theTouchable->GetRotation()).inverse())(momCh);
381 
382             aParticleChange.ProposeMomentumDirection(mom.unit());
383             aParticleChange.ProposePolarization(fSpin);
384         }
385     }
386     else{
387         // if the volume has no lattice it resets the density factors
388         GetTrackData(aTrack)->Reset();
389     }
390     
391     return &aParticleChange;
392 }
393 
394 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
395