47G4DataVector* G4JAEAPolarizedElasticScatteringModel::Polarized_ES_Data[] = {
nullptr};
50 :
G4VEmModel(
"G4JAEAPolarizedElasticScatteringModel"),isInitialised(false)
53 lowEnergyLimit = 100 * keV;
54 fLinearPolarizationSensitvity1=1;
55 fLinearPolarizationSensitvity2=1;
56 fCircularPolarizationSensitvity=1;
66 G4cout <<
"G4JAEAPolarizedElasticScatteringModel is constructed " <<
G4endl;
76 for(
G4int i=0; i<=maxZ; ++i) {
81 if (Polarized_ES_Data[i]){
82 delete Polarized_ES_Data[i];
83 Polarized_ES_Data[i] =
nullptr;
96 G4cout <<
"Calling Initialise() of G4JAEAPolarizedElasticScatteringModel." <<
G4endl
114 for(
G4int i=0; i<numOfCouples; ++i)
122 for (std::size_t j=0; j<nelm; ++j)
126 else if(
Z > maxZ) {
Z = maxZ; }
127 if( (!dataCS[
Z]) ) { ReadData(
Z, path); }
132 if(isInitialised) {
return; }
134 isInitialised =
true;
148void G4JAEAPolarizedElasticScatteringModel::ReadData(std::size_t
Z,
const char* path)
150 if (verboseLevel > 1)
152 G4cout <<
"Calling ReadData() of G4JAEAPolarizedElasticScatteringModel"
156 if(dataCS[
Z]) {
return; }
158 const char* datadir = path;
164 G4Exception(
"G4JAEAPolarizedElasticScatteringModel::ReadData()",
"em0006",
166 "Environment variable G4LEDATA not defined");
171 std::ostringstream ostCS;
172 ostCS << datadir <<
"/JAEAESData/amp_Z_" <<
Z ;
173 std::ifstream ES_Data_Buffer(ostCS.str().c_str(),ios::binary);
174 if( !ES_Data_Buffer.is_open() )
177 ed <<
"G4JAEAPolarizedElasticScattering Model data file <" << ostCS.str().c_str()
178 <<
"> is not opened!" <<
G4endl;
180 ed,
"G4LEDATA version should be G4EMLOW7.11 or later. Polarized Elastic Scattering Data are not loaded");
185 if(verboseLevel > 3) {
186 G4cout <<
"File " << ostCS.str()
187 <<
" is opened by G4JAEAPolarizedElasticScatteringModel" <<
G4endl;
192 if (!Polarized_ES_Data[
Z])
196 while (ES_Data_Buffer.read(
reinterpret_cast<char*
>(&buffer_var),
sizeof(
float)))
198 Polarized_ES_Data[
Z]->push_back(buffer_var);
203 for (
G4int i=0;i<300;++i)
204 dataCS[
Z]->PutValues(i,10.*i*1e-3,Polarized_ES_Data[
Z]->at(i)*1e-22);
222 if (verboseLevel > 1)
224 G4cout <<
"G4JAEAPolarizedElasticScatteringModel::ComputeCrossSectionPerAtom()"
228 if(GammaEnergy < lowEnergyLimit) {
return 0.0; }
234 if(intZ < 1 || intZ > maxZ) {
return xs; }
243 if(!pv) {
return xs; }
251 }
else if(e >= pv->
Energy(0)) {
257 G4cout <<
"****** DEBUG: tcs value for Z=" <<
Z <<
" at energy (MeV)="
259 G4cout <<
" cs (Geant4 internal unit)=" << xs <<
G4endl;
260 G4cout <<
" -> first E*E*cs value in CS data file (iu) =" << (*pv)[0]
262 G4cout <<
" -> last E*E*cs value in CS data file (iu) =" << (*pv)[n]
264 G4cout <<
"*********************************************************"
274 std::vector<G4DynamicParticle*>*,
279 if (verboseLevel > 1) {
281 G4cout <<
"Calling SampleSecondaries() of G4JAEAPolarizedElasticScatteringModel."
287 if (photonEnergy0 <= lowEnergyLimit)
300 G4int energyindex=round(100*photonEnergy0)-1;
302 for (
G4int i=0;i<=180;++i)
304 a1=Polarized_ES_Data[
Z]->at(4*i+300+181*4*(energyindex));
305 a2=Polarized_ES_Data[
Z]->at(4*i+1+300+181*4*(energyindex));
306 a3=Polarized_ES_Data[
Z]->at(4*i+2+300+181*4*(energyindex));
307 a4=Polarized_ES_Data[
Z]->at(4*i+3+300+181*4*(energyindex));
308 distribution[i]=a1*a1+a2*a2+a3*a3+a4*a4;
316 G4int theta_in_degree =round(theta*180./CLHEP::pi);
320 G4double am1=0,am2=0,am3=0,am4=0,aparaSquare=0,aperpSquare=0,
321 apara_aper_Asterisk=0,img_apara_aper_Asterisk=0;
322 am1=Polarized_ES_Data[
Z]->at(4*theta_in_degree+300+181*4*(energyindex));
323 am2=Polarized_ES_Data[
Z]->at(4*theta_in_degree+1+300+181*4*(energyindex));
324 am3=Polarized_ES_Data[
Z]->at(4*theta_in_degree+2+300+181*4*(energyindex));
325 am4=Polarized_ES_Data[
Z]->at(4*theta_in_degree+3+300+181*4*(energyindex));
326 aparaSquare=am1*am1+am2*am2;
327 aperpSquare=am3*am3+am4*am4;
328 apara_aper_Asterisk=2*a1*a3+2*a2*a4;
329 img_apara_aper_Asterisk=2*a1*a4-2*a2*a3;
341 G4double Xi1=0, Xi2=0, Xi3=0, Xi1_Prime=0,Xi2_Prime=0,Xi3_Prime=0;
345 Xi1=gammaPolarization0.
x();
346 Xi2=gammaPolarization0.
y();
347 Xi3=gammaPolarization0.
z();
350 if ((gammaPolarization0.
mag())>1.05 || (Xi1*Xi1>1.05) || (Xi2*Xi2>1.05) || (Xi3*Xi3>1.05))
352 G4Exception(
"G4JAEAPolarizedElasticScatteringModel::SampleSecondaries()",
"em1006",
354 "WARNING: G4JAEAPolarizedElasticScatteringModel is only compatible with a unit polarization vector.");
358 if (Xi1==0 && Xi2==0 && Xi3==0)
361 if (fLinearPolarizationSensitvity1)
362 Phi_Unpolarized=GeneratePolarizedPhi(aparaSquare,aperpSquare,0.);
365 Direction_Unpolarized.
setX(sin(theta)*cos(Phi_Unpolarized));
366 Direction_Unpolarized.
setY(sin(theta)*sin(Phi_Unpolarized));
367 Direction_Unpolarized.
setZ(cos(theta));
369 Xi1_Prime=(aparaSquare-aperpSquare)/(aparaSquare+aperpSquare);
370 Polarization_Unpolarized.
setX(Xi1_Prime);
371 Polarization_Unpolarized.
setY(0.);
372 Polarization_Unpolarized.
setZ(0.);
380 if(InitialAzimuth<0) InitialAzimuth=InitialAzimuth+CLHEP::twopi;
384 Phi_Linear1 = GeneratePolarizedPhi(aparaSquare+aperpSquare+Xi1*(aparaSquare-aperpSquare),
385 aparaSquare+aperpSquare-Xi1*(aparaSquare-aperpSquare),InitialAzimuth);
387 Xi1_Prime=((aparaSquare-aperpSquare)+Xi1*(aparaSquare+aperpSquare)*cos(2*Phi_Linear1))/
388 ((aparaSquare+aperpSquare)+Xi1*(aparaSquare-aperpSquare)*cos(2*Phi_Linear1));
389 Xi2_Prime=(-Xi1*apara_aper_Asterisk*sin(2*Phi_Linear1))/
390 ((aparaSquare+aperpSquare)+Xi1*(aparaSquare-aperpSquare)*cos(2*Phi_Linear1));
391 Xi3_Prime=(-Xi1*img_apara_aper_Asterisk*sin(2*Phi_Linear1))/
392 ((aparaSquare+aperpSquare)+Xi1*(aparaSquare-aperpSquare)*cos(2*Phi_Linear1));
394 Direction_Linear1.
setX(sin(theta)*cos(Phi_Linear1));
395 Direction_Linear1.
setY(sin(theta)*sin(Phi_Linear1));
396 Direction_Linear1.
setZ(cos(theta));
397 Polarization_Linear1.
setX(Xi1_Prime);
398 Polarization_Linear1.
setY(Xi2_Prime);
399 Polarization_Linear1.
setZ(Xi3_Prime);
402 Xi1_Prime=Xi1_Prime*fLinearPolarizationSensitvity1;
403 Xi2_Prime=Xi2_Prime*fLinearPolarizationSensitvity2;
404 Xi3_Prime=Xi3_Prime*fCircularPolarizationSensitvity;
407 if(abs(Xi1)>0.0) dsigmaL1=0.25*((aparaSquare+aperpSquare)*
408 (1+Xi1*Xi1_Prime*cos(2*Phi_Linear1))+
409 (aparaSquare-aperpSquare)*(Xi1*cos(2*Phi_Linear1)+Xi1_Prime)
410 -Xi1*Xi2_Prime*apara_aper_Asterisk*sin(2*Phi_Linear1)-
411 Xi1*Xi3_Prime*img_apara_aper_Asterisk*sin(2*Phi_Linear1));
417 InitialAzimuth=InitialAzimuth-CLHEP::pi/4.;
418 if(InitialAzimuth<0) InitialAzimuth=InitialAzimuth+CLHEP::twopi;
420 Phi_Linear2 = GeneratePolarizedPhi(aparaSquare+aperpSquare+Xi1*(aparaSquare-aperpSquare)
421 ,aparaSquare+aperpSquare-Xi1*(aparaSquare-aperpSquare),InitialAzimuth);
423 Xi1_Prime=((aparaSquare-aperpSquare)+Xi2*(aparaSquare+aperpSquare)*sin(2*Phi_Linear2))/
424 ((aparaSquare+aperpSquare)+Xi2*(aparaSquare-aperpSquare)*sin(2*Phi_Linear2));
425 Xi2_Prime=(Xi2*apara_aper_Asterisk*cos(2*Phi_Linear2))/
426 ((aparaSquare+aperpSquare)+Xi2*(aparaSquare-aperpSquare)*sin(2*Phi_Linear2));
427 Xi3_Prime=(Xi2*img_apara_aper_Asterisk*cos(2*Phi_Linear2))/
428 ((aparaSquare+aperpSquare)+Xi2*(aparaSquare-aperpSquare)*sin(2*Phi_Linear2));
430 Direction_Linear2.
setX(sin(theta)*cos(Phi_Linear2));
431 Direction_Linear2.
setY(sin(theta)*sin(Phi_Linear2));
432 Direction_Linear2.
setZ(cos(theta));
433 Polarization_Linear2.
setX(Xi1_Prime);
434 Polarization_Linear2.
setY(Xi2_Prime);
435 Polarization_Linear2.
setZ(Xi3_Prime);
438 Xi1_Prime=Xi1_Prime*fLinearPolarizationSensitvity1;
439 Xi2_Prime=Xi2_Prime*fLinearPolarizationSensitvity2;
440 Xi3_Prime=Xi3_Prime*fCircularPolarizationSensitvity;
444 dsigmaL2=0.25*((aparaSquare+aperpSquare)*(1+Xi2*Xi1_Prime*sin(2*Phi_Linear2))+
445 (aparaSquare-aperpSquare)*(Xi2*sin(2*Phi_Linear2)+Xi1_Prime)
446 +Xi2*Xi2_Prime*apara_aper_Asterisk*cos(2*Phi_Linear2)-
447 Xi2*Xi3_Prime*img_apara_aper_Asterisk*cos(2*Phi_Linear2));
453 Xi1_Prime=(aparaSquare-aperpSquare)/(aparaSquare+aperpSquare);
454 Xi2_Prime=(-Xi3*img_apara_aper_Asterisk)/(aparaSquare+aperpSquare);
455 Xi3_Prime=(Xi3*apara_aper_Asterisk)/(aparaSquare+aperpSquare);
457 Polarization_Circular.
setX(Xi1_Prime);
458 Polarization_Circular.
setY(Xi2_Prime);
459 Polarization_Circular.
setZ(Xi3_Prime);
462 Xi1_Prime=Xi1_Prime*fLinearPolarizationSensitvity1;
463 Xi2_Prime=Xi2_Prime*fLinearPolarizationSensitvity2;
464 Xi3_Prime=Xi3_Prime*fCircularPolarizationSensitvity;
468 dsigmaC=0.25*(aparaSquare+aperpSquare+Xi1_Prime*(aparaSquare-aperpSquare)-
469 Xi3*Xi2_Prime*img_apara_aper_Asterisk
470 +Xi3*Xi3_Prime*apara_aper_Asterisk);
472 if (abs(Xi3)==0.0 && abs(Xi1_Prime)==0.0)
474 Direction_Circular.
setX(sin(theta)*cos(Phi_Circular));
475 Direction_Circular.
setY(sin(theta)*sin(Phi_Circular));
476 Direction_Circular.
setZ(cos(theta));
481 for (
G4int i=0;i<=180;++i)
483 c1=Polarized_ES_Data[
Z]->at(4*i+300+181*4*(energyindex));
484 c2=Polarized_ES_Data[
Z]->at(4*i+1+300+181*4*(energyindex));
485 c3=Polarized_ES_Data[
Z]->at(4*i+2+300+181*4*(energyindex));
486 c4=Polarized_ES_Data[
Z]->at(4*i+3+300+181*4*(energyindex));
487 cdistribution[i]=0.25*((c1*c1+c2*c2+c3*c3+c4*c4)+
488 Xi1_Prime*(c1*c1+c2*c2-c3*c3-c4*c4)-
489 Xi3*Xi2_Prime*(2*c1*c4-2*c2*c3)
490 +Xi3*Xi3_Prime*(2*c1*c4-2*c2*c3));
493 Theta_Circular=CLHEP::pi*GenTheta_Circ_Dist.
shoot();
494 Direction_Circular.
setX(sin(Theta_Circular)*cos(Phi_Circular));
495 Direction_Circular.
setY(sin(Theta_Circular)*sin(Phi_Circular));
496 Direction_Circular.
setZ(cos(Theta_Circular));
500 G4double totalSigma= dsigmaL1+dsigmaL2+dsigmaC;
506 if (abs(probc - dsigmaC/totalSigma)>=0.0001)
508 G4Exception(
"G4JAEAPolarizedElasticScatteringModel::SampleSecondaries()",
"em1007",
510 "WARNING: Polarization mixing might be incorrect.");
521 finaldirection.
setX(Direction_Linear1.
x());
522 finaldirection.
setY(Direction_Linear1.
y());
523 finaldirection.
setZ(Direction_Linear1.
z());
524 outcomingPhotonPolarization.
setX(Polarization_Linear1.
x());
525 outcomingPhotonPolarization.
setY(Polarization_Linear1.
y());
526 outcomingPhotonPolarization.
setZ(Polarization_Linear1.
z());
528 else if ((polmix>prob1) && (polmix<=prob1+prob2))
530 finaldirection.
setX(Direction_Linear2.
x());
531 finaldirection.
setY(Direction_Linear2.
y());
532 finaldirection.
setZ(Direction_Linear2.
z());
533 outcomingPhotonPolarization.
setX(Polarization_Linear2.
x());
534 outcomingPhotonPolarization.
setY(Polarization_Linear2.
y());
535 outcomingPhotonPolarization.
setZ(Polarization_Linear2.
z());
537 else if (polmix>prob1+prob2)
539 finaldirection.
setX(Direction_Circular.
x());
540 finaldirection.
setY(Direction_Circular.
y());
541 finaldirection.
setZ(Direction_Circular.
z());
542 outcomingPhotonPolarization.
setX(Polarization_Circular.
x());
543 outcomingPhotonPolarization.
setY(Polarization_Circular.
y());
544 outcomingPhotonPolarization.
setZ(Polarization_Circular.
z());
557G4double G4JAEAPolarizedElasticScatteringModel::GeneratePolarizedPhi(
G4double Sigma_para,
563 G4double Probability=Sigma_perp/(Sigma_para+Sigma_perp);
569 phiProbability = cos(phi+initial_Pol_Plane)*cos(phi+initial_Pol_Plane);
579 phiProbability = sin(phi+initial_Pol_Plane)*sin(phi+initial_Pol_Plane);
592 G4AutoLock l(&G4JAEAPolarizedElasticScatteringModelMutex);
595 if(!dataCS[
Z]) { ReadData(
Z); }
std::vector< const G4Element * > G4ElementVector
const char * G4FindDataDir(const char *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
#define G4MUTEX_INITIALIZER
G4GLOB_DLL std::ostream G4cout
Hep3Vector & rotateUz(const Hep3Vector &)
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4ThreeVector & GetPolarization() const
G4JAEAPolarizedElasticScatteringModel()
void InitialiseLocal(const G4ParticleDefinition *, G4VEmModel *masterModel) override
G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *, G4double kinEnergy, G4double Z, G4double A=0, G4double cut=0, G4double emax=DBL_MAX) override
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
void InitialiseForElement(const G4ParticleDefinition *, G4int Z) override
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
virtual ~G4JAEAPolarizedElasticScatteringModel()
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
size_t GetNumberOfElements() const
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposePolarization(const G4ThreeVector &dir)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
G4double Energy(const std::size_t index) const
G4double Value(const G4double energy, std::size_t &lastidx) const
std::size_t GetVectorLength() const
void FillSecondDerivatives(const G4SplineType=G4SplineType::Base, const G4double dir1=0.0, const G4double dir2=0.0)
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
void SetElementSelectors(std::vector< G4EmElementSelector * > *)
G4ParticleChangeForGamma * GetParticleChangeForGamma()
G4double LowEnergyLimit() const
std::vector< G4EmElementSelector * > * GetElementSelectors()
G4double HighEnergyLimit() const
const G4Element * SelectRandomAtom(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
void InitialiseElementSelectors(const G4ParticleDefinition *, const G4DataVector &)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)