Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4LowPAIH2O.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28//
29// G4LowPAIH2O.cc -- class implementation file
30//
31// GEANT 4 class implementation file
32//
33// For information related to this code, please, contact
34// the Geant4 Collaboration.
35//
36// R&D: Vladimir.Grichine@cern.ch
37//
38// History:
39//
40// 20.07.23 V. Grichine, 1st version
41//
42
43#include "G4LowPAIH2O.hh"
44#include "G4LowDataH2O.hh"
45
46#include "globals.hh"
48#include "G4SystemOfUnits.hh"
49#include "G4ios.hh"
51#include "G4Integrator.hh"
52#include "G4PhysicsLogVector.hh"
53#include "G4PhysicsTable.hh"
54#include "Randomize.hh"
55#include "G4Poisson.hh"
56#include "G4RandomDirection.hh"
57#include "G4Electron.hh"
58#include "G4Proton.hh"
60#include "G4NistManager.hh"
61#include "G4Material.hh"
64
65
66using namespace std;
67using namespace CLHEP;
68
69//////////////////////////////////////////////////////////////////
70//
71// Constructor
72
74 const G4String& nam )
76{
77 fCof = fine_structure_const/hbarc/pi;
78 fBeta = 0.5;
79 fBe2 = fBeta*fBeta;
80 fTkin = eV * 1.;
81 fBias = 1.; //
83 fMat = man->FindOrBuildMaterial("G4_WATER");
84 // (?)
85 fElectronDensity = fMat->GetElectronDensity();
86 fNat = fMat->GetTotNbOfAtomsPerVolume();
87 // G4cout<<"fNat = "<<fNat*cm3<<" 1/cm3"<<G4endl;
88 fNel = fMat->GetTotNbOfElectPerVolume();
89 // G4cout<<"fNel = "<<fNel*cm3<<" 1/cm3"<<G4endl;
90 theElectron = G4Electron::Electron();
91 theProton = G4Proton::Proton();
92 fParticleChange = nullptr;
93 const G4DataVector cuts;
94
95 if( IsMaster() )
96 {
98 }
99 if(nullptr == fParticleChange)
100 {
101 fParticleChange = GetParticleChangeForLoss();
102 }
103 fTotBin = 200; //
104 fBinTr = 100;
105 fBmin = 1.e-3;
106 fBmax = 0.98; // gamma ~ 4 min of dE/dx
107
108 fBetaVector = new G4PhysicsLogVector( fBmin, fBmax, fTotBin );
109
110 fWmin = eV * 0.1; //
111 InitRuthELF();
112 // BuildPhysicsTable(theProton);
113 // BuildPhysicsTable(theElectron);
114}
115
116////////////////////////////////////////////////////////////////////////////
117//
118// Destructor
119
121{
122 if(fBetaVector) delete fBetaVector;
123 if(fTransferVector) delete fTransferVector;
124 if(fPrEnergyTable)
125 {
126 fPrEnergyTable->clearAndDestroy();
127 delete fPrEnergyTable;
128 }
129 if(fElEnergyTable)
130 {
131 fElEnergyTable->clearAndDestroy();
132 delete fElEnergyTable;
133 }
134}
135
136//////////////////////////////////////////
137
139 const G4DataVector& )
140{
141 if(nullptr == fParticleChange)
142 {
143 fParticleChange = GetParticleChangeForLoss();
144 }
145 // InitRuthELF();
146 BuildPhysicsTable( pd );
147 return;
148}
149
150////////////////////////////////
151
153 G4VEmModel* masterModel)
154{
155 if(nullptr == fParticleChange)
156 {
157 fParticleChange = GetParticleChangeForLoss();
158 }
160 BuildPhysicsTable( pd );
161 return;
162}
163
164////////////////////////////////////////////
165
167{
168 if( nullptr == fParticleChange )
169 {
170 fParticleChange = GetParticleChangeForLoss();
171 }
172 return;
173}
174
175///////////////////////////////////////////////////////////
176//
177// Reading static const arrays to local data vectors for fast searching
178
180{
181 G4int i(0), nn(0);
182 G4double ee(0.), elf(0.), ruth(0.);
183
184 nn = theBin;
185
186 for( i = 0; i < nn; ++i )
187 {
188 ee = theEsum[i];
189 elf = theELFsum[i];
190 ruth = theRuthSum[i];
191 fEsum.push_back(ee);
192 fELFsum.push_back(elf);
193 fRuthSum.push_back(ruth);
194 }
195 G4cout<<G4endl;
196}
197
198//////////////////////////////////////////////////
199
201{
202 if( pd == theProton ) BuildPrEnergyTable();
203 else if( pd == theElectron ) BuildElEnergyTable();
204 else G4cout<<" G4LowPAIH2O::BuildPhysicsTable is not applicable for "
205 <<pd->GetParticleName()<<G4endl;
206 return;
207}
208
209//////////////////////////////////////////////
210//
211// Biased dN/dx
212
214 const G4ParticleDefinition* pd,
215 G4double Tkin,
216 G4double, // cutEnergy,
217 G4double ) // maxEnergy)
218{
219 G4double dNdx(0.);
220
221 if( pd == theProton ) dNdx = GetPrdNdx( Tkin );
222 else if( pd == theElectron ) dNdx = GetEldNdx( Tkin );
223 else G4cout<<" G4LowPAIH2O::CrossSectionPerVolume is not applicable for "
224 <<pd->GetParticleName()<<G4endl;
225 dNdx /= fBias; //
226
227 return dNdx;
228}
229
230///////////////////////////
231
233 G4double Tkin,
234 G4double, // Z,
235 G4double, // A,
236 G4double cutEnergy,
237 G4double maxEnergy)
238{
239 return CrossSectionPerVolume(nullptr, pd, Tkin, cutEnergy, maxEnergy)/fNat;
240}
241
242/////////////////////////////
243
245 const G4ParticleDefinition* pd,
246 G4double Tkin,
247 G4double cutEnergy,
248 G4double maxEnergy)
249{
250 return CrossSectionPerVolume(nullptr, pd, Tkin, cutEnergy, maxEnergy)/fNel;
251}
252
253////////////////////////////////////////////////
254
256{
257 // G4cout<<"G4LowPAIH2O::BuildPrEnergyTable is called"<<G4endl<<G4endl;
258 G4int iBeta(0), iTransfer(0);
259 G4double be(0.), be2(0.), gg(1.);
260 G4double tp(0.), sum(0.), tmp(0.), mp = proton_mass_c2;
261
263 fPrEnergyTable = new G4PhysicsTable();
264
265 for( iBeta = 0; iBeta < fTotBin; ++iBeta )
266 {
267 be = fBetaVector->GetLowEdgeEnergy(iBeta);
268 be2 = be*be;
269 SetBe2(be2);
270 gg = sqrt( 1./( 1. - be2 ) );
271 tp = ( gg - 1.)*mp;
272 fWmax = GetProtonTmax(tp);
273 if( fWmax <= fWmin ) fWmax = fWmin*1.01;
274 fTransferVector = new G4PhysicsLogVector( fWmin, fWmax, fBinTr );
275 fPrWmaxVector.push_back(fWmax);
276 sum = 0.;
277 fTransferVector->PutValue(fBinTr-1,sum);
278
279 for( iTransfer = fBinTr-2; iTransfer >= 0; --iTransfer)
280 {
281 tmp = integral.Legendre10( this, &G4LowPAIH2O::PrPAId2Ndxdw,
282 fTransferVector->GetLowEdgeEnergy(iTransfer),
283 fTransferVector->GetLowEdgeEnergy(iTransfer+1)
284 );
285 sum += tmp*fCof/be2;
286 // G4cout<<sum*micrometer<<", ";
287 fTransferVector->PutValue(iTransfer,sum);
288 }
289 fPrEnergyTable->insertAt(iBeta, fTransferVector);
290 }
291 return;
292}
293
294////////////////////////////////////////////////
295
297{
298 // std::size_t
299 G4int iBeta(0), iTransfer(0);
300 G4double be(0.), be2(0.), gg(1.), mp = proton_mass_c2;
301 G4double rr1(0.), rr2(0.), tr1(0.), tr2(0.), transfer(0.);
302 G4double mean1(0.), mean2(0.);
303 gg = 1. + Tkin/mp;
304 be2 = 1. - 1./gg/gg;
305 if( be2 < 0. ) be2 = 0.;
306 be = sqrt(be2);
307
308 for( iBeta = 0; iBeta < fTotBin; ++iBeta )
309 {
310 if( be <= fBetaVector->GetLowEdgeEnergy(iBeta) ) break;
311 }
312 if (iBeta == 0 || iBeta == fTotBin-1)
313 {
314 rr1 = G4UniformRand()*(*(*fPrEnergyTable)(iBeta))(0);
315
316 for( iTransfer = fBinTr-2; iTransfer >= 0; --iTransfer)
317 {
318 if( (*(*fPrEnergyTable)(iBeta))(iTransfer) >= rr1 ) break;
319 }
320 if( iTransfer == 0 || iTransfer == fBinTr-2 )
321 {
322 transfer = (*fPrEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer);
323 }
324 else
325 {
326 tr1 = (*fPrEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer-1);
327 tr2 = (*fPrEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer);
328 transfer = tr1 + (tr2-tr1)*G4UniformRand();
329 }
330 }
331 else
332 {
333 rr1 = G4UniformRand()*(*(*fPrEnergyTable)(iBeta-1))(0);
334
335 for( iTransfer = fBinTr-2; iTransfer >= 0; --iTransfer)
336 {
337 if( (*(*fPrEnergyTable)(iBeta-1))(iTransfer) >= rr1 ) break;
338 }
339 if( iTransfer == 0 || iTransfer == fBinTr-2 )
340 {
341 transfer = (*fPrEnergyTable)(iBeta-1)->GetLowEdgeEnergy(iTransfer);
342 }
343 else
344 {
345 tr1 = (*fPrEnergyTable)(iBeta-1)->GetLowEdgeEnergy(iTransfer-1);
346 tr2 = (*fPrEnergyTable)(iBeta-1)->GetLowEdgeEnergy(iTransfer);
347 mean1 = tr1 + (tr2-tr1)*G4UniformRand();
348 }
349 rr2 = G4UniformRand()*(*(*fPrEnergyTable)(iBeta))(0);
350
351 for( iTransfer = fBinTr-2; iTransfer >= 0; --iTransfer)
352 {
353 if( (*(*fPrEnergyTable)(iBeta))(iTransfer) >= rr2 ) break;
354 }
355 if( iTransfer == 0 || iTransfer == fBinTr-2 )
356 {
357 transfer = (*fPrEnergyTable)(iBeta-1)->GetLowEdgeEnergy(iTransfer);
358 }
359 else
360 {
361 tr1 = (*fPrEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer-1);
362 tr2 = (*fPrEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer);
363 mean2 = tr1 + (tr2-tr1)*G4UniformRand();
364 }
365 transfer = mean1 + ( mean2 - mean1 )*G4UniformRand();
366 }
367 transfer *= CorrectPrTransfer( Tkin );
368 // G4cout<<transfer/eV<<" ";
369 return transfer;
370}
371
372/////////////////////////////////////////
373//
374// Correction for dN/dx -> dE/dx
375
377{
378 // tuning
379 G4double Tref = keV * 100.; // 100.; //
380 G4double T2 = Tref * 1.; //1.1; //
381 G4double T1 = Tref * 1.; // 0.9; // 0.8; //
382 G4double rat2 = Tkin/T2;
383 G4double rat1 = Tkin/T1;
384 G4double yy(0.);
385 G4double kk = 0.22; // 0.24; //
386 if( Tkin >= T2 ) yy = kk/pow( rat2, 0.15); //
387 else if( Tkin <= T1) yy = kk/pow( rat1, 0.75); //
388 else yy = kk * 1.; // 1.2; // 1.1; //
389
390 return yy;
391}
392
393/////////////////////////////
394//
395// Correction for dN/dx -> dE/dx
396
398{
399 // tuning
400 G4double Tref = eV * 70.; // 100.; //
401 G4double T2 = Tref * 1.; //1.1; //
402 G4double T1 = Tref * 1.; // 0.9; // 0.8; //
403 G4double rat2 = Tkin/T2;
404 G4double rat1 = T1/Tkin; // Tkin/T1; //
405 G4double yy(0.);
406 G4double kk = 0.6; // 0.55; // 0.22; //
407 if( Tkin >= T2 ) yy = kk/pow( rat2, 0.2); // 0.4); //
408 else if( Tkin <= T1) yy = kk*pow( rat1, 0.9); // 0.75); //
409 else yy = kk * 1.; // 1.2; // 1.1; //
410
411 return yy;
412}
413
414////////////////////////////////////////////////
415
417{
418 // std::size_t
419 G4int iBeta(0);
420 G4double be(0.), be2(0.), gg(1.), mp = proton_mass_c2;
421 G4double rr1(0.), rr2(0.), dndx(0.);
422 gg = 1. + Tkin/mp;
423 be2 = 1. - 1./gg/gg;
424 if(be2 < 0.) be2 = 0.;
425 be = sqrt(be2);
426 for( iBeta = 0; iBeta < fTotBin; ++iBeta )
427 {
428 if( be <= fBetaVector->GetLowEdgeEnergy(iBeta) ) break;
429 }
430 if (iBeta <= 0 )
431 {
432 dndx = (*(*fPrEnergyTable)(0))(0);
433 }
434 else if (iBeta >= fTotBin-1)
435 {
436 dndx = (*(*fPrEnergyTable)(fTotBin-1))(0);
437 }
438 else
439 {
440 rr1 = (*(*fPrEnergyTable)(iBeta-1))(0);
441 rr2 = (*(*fPrEnergyTable)(iBeta))(0);
442 dndx = rr1 +(rr2-rr1)*G4UniformRand();
443 }
444 return dndx;
445}
446
447////////////////////////////////////////////////
448
450{
451 G4double dndx = GetPrdNdx(Tkin);
452 G4double mfp(0.);
453 if( dndx > 0.) mfp = 1./dndx;
454 else mfp = DBL_MAX;
455 return mfp;
456}
457
458////////////////////////////////////////////////
459
461{
462 // std::size_t
463 G4int iBeta(0);
464 G4double be(0.), be2(0.), gg(1.), me = electron_mass_c2;
465 G4double rr1(0.), rr2(0.), dndx(0.);
466 gg = 1. + Tkin/me;
467 be2 = 1. - 1./gg/gg;
468 if(be2 < 0.) be2 = 0.;
469 be = sqrt(be2);
470 for( iBeta = 0; iBeta < fTotBin; ++iBeta )
471 {
472 if( be <= fBetaVector->GetLowEdgeEnergy(iBeta) ) break;
473 }
474 if (iBeta <= 0 )
475 {
476 dndx = (*(*fElEnergyTable)(0))(0);
477 }
478 else if (iBeta >= fTotBin-1)
479 {
480 dndx = (*(*fElEnergyTable)(fTotBin-1))(0);
481 }
482 else
483 {
484 rr1 = (*(*fElEnergyTable)(iBeta-1))(0);
485 rr2 = (*(*fElEnergyTable)(iBeta))(0);
486 dndx = rr1 + ( rr2 - rr1 )*G4UniformRand();
487 }
488 return dndx;
489}
490
491////////////////////////////////////////////////
492
494{
495 G4double dndx = GetEldNdx(Tkin);
496 G4double mfp(0.);
497 if( dndx > 0.) mfp = 1./dndx;
498 else mfp = DBL_MAX;
499 return mfp;
500}
501
502////////////////////////////////////////////////
503
505{
506 // G4cout<<"G4LowPAIH2O::BuildElEnergyTable is called"<<G4endl<<G4endl;
507 G4int iBeta(0), iTransfer(0);
508 G4double be(0.), be2(0.), gg(1.);
509 G4double tp(0.), sum(0.), tmp(0.), me = electron_mass_c2;
510
512 fElEnergyTable = new G4PhysicsTable();
513
514 for( iBeta = 0; iBeta < fTotBin; ++iBeta )
515 {
516 be = fBetaVector->GetLowEdgeEnergy(iBeta);
517 be2 = be*be;
518 SetBe2(be2);
519 gg = sqrt( 1./( 1. - be2 ) );
520 tp = ( gg - 1.)*me;
521 fWmax = GetElectronTmax(tp);
522 if( fWmax <= fWmin ) fWmax = fWmin*1.01;
523 fTransferVector = new G4PhysicsLogVector( fWmin, fWmax, fBinTr );
524
525 sum = 0.;
526 fTransferVector->PutValue( fBinTr-1, sum );
527
528 for( iTransfer = fBinTr-2; iTransfer >= 0; --iTransfer)
529 {
530 tmp = integral.Legendre10( this, &G4LowPAIH2O::ElPAId2Ndxdw,
531 fTransferVector->GetLowEdgeEnergy(iTransfer),
532 fTransferVector->GetLowEdgeEnergy(iTransfer+1)
533 );
534
535 sum += tmp; // *fCof/be2;
536
537 fTransferVector->PutValue( iTransfer, sum );
538 }
539 fElEnergyTable->insertAt( iBeta, fTransferVector );
540 }
541 return;
542}
543
544/////////////////////////////////////////////////////
545//
546// return d2Ndxdw (?) collision electron limit
547
549{
550 G4double be2 = GetBe2();
551 omega *= 1.7; // tune from p to e-
552
553 G4double elf = GetSumELF(omega);
554 G4double ruth = GetSumRuth(omega);
555 G4double me = electron_mass_c2;
556
557 G4double d2Ndxdw = elf; // 0.; //
558
559 d2Ndxdw *= log( 2*me*be2/omega );
560
561 d2Ndxdw += ruth;
562
563 d2Ndxdw *= fCof/be2;
564
565 d2Ndxdw *= 1.3; // norm to max exp
566
567 return d2Ndxdw;
568}
569
570////////////////////////////////////////////////
571
573{
574 // std::size_t
575 G4int iBeta, iTransfer;
576 G4double be(0.), be2(0.), gg(1.), me = electron_mass_c2;
577 G4double rr1(0.), rr2(0.), tr1(0.), tr2(0.), transfer(0.);
578 G4double mean1(0.), mean2(0.);
579 gg = 1. + Tkin/me;
580 be2 = 1. - 1./gg/gg;
581 if( be2 < 0.) be2 = 0.;
582 be = sqrt(be2);
583
584 for( iBeta = 0; iBeta < fTotBin; ++iBeta )
585 {
586 if( be <= fBetaVector->GetLowEdgeEnergy(iBeta) ) break;
587 }
588 if (iBeta == 0 || iBeta == fTotBin-1)
589 {
590 rr1 = G4UniformRand()*(*(*fElEnergyTable)(iBeta))(0);
591
592 for( iTransfer = fBinTr-2; iTransfer >= 0; --iTransfer)
593 {
594 if( (*(*fElEnergyTable)(iBeta))(iTransfer) >= rr1 ) break;
595 }
596 if( iTransfer == 0 || iTransfer == fBinTr-2 )
597 {
598 transfer = (*fElEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer);
599 }
600 else
601 {
602 tr1 = (*fElEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer-1);
603 tr2 = (*fElEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer);
604 transfer = tr1 + (tr2-tr1)*G4UniformRand();
605 }
606 }
607 else
608 {
609 rr1 = G4UniformRand()*(*(*fElEnergyTable)(iBeta-1))(0);
610
611 for( iTransfer = fBinTr-2; iTransfer >= 0; --iTransfer)
612 {
613 if( (*(*fElEnergyTable)(iBeta-1))(iTransfer) >= rr1 ) break;
614 }
615 if( iTransfer == 0 || iTransfer == fBinTr-2 )
616 {
617 transfer = (*fElEnergyTable)(iBeta-1)->GetLowEdgeEnergy(iTransfer);
618 }
619 else
620 {
621 tr1 = (*fElEnergyTable)(iBeta-1)->GetLowEdgeEnergy(iTransfer-1);
622 tr2 = (*fElEnergyTable)(iBeta-1)->GetLowEdgeEnergy(iTransfer);
623 mean1 = tr1 + (tr2-tr1)*G4UniformRand();
624 }
625 rr2 = G4UniformRand()*(*(*fElEnergyTable)(iBeta))(0);
626
627 for( iTransfer = fBinTr-2; iTransfer >= 0; --iTransfer)
628 {
629 if( (*(*fElEnergyTable)(iBeta))(iTransfer) >= rr2 ) break;
630 }
631 if( iTransfer == 0 || iTransfer == fBinTr-2 )
632 {
633 transfer = (*fElEnergyTable)(iBeta-1)->GetLowEdgeEnergy(iTransfer);
634 }
635 else
636 {
637 tr1 = (*fElEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer-1);
638 tr2 = (*fElEnergyTable)(iBeta)->GetLowEdgeEnergy(iTransfer);
639 mean2 = tr1 + (tr2-tr1)*G4UniformRand();
640 }
641 transfer = mean1 +(mean2-mean1)*G4UniformRand();
642 }
643 transfer *= CorrectElTransfer( Tkin );
644 if( transfer < 0. ) return 0.;
645 // G4cout<<transfer/eV<<" ";
646 return transfer;
647}
648
649//////////////////////////////////////////////////
650
652{
653 G4double be2 = GetBe2();
654 G4double elf = GetSumELF(omega);
655 G4double ruth = GetSumRuth(omega);
656 G4double me = electron_mass_c2;
657 G4double d2Ndxdw = elf;
658
659 d2Ndxdw *= log( 2*me*be2/omega );
660
661 d2Ndxdw += ruth;
662
663 return d2Ndxdw;
664}
665
666///////////////////////////////////////////////
667
668void G4LowPAIH2O::SampleSecondaries( std::vector<G4DynamicParticle*>* vdp,
669 const G4MaterialCutsCouple*, // matCC,
670 const G4DynamicParticle* dp,
671 G4double, // tmin,
672 G4double) // maxEnergy )
673{
674 G4double kineticEnergy = dp->GetKineticEnergy();
675 const G4ParticleDefinition* pd = dp->GetDefinition();
676
677 G4double deltaTkin(0.);
678 if( pd == theProton ) deltaTkin = GetPrTransfer(kineticEnergy);
679 else if( pd == theElectron ) deltaTkin = GetElTransfer(kineticEnergy);
680 else
681 {
682 G4cout<<" G4LowPAIH2O::SampleSecondaries is not applicable for "
683 <<pd->GetParticleName()<<G4endl;
684 return;
685 }
686 G4ThreeVector direction= dp->GetMomentumDirection();
687 fMass = pd->GetPDGMass();
688 G4double totalMomentum = sqrt( kineticEnergy*( kineticEnergy + 2.*fMass ) );
689
690 if( !(deltaTkin <= 0.) && !(deltaTkin > 0))
691 {
692 G4cout<<"G4LowPAIH2O::SampleSecondaries; deltaTkin = "<<deltaTkin/keV
693 <<" keV "<< " for Tkin(MeV)= " << kineticEnergy << G4endl;
694 return;
695 }
696 if( deltaTkin < 0.)
697 {
698 G4cout<<deltaTkin/eV<<"-"<<kineticEnergy/MeV<<", ";
699 return;
700 }
701 if( kineticEnergy > deltaTkin) kineticEnergy -= deltaTkin;
702 else
703 {
704 deltaTkin = kineticEnergy;
705 kineticEnergy = 0.;
706 }
707 G4double momD = sqrt( deltaTkin*( deltaTkin + 2.*electron_mass_c2 ) );
708 G4ThreeVector dirD = G4RandomDirection(); // low e- cloud
709
710 G4ThreeVector dir = totalMomentum*direction - dirD*momD;
711 direction = dir.unit();
712 fParticleChange->SetProposedKineticEnergy(kineticEnergy);
713 fParticleChange->SetProposedMomentumDirection(direction);
714
715 if( deltaTkin < eV * 1.) // 10.) //
716 {
717 fParticleChange->ProposeLocalEnergyDeposit(deltaTkin);
718 }
719 else
720 {
721 auto deltaRay = new G4DynamicParticle( theElectron, dirD, deltaTkin );
722 vdp->push_back( deltaRay );
723 }
724 return;
725}
726
727/////////////////////////////////////////
728
730 const G4DynamicParticle* dp,
731 const G4double, // tcut,
732 const G4double, // tmax,
733 const G4double length,
734 const G4double) // meanLoss )
735{
736 G4double eloss(0.), mfp(0.), sumW(0.), sumL(0.), transfer(0.);
737 G4double Tkin = dp->GetKineticEnergy();
738 const G4ParticleDefinition* pd = dp->GetDefinition();
739
740 if( pd != theProton && pd != theElectron)
741 {
742 eloss = 0.;
743 return eloss;
744 }
745
746 if( pd == theProton )
747 {
748 do
749 {
750 mfp = GetPrMFP(Tkin);
751 sumL += RandExponential::shoot(mfp);
752 transfer = GetPrTransfer(Tkin);
753 sumW += transfer;
754 // nn++;
755 if( Tkin >= transfer ) Tkin -= transfer;
756 else
757 {
758 transfer = Tkin;
759 Tkin = 0.;
760 }
761 }
762 while( sumL <= length && Tkin >= keV * 0.01 ); //
763 }
764 else if( pd == theElectron ) // e-
765 {
766 do
767 {
768 mfp = GetElMFP(Tkin);
769 sumL += RandExponential::shoot(mfp);
770 transfer = GetElTransfer(Tkin);
771 sumW += transfer;
772 Tkin -= transfer;
773 }
774 while( sumL <= length && Tkin >= 0. );
775 }
776 eloss = sumW;
777 if(eloss < 0.) { eloss = 0.; }
778 fParticleChange->SetProposedKineticEnergy( Tkin );
779 fParticleChange->ProposeLocalEnergyDeposit( eloss );
780 // G4cout<<Tkin/MeV<<"/"<<eloss/eV<<"/"<<nn<<", ";
781
782 return eloss;
783}
784
785/////////////////////////////////////////////
786
788 const G4ParticleDefinition* pd,
789 const G4double Tkin,
790 const G4double,
791 const G4double& length,
792 G4double& eloss)
793{
794 G4double mfp(0.), sumW(0.);
795
796 if ( pd == theProton ) mfp = GetPrMFP(Tkin);
797 else if( pd == theElectron ) mfp = GetElMFP(Tkin);
798 else
799 {
800 eloss = 0.;
801 return;
802 }
803 G4int NN = static_cast<G4int>(RandPoisson::shoot(length/mfp));
804
805 if( pd == theProton )
806 {
807 for (G4int nn = 0; nn < NN; ++nn )
808 {
809 sumW += GetPrTransfer( Tkin );
810 }
811 }
812 else // e-
813 {
814 for (G4int nn = 0; nn < NN; ++nn )
815 {
816 sumW += GetElTransfer( Tkin );
817 }
818 }
819 if( sumW < Tkin ) eloss = sumW;
820 else eloss = Tkin;
821 // G4cout<<eloss/eV<<".. ";
822 fParticleChange->ProposeLocalEnergyDeposit(eloss);
823 fParticleChange->SetProposedKineticEnergy(Tkin);
824 return;
825}
826
827/////////////////////////////////////////////
828//
829// Transition from secondary e- to radicals
830
832{
833 fTkin = tt;
834 return tt*0.5;
835
836 // algorithm below is doing the same
837 /*
838 G4double tmax(0.), cof(1.);
839 G4double mt = eV * 18.; // 32.; // 30.; // 50.; //
840 G4double dt = eV * 10.; // 5.; // 20.; // 25.; //
841
842 G4double lim1 = 0.5; // 0.6; //
843 G4double lim2 = 1.; // 0.8; //
844 G4double dlim = (lim2-lim1)*0.5;
845
846 G4double xx = ( tt - mt )/dt;
847
848 if( xx > 0.) tmax = tt*( lim1 + dlim*exp(-xx) );
849 else tmax = tt*( lim2 - dlim*exp(+xx) );
850
851 dt = mt *0.5; // eV * 38.; // 27.; //
852
853 if(tt > mt+dt) tmax = tt*0.5;
854 else if (tt < mt-dt) tmax = tt;
855 else
856 {
857 cof = 1. - (tt-mt+dt)*0.25/dt;
858 tmax = tt*cof;
859 }
860 tmax = tt * 0.5; //
861
862 if( tmax > tt ) tmax = tt;
863
864 return tmax;
865 */
866}
867
868/////////////////////////////////////////////////////
869
871{
872 G4double mp = proton_mass_c2;
873 G4double Et = eV * 13.6; //
874 G4double tau = Tkin/mp;
875 G4double gamma = tau + 1.0;
876 G4double bg2 = tau*( tau + 2.0 );
877 // G4double beta2 = bg2/(gamma*gamma);
878 G4double me = electron_mass_c2;
879 G4double rateMass = me/mp;
880
881 if( Tkin < Et ) rateMass = 1.;
882
883 G4double Tmax = 2.0*me*bg2
884 /( 1. + 2.*gamma*rateMass + rateMass*rateMass );
885
886 return Tmax;
887}
888
889//
890//
891//////////////////////////////////////////////////
G4ThreeVector G4RandomDirection()
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
Hep3Vector unit() const
static long shoot(double mean=1.0)
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition G4Electron.cc:91
G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy) override
void Initialize()
G4double GetPrMFP(G4double Tkin)
void BuildPrEnergyTable()
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
G4double GetElectronTmax(G4double Tkin)
G4double GetSumELF(G4double energy)
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel) override
void BuildPhysicsTable(const G4ParticleDefinition *pd)
G4double PrPAId2Ndxdw(G4double omega)
G4double CrossSectionPerAtom(const G4ParticleDefinition *, G4double kineticEnergy, G4double Z, G4double A, G4double cutEnergy, G4double maxEnergy)
G4double GetProtonTmax(G4double Tkin)
G4double CorrectElTransfer(G4double Tkin)
G4double SampleFluctuations(const G4MaterialCutsCouple *, const G4DynamicParticle *, const G4double tcut, const G4double tmax, const G4double length, const G4double meanLoss) override
G4double GetElMFP(G4double Tkin)
G4double GetPrdNdx(G4double Tkin)
void SetBe2(G4double be2)
G4double GetElTransfer(G4double Tkin)
void InitRuthELF()
void BuildElEnergyTable()
~G4LowPAIH2O() override
G4double ElPAId2Ndxdw(G4double omega)
G4double GetBe2()
G4LowPAIH2O(const G4ParticleDefinition *p=nullptr, const G4String &nam="lowpaih2o")
G4double GetSumRuth(G4double energy)
G4double CorrectPrTransfer(G4double Tkin)
G4double GetPrTransfer(G4double Tkin)
void CorrectionsAlongStep(const G4Material *, const G4ParticleDefinition *, const G4double kinEnergy, const G4double cutEnergy, const G4double &length, G4double &eloss) override
G4double GetEldNdx(G4double Tkin)
virtual G4double ComputeCrossSectionPerElectron(const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy)
G4double GetElectronDensity() const
G4Material * FindOrBuildMaterial(const G4String &name, G4bool isotopes=true, G4bool warning=false)
static G4NistManager * Instance()
const G4String & GetParticleName() const
static G4Proton * Proton()
Definition G4Proton.cc:90
G4VEmFluctuationModel(const G4String &nam)
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
std::vector< G4EmElementSelector * > * GetElementSelectors()
G4bool IsMaster() const
G4VEmModel(const G4String &nam)
Definition G4VEmModel.cc:67
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
G4ParticleChangeForLoss * GetParticleChangeForLoss()
#define DBL_MAX
Definition templates.hh:62