254 lines
7.3 KiB
C++
254 lines
7.3 KiB
C++
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
// LOW ENERGY MUON SPIN RELAXATION, ROTATION, RADIATION
|
|
//
|
|
// ID : LEMuSRAtRestSpinRotation.cc , v 1.3
|
|
// AUTHOR: Taofiq PARAISO
|
|
// DATE : 2006-01-19 16:15
|
|
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
//
|
|
// & &&&&&&&&&& &&&&&&& &&&&&&&&
|
|
// & & && && & &&
|
|
// & & & & & & &&
|
|
// & &&&&&&& & & &&&&&& &&&&&&&&
|
|
// & & & && & & &&
|
|
// & & && & & && && & &
|
|
// &&&&&&&&&& &&&&&&&&&& & &&&&& && &&&&&&& & &&
|
|
// &
|
|
// &
|
|
// &
|
|
// &
|
|
// AT REST SPIN ROTATION
|
|
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
|
|
|
|
#include "LEMuSRAtRestSpinRotation.hh"
|
|
|
|
#include "G4ThreeVector.hh"
|
|
#include "G4MagneticField.hh"
|
|
#include "G4Track.hh"
|
|
#include "G4FieldManager.hh"
|
|
#include <iomanip>
|
|
#include "globals.hh"
|
|
#include "G4ParticleChange.hh"
|
|
#include "G4ios.hh"
|
|
#include "G4Transform3D.hh"
|
|
#include "G4UnitsTable.hh"
|
|
|
|
#include "G4ParticleTable.hh"
|
|
#include "G4ParticleDefinition.hh"
|
|
|
|
#include "G4ProcessVector.hh"
|
|
#include "G4ProcessManager.hh"
|
|
|
|
|
|
LEMuSRAtRestSpinRotation::LEMuSRAtRestSpinRotation(const G4String& processName)
|
|
: G4VRestProcess (processName)
|
|
{
|
|
G4cout << GetProcessName() << " is created "<< G4endl;
|
|
pointer = this;
|
|
}
|
|
|
|
|
|
LEMuSRAtRestSpinRotation::~LEMuSRAtRestSpinRotation()
|
|
{;}
|
|
|
|
|
|
LEMuSRAtRestSpinRotation* LEMuSRAtRestSpinRotation::pointer=0;
|
|
LEMuSRAtRestSpinRotation* LEMuSRAtRestSpinRotation::GetInstance()
|
|
{
|
|
return pointer;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//$$$$$$$$$$$$$$$$$$$$$$$$$$ AT REST DO IT $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
|
|
/*!
|
|
* This method contains the list of modifications to do when the particle come to rest state. It is the implementation of a virtual method of G4VProcess. Therefore, it's name should not be changed.
|
|
*
|
|
* The procedure is the following:
|
|
* -# Initialize the particle change object according to the particle's properties taken from the track object.
|
|
* -# Propose a status for the track, a position, momentum, energy, and time change.
|
|
* -# Check is the volume where the particle is at rest contains a magnetic field
|
|
* -# If there is a magnetic field, get the B vector and call the RotateSpin method to rotate the spin.
|
|
* -# Propose a spin change
|
|
* -# Return the particle change object.
|
|
* .
|
|
* Then the AtRestUpdateStep method is called cf LEMuSRParticleChangeForSR.
|
|
*/
|
|
G4VParticleChange* LEMuSRAtRestSpinRotation::AtRestDoIt(const G4Track& theTrack, const G4Step& aStep)
|
|
{
|
|
|
|
theParticleChange.Initialize(theTrack);
|
|
theParticleChange.ProposeTrackStatus(fAlive);
|
|
theParticleChange.ProposePosition(theTrack.GetPosition());
|
|
theParticleChange.ProposeMomentumDirection(theTrack.GetMomentumDirection());
|
|
theParticleChange.ProposeEnergy(theTrack.GetKineticEnergy());
|
|
|
|
// Get Time
|
|
itime = theTrack.GetProperTime();
|
|
G4double gtime = theTrack.GetGlobalTime();
|
|
ftime = theTrack.GetDynamicParticle()->GetPreAssignedDecayProperTime();
|
|
|
|
|
|
|
|
deltatime = ftime - itime;
|
|
theParticleChange.ProposeGlobalTime(deltatime + itime -gtime);
|
|
theParticleChange.ProposeProperTime(deltatime);
|
|
|
|
polar = aStep.GetTrack()->GetPolarization();
|
|
|
|
|
|
if(aStep.GetTrack()->GetVolume()->GetLogicalVolume()->GetFieldManager())
|
|
{
|
|
|
|
|
|
G4FieldManager *fMgr = theTrack.GetVolume()->GetLogicalVolume()->GetFieldManager();
|
|
|
|
|
|
// if(!fMgr->DoesFieldChangeEnergy())//then we have a magnetic field
|
|
if(fMgr->FieldHasMagComponent())//then we have a magnetic field
|
|
{
|
|
|
|
#ifdef G4SRVERBOSE
|
|
G4cout<<"AT REST::: MAGNETIC FIELD HERE" <<G4endl;
|
|
#endif
|
|
|
|
// Get B Field vector
|
|
point[0]=theTrack.GetPosition().x();
|
|
point[1]=theTrack.GetPosition().y();
|
|
point[2]=theTrack.GetPosition().z();
|
|
|
|
mfield = fMgr->GetDetectorField();
|
|
|
|
mfield->GetFieldValue(point,B);
|
|
|
|
#ifdef G4SRVERBOSE
|
|
G4cout <<"AT REST::: MAGNETIC FIELD B="<< B[0] <<" " << B[1] <<" " << B[2] <<G4endl;
|
|
|
|
#endif
|
|
|
|
#ifdef G4SRVERBOSE
|
|
G4cout <<"AT REST::: TIME= proper: "<< itime <<" ; global: " << gtime <<" decay: " << ftime <<G4endl;
|
|
#endif
|
|
|
|
|
|
G4ThreeVector magField(B[0],B[1],B[2]);
|
|
RotateSpin(aStep,magField,deltatime);
|
|
|
|
|
|
#ifdef G4SRVERBOSE
|
|
G4cout<<"AT REST::: spin rotated";
|
|
#endif
|
|
|
|
}
|
|
|
|
theParticleChange.ProposePolarization(polar);
|
|
|
|
|
|
|
|
#ifdef G4SRVERBOSE
|
|
theParticleChange.DumpInfo();
|
|
#endif
|
|
|
|
|
|
return &theParticleChange;
|
|
|
|
// then the AtRestUpdateStep method is called cf LEMuSRParticleChangeForSpinRotation (SR)
|
|
|
|
}
|
|
|
|
else
|
|
{
|
|
// G4cout <<"No MAGNETIC FIELD do not call AtRestPrecession :: RotateSpin!!! ";
|
|
return &theParticleChange;
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//$$$$$$$$$$$$$$$$$$$$$$$$$$ ROTATE SPIN $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
|
|
|
|
/*!
|
|
* This method rotates the spin of the particle according to the field value.It also takes the gyromagnetic parameters from the particle definition. It will make the spin precess until the particle decays. The gyromagnetic factor is taken from the particle definition.
|
|
*/
|
|
void LEMuSRAtRestSpinRotation::RotateSpin( const G4Step& aStep, G4ThreeVector B, G4double deltatime )
|
|
{
|
|
|
|
|
|
G4Transform3D Spin_rotation;
|
|
|
|
G4double Bnorm = sqrt(sqr(B[0]) + sqr(B[1]) +sqr(B[2]) );
|
|
|
|
#ifdef G4SRVERBOSE
|
|
G4cout<< "AT REST::: PARAMETERS\n"
|
|
<< "Magnetic Field Norm : " << G4BestUnit(Bnorm,"Magnetic flux density") <<"\n";
|
|
#endif
|
|
|
|
G4double omega,q,a,fqz;
|
|
G4double gamma;
|
|
q= aStep.GetTrack()->GetDefinition()->GetPDGCharge();
|
|
a= 1.165922e-3;
|
|
fqz = 8.5062e+7*rad/(s*kilogauss);
|
|
|
|
gamma = aStep.GetTrack()->GetDefinition()->GetGyromagneticRatio()*rad;
|
|
|
|
// G4cout<< fqz*(s*tesla)<<G4endl;
|
|
// G4cout<< gamma*(s*tesla)<<G4endl;
|
|
|
|
|
|
|
|
#ifdef G4SRVERBOSE
|
|
G4cout<< "AT REST::: PARAMETERS\n"
|
|
<< "Charge : " << q <<"\n";
|
|
#endif
|
|
|
|
// omega= - (fqz)*(1.+a) * Bnorm;
|
|
omega= - (gamma) * Bnorm;
|
|
|
|
#ifdef G4SRVERBOSE
|
|
G4cout<< "AT REST::: PARAMETERS\n"
|
|
<< "Frequency: " << G4BestUnit(fqz*gauss/(2*M_PI*rad),"Frequency") <<"\n";
|
|
G4cout<< "AT REST::: PARAMETERS\n"
|
|
<< "FrequencyG: " << G4BestUnit(gamma*gauss/(2*M_PI*rad),"Frequency") <<"\n";
|
|
#endif
|
|
|
|
|
|
rotation_angle = deltatime*omega;
|
|
|
|
|
|
Spin_rotation= G4Rotate3D(rotation_angle,B/Bnorm);
|
|
|
|
HepVector3D spin = aStep.GetTrack()->GetPolarization();
|
|
HepVector3D newspin;
|
|
newspin = Spin_rotation*spin;
|
|
|
|
G4double x,y,z,alpha;
|
|
x = sqrt(spin*spin);
|
|
y = sqrt(newspin*newspin);
|
|
z = spin*newspin/x/y;
|
|
alpha = acos(z);
|
|
|
|
#ifdef G4SRVERBOSE
|
|
G4cout<< "AT REST::: PARAMETERS\n"
|
|
<< "Initial spin : " << spin <<"\n"
|
|
<< "Delta time : " << deltatime <<"\n"
|
|
<< "Rotation angle: " << rotation_angle/(M_PI*rad) <<"\n"
|
|
<< "New spin : " << newspin <<"\n"
|
|
<< "Checked norms : " << x <<" " <<y <<" \n"
|
|
<< G4endl;
|
|
#endif
|
|
|
|
polar = newspin;
|
|
|
|
}
|