Files
geant4/source/processes/hadronic/models/coherent_elastic/src/G4ElasticHadrNucleusHE.cc
T
2016-06-09 14:36:02 +02:00

1013 lines
31 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4ElasticHadrNucleusHE.cc,v 1.25 2005/11/28 18:00:46 gcosmo Exp $
// GEANT4 tag $Name: geant4-08-00 $
//
// G4ElasticHadrNucleusHE class
//
//
// The generator of high energy hadron-nucleus elastic scattering
// The hadron kinetic energy T > 1 GeV
// N. Starkov 2003.
//
// Modifications:
// 19.05.04 Variant for G4 6.1: The 'ApplyYourself' was changed
// 14.11.05 The HE elastic scattering on proton is added (N.Starkov)
// 23.11.05 int -> G4int, fabs -> abs (V.Ivanchenko)
//
#include "G4ElasticHadrNucleusHE.hh"
#include "Randomize.hh"
#include <sstream>
#include <iostream>
#include <fstream>
#include "G4ios.hh"
#include "G4ParticleTable.hh"
using namespace std;
G4ElasticHadrNucleusHE::G4ElasticHadrNucleusHE()
: G4DiffElasticHadrNucleus()
{;}
// +++++++ The constructor for the preparation of data +++++++
G4ElasticHadrNucleusHE::
G4ElasticHadrNucleusHE(const G4ParticleDefinition * aHadron1,
G4Nucleus * aNucleus)
: G4DiffElasticHadrNucleus(), G4HadronicInteraction()
{
// ------------- here all variables are in MeV ---------------
G4int ii, kk, ik;
iKindWork = 3;
iPoE = 5;
Nstep = ONQ2;
G4ParticleDefinition * aHadron =
const_cast<G4ParticleDefinition *>(aHadron1);
G4String sNameHdr = aHadron->GetParticleName();
G4int iNnucl = (G4int) aNucleus->GetN();
G4double Energies[5]; // = {1.95, 2.0, 4.0, 6.0, 10.0};
G4double Kinetic[5] = {1.0, 1.5, 2.5, 4.0, 6.0};
if(iNnucl==1) return;
if(iNnucl==2 || iNnucl==3)
G4Exception(" This nucleus is very light for this model !!!");
if(iNnucl>238)
G4Exception(" This nucleus is very heavy for this model !!!");
// MyIonTable = const_cast<G4IonTable *>
// (G4ParticleTable::GetParticleTable()->GetIonTable());
Factorials1[0] = 1;
for( ii = 1; ii<110; ii++)
Factorials1[ii] = Factorial1(ii);
G4DynamicParticle * innerHadron = new G4DynamicParticle();
innerHadron->SetDefinition(aHadron);
G4ThreeVector inVector(0.,0.,0.);
G4double mHadr = aHadron->GetPDGMass(); // MeV
G4double curE, curP;
for(ii=0; ii<iPoE; ii++) Energies[ii] = Kinetic[ii]+mHadr/1000;
innerHadron->SetDefinition(aHadron);
G4double dPower=1000.0;
G4cout<<G4endl<<" The preparing of elastic Data array "<<G4endl;
G4cout<<" for '"<<sNameHdr<<"' on nucleus "<<iNnucl<<G4endl<<G4endl;
for( ik = 0; ik<AreaNumb; ik++)
{
for( ii = 0; ii<iPoE; ii++)
{
curE = Energies[ii]*dPower;
curP = std::sqrt(curE*curE-mHadr*mHadr); // MeV
pTableE[ii+ik*iPoE] = curE;
inVector.setZ(curP); // MeV
innerHadron->SetMomentum(inVector);
// ------ The creating of the distribution function array ------
CreationArray(innerHadron, aNucleus);
for( kk = 0; kk<ONQ2; kk++)
pTableCrSec[ii*ONQ2+kk+ik*ONQ2XE] = iIntgr[kk];
G4cout<<" Energy of "<<sNameHdr<<" = "<<curE<<G4endl;
} // ii step Ei
dPower *= 10.0;
} // ik step power
G4cout<<" The array for elastic scattering of the "<<sNameHdr<<G4endl;
G4cout<<" on the Nuclues "<<iNnucl<<" has been prepared !"
<<G4endl<<G4endl;
// --------- The writing of array into sName File ---------
G4String sPath;
if(getenv("G4ELASTICDATA"))
{
sPath = getenv("G4ELASTICDATA");
sPath = sPath+"/Elastic/";
}
else sPath = "./Elastic/";
// G4cout<<" Path : "<<sPath<<G4endl;
std::ostringstream sNameFile;
sNameFile<<sPath<<sNameHdr<<"_"<<iNnucl<<".dat"<<std::ends;
// sNameFile<<"Elastic//"<<sNameHdr<<"_"<<iNnucl<<".dat"<<ends;
G4String str = sNameFile.str();
std::ofstream TestFile(str, std::ios::out);
TestFile.setf(std::ios::scientific, std::ios::floatfield);
TestFile.precision(9);
TestFile <<iPoE<<G4endl;
G4int Mult;
dPower = 1000.0;
for( ik=0; ik<AreaNumb; ik++)
{
for(kk=0; kk<iPoE; kk++)
{
curE = Energies[kk]*dPower;
Mult = (G4int) curE;
TestFile<<" "<<Mult<<" ";
}
TestFile<<G4endl;
for(ii=0; ii<ONQ2; ii++)
{
for(kk=0; kk<iPoE; kk++)
TestFile << pTableCrSec[kk*ONQ2+ii+ik*ONQ2XE]<<" ";
TestFile << G4endl;
} // ii
TestFile<<G4endl;
dPower *= 10.0;
} // ik
TestFile.close();
if(getenv("HEElastic_debug"))
{
G4cout<<" The array for elastic scattering of "<<sNameHdr<<G4endl;
G4cout<<" on the Nuclues "<<iNnucl<<" has been written !"<<G4endl;
G4cout<<" The Name of File is "<<sNameFile.str()<<G4endl<<G4endl;
}
iContr = 0;
} // Constructor
G4ElasticHadrNucleusHE::~G4ElasticHadrNucleusHE()
{} // Destructor
// ######################################################
G4int G4ElasticHadrNucleusHE::ReadOfData(G4ParticleDefinition * aHadron,
G4Nucleus * aNucleus)
{
G4int ii, kk, ik;
G4String sNameHdr = aHadron->GetParticleName();
G4int iNnucl = (G4int) aNucleus->GetN();
if(iNnucl==2 || iNnucl==3)
G4Exception(" This nucleus is very light for this model !!!");
if(iNnucl>238)
G4Exception(" This nucleus is very heavy for this model !!!");
G4String sPath;
if(getenv("G4ELASTICDATA"))
{
sPath = getenv("G4ELASTICDATA");
sPath = sPath+"/Elastic/";
}
else sPath = "./Elastic/";
std::ostringstream sNameFile;
sNameFile<<sPath<<sNameHdr<<"_"<<iNnucl<<".dat"<<std::ends;
if(getenv("HEElastic_debug"))
{
G4cout <<" Reading file for: Hadron - "<<sNameHdr
<<". Nucleus - "<<iNnucl<<G4endl;
G4cout <<" The Name of File is "<<sNameFile.str()<<G4endl;
}
// MyIonTable = const_cast<G4IonTable *>
// (G4ParticleTable::GetParticleTable()->GetIonTable());
GetNucleusParameters(aNucleus);
iContr = iPoE;
Nstep = ONQ2;
iKindWork = 4;
// G4double nuclMass = (G4double) iNnucl;
// R1 = 0.74*std::pow(nuclMass,0.3333)*5.0;
maxQ2 = GetQ2limit(R1); // MeV^2
G4String str = sNameFile.str();
std::ifstream TestFile(str, std::ios::in);
TestFile.setf(std::ios::scientific);
if(TestFile)
{
ElasticData ElD;
if(getenv("HEElastic_debug")) G4cout<<" The file exists "<<G4endl;
ElD.hadrName = sNameHdr;
ElD.nuclAtomicNumber = iNnucl;
TestFile >> iPoE;
G4double dPower;
for(ik=0; ik<AreaNumb; ik++)
{
dPower = std::pow(10.0,ik);
for(kk=0; kk<iPoE; kk++) TestFile >> ElD.TableE[kk+ik*iPoE];
for(ii=0; ii<ONQ2; ii++)
{
ElD.TableQ2[ii] = iQ2[ii];
for(kk=0; kk<iPoE; kk++)
TestFile >> ElD.TableCrossSec[kk*ONQ2+ii+ik*ONQ2XE];
} // ii
} // ik
TestFile.close();
SetOfElasticData.push_back(ElD);
if(getenv("HEElastic_debug"))
{
G4cout<<" The array for elastic scattering of "<<sNameHdr;
G4cout<<" on the Nuclues "<<iNnucl<<G4endl;
G4cout<<" from the file "<<sNameFile.str()<<" has been readout !"
<<G4endl<<G4endl;
}
return 1;
} // if check
else return -1;
} // ReadOfData
// ++++++++++++++++++++ GetQ2limit +++++++++++++++++++
G4double G4ElasticHadrNucleusHE::GetQ2limit(G4double R1)
{
G4double maxQ2 = 35*1000*1000/R1/R1;
dQ2 = maxQ2/(Nstep*3./2.-1.);
iQ2[0] = 1;
for(G4int ii=1; ii<Nstep; ii++)
iQ2[ii] = ii<Nstep/2 ? iQ2[ii-1]+dQ2 : iQ2[ii-1]+2*dQ2;
return maxQ2;
}
// ========================================================
void G4ElasticHadrNucleusHE::
GetHadronNucleusData(G4DynamicParticle * aParticle,
G4Nucleus * aNucleus,
ElasticData & ElD)
{
ElD.Clean();
G4int nN = (G4int) aNucleus->GetN();
G4String hadrName =
aParticle->GetDefinition()->GetParticleName();
G4ParticleDefinition * PartDef = aParticle->GetDefinition();
G4int SizeData = SetOfElasticData.size();
G4int NumberOfRecord = 0;
if( SizeData!= 0)
{
for(G4int kk = 0; kk<SizeData; kk++)
{
if( SetOfElasticData[kk].nuclAtomicNumber == nN &&
SetOfElasticData[kk].hadrName == hadrName)
NumberOfRecord = kk;
}
}
if(NumberOfRecord > 0)
{
ElD = SetOfElasticData[NumberOfRecord-0];
}
else
{
G4int TestFile = ReadOfData(PartDef, aNucleus);
SizeData = SetOfElasticData.size();
NumberOfRecord = SizeData-1;
if(TestFile < 0)
{
G4cout<<" File for elastic scattering of hadron \""
<<hadrName<<"\""<<G4endl;
G4cout<<" on nucleus \""
<<nN<<"\" does not exist!"<<G4endl;
G4cout<<" You must prepare it by costructor: "<<G4endl;
G4cout<<
" G4ElasticHadrNucleusHE(G4DynamicParticle *, G4Nucleus *) "
<<G4endl;
return;
}
else ElD = SetOfElasticData[NumberOfRecord];
}
SizeData = SetOfElasticData.size();
}
// ++++++++++++++++++ ApplayYourself ++++++++++++++++++++
G4HadFinalState * G4ElasticHadrNucleusHE::ApplyYourself(
const G4HadProjectile &aHadron,
G4Nucleus &aNucleus)
{
iContr = 133;
if(iContr==137)
G4cout<<G4endl<<"----------- Begin Applay ------------"<<G4endl;
G4Nucleus * aNucl = &aNucleus;
// G4double hadrMass;
// G4String hadrName;
theParticleChange.Clear();
// --------------- Hadron Definition ---------------
G4ParticleDefinition * hadrDef =
const_cast<G4ParticleDefinition *>(aHadron.GetDefinition());
// hadrMass = hadrDef->GetPDGMass();
// hadrName = hadrDef->GetParticleName();
G4ThreeVector hadrMomentum = aHadron.Get4Momentum().vect();
G4DynamicParticle * aParticle = new G4DynamicParticle();
aParticle->SetDefinition(hadrDef);
aParticle->SetMomentum(hadrMomentum);
/*
G4double inLabMom = aHadron.GetTotalMomentum(); // MeV
G4double inEnHadr = aHadron.GetTotalEnergy(); // MeV
if(iContr==137)
G4cout<<" Hadr: Energy TotMom "<<inLabMom<<" "<<inEnHadr<<G4endl;
*/
// --------------- Nucleus Definition ---------------
G4double A = aNucl->GetN();
G4int nA = (G4int) A;
G4int nZ = (G4int) (aNucl->GetZ()+0.5);
G4ParticleDefinition * secNuclDef = 0;
if(nZ == 1 && nA == 1) {
secNuclDef = G4Proton::Proton();
} else {
if(G4UniformRand()<A-nA) nA++;
secNuclDef = G4ParticleTable::GetParticleTable()->FindIon(nZ,nA,0,nZ);
}
G4DynamicParticle * secNuclDyn = new G4DynamicParticle();
secNuclDyn->SetDefinition(secNuclDef);
// ----------------------------------------------------
// ----------------_ Randomization of Q2 as dSig/dt --------------
// if(iKindWork == 0) ranQ2 = RandomElastic0(aParticle, aNucl);
// else
G4double ranQ2;
if(nA>1)
{
ElasticData ElD;
GetHadronNucleusData(aParticle, aNucl, ElD);
ranQ2 = RandomElastic1(aParticle, & ElD);
}
else ranQ2 = HadronProtonQ2(aParticle);
// ---------------- Hadron kinematics ----------------
G4double m1=aParticle->GetDefinition()->GetPDGMass();
G4double m2 = secNuclDef->GetPDGMass();
G4LorentzVector lv1 = aParticle->Get4Momentum();
G4LorentzVector lv0(0.0,0.0,0.0,m2);
G4LorentzVector lv = lv0 + lv1;
G4ThreeVector bst = lv.boostVector();
lv1.boost(-bst);
lv0.boost(-bst);
G4ThreeVector p1 = lv1.vect();
G4double ptot = p1.mag();
// Sampling in CM system
G4double phi = G4UniformRand()*twopi;
G4double cost = 1. - 0.5*ranQ2/(ptot*ptot);
G4double sint = 0.0;
if(cost > 1.0) cost = 1.0;
else if(cost < -1.0) cost = -1.0;
else sint = std::sqrt((1.0-cost)*(1.0+cost));
// G4cout << "Entering elastic scattering 3"<<G4endl;
if (verboseLevel > 1)
G4cout << "cos(t)=" << cost << " sin(t)=" << sint << G4endl;
G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
p1 = p1.unit();
v1.rotateUz(p1);
v1 *= ptot;
G4LorentzVector nlv11(v1.x(),v1.y(),v1.z(),std::sqrt(ptot*ptot + m1*m1));
G4LorentzVector nlv01 = lv0 + lv1 - nlv11;
nlv01.boost(bst);
nlv11.boost(bst);
theParticleChange.SetMomentumChange(nlv11.vect().unit());
theParticleChange.SetEnergyChange(nlv11.e() - m1);
secNuclDyn->SetMomentum(nlv01.vect());
theParticleChange.AddSecondary(secNuclDyn);
delete aParticle;
//G4cout << " ion info "<<atno2 << " "<<A<<" "<<Z<<" "<<zTarget<<G4endl;
return &theParticleChange;
}
/*
G4double MassHadr = aParticle->GetMass(); // MeV
G4double MassNucl = aNucleus.GetN()*938.27; // MeV
G4double sqrMass = MassNucl*MassNucl+MassHadr*MassHadr;
// --------------- For final state of hadron ------------------
G4double invS = sqrMass+2*inEnHadr*MassNucl; // MeV^2
G4double invU = 2*sqrMass-invS+ranQ2; // MeV^2
G4double outEnHadr = (sqrMass-invU)/2/MassNucl; // MeV
G4double outMomHdr = std::sqrt(outEnHadr*outEnHadr- // MeV
MassHadr*MassHadr);
G4double cosHadr = (-ranQ2-2*MassHadr*MassHadr+
2*inEnHadr*outEnHadr)/2
/inLabMom/outMomHdr;
//---------------- For final state of nucleus -----------------
G4double outEnNucl = (2*MassNucl*MassNucl+ranQ2)/2/MassNucl;
G4double outMomNcl = std::sqrt(outEnNucl*outEnNucl- // MeV
MassNucl*MassNucl);
G4double cosNucl = (invU-sqrMass+2*inEnHadr*outEnNucl)
/2/inLabMom/outMomNcl;
G4double ranFi = 6.2832*G4UniformRand();
// ------ The transformation from Hadron frame to absolute one -------
G4double RotMatrix[3][3];
G4double NewMomHdrSys[3];
G4double NewMomOldSys[3];
G4double NucMomHdrSys[3];
G4double NucMomOldSys[3];
// ------------ The hadron angles in its own system ------------
G4double sinHadr = std::sqrt(1-cosHadr*cosHadr);
G4double sinFiHadr = std::sin(ranFi);
G4double cosFiHadr = std::cos(ranFi);
// ---- The unit vector of a hadron momentum in its own system ---
NewMomHdrSys[0] = sinHadr*cosFiHadr;
NewMomHdrSys[1] = sinHadr*sinFiHadr;
NewMomHdrSys[2] = cosHadr;
G4double sinNucl = std::sqrt(1-cosNucl*cosNucl);
// ----------- The unit vector of a nucleus momentum -----------
NucMomHdrSys[0] = -sinNucl*cosFiHadr;
NucMomHdrSys[1] = -sinNucl*sinFiHadr;
NucMomHdrSys[2] = cosNucl;
// __________ The angles of unit vector in absolute system ----------
G4double cosTet = aParticle->GetMomentumDirection().z();
G4double sinTet;
G4double sinFi;
G4double cosFi;
if(cosTet>0.99999 || cosTet<-0.99999)
{
sinTet = 0;
sinFi = 0;
cosFi = 1;
}
else
{
sinTet = std::sqrt(1-cosTet*cosTet);
sinFi = aParticle->GetMomentumDirection().y()/sinTet;
cosFi = aParticle->GetMomentumDirection().x()/sinTet;
}
// ----------------- The rotation matrix ---------------
RotMatrix[0][0] = cosFi*cosTet;
RotMatrix[0][1] = sinFi;
RotMatrix[0][2] = -cosFi*sinTet;
RotMatrix[1][0] = -sinFi*cosTet;
RotMatrix[1][1] = cosFi;
RotMatrix[1][2] = sinFi*sinTet;
RotMatrix[2][0] = sinTet;
RotMatrix[2][1] = 0;
RotMatrix[2][2] = cosTet;
// -------------- Rotation of momenta ----------------
for(G4int ii=0; ii<3; ii++)
{
NewMomOldSys[ii] = 0;
NucMomOldSys[ii] = 0;
for(G4int ll=0; ll<3; ll++)
{
// -------------- Rotation of Hadron ------------------
NewMomOldSys[ii] = NewMomOldSys[ii]+
RotMatrix[ii][ll]*NewMomHdrSys[ll];
// -------------- Rotation of Nucleus ------------------
NucMomOldSys[ii] = NucMomOldSys[ii]+
RotMatrix[ii][ll]*NucMomHdrSys[ll];
}
}
// -------------- The Nucleus Momentum -------------
G4ThreeVector aNuclMom( NucMomOldSys[0]*outMomNcl,
NucMomOldSys[1]*outMomNcl,
NucMomOldSys[2]*outMomNcl);
secNuclDyn->SetMomentum(aNuclMom);
// -------------- The Direction of Hadron Momentum ---------------
G4double pxnew = NewMomOldSys[0]; // In MeV
G4double pynew = NewMomOldSys[1]; // Mev
G4double pznew = NewMomOldSys[2]; // Mev
/// ---------------------------------------------
/// if(iKindWork>0)
/// theParticleChange.AddSecondary( &secNuclTrack);
// ---------------------------------------------
G4int NumbPart;
NumbPart = theParticleChange.GetNumberOfSecondaries();
if(iKindWork>0) theParticleChange.AddSecondary(secNuclDyn);
theParticleChange.SetEnergyChange(outEnHadr);
theParticleChange.SetMomentumChange(pxnew, pynew, pznew);
NumbPart = theParticleChange.GetNumberOfSecondaries();
// ----------------------------------------------------
return &theParticleChange;
}
*/
// ==========================================================
G4double G4ElasticHadrNucleusHE::HadronNucleusQ2(
G4DynamicParticle * aHadron,
G4Nucleus & aNucleus)
{
G4int nN;
G4double ranQ2;
ElasticData ElD;
nN = (G4int) aNucleus.GetN();
if(nN<2) ranQ2 = HadronProtonQ2(aHadron);
else
{
GetHadronNucleusData(aHadron, & aNucleus, ElD);
ranQ2 = RandomElastic1(aHadron, & ElD);
}
return ranQ2;
}
// +++++++ The randomization of one dimensional array ++++++
G4double G4ElasticHadrNucleusHE::RandomElastic0()
{
G4double ranQ2;
G4double ranUni = G4UniformRand();
G4int kk = 0;
while( ranUni > iIntgr[kk]) kk ++;
if(kk == 1 ) kk = 2;
G4double F1 = iIntgr[kk-2];
G4double F2 = iIntgr[kk-1];
G4double F3 = iIntgr[kk];
G4double F12 = F1*F1;
G4double F22 = F2*F2;
G4double F32 = F3*F3;
G4double X1 = iQ2[kk-2]; // MeV^2
G4double X2 = iQ2[kk-1];
G4double X3 = iQ2[kk];
G4double D0 = F12*F2+F1*F32+F3*F22-F32*F2-F22*F1-F12*F3;
if(D0 == 0)
ranQ2 = (iQ2[kk-1]+(ranUni-iIntgr[kk-1])*
(iQ2[kk]-iQ2[kk-1])
/(iIntgr[kk]-iIntgr[kk-1]));
else
{
G4double DA = X1*F2+X3*F1+X2*F3-X3*F2-X1*F3-X2*F1;
G4double DB = X2*F12+X1*F32+X3*F22-X2*F32-X3*F12-X1*F22;
G4double DC = X3*F2*F12+X2*F1*F32+X1*F3*F22
-X1*F2*F32-X2*F3*F12-X3*F1*F22;
ranQ2 = (DA*ranUni*ranUni+DB*ranUni+DC)/D0;
}
return ranQ2; // MeV^2
}
// +++++++++ The randomization of two dimensoinal array ++++++++
G4double G4ElasticHadrNucleusHE::RandomElastic1(
const G4DynamicParticle * aHadron,
const ElasticData * ElD)
{
G4double forQ2[3];
G4double curE = aHadron->GetTotalEnergy(); // in MeV
G4double X1;
G4double X2;
G4double X3;
G4double Y1;
G4double Y2;
G4double Y3;
G4int iiE = 0;
G4int k[3];
while(curE > ElD->TableE[iiE] ) iiE++;
G4double ranQ2;
G4double ranUni = G4UniformRand();
G4int kk;
for(G4int mm=0; mm<3; mm++)
{
kk = 0;
while( ranUni >
ElD->TableCrossSec[iiE*ONQ2+mm*ONQ2+kk-ONQ2])
{
kk ++;
k[mm]=kk;
} // while
// if(kk == 1 ) kk = 2;
X1 = ElD->TableCrossSec[iiE*ONQ2+mm*ONQ2+kk-ONQ2-1];
X2 = ElD->TableCrossSec[iiE*ONQ2+mm*ONQ2+kk-ONQ2];
X3 = ElD->TableCrossSec[iiE*ONQ2+mm*ONQ2+kk-ONQ2+1];
Y1 = ElD->TableQ2[kk-1]; // MeV^2
Y2 = ElD->TableQ2[kk];
Y3 = ElD->TableQ2[kk+1];
forQ2[mm] = InterPol(X1, X2, X3, Y1, Y2, Y3, ranUni);
} // mm
X1 = ElD->TableE[iiE-1];
X2 = ElD->TableE[iiE];
X3 = ElD->TableE[iiE+1];
Y1 = forQ2[0]; // MeV^2
Y2 = forQ2[1];
Y3 = forQ2[2];
ranQ2 = InterPol(X1, X2, X3, Y1, Y2, Y3, curE);
return ranQ2; // MeV^2
}
// ++++++++++++ The filling of the one-dimensional array +++++++++++++
void G4ElasticHadrNucleusHE::CreationArray(
const G4DynamicParticle * aHadron,
G4Nucleus * aNucleus)
{
GetNucleusParameters(aNucleus);
Nstep = ONQ2;
maxQ2 = GetQ2limit(R1); // Mev^2
if(aNucleus->GetN() > MaxN )
ArrayForHeavy( aHadron, aNucleus);
else
ArrayForLight( aHadron, aNucleus);
}
// +++++++++++++ The method for heavy nucleus ++++++++++++++++
void G4ElasticHadrNucleusHE::ArrayForHeavy(
const G4DynamicParticle * aHadron,
G4Nucleus * aNucleus)
{
GetNucleusParameters(aNucleus);
////// G4double aNuc = aNucleus->GetN();
G4double intgrS=0., intgStep;
G4int ii, Kind=0;
iIntgr[0] = 0;
for( ii=0; ii<Nstep-1; ii++)
{
// ---------------- The integration -------------
G4double curQ2 = iQ2[ii]; // MeV^2
G4double ddQ2 =(iQ2[ii+1]-curQ2)/20; // MeV^2
G4double curSum = 0;
G4double curSec = 0;
G4double aSimp = 1;
for(G4int ll=0; ll<20; ll++)
{
// curSec = aDiffElHadNcls.
// HadrNuclDifferCrSec(aHadron, aNucleus, curQ2);
curSec = aDiffElHadNcls.
HadrNuclDifferCrSecT(aHadron, aNucleus,
curQ2, Kind);
curQ2 = curQ2 + ddQ2;
curSum = curSum + curSec*aSimp;
if(aSimp > 3 ) aSimp = 2;
else aSimp = 4;
if(ll == 0) aSimp = 4;
Kind = 1;
} // ll
intgStep = curSum*ddQ2/3;
// --------------------------------------------------------------------
iIntgr[ii+1] = iIntgr[ii]+intgStep;
intgrS = intgrS + intgStep;
} // ii
// ------------------- The normalization ----------------
for( ii=0; ii<Nstep; ii++)
iIntgr[ii] = iIntgr[ii]/iIntgr[Nstep-1];
} // end subroutine
// +++++++++++++++++ The method for light nucleus +++++++++++++++++++
void G4ElasticHadrNucleusHE::ArrayForLight(
const G4DynamicParticle * aHadron,
G4Nucleus * aNucleus)
{
// -------------- !!! Here the main unit is GeV !!! ---------------
G4HadronValues::GetHadronValues(aHadron);
G4double aNuc = aNucleus->GetN();
G4int Nucleus = (G4int) aNuc;
GetNucleusParameters(aNucleus);
maxQ2 = GetQ2limit(R1)/1000/1000; // GeV^2
// ---------------- The preparing of probability function ------------
G4double MbToB = 2.568; // from mb to GeV^-2
G4double Pi1 = 3.1416;
G4double Stot = HadrTot*MbToB; // Gev^-2
G4double Bhad = HadrSlope; // GeV^-2
G4double Asq = 1+HadrReIm*HadrReIm;
G4double Rho2 = std::sqrt(Asq);
G4double R12 = R1*R1;
G4double R22 = R2*R2;
G4double R12B = R12+2*Bhad;
G4double R22B = R22+2*Bhad;
/// G4double R12Bp = R12+20;
/// G4double R22Bp = R22+20;
/// G4double R13Bp = R12*R1/R12Bp;
/// G4double R23Bp = R22*R2/R22Bp;
/// G4double R12Ap = R12+20;
/// G4double R22Ap = R22+20;
/// G4double R13Ap = R12*R1/R12Ap;
/// G4double R23Ap = R22*R2/R22Ap*PnuclP;
/// G4double R23dR13 = R23Ap/R13Ap;
/// G4double R12Apd = 2/R12Ap;
/// G4double R22Apd = 2/R22Ap;
G4double Norm = R12*R1-Pnucl*R22*R2;
/// G4double NormP = R12*R1-PnuclP*R22*R2;
G4double R13 = R12*R1/R12B;
G4double R23 = Pnucl*R22*R2/R22B;
G4double Unucl = Stot/2/Pi1/Norm*R13;
//// G4double Unclprod = Stot/2/Pi1/NormP*R13Ap;
G4double FiH = std::asin(HadrReIm/Rho2);
G4double NN2 = R23/R13;
/// G4double DDSec1p = (DDSect2+
/// DDSect3*std::log(1.06*2*Ehad/R1/4));
/// G4double DDSec2p = (DDSect2+
/// DDSect3*std::log(1.06*2*Ehad/
// std::sqrt((R12+R22)/2)/4));
/// G4double DDSec3p = (DDSect2+
/// DDSect3*std::log(1.06*2*Ehad/R2/4));
/// G4double R12ApdR22Ap = 0.5*(R12Apd+R22Apd);
iIntgr[0] = 0;
G4int ii;
for(ii=0; ii<Nstep-1; ii++)
{
G4double Q2 = iQ2[ii+1]/1000/1000;// internal in GeV^2
G4double Prod0 = 0;
G4double N1 = -1;
G4double Tot0 = 0;
G4double exp1;
for(G4int i1 = 1; i1<= Nucleus; i1++) ////++++++++++ i1
{
N1 = -N1*Unucl*(Nucleus-i1+1)/i1*Rho2;
G4double Prod1 = 0;
Tot0 = 0;
G4double N2 = -1;
for(G4int i2 = 1; i2<=Nucleus; i2++) ////+++++++++ i2
{
N2 = -N2*Unucl*(Nucleus-i2+1)/i2*Rho2;
G4double Prod2 = 0; //std::exp(-Q2/i2*R12B/4)/i2*R12B;
G4double N5 = -1/NN2;
for(G4int m2=0; m2<= i2; m2++) ////+++++++++ m2
{
G4double Prod3 = 0;
G4double exp2 = m2/R22B+(i2-m2)/R12B;
N5 = -N5*NN2;
G4double N4 = -1/NN2;
for(G4int m1=0; m1<=i1; m1++) ////++++++++ m1
{
exp1 = m1/R22B+(i1-m1)/R12B;
N4 = -N4*NN2;
Prod3 = Prod3+N4/exp1/exp2*
(1-std::exp(-Q2*(1/exp1+1/exp2)/4))/
(1/exp1+1/exp2)*4*
Factorials1[i1]/
Factorials1[m1]/
Factorials1[i1-m1];
} // m1
Prod2 = Prod2 +Prod3*N5*
Factorials1[i2]/
Factorials1[m2]/
Factorials1[i2-m2];
} // m2
Prod1 = Prod1 + Prod2*N2*std::cos(FiH*(i1-i2));
Tot0 = Tot0 + Prod2*N2*std::sin(FiH*(i1-i2));
if (std::abs(Prod2*N2/Prod1)<1e-6) break;
} // i2
// ImDistr = Tot0 + Tot0*N1;
Prod0 = Prod0 + Prod1*N1;
if(std::abs(N1*Prod1/Prod0) < 1e-6) break;
} // i1
Prod0 = Prod0*Pi1/2.568/4; // This is in mb
iIntgr[ii+1] = Prod0; //iIntgr[ii-1]+Prod0;
} // ii (Q2)
for(ii = 0; ii<Nstep; ii++)
iIntgr[ii]=iIntgr[ii]/iIntgr[Nstep-1];
} // subroutine
// ++++++++++++++++++++ The interpolation +++++++++++++++++++++
G4double G4ElasticHadrNucleusHE::InterPol(
G4double X1, G4double X2, G4double X3,
G4double Y1, G4double Y2, G4double Y3,
G4double X)
{
G4double ranQ2;
G4double F12 = X1*X1;
G4double F22 = X2*X2;
G4double F32 = X3*X3;
G4double D0 = F12*X2+X1*F32+X3*F22-F32*X2-F22*X1-F12*X3;
if(std::abs(D0) < 1e-8 || D0 == 0)
ranQ2 = (Y2+(X-X2)*(Y3-Y2) /(X3-X2)); // MeV^2
else
{
G4double DA = Y1*X2 +Y3*X1 +Y2*X3 -Y3*X2 -Y1*X3 -Y2*X1;
G4double DB = Y2*F12 +Y1*F32 +Y3*F22-Y2*F32-Y3*F12-Y1*F22;
G4double DC = Y3*X2*F12+Y2*X1*F32+Y1*X3*F22
-Y1*X2*F32-Y2*X3*F12-Y3*X1*F22;
ranQ2 = (DA*X*X+DB*X+DC)/D0; // MeV^2
}
return ranQ2;
}
// ============================================================
G4float G4ElasticHadrNucleusHE::GetFt(G4double Q2)
{
G4float Fdistr, SqrQ2 = std::sqrt(Q2);
Fdistr = (1-Coeff1-Coeff0/*-0.0*Coeff2*std::exp(ConstU)*/)
/Slope*(1-std::exp(-Slope*Q2))
+Coeff0*(1-std::exp(-Slope0*Q2))
+Coeff2/Slope2*std::exp(Slope2*ConstU)*
(std::exp(Slope2*Q2)-1)
+2*Coeff1/Slope1*(1/Slope1-(1/Slope1+SqrQ2)*
std::exp(-Slope1*SqrQ2))
;
return Fdistr;
}
// +++++++++++++++++++++++++++++++++++++++
G4float G4ElasticHadrNucleusHE::GetDistrFun(G4double Q2)
{
G4float Fq2;
Fq2 = GetFt(Q2);
return Fq2/FmaxT;
}
// +++++++++++++++++++++++++++++++++++++++
G4double G4ElasticHadrNucleusHE::
GetQ2(G4double Ran)
{
G4double DDD0=MaxTR*0.5, DDD1=0.0, DDD2=MaxTR, delta;
G4double Q2;
FmaxT = GetFt(MaxTR);
delta = GetDistrFun(DDD0)-Ran;
while(std::abs(delta) > 0.0001)
{
if(delta>0)
{
DDD2 = DDD0;
DDD0 = (DDD0+DDD1)*0.5;
}
else if(delta<0)
{
DDD1 = DDD0;
DDD0 = (DDD0+DDD2)*0.5;
}
delta = GetDistrFun(DDD0)-Ran;
}
Q2 = DDD0;
return Q2;
}
// ++++++++++++++++++++++++++++++++++++++++++
G4double G4ElasticHadrNucleusHE::HadronProtonQ2(
G4DynamicParticle * aHadron)
{
G4double Ran = G4UniformRand(), Q2;
GetKinematics(aHadron);
// G4cout<<" HRQ2HE Ran "<<Ran<<G4endl;
Q2 = GetQ2(Ran);
return Q2*1000*1000;
}
// ===========================================
/* End of file */