00001
00002
00003
00005 #include "Swimmer/SwimDefStepper.h"
00006 #include "Swimmer/SwimParticle.h"
00007 #include "Swimmer/SwimStepData.h"
00008 #include "BField/BField.h"
00009 #include "Conventions/Munits.h"
00010 #include "Conventions/Mphysical.h"
00011 #include <iostream>
00012 #include "TMath.h"
00013 #include "MessageService/MsgService.h"
00014
00015 CVSID("$Id: SwimDefStepper.cxx,v 1.20 2008/02/20 11:40:34 bckhouse Exp $");
00016
00017
00018
00019 SwimDefStepper::SwimDefStepper(BField* f) : fBfield(f)
00020 {
00021 this->SetUpIntegrator();
00022 }
00023
00024
00025
00026 SwimDefStepper::SwimDefStepper(BField* f, double min, double acc) :
00027 fMinStepSize(min),
00028 fAcc(acc),
00029 fBfield(f)
00030 {
00031 this->SetUpIntegrator();
00032 }
00033
00034
00035
00036 void SwimDefStepper::SetUpIntegrator()
00037 {
00038
00039
00040
00041 double s[6] = {1.0,1.0,1.0,
00042 1.0,1.0,1.0};
00043
00044 fIntegrator.SetNvar(6);
00045 fIntegrator.SetScales(s);
00046 fIntegrator.SetAccuracy(fAcc);
00047 fIntegrator.SetMinStepSize(fMinStepSize);
00048 fIntegrator.SetDerivFunc(fDerivFunc);
00049 }
00050
00051
00052
00053 bool SwimDefStepper::StepOnce(SwimParticle& particle,
00054 SwimStepData* stepData)
00055 {
00056
00057 fX[0] = particle.GetPosition().X();
00058 fX[1] = particle.GetPosition().Y();
00059 fX[2] = particle.GetPosition().Z();
00060 fX[3] = particle.GetMomentum().X();
00061 fX[4] = particle.GetMomentum().Y();
00062 fX[5] = particle.GetMomentum().Z();
00063 double stepSize = stepData->GetStepSize();
00064
00065 double density = SwimGeo::GetSwimMaterialDensity(stepData->GetSwimMaterial());
00066 TVector3 startpos, path, startmom, deltamom;
00067 startpos = particle.GetPosition();
00068 startmom = particle.GetMomentum();
00069
00070 fDerivFunc.SetChargeBField(particle.GetCharge(),fBfield);
00071
00072
00073
00074
00075
00076 fIntegrator.SetInitialCondition(fX);
00077 fIntegrator.SetStartPoint(0.0);
00078 if (stepData->GetIsForward())
00079 fIntegrator.SetEndPoint(stepSize);
00080 else
00081 fIntegrator.SetEndPoint(-stepSize);
00082
00083
00084 if(stepSize > 0){
00085 fIntegrator.SetStepSize(stepSize);
00086 }
00087 else{
00088 MSG("Swim", Msg::kError) << "Unexpected stepSize of " << stepSize << " bailing...\n";
00089 return false;
00090 }
00091
00092 bool aok = fIntegrator.Integrate(fX);
00093
00094
00095 TVector3 position;
00096 TVector3 momentum;
00097 double pModulus2 = fX[3]*fX[3]+fX[4]*fX[4]+fX[5]*fX[5];
00098 position.SetXYZ(fX[0],fX[1],fX[2]);
00099 particle.SetPosition(position);
00100 if (pModulus2!=0.0)
00101 momentum.SetXYZ(fX[3],fX[4],fX[5]);
00102 else
00103 momentum.SetXYZ(0.0,0.0,0.0);
00104 particle.SetMomentum(momentum);
00105
00106
00107 path = particle.GetPosition();
00108
00109 double endz =path[2];
00110 deltamom = particle.GetMomentum();
00111 path -= startpos;
00112 deltamom -= startmom;
00113 particle.AddS(path.Mag());
00114 particle.AddRange(density*path.Mag()/(Munits::g/Munits::cm2));
00115
00116 MSG("Swim",Msg::kDebug) << " start/end z " << startpos[2] << "/" << endz << " density " << density/1000. << " dzds " << fabs(path[2]/path.Mag()) << " dRange " << density*path.Mag() << endl;
00117
00118 particle.AddVxB(deltamom.Mag());
00119
00120 return aok;
00121 }
00122
00123
00124
00125 SwimDefStepper::DerivFunc::DerivFunc(double q, BField* b)
00126 {
00127
00128 this->SetChargeBField(q,b);
00129 }
00130
00131
00132
00133 void SwimDefStepper::DerivFunc::SetChargeBField(double q, BField* b)
00134 {
00135
00136 static const double unitsC =
00137 (Mphysical::c_light/(Munits::m/Munits::s))/1.0e9;
00138 fForceCoef = unitsC*q;
00139 fBfield = b;
00140 }
00141
00142
00143
00144 void SwimDefStepper::DerivFunc::operator()(double ,
00145 const double* y,
00146 double* dydx)
00147 {
00148
00149
00150
00151
00152
00153
00154
00155 double ptotSqr = y[3]*y[3]+y[4]*y[4]+y[5]*y[5];
00156 if (ptotSqr != 0.0) {
00157 double oneOverPtot = 1.0/TMath::Sqrt(ptotSqr);
00158 dydx[0] = y[3]*oneOverPtot;
00159 dydx[1] = y[4]*oneOverPtot;
00160 dydx[2] = y[5]*oneOverPtot;
00161
00162
00163
00164 TVector3 xyz(y[0],y[1],y[2]);
00165
00166
00167 TVector3 B = fBfield->GetBField(xyz);
00168
00169
00170 double qOverE = fForceCoef*oneOverPtot;
00171 dydx[3] = (y[4]*B[2]-y[5]*B[1])*qOverE;
00172 dydx[4] = (y[5]*B[0]-y[3]*B[2])*qOverE;
00173 dydx[5] = (y[3]*B[1]-y[4]*B[0])*qOverE;
00174 }
00175 else {
00176
00177 dydx[0] = 0.0;
00178 dydx[1] = 0.0;
00179 dydx[2] = 0.0;
00180 dydx[3] = 0.0;
00181 dydx[4] = 0.0;
00182 dydx[5] = 0.0;
00183 }
00184 }
00185