Public Member Functions | Private Member Functions | Private Attributes | List of all members
LBNFMagneticFieldPolyconeHorn Class Reference

#include <LBNFMagneticFieldPolyconeHorn.hh>

Inheritance diagram for LBNFMagneticFieldPolyconeHorn:

Public Member Functions

 LBNFMagneticFieldPolyconeHorn (size_t iH)
 
 ~LBNFMagneticFieldPolyconeHorn ()
 
virtual void GetFieldValue (const double Point[3], double *Bfield) const
 
void SetHornCurrent (G4double ihorn)
 
G4double GetHornCurrent () const
 
void SetSkinDepthInnerRad (G4double f)
 
void SetZShiftDrawingCoordinate (double z)
 
void SetEffectiveLength (double z)
 
void SetDeltaEccentricityIO (G4double f)
 
void SetDeltaEllipticityI (G4double f)
 
double GetEffectiveInnerRad () const
 
double GetEffectiveOuterRad () const
 
double GetEffectiveSkinDepthFact () const
 
void SetCurrentEqualizerLongAbsLength (double v)
 
void SetCurrentEqualizerQuadAmpl (double v)
 
void SetCurrentEqualizerOctAmpl (double v)
 
void SetFileNameFieldMapForCE (std::string s)
 
double GetCurrentEqualizerQuadAmpl () const
 
std::string GetFileNameFieldMapForCE () const
 
void dumpField () const
 
void TestDivergence (int opt) const
 
void TestEccentricityBerkeley () const
 
void writeFieldMapCurrentEqualizer () const
 
void readFieldMapCurrentEqualizer () const
 

Private Member Functions

void getFieldFrom3DMapCurrentEqualizer (const double Point[3], double *Bfield) const
 
void fill3DMapCurrentEqualizer () const
 
void fillHornPolygonRadii (double z, double *rIn, double *rOut) const
 
void fillTrajectories (const double Point[3], double bx, double by) const
 
double getNormCurrDensityInnerC (double deltaR, double rOut) const
 

Private Attributes

size_t hornNumber
 
G4double fHornCurrent
 
std::vector< double > fZDCBegin
 
std::vector< double > fRadsInnerC
 
std::vector< double > fRadsOuterC
 
bool fHornIsMisaligned
 
G4RotationMatrix fRotMatrixHornContainer
 
double fEffectiveLength
 
double fOuterRadius
 
double fOuterRadiusEff
 
G4double fSkinDepth
 
G4double fSkinDepthInnerRad
 
G4double fSkinDepthIIRInv
 
double fDeltaEccentricityIO
 
double fDeltaEllipticityI
 
double fCurrentEqualizerLongAbsLength
 
double fCurrentEqualizerQuadAmpl
 
double fCurrentEqualizerOctAmpl
 
std::ofstream fOutTraj
 
bool fDebugIsOn
 
double fEffectiveInnerRad
 
double fEffectiveOuterRad
 
double fEffectiveSkinDepthFact
 
std::vector< double > fShift
 
std::vector< double > fShiftSlope
 
G4double fZShiftDrawingCoordinate
 
std::string fFileNameFieldMapForCE
 
unsigned int fNumZPtsForCE
 
unsigned int fNumRPtsForCE
 
unsigned int fNumPhiPtsForCE
 
double fField3DMapCurrentEqualizerZMin
 
double fField3DMapCurrentEqualizerZStep
 
double fField3DMapCurrentEqualizerPhiStep
 
std::map< unsigned int, std::pair< float, float > > fField3DMapCurrentEqualizer
 
std::vector< double > fField3DMapCurrentEqualizerRadSqAtZ
 
std::vector< double > fField3DMapCurrentEqualizerRadSqRStepAtZ
 

Detailed Description

Definition at line 17 of file LBNFMagneticFieldPolyconeHorn.hh.

Constructor & Destructor Documentation

LBNFMagneticFieldPolyconeHorn::LBNFMagneticFieldPolyconeHorn ( size_t  iH)
explicit

Definition at line 19 of file LBNFMagneticFieldPolyconeHorn.cc.

19  :
20 hornNumber(iH), // indexed 0 to 4..
21 fHornCurrent(0.),
23 fOuterRadius(1.0e9),
24 fOuterRadiusEff(1.0e9),
25 fSkinDepth(4.1*CLHEP::mm),
26 fSkinDepthInnerRad(1.0e10*CLHEP::mm), // Unrealistic high, because that was the default sometime ago.
30 fShift(2, 0.),
31 fShiftSlope(2,0.)
32 {
33 //
34 // Magnetic field for the simple Polycone horn. This field is attached to container volume
35 // LBNFSimpleHornxContainer, which is a box. The field is defined the Polycone, we keep our own geometry
36 // such we can implement field error in the future, should it be necessary..
37 //
38  const LBNEVolumePlacements *aPlacementHandler = LBNEVolumePlacements::Instance();
39  fZShiftDrawingCoordinate = 0.; // Check with Geantino here...
40  fZDCBegin.clear();
41  fRadsInnerC.clear();
42  fRadsOuterC.clear();
43  double zzMinTmp = 1.0e20;
44  double zzMaxTmp = -1.0e20;
45  fOuterRadius = aPlacementHandler->GetHornsPolyOuterRadius(hornNumber + 1);
47  if (aPlacementHandler->IsHornPnParabolic(hornNumber + 1)) {
48  size_t nPts = aPlacementHandler->GetHornParabolicNumInnerPts(iH);
49  const double epsil = 0.050*CLHEP::mm; // from LBNEVolumePlacements::UpdateParamsForHornMotherPolyNum
50  for (size_t k=0; k != nPts; k++) {
51  const double zzz = aPlacementHandler->GetHornParabolicRZCoord(iH, k) + fZShiftDrawingCoordinate + epsil;
52  zzMinTmp = std::min(zzMinTmp, zzz);
53  zzMaxTmp = std::max(zzMaxTmp, zzz);
54  fZDCBegin.push_back(zzz);
55  const double rIn = aPlacementHandler->GetHornParabolicRIn(iH, k) - epsil;
56  fRadsInnerC.push_back(rIn);
57  const double rOut = rIn + aPlacementHandler->GetHornParabolicThick(iH, k);
58  fRadsOuterC.push_back(rOut);
59  }
60  } else {
61  if ((hornNumber == 0) && aPlacementHandler->GetUseLBNFOptimConceptDesignHornA()) {
62  fZDCBegin = aPlacementHandler->GetHornsPolyInnerConductorZsHornARev2();
63  std::cerr << " First fZDCBegin for horn A " << fZDCBegin[0]+ fZShiftDrawingCoordinate << std::endl;
64  // We shift in global coordinate..
65  std::cerr << "LBNFMagneticFieldPolyconeHorn::LBNFMagneticFieldPolyconeHorn, CD HornA, fZShiftDrawingCoordinate "
67 // std::cerr << " And quit after Horn A " << std::endl; exit(2);
68  for (size_t k=0; k !=fZDCBegin.size(); k++) { fZDCBegin[k] += fZShiftDrawingCoordinate; }
71  for (size_t k=0; k != fRadsInnerC.size(); k++) { fRadsOuterC[k] += aPlacementHandler->GetThickICDRevisedHornA(); }
72  std::cerr << " .... /Rin/Rout map, global coordinate system " << std::endl;
73  for (size_t k=0; k !=fZDCBegin.size(); k++)
74  std::cerr << " " << k << " "
75  << fZDCBegin[k] << " " << fRadsInnerC[k] << " " << fRadsOuterC[k] << std::endl;
76  zzMinTmp = fZDCBegin[0];
77  zzMaxTmp = fZDCBegin[fZDCBegin.size()-1];
78  } else if ((hornNumber == 1) && aPlacementHandler->GetUseLBNFOptimConceptDesignHornB()) {
79  fZDCBegin = aPlacementHandler->GetHornsPolyInnerConductorZsHornBRev2();
80  // We shift in global coordinate..
81  std::cerr << "LBNFMagneticFieldPolyconeHorn::LBNFMagneticFieldPolyconeHorn, CD HornB, fZShiftDrawingCoordinate "
83  for (size_t k=0; k !=fZDCBegin.size(); k++) { fZDCBegin[k] += fZShiftDrawingCoordinate; }
86  for (size_t k=0; k != fRadsInnerC.size(); k++) { fRadsOuterC[k] += aPlacementHandler->GetThickICDRevisedHornB(); }
87  std::cerr << " .... /Rin/Rout map, global coordinate system " << std::endl;
88  for (size_t k=0; k !=fZDCBegin.size(); k++)
89  std::cerr << " " << k << " "
90  << fZDCBegin[k] << " " << fRadsInnerC[k] << " " << fRadsOuterC[k] << std::endl;
91 
92  zzMinTmp = fZDCBegin[0];
93  zzMaxTmp = fZDCBegin[fZDCBegin.size()-1];
94  } else if ((hornNumber == 2) && aPlacementHandler->GetUseLBNFOptimConceptDesignHornC()) {
95  fZDCBegin = aPlacementHandler->GetHornsPolyInnerConductorZsHornCRev2();
96  // We shift in global coordinate..
97  std::cerr << "LBNFMagneticFieldPolyconeHorn::LBNFMagneticFieldPolyconeHorn, CD HornC, fZShiftDrawingCoordinate "
99  for (size_t k=0; k !=fZDCBegin.size(); k++) { fZDCBegin[k] += fZShiftDrawingCoordinate; }
102  for (size_t k=0; k != fRadsInnerC.size(); k++) { fRadsOuterC[k] += aPlacementHandler->GetThickICDRevisedHornC(); }
103  std::cerr << " .... /Rin/Rout map, global coordinate system " << std::endl;
104  for (size_t k=0; k !=fZDCBegin.size(); k++)
105  std::cerr << " " << k << " "
106  << fZDCBegin[k] << " " << fRadsInnerC[k] << " " << fRadsOuterC[k] << std::endl;
107 
108  zzMinTmp = fZDCBegin[0];
109  zzMaxTmp = fZDCBegin[fZDCBegin.size()-1];
110  } else { // simplified geometry for the horns.
111  for (size_t k=0; k!= static_cast<size_t>(aPlacementHandler->GetUseHornsPolyNumInnerPts(hornNumber + 1)); k++) {
112  const double zzz = aPlacementHandler->GetHornsPolyInnerConductorZCoord(hornNumber + 1, k) + fZShiftDrawingCoordinate;
113  zzMinTmp = std::min(zzMinTmp, zzz);
114  zzMaxTmp = std::max(zzMaxTmp, zzz);
115  fZDCBegin.push_back(zzz);
116  double rIn = aPlacementHandler->GetHornsPolyInnerConductorRadius(hornNumber + 1, k);
117  double rOut = rIn + aPlacementHandler->GetHornsPolyInnerConductorThickness(hornNumber + 1, k);
118  fRadsInnerC.push_back(rIn);
119  fRadsOuterC.push_back(rOut);
120  }
121 // std::cerr << " k " << k << " z " << fZDCBegin[fZDCBegin.size()-1] << " InnerC " << rIn << " out " << rOut << std::endl;
122  }
123  }
124  fEffectiveLength = zzMaxTmp - zzMinTmp;
125 
126 // std::cerr << " And quit for now.. I say so.. " << std::endl; exit(2);
127 //
128 
129 // Use now the survey data (simulated for now.. ) to establish the coordinate transform..
130 //
131  LBNESurveyor *theSurvey= LBNESurveyor::Instance();
132  std::ostringstream hornIndexStrStr; hornIndexStrStr << hornNumber+1;
133  std::string hornIndexStr(hornIndexStrStr.str());
134  std::string upstrStr("Upstream");std::string downstrStr("Downstream");
135  std::string leftStr("Left"); std::string rightStr("Right");
136  std::string ballStr("BallHorn");
138  theSurvey->GetPoint(G4String(upstrStr + leftStr + ballStr + hornIndexStr));
140  theSurvey->GetPoint(G4String(upstrStr + rightStr + ballStr + hornIndexStr));
142  theSurvey->GetPoint(G4String(downstrStr + leftStr + ballStr + hornIndexStr));
144  theSurvey->GetPoint(G4String(downstrStr + rightStr + ballStr + hornIndexStr));
145  const G4ThreeVector pUpLeft = itUpLeft->GetPosition();
146  const G4ThreeVector pUpRight = itUpRight->GetPosition();
147  const G4ThreeVector pDwLeft = itDwLeft->GetPosition();
148  const G4ThreeVector pDwRight = itDwRight->GetPosition();
149  std::cerr << " For Horn " << hornNumber+1 << " pUpLeft "
150  << pUpLeft << " right " << pUpRight << " pDwLeft "
151  << pDwLeft << " effLength " << fEffectiveLength << std::endl;
152  fHornIsMisaligned = false;
153  for (size_t k=0; k!=2; k++) {
154  fShift[k] = -0.50*(pUpLeft[k] + pUpRight[k]); // minus sign comes from the global to local.
155  // Transverse shoft at the upstream entrance of Horn1
156  fShiftSlope[k] = 0.5*(pUpLeft[k] + pUpRight[k] - pDwLeft[k] - pDwRight[k])/fEffectiveLength;
157  if (std::abs(fShiftSlope[k]) > 1.0e-8) fHornIsMisaligned = true;
158  }
159  if (fHornIsMisaligned) {
160  std::ostringstream aNameStrStr; aNameStrStr << "LBNFSimpleHorn" << (hornNumber+1) << "Container";
161  std::string namePlacedVol(aNameStrStr.str());
162  if (hornNumber == 0) namePlacedVol = std::string("Horn1PolyM1");
163  const LBNEVolumePlacementData* plDat=
164  aPlacementHandler->Find("BFieldInitialization", namePlacedVol.c_str(), "BFieldInitialization");
166  std::cerr << " Horn " << hornNumber+1 << " is misaligned "
167  << " xz term " << fRotMatrixHornContainer[0][2] << " yz " << fRotMatrixHornContainer[1][2] << std::endl;
168 // fHornIsMisaligned = false;
169 // std::cerr << " !!!! Back door setting of the HornisMialigned, we will not rotate the field " << std::endl;
170  }
171 
172 //
173 // Open a file to study the value of the field for displaced trajectory...
174 //
175 // if (!fOutTraj.is_open()) {
176 // G4String fNameStr("./FieldTrajectories_Horn");
177 // if (amHorn1) fNameStr += G4String("1_1.txt");
178 // else fNameStr += G4String("2_1.txt");
179 // fOutTraj.open(fNameStr.c_str()); // we will place a GUI interface at a later stage...
180 // fOutTraj << " id x y z bx by " << std::endl;
181 // }
182 // if (hornNumber == 1) this->TestDivergence(0); Not to be done here, the correction term are not yet declared.
183 // See LBNEDetectorConstruction, at debug line "Defining Polycone Mag field, usedNumberOfHornsPoly"
184 //
185 // Build the field if the Quadrupole amplitude greater than 1.
186 //
187  fField3DMapCurrentEqualizer.clear(); // Optional fill below.. Once we know the parameters for the simulation..
188  fDebugIsOn = false;
192 }
const LBNEVolumePlacementData * Find(const G4String &name, const char *motherName, const char *method) const
bool GetUseLBNFOptimConceptDesignHornB() const
std::string string
Definition: nybbler.cc:12
std::vector< LBNESurveyedPt >::const_iterator GetPoint(const std::string &aName) const
static LBNEVolumePlacements * Instance()
bool GetUseLBNFOptimConceptDesignHornC() const
std::vector< double > GetHornsPolyInnerConductorRadiiHornARev2() const
intermediate_table::const_iterator const_iterator
double GetHornsPolyInnerConductorZCoord(size_t iH, size_t numPts) const
bool GetUseLBNFOptimConceptDesignHornA() const
double GetHornParabolicRZCoord(size_t iH, size_t k) const
double GetThickICDRevisedHornB() const
T abs(T value)
std::vector< double > GetHornsPolyInnerConductorZsHornARev2() const
static LBNESurveyor * Instance()
std::vector< double > GetHornsPolyInnerConductorRadiiHornBRev2() const
double GetHornsPolyOuterRadius(size_t iH) const
double GetHornsPolyZStartPos(size_t iH) const
std::vector< double > GetHornsPolyInnerConductorRadiiHornCRev2() const
double GetHornsPolyInnerConductorThickness(size_t iH, size_t numPts) const
static int max(int a, int b)
bool IsHornPnParabolic(size_t numHorn) const
int GetUseHornsPolyNumInnerPts(size_t i) const
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
std::vector< double > GetHornsPolyInnerConductorZsHornCRev2() const
double GetHornsPolyInnerConductorRadius(size_t iH, size_t numPts) const
double GetThickICDRevisedHornC() const
double GetHornParabolicThick(size_t iH, size_t k) const
double GetThickICDRevisedHornA() const
double GetHornParabolicRIn(size_t iH, size_t k) const
std::map< unsigned int, std::pair< float, float > > fField3DMapCurrentEqualizer
size_t GetHornParabolicNumInnerPts(size_t iH) const
QTextStream & endl(QTextStream &s)
std::vector< double > GetHornsPolyInnerConductorZsHornBRev2() const
LBNFMagneticFieldPolyconeHorn::~LBNFMagneticFieldPolyconeHorn ( )

Definition at line 1195 of file LBNFMagneticFieldPolyconeHorn.cc.

1195  {
1196  std::cerr << " Closing Output Trajectory file in LBNFMagneticFieldPolyconeHorn " << std::endl;
1197  if (fOutTraj.is_open()) fOutTraj.close();
1198 }
QTextStream & endl(QTextStream &s)

Member Function Documentation

void LBNFMagneticFieldPolyconeHorn::dumpField ( ) const

Definition at line 403 of file LBNFMagneticFieldPolyconeHorn.cc.

403  {
404 // this->TestEccentricityBerkeley();
405  fDebugIsOn = true;
406  std::ostringstream fNameStr; fNameStr << "./FieldMapHornTmpV3" << (hornNumber +1);
407  if (std::abs(fDeltaEccentricityIO) > 1.0e-20) fNameStr << "Ecc.txt";
408  else fNameStr << ".txt";
409  std::string fName(fNameStr.str());
410  std::ofstream fOut(fName.c_str());
411 // const double zStart = fZShiftDrawingCoordinate;
412 // const double zEnd = zStart + fEffectiveLength + 1000. ;
413 // Study Horn A only.
414  const double zStart = 2219.;
415 // const double zEnd = 2200.0000001;
416  const double zEnd = 2219.0000001;
417  std::cerr << "LBNFMagneticFieldPolyconeHorn::dumpField .. fZShiftDrawingCoordinate "
418  << fZShiftDrawingCoordinate << " length " << fEffectiveLength
419  << " Z start/end " << zStart << "/" << zEnd << std::endl;
420 // if ((std::abs(fDeltaEllipticityI) < 1.0e-20) && (std::abs(fDeltaEccentricityIO) < 1.0e-20) ) {
421 // Splitting this method in two parts was a bad idea, as it prevented us to make maps with the exactly the same grid,
422 // but different option.. I'll leave the code there for now, in case we want to generate simple maps, but disable it..
423  if (std::abs(zEnd) < -1.e10) { // to ensure the same map.
424  fOut << " z zd r bphi br " << std::endl;
425  double rMax = fOuterRadius + 5.0*CLHEP::mm;
426 // if (amHorn1) std::cerr << " Horn1, Dumpfield, r Max = " << rMax << std::endl;
427 // else std::cerr << " Horn2, Dumpfield, r Max = " << rMax << std::endl;
428  const int numZStep = 200;
429  const int numRStep= 200;
430  const double zStep = (zEnd-zStart)/numZStep;
431  const double rStep = rMax/numRStep;
432  double point[3];
433  for (int iZ=0; iZ !=numZStep; iZ++) {
434  double z = zStart + iZ*zStep;
435  point[2] = z;
436  const double zLocD = point[2];
437  double radIC = 0.; double radOC = 0.;
438  this->fillHornPolygonRadii(zLocD, &radIC, &radOC);
439  double r = radIC - 0.25*CLHEP::mm;
440  // inside the conductor...
441  while (r < rMax/2.) {
442  const double phi = 2.0*M_PI*G4RandFlat::shoot();
443  point[0] = r*std::cos(phi);
444  point[1] = r*std::sin(phi);
445  double bf[3];
446  this->GetFieldValue(point, &bf[0]);
447  const double bphi = bf[0]*std::sin(phi) - bf[1]*std::cos(phi);
448  const double br = bf[0]*std::cos(phi) + bf[1]*std::sin(phi);
449  fOut << " " << z << " " << zLocD << " " << r << " "
450  << bphi/CLHEP::tesla << " " << br/CLHEP::tesla << std::endl;
451  if (r < (radIC + 5.0*CLHEP::mm)) r += 0.1*CLHEP::mm;
452  else r += rStep;
453  }
454  }
455  } else {
456  fOut << " z zd x y r bphi br bx by " << std::endl;
457 // if (amHorn1) std::cerr << " Horn1, Dumpfield, r Max = " << rMax << std::endl;
458 // else std::cerr << " Horn2, Dumpfield, r Max = " << rMax << std::endl;
459 // const int numZStep = 200;
460  const int numZStep = 1;
461  const int numRStep= 200;
462  const int numPhiStep= 100;
463  const double zStep = (zEnd-zStart)/numZStep;
464  double point[3];
465  const double rInit = 20.;
466 // const double rMax = radIC + 10.0*CLHEP::mm;
467  const double rMax = 50.0*CLHEP::mm;
468 // const double rMax = radIC - 0.1*CLHEP::mm;
469  const double rStep = (rMax - rInit)/numRStep;
470  for (int iZ=0; iZ !=numZStep; iZ++) {
471  double z = zStart + iZ*zStep;
472  point[2] = z;
473  const double zLocD = point[2];
474  double radIC = 0.; double radOC = 0.;
475  this->fillHornPolygonRadii(zLocD, &radIC, &radOC);
476  // inside the conductor...
477  double r = rInit;
478  while (r < rMax) {
479  for (size_t kPhi=0; kPhi!= (numPhiStep); kPhi++) {
480  const double phi = (2.0*M_PI*kPhi)/numPhiStep;
481  point[0] = r*std::cos(phi);
482  point[1] = r*std::sin(phi);
483  double bf[3];
484  this->GetFieldValue(point, &bf[0]);
485  const double bphi = bf[0]*std::sin(phi) - bf[1]*std::cos(phi);
486  const double br = bf[0]*std::cos(phi) + bf[1]*std::sin(phi);
487  fOut << " " << z << " " << zLocD << " " << point[0] << " " << point[1] << " " << r << " "
488  << bphi/CLHEP::tesla << " " << br/CLHEP::tesla
489  << " " << bf[0]/CLHEP::tesla << " " << bf[1]/CLHEP::tesla << std::endl;
490  }
491  r += rStep;
492  }
493  }
494  }
495  std::cerr << " And quit for now... " << std::endl; exit(2);
496  fOut.close();
497  //
498  // Provide the arrow plot to visualize the correction to the Current equalizer section..
499  //
500  std::ostringstream fNameAStr;
501  fNameAStr << "./FieldMapHorn" << (hornNumber +1)
502  << "_ArrowPlot_" << fNumZPtsForCE << "_" << fNumRPtsForCE << "_" << fNumPhiPtsForCE << "_V2.txt";
503  std::string fNameA(fNameAStr.str());
504  fOut.open(fNameA.c_str());
505  fOut << " x y r bx by " << std::endl;
506  const int numR = 20;
507  const int numPhi = 10.;
508  const double stepPhi = (M_PI/2.) / numPhi;
509  G4ThreeVector dir;
510  double pos[3];
511  size_t iPtZSel = fRadsInnerC.size()/2;
512  pos[2] = fZDCBegin[iPtZSel];
513  const double zLoc = pos[2];
514  double radICAr=0.; double radOCAr=0.;
515  this->fillHornPolygonRadii(zLoc, &radICAr, &radOCAr);
516  const double rStep = (fOuterRadius - radOCAr)/numR;
517 
518  double bField[3];
519  for (int iR = 0; iR != numR; iR++) {
520  double r = radOCAr + iR*rStep;
521  if (iR == 0) r = radOCAr + 5.0*CLHEP::mm;
522  else r = radOCAr + 2.0*CLHEP::mm + iR*rStep; // for graphical clarity ..
523  for (int iPhi = 0; iPhi != numPhi; iPhi++) {
524  const double phi = 0.3333*stepPhi + iPhi*stepPhi;
525  pos[0] = r * std::cos(phi); pos[1] = r * std::sin(phi);
526  this->GetFieldValue(pos, bField);
527  fOut << " " << pos[0] << " " << pos[1] << " " << r << " "
528  << bField[0]/CLHEP::tesla << " " << bField[1]/CLHEP::tesla << std::endl;
529  }
530  }
531  fOut.close();
532  //
533  // Special map to debug the CurrentEqualizer induced azimuthal variation in the current.
534 
535  if (fCurrentEqualizerQuadAmpl > 1.) {
536  std::ostringstream fNameBStr; fNameBStr << "./FieldMapHornCEQ_" << (hornNumber +1) << "_Debug.txt";
537  std::string fNameB(fNameBStr.str());
538  fOut.open(fNameB.c_str());
539  fOut << " x y z bx by bNorm br bphi" << std::endl;
540  const int numRCE = 50;
541  const int numPhiCE = 100.;
542  const double stepPhiCE = (2.0*M_PI) / numPhiCE;
543  double posCE[3];
545  double radIC; double radOC;
546  this->fillHornPolygonRadii(zGrid, &radIC, &radOC);
547  double bFieldCE[3];
548  for (int iZCE=0; iZCE != 10; iZCE++) {
549  posCE[2] = zGrid + (iZCE-1)*fField3DMapCurrentEqualizerZStep/5.;
550  const double rStepCE = (fOuterRadius - radOC- 2.5*CLHEP::mm)/numRCE;
551  for (int iR = 0; iR != numRCE; iR++) {
552  const double r = radOC -1.*CLHEP::mm + iR*rStepCE;
553  for (int iPhi = 0; iPhi != numPhiCE; iPhi++) {
554  const double phi = iPhi*stepPhiCE;
555  posCE[0] = r * std::cos(phi); posCE[1] = r * std::sin(phi);
556 // if ((iR == 15) && (iPhi > 20) && (iPhi < 25)) fDebugIsOn = true;
557 // if ((r < 225.) && (iPhi > 20) && (iPhi < 25)) fDebugIsOn = true;
558  if ((std::abs(r - 205.997) < 1.) && (std::abs(phi) < 1.0)) fDebugIsOn = true;
559  else fDebugIsOn = false;
560  this->GetFieldValue(posCE, bFieldCE);
561  const double bNorm = sqrt(bFieldCE[0]*bFieldCE[0] + bFieldCE[1]*bFieldCE[1]);
562  const double bR = bFieldCE[0]*std::cos(phi) + bFieldCE[1]*std::sin(phi);
563  const double bPhi = bFieldCE[1]*std::cos(phi) - bFieldCE[0]*std::sin(phi);
564 
565  fOut << " " << posCE[0] << " " << posCE[1] << " " << posCE[2] << " "
566  << bFieldCE[0]/CLHEP::tesla << " " << bFieldCE[1]/CLHEP::tesla << " " << bNorm/CLHEP::tesla
567  << " " << bR/CLHEP::tesla << " " << bPhi/CLHEP::tesla << std::endl;
568  }
569  }
570  }
571  }
572  fOut.close();
573 }
std::string string
Definition: nybbler.cc:12
virtual void GetFieldValue(const double Point[3], double *Bfield) const
T abs(T value)
double z
void fillHornPolygonRadii(double z, double *rIn, double *rOut) const
QTextStream & endl(QTextStream &s)
void LBNFMagneticFieldPolyconeHorn::fill3DMapCurrentEqualizer ( ) const
private

Definition at line 908 of file LBNFMagneticFieldPolyconeHorn.cc.

908  {
909  //
910  if (fFileNameFieldMapForCE != std::string("?")) {
912  fDebugIsOn = false;
913 // this->dumpField();
914  return;
915  }
916 
917  if (fDebugIsOn) std::cerr << " LBNFMagneticFieldPolyconeHorn::fill3DMapCurrentEqualizer, starting .. " << std::endl;
918  const G4double current = fHornCurrent/CLHEP::ampere/1000.;
919  double magBField = current / (5./CLHEP::cm)/10*CLHEP::tesla; //B(kG)=i(kA)/[5*r(cm)], 1T=10kG
920  // The 1/r dependence is included in the map.
922  const double AQuad = fCurrentEqualizerQuadAmpl/100.; // temporary convention..
923  fNumZPtsForCE = 400; // a bit arbitrary...
924  fNumRPtsForCE = 200;
925  fNumPhiPtsForCE = 128;
928  fField3DMapCurrentEqualizerPhiStep = (M_PI/2.)/(fNumPhiPtsForCE-1); // Only one quadrant..
929  const int numWires = 500; // Really arbitrary..
930  const double phiWStep = 2.0*M_PI/numWires; // Over two pi, full sources.
931  for (unsigned int iZ = 0; iZ != fNumZPtsForCE; iZ++) {
932 // std::cerr << " At Z index " << iZ << std::endl;
934  double radIC=0.;
935  double radOC=0.;
936  this->fillHornPolygonRadii(z, &radIC, &radOC);
937  fField3DMapCurrentEqualizerRadSqAtZ.push_back(radOC*radOC);
938  double stepRadial = (fOuterRadius*fOuterRadius - radOC*radOC)/(fNumRPtsForCE-1);
939  fField3DMapCurrentEqualizerRadSqRStepAtZ.push_back(stepRadial);
940  double zFactAzi = 1.0e-6;
941  switch(hornNumber) {
942  case 0:
943  case 2:
944  zFactAzi = ((z - fZDCBegin[0]) > 0.) ? (z - fZDCBegin[0])/fCurrentEqualizerLongAbsLength : 1.0e-6;
945  break;
946  case 1:
947  zFactAzi = ((fZDCBegin[fZDCBegin.size() -1] - z) > 0.) ?
948  (fZDCBegin[fZDCBegin.size() -1] - z)/fCurrentEqualizerLongAbsLength : 1.0e-6;
949  break;
950  default:
951  zFactAzi = 1.0e-6; // undefined, only 3 horns
952  }
953  const double factCE = std::exp(-1.0*std::abs(zFactAzi));
954  if (fDebugIsOn) {
955  std::cerr << " At z = " << z << "radIC " << radIC << " radOC "
956  << radOC << " zFactAzi " << factCE << " " << magBField << std::endl;
957  std::cerr << " Size of the map " << fField3DMapCurrentEqualizer.size() << std::endl;
958  }
959  for (unsigned int iR=0; iR != fNumRPtsForCE; iR++) {
960  // Choose a quadratic spacing...
961  const double r = 1.0e-12 + sqrt(radOC*radOC + iR*stepRadial); // 1 microns to avoid numerics
962  for (unsigned int iPhi=0; iPhi != fNumPhiPtsForCE; iPhi++) {
963  const double phi = iPhi*fField3DMapCurrentEqualizerPhiStep;
964  const double xP = r * std::cos(phi);
965  const double yP = r * std::sin(phi);
966  double bX = 0.; double bY = 0.;
967  // Discretize the current density on the conductor. Normalize to the unform current density,
968  //
969  double sumCurrent = 0.;
970  for (int iW=0; iW != numWires; iW++) {
971  const double phiW = 1.0e-4 + phiWStep*(iW-1);
972  const double xW = radOC*std::cos(phiW);
973  const double yW = radOC*std::sin(phiW);
974  const double xWf = xP - xW;
975  const double yWf = yP - yW;
976  const double phiff = atan2(yWf, xWf);
977  const double radff = std::sqrt(xWf*xWf + yWf*yWf);
978  const double iDens = 1.0 + AQuad*factCE*std::abs(sin(2.0*phiW));
979  sumCurrent += iDens;
980  const double iDensByR = iDens/radff;
981  bX -= iDensByR*std::sin(phiff);
982  bY += iDensByR*std::cos(phiff);
983  if (std::isnan(bX) || std::isnan(bY) || std::isinf(bX) || std::isinf(bY)) {
984  std::cerr << " Numerics problem, xP " << xP << " yP " << yP << " iW "
985  << iW << " xWf " << xWf << " yWf " << yWf << std::endl;
986  std::cerr << " And quit here ! " << std::endl;
987  exit(2);
988  }
989  }
990  if (sumCurrent < 1.0e-10) { bX = 0.; bY = 0.; } else {
991  bX *=magBField/sumCurrent; bY *= magBField/sumCurrent;
992  }
993  const unsigned int ii = fNumZPtsForCE*(fNumRPtsForCE*iPhi + iR) + iZ;
994  fField3DMapCurrentEqualizer.emplace(ii,
995  std::pair<float, float>(static_cast<float>(bX), static_cast<float>(bY)));
996  } // On phi;
997  } // on R
998  } // on Z
999  /*
1000  std::cerr << " ... size of final Field map .. " << fField3DMapCurrentEqualizer.size() << std::endl;//
1001  std::map<unsigned int, std::pair<float, float> >::const_iterator itCheck0 =
1002  fField3DMapCurrentEqualizer.find(84029);
1003  std::cerr << " Check map at location 84029 " << itCheck0->second.first << " / " << itCheck0->second.second << std::endl;
1004  std::map<unsigned int, std::pair<float, float> >::const_iterator itCheck1 =
1005  fField3DMapCurrentEqualizer.find(84009);
1006  std::cerr << " Check map at location 84009 " << itCheck1->second.first << " / " << itCheck1->second.second << std::endl;
1007  std::map<unsigned int, std::pair<float, float> >::const_iterator itCheck2 =
1008  fField3DMapCurrentEqualizer.find(86009);
1009  std::cerr << " Check map at location 86009 " << itCheck2->second.first << " / " << itCheck2->second.second << std::endl;
1010 
1011  */
1012  fDebugIsOn = false;
1013 // this->dumpField();
1014  //
1015  // Write the map out ..
1016  //
1018 // std::cerr << " And quit !. " << std::endl; exit(2);
1019 
1020 }
std::vector< double > fField3DMapCurrentEqualizerRadSqRStepAtZ
std::string string
Definition: nybbler.cc:12
T abs(T value)
double z
static Entry * current
void fillHornPolygonRadii(double z, double *rIn, double *rOut) const
std::vector< double > fField3DMapCurrentEqualizerRadSqAtZ
std::map< unsigned int, std::pair< float, float > > fField3DMapCurrentEqualizer
QTextStream & endl(QTextStream &s)
void LBNFMagneticFieldPolyconeHorn::fillHornPolygonRadii ( double  z,
double *  rIn,
double *  rOut 
) const
inlineprivate

Definition at line 85 of file LBNFMagneticFieldPolyconeHorn.hh.

85  {
86  size_t kLow = 0;
87  size_t kHigh = fZDCBegin.size() - 1;
88  for (size_t k=0; k != fZDCBegin.size() - 1; k++) {
89  if ((z >= fZDCBegin[k]) && (z < fZDCBegin[k+1])) {
90  kLow = k;
91  kHigh = k+1;
92  const double dzFrac = (z - fZDCBegin[kLow])/(fZDCBegin[kHigh] - fZDCBegin[kLow]);
93  *rIn = fRadsInnerC[kLow] + dzFrac*(fRadsInnerC[kHigh] - fRadsInnerC[kLow]);
94  *rOut = fRadsOuterC[kLow] + dzFrac*(fRadsOuterC[kHigh] - fRadsOuterC[kLow]);
95 // if ((*rIn) < 160.) std::cerr << " .......... z " << z << " k " << k << " rIn " << (*rIn) << " rOut " << (*rOut) << std::endl;
96  return;
97  }
98  }
99  *rIn = 1.0e10;
100  *rOut = 2.0e10;
101  }
double z
void LBNFMagneticFieldPolyconeHorn::fillTrajectories ( const double  Point[3],
double  bx,
double  by 
) const
private

Definition at line 575 of file LBNFMagneticFieldPolyconeHorn.cc.

575  {
576  if (!fOutTraj.is_open()) return;
577  LBNERunManager* pRunManager = dynamic_cast<LBNERunManager*>(G4RunManager::GetRunManager());
578  fOutTraj << " " << pRunManager->GetCurrentEvent()->GetEventID();
579  for (size_t k=0; k!= 3; k++) fOutTraj << " " << Point[k];
580  fOutTraj << " " << bx/CLHEP::tesla << " " << " " << by/CLHEP::tesla << std::endl;
581  // we flush, the destructor never called..
582  fOutTraj.flush();
583 }
QTextStream & endl(QTextStream &s)
double LBNFMagneticFieldPolyconeHorn::GetCurrentEqualizerQuadAmpl ( ) const
inline
double LBNFMagneticFieldPolyconeHorn::GetEffectiveInnerRad ( ) const
inline
double LBNFMagneticFieldPolyconeHorn::GetEffectiveOuterRad ( ) const
inline
double LBNFMagneticFieldPolyconeHorn::GetEffectiveSkinDepthFact ( ) const
inline
void LBNFMagneticFieldPolyconeHorn::getFieldFrom3DMapCurrentEqualizer ( const double  Point[3],
double *  Bfield 
) const
private

Definition at line 669 of file LBNFMagneticFieldPolyconeHorn.cc.

670  {
671 
672  if (fDebugIsOn) std::cerr << " LBNFMagneticFieldPolyconeHorn::getFieldFrom3DMapCurrentEqualizer xyz "
673  << Point[0] << " / " << Point[1] << " / " << Point[2] << std::endl;
674  for (int k=0; k !=3; k++) Bfield[k] = 0.;
675  if (fField3DMapCurrentEqualizer.size() == 0) return; // should not happen
676  if (Point[2] < fField3DMapCurrentEqualizerZMin) return;
677  const unsigned int iZ1 =
678  static_cast<unsigned int>(std::floor((Point[2] - fField3DMapCurrentEqualizerZMin)/fField3DMapCurrentEqualizerZStep));
679  if( iZ1 >= fNumZPtsForCE) return;
680  const unsigned int iZ2 = (iZ1 == (fNumZPtsForCE-1)) ? iZ1 : (iZ1 + 1);
681  if(fDebugIsOn) std::cerr << " ..... Z " << Point[2] << " indices " << iZ1 << " / " << iZ2 << std::endl;
682  double phi = std::atan2(Point[1], Point[0]);
683  if (phi < 0.) phi += 2.0*M_PI;
684  const unsigned int iQuadrant = (unsigned int) std::floor(2.0*phi/M_PI);
685  const double phiFirst = phi - iQuadrant*M_PI/2.;
686  const unsigned int iPhi1 =
687  static_cast<unsigned int>(phiFirst/fField3DMapCurrentEqualizerPhiStep);
688  const unsigned int iPhi2 = (iPhi1 == (fNumPhiPtsForCE-1)) ? 0 : (iPhi1 + 1);
689 
690  if (fDebugIsOn) std::cerr << " ..... phi " << phi << " phiFirst " << phiFirst
691  << " indices " << iPhi1 << " / " << iPhi2 << std::endl;
692  const double rSqRequested = Point[0]*Point[0] + Point[1]*Point[1];
693  const double rSqZ1 = rSqRequested - fField3DMapCurrentEqualizerRadSqAtZ[iZ1];
694  const double rSqZ2 = rSqRequested - fField3DMapCurrentEqualizerRadSqAtZ[iZ2];
695  if ((rSqZ1 < 0.) && (rSqZ2 < 0.)) return;
696  double radOCAtZ = 0.;
697  double radICAtZ = 0.; // irrelevant if no OC crossing betwen Z1 and Z2
698  if ((rSqZ1 < 0.) || (rSqZ2 < 0.)) {
699  this->fillHornPolygonRadii(Point[2], &radICAtZ, &radOCAtZ);
700  if (rSqRequested < (radOCAtZ*radOCAtZ)) return;
701  }
702  const unsigned int iR1Z1 = (rSqZ1 < 0.) ? 0 : std::floor(rSqZ1 /fField3DMapCurrentEqualizerRadSqRStepAtZ[iZ1]);
703  const unsigned int iR2Z1 = (rSqZ1 < 0.) ? 0 : ((iR1Z1 == (fNumRPtsForCE-1)) ? iR1Z1 : (iR1Z1 + 1));
704  const unsigned int iR1Z2 = (rSqZ2 < 0.) ? 0 : std::floor(rSqZ2 /fField3DMapCurrentEqualizerRadSqRStepAtZ[iZ2]);
705  const unsigned int iR2Z2 = (rSqZ2 < 0.) ? 0 : ((iR1Z2 == (fNumRPtsForCE-1)) ? iR1Z2 : (iR1Z2 + 1));
706  if ((iR1Z1 >= fNumRPtsForCE) || (iR1Z2 >= fNumRPtsForCE)) return;
707  // bilinear interposlation on the phiXRsq plane, the linear interpolation on Z
708  if (fDebugIsOn) std::cerr << " ..... RsQ, Z1 " << rSqZ1 << " at Z2 " << rSqZ2 << " indices "
709  << iR1Z1 << " / " << iR2Z1 << " / " << iR1Z2 << " / " << iR2Z2 << std::endl;
710 
711  const unsigned int ii1 = fNumZPtsForCE*(fNumRPtsForCE*iPhi1 + iR1Z1) + iZ1;
712  const unsigned int ii2 = fNumZPtsForCE*(fNumRPtsForCE*iPhi1 + iR2Z1) + iZ1;
713  const unsigned int ii3 = fNumZPtsForCE*(fNumRPtsForCE*iPhi2 + iR2Z1) + iZ1;
714  const unsigned int ii4 = fNumZPtsForCE*(fNumRPtsForCE*iPhi2 + iR1Z1) + iZ1;
715  const double ui = (iPhi2 == 0) ? (phiFirst - (fNumPhiPtsForCE - 1)*
718 
719  if (fDebugIsOn) std::cerr << " ..... ii indices " << ii1 << " / " << ii2 << " / " << ii3 << " / " << ii4
720  << " ui " << ui << std::endl;
721  double bxIz1 = 0.; double byIz1 = 0.;
722  // Same at the point iZ2..
723  //
724  const unsigned int jj1 = fNumZPtsForCE*(fNumRPtsForCE*iPhi1 + iR1Z2) + iZ2;
725  const unsigned int jj2 = fNumZPtsForCE*(fNumRPtsForCE*iPhi1 + iR2Z2) + iZ2;
726  const unsigned int jj3 = fNumZPtsForCE*(fNumRPtsForCE*iPhi2 + iR2Z2) + iZ2;
727  const unsigned int jj4 = fNumZPtsForCE*(fNumRPtsForCE*iPhi2 + iR1Z2) + iZ2;
728  double bxIz2 = 0.; double byIz2 = 0.;
729  if (((iR2Z1 == iR1Z1) || (iR2Z2 == iR1Z2)) && (iR1Z1 != 0) &&
730  (iR1Z2 != 0) && (iR2Z1 != 0) && (iR2Z2 != 0) ) { // only do the interpolation in phi . Far away from the IC,
731  // does not matter which interpolation table section we use.. Field too small.
732  std::map<unsigned int, std::pair<float, float> >::const_iterator itm1 =
733  fField3DMapCurrentEqualizer.find(ii1);
734  std::map<unsigned int, std::pair<float, float> >::const_iterator itm4 =
735  fField3DMapCurrentEqualizer.find(ii4);
736  const double bix1 = static_cast<double>(itm1->second.first);
737  const double biy1 = static_cast<double>(itm1->second.second);
738  const double bix4 = static_cast<double>(itm4->second.first);
739  const double biy4 = static_cast<double>(itm4->second.second);
740  bxIz1 = (1. - ui)*bix1 + ui*bix4;
741  byIz1 = (1. - ui)*biy1 + ui*biy4;
742  if (iZ1 == iZ2) {
743  Bfield[0] = bxIz1;
744  Bfield[1] = byIz1;
745  } else {
746  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm1 =
747  fField3DMapCurrentEqualizer.find(jj1);
748  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm4 =
749  fField3DMapCurrentEqualizer.find(jj4);
750  const double bjx1 = static_cast<double>(jtm1->second.first);
751  const double bjy1 = static_cast<double>(jtm1->second.second);
752  const double bjx4 = static_cast<double>(jtm4->second.first);
753  const double bjy4 = static_cast<double>(jtm4->second.second);
754  bxIz2 = (1. - ui)*bjx1 + ui*bjx4;
755  byIz2 = (1. - ui)*bjy1 + ui*bjy4;
756  const double v =
759  Bfield[0] = (1.0 - v)*bxIz1 + v*bxIz2;
760  Bfield[1] = (1.0 - v)*byIz1 + v*byIz2;
761  }
762  if (fDebugIsOn) std::cerr << " ....Phi/Z interpolation only. "
763  << " Bfield " << Bfield[0] << " / " << Bfield[1] << std::endl;
764  } else {
765  if (rSqZ1 < 0.) {
766  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm1 =
767  fField3DMapCurrentEqualizer.find(jj1);
768  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm2 =
769  fField3DMapCurrentEqualizer.find(jj2);
770  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm3 =
771  fField3DMapCurrentEqualizer.find(jj3);
772  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm4 =
773  fField3DMapCurrentEqualizer.find(jj4);
774  const double bjx1 = static_cast<double>(jtm1->second.first);
775  const double bjy1 = static_cast<double>(jtm1->second.second);
776  const double bjx2 = static_cast<double>(jtm2->second.first);
777  const double bjy2 = static_cast<double>(jtm2->second.second);
778  const double bjx3 = static_cast<double>(jtm3->second.first);
779  const double bjy3 = static_cast<double>(jtm3->second.second);
780  const double bjx4 = static_cast<double>(jtm4->second.first);
781  const double bjy4 = static_cast<double>(jtm4->second.second);
782  const double tj =
783  std::max(std::abs((rSqZ2 - radOCAtZ*radOCAtZ)/fField3DMapCurrentEqualizerRadSqRStepAtZ[iZ2]), 1.); // Approximate!.
784  bxIz2 = (1. - ui)*(1.0 - tj)*bjx1 + (1.0 - ui)*tj*bjx2 + ui*tj*bjx3 + (1.0 - tj)*ui*bjx4 ;
785  byIz2 = (1. - ui)*(1.0 - tj)*bjy1 + (1.0 - ui)*tj*bjy2 + ui*tj*bjy3 + (1.0 - tj)*ui*bjy4 ;
786  if (fDebugIsOn) {
787  std::cerr << " tj " << tj << " bjxs " << bjx1 << " / " << bjx2 << " / " << bjx3 << " / " << bjx4 << std::endl;
788  std::cerr << " bjys " << bjy1 << " / " << bjy2 << " / " << bjy3 << " / " << bjy4 << std::endl;
789  std::cerr << " bxIz2 " << bxIz2 << " byIz2 " << byIz2 << std::endl;
790  }
791  const double v =
794  Bfield[0] = v*bxIz2;
795  Bfield[1] = v*byIz2;
796  if (fDebugIsOn) std::cerr << " .... v " << v << " Bfield " << Bfield[0] << " / " << Bfield[1] << std::endl;
797  } else if (rSqZ2 < 0.) {
798  std::map<unsigned int, std::pair<float, float> >::const_iterator itm1 =
799  fField3DMapCurrentEqualizer.find(ii1);
800  std::map<unsigned int, std::pair<float, float> >::const_iterator itm2 =
801  fField3DMapCurrentEqualizer.find(ii2);
802  std::map<unsigned int, std::pair<float, float> >::const_iterator itm3 =
803  fField3DMapCurrentEqualizer.find(ii3);
804  std::map<unsigned int, std::pair<float, float> >::const_iterator itm4 =
805  fField3DMapCurrentEqualizer.find(ii4);
806  const double bix1 = static_cast<double>(itm1->second.first);
807  const double biy1 = static_cast<double>(itm1->second.second);
808  const double bix2 = static_cast<double>(itm2->second.first);
809  const double biy2 = static_cast<double>(itm2->second.second);
810  const double bix3 = static_cast<double>(itm3->second.first);
811  const double biy3 = static_cast<double>(itm3->second.second);
812  const double bix4 = static_cast<double>(itm4->second.first);
813  const double biy4 = static_cast<double>(itm4->second.second);
814  const double ti =
815  std::max(std::abs((rSqZ1 - radOCAtZ*radOCAtZ)/fField3DMapCurrentEqualizerRadSqRStepAtZ[iZ1]) , 1.);
816  bxIz1 = (1. - ui)*(1.0 - ti)*bix1 + (1.0 - ui)*ti*bix2 + ui*ti*bix3 + (1.0 - ti)*ui*bix4 ;
817  byIz1 = (1. - ui)*(1.0 - ti)*biy1 + (1.0 - ui)*ti*biy2 + ui*ti*biy3 + (1.0 - ti)*ui*biy4 ;
818  if (fDebugIsOn) {
819  std::cerr << " ui " << ui << " ti " << ti << std::endl;
820  std::cerr << " bixs " << bix1 << " / " << bix2 << " / " << bix3 << " / " << bix4 << std::endl;
821  std::cerr << " biys " << biy1 << " / " << biy2 << " / " << biy3 << " / " << biy4 << std::endl;
822  std::cerr << " bxIz1 " << bxIz1 << " byIz1 " << byIz1 << std::endl;
823  }
824  const double v =
827  Bfield[0] = (1.0 - v)*bxIz1;
828  Bfield[1] = (1.0 - v)*byIz1;
829  if (fDebugIsOn) std::cerr << " .... v " << v << " Bfield " << Bfield[0] << " / " << Bfield[1] << std::endl;
830 
831  } else {
832  std::map<unsigned int, std::pair<float, float> >::const_iterator itm1 =
833  fField3DMapCurrentEqualizer.find(ii1);
834  std::map<unsigned int, std::pair<float, float> >::const_iterator itm2 =
835  fField3DMapCurrentEqualizer.find(ii2);
836  std::map<unsigned int, std::pair<float, float> >::const_iterator itm3 =
837  fField3DMapCurrentEqualizer.find(ii3);
838  std::map<unsigned int, std::pair<float, float> >::const_iterator itm4 =
839  fField3DMapCurrentEqualizer.find(ii4);
840  const double bix1 = static_cast<double>(itm1->second.first);
841  const double biy1 = static_cast<double>(itm1->second.second);
842  const double bix2 = static_cast<double>(itm2->second.first);
843  const double biy2 = static_cast<double>(itm2->second.second);
844  const double bix3 = static_cast<double>(itm3->second.first);
845  const double biy3 = static_cast<double>(itm3->second.second);
846  const double bix4 = static_cast<double>(itm4->second.first);
847  const double biy4 = static_cast<double>(itm4->second.second);
848  const double ti =
850  bxIz1 = (1. - ui)*(1.0 - ti)*bix1 + (1.0 - ui)*ti*bix2 + ui*ti*bix3 + (1.0 - ti)*ui*bix4 ;
851  byIz1 = (1. - ui)*(1.0 - ti)*biy1 + (1.0 - ui)*ti*biy2 + ui*ti*biy3 + (1.0 - ti)*ui*biy4 ;
852  if (fDebugIsOn) {
853  std::cerr << " ui " << ui << " ti " << ti << std::endl;
854  std::cerr << " bixs " << bix1 << " / " << bix2 << " / " << bix3 << " / " << bix4 << std::endl;
855  std::cerr << " biys " << biy1 << " / " << biy2 << " / " << biy3 << " / " << biy4 << std::endl;
856  std::cerr << " bxIz1 " << bxIz1 << " byIz1 " << byIz1 << std::endl;
857  }
858  if (iZ1 == iZ2) {
859  Bfield[0] = bxIz1;
860  Bfield[1] = byIz1;
861  } else {
862  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm1 =
863  fField3DMapCurrentEqualizer.find(jj1);
864  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm2 =
865  fField3DMapCurrentEqualizer.find(jj2);
866  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm3 =
867  fField3DMapCurrentEqualizer.find(jj3);
868  std::map<unsigned int, std::pair<float, float> >::const_iterator jtm4 =
869  fField3DMapCurrentEqualizer.find(jj4);
870  const double bjx1 = static_cast<double>(jtm1->second.first);
871  const double bjy1 = static_cast<double>(jtm1->second.second);
872  const double bjx2 = static_cast<double>(jtm2->second.first);
873  const double bjy2 = static_cast<double>(jtm2->second.second);
874  const double bjx3 = static_cast<double>(jtm3->second.first);
875  const double bjy3 = static_cast<double>(jtm3->second.second);
876  const double bjx4 = static_cast<double>(jtm4->second.first);
877  const double bjy4 = static_cast<double>(jtm4->second.second);
878  const double tj =
880  bxIz2 = (1. - ui)*(1.0 - tj)*bjx1 + (1.0 - ui)*tj*bjx2 + ui*tj*bjx3 + (1.0 - tj)*ui*bjx4 ;
881  byIz2 = (1. - ui)*(1.0 - tj)*bjy1 + (1.0 - ui)*tj*bjy2 + ui*tj*bjy3 + (1.0 - tj)*ui*bjy4 ;
882  if (fDebugIsOn) {
883  std::cerr << " tj " << tj << " bjxs " << bjx1 << " / " << bjx2 << " / " << bjx3 << " / " << bjx4 << std::endl;
884  std::cerr << " bjys " << bjy1 << " / " << bjy2 << " / " << bjy3 << " / " << bjy4 << std::endl;
885  std::cerr << " bxIz2 " << bxIz2 << " byIz2 " << byIz2 << std::endl;
886  }
887  const double v =
890  Bfield[0] = (1.0 - v)*bxIz1 + v*bxIz2;
891  Bfield[1] = (1.0 - v)*byIz1 + v*byIz2;
892  if (fDebugIsOn) std::cerr << " .... v " << v << " Bfield " << Bfield[0] << " / " << Bfield[1] << std::endl;
893  }
894  } // both rSqZ1 and rSqZ2 positiv
895  }
896  if (iQuadrant == 0) return;
897  double bfQ[2]; bfQ[0] = Bfield[0]; bfQ[1] = Bfield[1];
898  switch (iQuadrant ) {
899  case 1:
900  Bfield[0] = -bfQ[1]; Bfield[1] = bfQ[0]; break;
901  case 2:
902  Bfield[0] = -bfQ[0]; Bfield[1] = -bfQ[1]; break;
903  case 3:
904  Bfield[0] = bfQ[1]; Bfield[1] = -bfQ[0]; break;
905  }
906  return;
907 }
std::vector< double > fField3DMapCurrentEqualizerRadSqRStepAtZ
T abs(T value)
static int max(int a, int b)
void fillHornPolygonRadii(double z, double *rIn, double *rOut) const
std::vector< double > fField3DMapCurrentEqualizerRadSqAtZ
std::map< unsigned int, std::pair< float, float > > fField3DMapCurrentEqualizer
QTextStream & endl(QTextStream &s)
void LBNFMagneticFieldPolyconeHorn::GetFieldValue ( const double  Point[3],
double *  Bfield 
) const
virtual

Definition at line 194 of file LBNFMagneticFieldPolyconeHorn.cc.

195 {
196 // std::cerr << " LBNFMagneticFieldPolyconeHorn::GetFieldValue, z = " << Point[2] << std::endl;
197  for (size_t k=0; k!=3; ++k) Bfield[k] = 0.;
198  const double zGlobal = Point[2];
199  // Intialization of the coordinate transform.
200 // const LBNEVolumePlacements *aPlacementHandler = LBNEVolumePlacements::Instance(); // no longer needed here. See above..
201  std::vector<double> ptTrans(3,0.);
202  for (size_t k=0; k != 2; k++)
203  ptTrans[k] = Point[k] + fShift[k] + (zGlobal-fZDCBegin[0])*fShiftSlope[k];
204  if ((fCurrentEqualizerQuadAmpl > 1.) && (fField3DMapCurrentEqualizer.size() == 0)) {
205  fDebugIsOn = false; // O.K. for Now, until debugged.
207  fDebugIsOn = false;
208  }
209  if (fCurrentEqualizerQuadAmpl > 1.) {
210  // From field map..
211  double bFieldFromMap[3];
212  ptTrans[2] = zGlobal;
213  this->getFieldFrom3DMapCurrentEqualizer(&ptTrans[0], bFieldFromMap);
214  Bfield[0] = bFieldFromMap[0];
215  Bfield[1] = bFieldFromMap[1];
216  if (fHornIsMisaligned) {
217  std::vector<double> bFieldLocal(3);
218  for(size_t k=0; k != 3; k++) { bFieldLocal[k] = Bfield[k]; Bfield[k] = 0.; }
219  for (size_t k1=0; k1 !=3; k1++) {
220  for (size_t k2=0; k2 !=3; k2++) Bfield[k1] += fRotMatrixHornContainer[k1][k2]*bFieldLocal[k2];
221  }
222  }
223  return; // No Correction for skin depth effect. Will be included in the map, if need be...
224  }
225  G4double current = fHornCurrent/CLHEP::ampere/1000.;
226 // std::cerr << " LBNFMagneticFieldPolyconeHorn::GetFieldValue Z gobal " << Point[2]
227 // << " fZDCBegin, first " << fZDCBegin[0] << " last " << fZDCBegin[fZDCBegin.size() -1]
228 // << " for horn " << (hornNumber+1) << " current " << current << std::endl;
229  const double r = std::sqrt(ptTrans[0]*ptTrans[0] + ptTrans[1]*ptTrans[1]);
230  const double phi = std::atan2(Point[1], Point[0]);
231  if (r > fOuterRadius) return;
232 // if ( r < 1.0e-3) return; // The field should go smoothly to zero at the center of the horm No longer valid if Eccentricity
233 
234  double magBField = current / (5.*r/CLHEP::cm)/10*CLHEP::tesla; //B(kG)=i(kA)/[5*r(cm)], 1T=10kG
235  // Implement the azimuthal anisotropy due to imperfection of the current equalizer section.
236  const bool doCurrentEqualizerCorr = ((std::abs(fCurrentEqualizerQuadAmpl) > 1.0e-9) ||
237  (std::abs(fCurrentEqualizerOctAmpl) > 1.0e-9) );
238  if (doCurrentEqualizerCorr) {
239  double zFactAzi = 1.0e-6;
240  switch(hornNumber) {
241  case 0:
242  case 2:
243  zFactAzi = ((zGlobal - fZDCBegin[0]) > 0.) ? (zGlobal - fZDCBegin[0])/fCurrentEqualizerLongAbsLength : 1.0e-6;
244  break;
245  case 1:
246  zFactAzi = ((fZDCBegin[fZDCBegin.size() -1] - zGlobal) > 0.) ?
247  (fZDCBegin[fZDCBegin.size() -1] - zGlobal)/fCurrentEqualizerLongAbsLength : 1.0e-6;
248  break;
249  default:
250  zFactAzi = 1.0e-6; // undefined, only 3 horns
251  }
252  const double factCE = std::exp(-1.0*std::abs(zFactAzi)) * (fCurrentEqualizerQuadAmpl*std::sin(2.0*phi)
253  + fCurrentEqualizerOctAmpl*std::sin(4.0*phi));
254  magBField *= (1.0 + factCE);
255 // std::cerr << " ... Current Equalizer factor " << factCE << " Z " << zFactAzi << std::endl;
256  }
257 
258 
259  double radIC=0.;
260  double radOC=0.;
261  this->fillHornPolygonRadii(zGlobal, &radIC, &radOC);
262  if (std::abs(radIC) > 1.0e6) {
263  fEffectiveInnerRad = -1.0;
264  fEffectiveOuterRad = -1.0;
265 // std::cerr << " No effective radius at z " << zGlobal << std::endl;
266  return;
267  } else {
268 // std::cerr << " At zGlobal " << zGlobal << " zLocal " << ptTrans[2] << " radIC "
269 // << radIC << " radOC " << radOC << std::endl;
270  }
271  fEffectiveInnerRad = radIC;
272  fEffectiveOuterRad = radOC;
274  // Study of systematic effects. Define an effective radIC wich is large than the physics radIC.
275  // We assume here that the finite skin depth matter, and the current density is not
276  // uniform. Simply increase the radIC
277  if (r < radIC && (fDeltaEccentricityIO < 1.0e-20)) {
278  return; // zero field region (Amps law).
279  }
280  // We assume that the eccentricity is along the X axis. The resulting dipole will then be vertical. It does not depend on r
281  // ( the variable magField goes like 1/r )
282  // Ref: NuMI note # 710, December 14 2000.
283  //
284  double dipoleAtInnerInner = 0.;
285  if (std::abs(fDeltaEccentricityIO) > 1.0e-20) {
286  // July 22 2017: flip this sign.
287  dipoleAtInnerInner = (-1.0)*magBField*r*fDeltaEccentricityIO/(radOC*radOC - radIC*radIC);
288  if (r < radIC && (std::abs(fDeltaEccentricityIO) > 1.0e-20)) {
289  Bfield[0] = 0.;
290  Bfield[1] = dipoleAtInnerInner; // Is this realy indepedent of phi? Or an approximation
291  // We skip the eventual additional complexity of the mis-aligned horn..
292  return;
293  }
294  } else {
295  if (r < radIC) return;
296  }
297 // const double deltaRIC = radOC - radIC;
298 // Version from Dec 18-19 2013.
299 // radIC += deltaRIC*std::min(0.99, fSkinDepthCorrInnerRad);
300  //
301 // if ((r > radIC) && (r < radOC)) {
302 // const double surfCyl = radOC*radOC - radIC*radIC;
303 // const double deltaRSq = (r*r - radIC*radIC);
304 // magBField *= deltaRSq/surfCyl; // Assume uniform current density and apply Amps law.
305 // }
306 // Skin Depth effect, current disctribution in the conductor itself,
307 // and Version from Zarko's thesis. ( (MINOS Document 5694-v1) )
308 //
309  double magFieldPhi = magBField;
310  double magFieldR = 0.;
311 
312  double factRInAlum = 1.0;
313  if ((r > radIC) && (r < radOC)) {
314  const double surfCyl = radOC*radOC - radIC*radIC;
315  const double deltaRSq = (r*r - radIC*radIC);
316  factRInAlum = deltaRSq/surfCyl; // Inside the alumimum
317  fEffectiveSkinDepthFact = factRInAlum;
318  if (fSkinDepthInnerRad > 10.*CLHEP::mm) { // default assume very large skin depth, assume constant current
319  // current density .
320  magFieldPhi *= factRInAlum; // Assume uniform current density and apply Amps law.
321  } else { // Realistic skin depth.
322  magFieldPhi *= factRInAlum*getNormCurrDensityInnerC((r-radIC), (radOC-radIC))
323  /getNormCurrDensityInnerC((radOC-radIC), (radOC-radIC));
324  }
325  }
326 // Sin and cos factor bphi -> bx, by
327 // std::cerr << " ....check r " << r << " magFieldPhi "
328 // << magFieldPhi << " magBField " << magBField << std::endl;
329 //
330 // See informal document given to Alberto M and Laura F. regarding the solution of
331 // divergence equation, for the multipole expansion. Sept 29, 2016.
332 //
333  double r12Fact = 1.0;
334  if (std::abs(fDeltaEllipticityI) > 1.0e-20) {
335  // NuMi note 0710 and/or NuMI 0471
336  const double rDelta = sqrt((ptTrans[0] - fDeltaEccentricityIO)*(ptTrans[0] - fDeltaEccentricityIO) +
337  ptTrans[1]*ptTrans[1]);
340  double deltaMagFieldPhiEc = magBField * r12Fact * (fDeltaEccentricityIO / rDelta) * std::cos(phi);
341  double magFieldREc = magBField * r12Fact * (fDeltaEccentricityIO / rDelta) * std::sin(phi);
342  double deltaMagFieldPhiEl = magBField * r12Fact * fEffectiveInnerRad * (fDeltaEllipticityI /(r*r)) * std::cos(2.0*phi);
343  double magFieldREl = magBField * r12Fact * fEffectiveInnerRad * (fDeltaEllipticityI /(r * r)) * std::sin(2.0*phi);
344  // Reintroduce the bug, by setting
345 // factRInAlum = 1.;
346  magFieldPhi = factRInAlum*(magBField - deltaMagFieldPhiEl - deltaMagFieldPhiEc);
347  magFieldR = factRInAlum*(magFieldREl + magFieldREc);
348 // magFieldPhi = (magBField - deltaMagFieldPhiEl - deltaMagFieldPhiEc);
349 // magFieldR = (magFieldREl + magFieldREc);
350  // To be checked for ellipticity.
351  }
352  Bfield[0] = -magFieldPhi*ptTrans[1]/r + magFieldR*ptTrans[0]/r;
353  Bfield[1] = magFieldPhi*ptTrans[0]/r + magFieldR*ptTrans[1]/r;
354  //
355  // Analytical calculation, in cartesian coordinate, for the eccentricity.
356  //
357  if (std::abs(fDeltaEccentricityIO) > 1.0e-20) {
358  // Two Cartesian coordinate system, the first one, centered on Outer surface of the IC
359  // The second one, translated by delta, say to the left, and with critical radius radIn
360  const double ITot = magBField * r; // Up to a constant..
361  const double JTot = ITot/(radOC*radOC - radIC*radIC);
362  const double BField1Phi = (r < radOC) ? ( JTot * r) : (JTot * radOC*radOC/ r);
363  const double BField1X = -1.0*BField1Phi*std::sin(phi);
364  const double BField1Y = BField1Phi*std::cos(phi);
365  const double h1 = r * std::sin(phi);
366  const double l2 = fDeltaEccentricityIO + r*std::cos(phi);
367  const double r2 = std::sqrt(l2*l2 + h1*h1); // with respect to the displaced inner radius.
368  const double phi2 = std::atan2(h1, l2);
369  const double BField2Phi = (r2 < radIC) ? ( JTot * r2) : (JTot * radIC*radIC/ r2);
370  const double BField2X = -1.0*BField2Phi*std::sin(phi2);
371  const double BField2Y = BField2Phi*std::cos(phi2);
372  Bfield[0] = BField1X - BField2X;
373  Bfield[1] = BField1Y - BField2Y;
374  }
375 // std::cerr << " Bfield .. " << Bfield[0]/CLHEP::tesla << " / " << Bfield[1]/CLHEP::tesla
376 // << " r " << r << " radIC " << radIC << " radIC-eff " << fEffectiveInnerRad << std::endl;
377  if (doCurrentEqualizerCorr) {
378  const double kOfPhiEQ =
379  (+1.0) * ( 2.0*fCurrentEqualizerQuadAmpl*std::cos(2.0*phi) +
380  4.0*fCurrentEqualizerOctAmpl*std::cos(4.0*phi)) * std::log(r/radIC);
381  // See 2-page solution
382  // The sign has been flipped, because the sign of magBField has been flipped
383  //for the main component..
384  // Based on the arrow plot, and the divergence test.
385  Bfield[0] += (magFieldPhi*ptTrans[0]/r) * kOfPhiEQ;
386  Bfield[1] += (magFieldPhi*ptTrans[1]/r) * kOfPhiEQ;
387  // We don't bother iwth the dadial componenent, too small..
388  }
389 //
390 // Important correction.. May 27 2017... ( a bug from a long time ago !?)
391 // One needs to rotate the field as well.
392  if (fHornIsMisaligned) {
393  std::vector<double> bFieldLocal(3);
394  for(size_t k=0; k != 3; k++) { bFieldLocal[k] = Bfield[k]; Bfield[k] = 0.; }
395  for (size_t k1=0; k1 !=3; k1++) {
396  for (size_t k2=0; k2 !=3; k2++) Bfield[k1] += fRotMatrixHornContainer[k1][k2]*bFieldLocal[k2];
397  }
398 // std::cerr << " Misaligned Horn" << hornNumber+1 << ", rotation of the field ... " << std::endl;
399 // for(size_t k=0; k != 3; k++) std::cerr << " Component " << k
400 // << " local " << bFieldLocal[k] << " global " << Bfield[k] << std::endl;
401  }
402 }
void getFieldFrom3DMapCurrentEqualizer(const double Point[3], double *Bfield) const
T abs(T value)
static Entry * current
double getNormCurrDensityInnerC(double deltaR, double rOut) const
void fillHornPolygonRadii(double z, double *rIn, double *rOut) const
std::map< unsigned int, std::pair< float, float > > fField3DMapCurrentEqualizer
std::string LBNFMagneticFieldPolyconeHorn::GetFileNameFieldMapForCE ( ) const
inline
G4double LBNFMagneticFieldPolyconeHorn::GetHornCurrent ( ) const
inline
double LBNFMagneticFieldPolyconeHorn::getNormCurrDensityInnerC ( double  deltaR,
double  rOut 
) const
inlineprivate

Definition at line 111 of file LBNFMagneticFieldPolyconeHorn.hh.

111  {
112  if (deltaR < 0.) return 0.;
113  const double xby2 = fSkinDepthIIRInv*deltaR/2.; // x must be less < 1, otherwise Taylor expansion fails..
114  const double xby2Out = fSkinDepthIIRInv*rOut/2.; // x must be less < 1, otherwise Taylor expansion fails..
115  // keep only 3 terms..
116  const double ber = 1.0 - std::pow(xby2, 4.)/4. + std::pow(xby2, 8.)/576.;
117  const double bei = std::pow(xby2, 2.) - std::pow(xby2, 6.)/36 + std::pow(xby2, 10.)/14400.;
118  const double beNSq = ber*ber + bei*bei;
119  const double berOut = 1.0 - std::pow(xby2Out, 4.)/4. + std::pow(xby2Out, 8.)/576.;
120  const double beiOut = std::pow(xby2Out, 2.) - std::pow(xby2Out, 6.)/36 + std::pow(xby2Out, 10.)/14400.;
121  const double beNSqOut = berOut*berOut + beiOut*beiOut;
122  return std::sqrt(beNSq/beNSqOut);
123  }
constexpr T pow(T x)
Definition: pow.h:72
void LBNFMagneticFieldPolyconeHorn::readFieldMapCurrentEqualizer ( ) const

Definition at line 1060 of file LBNFMagneticFieldPolyconeHorn.cc.

1060  {
1061 
1062  std::ifstream fInDat(fFileNameFieldMapForCE.c_str(), std::ios::in | std::ios::binary);
1063  if (!fInDat.is_open()) {
1064  std::string msg(" LBNFMagneticFieldPolyconeHorn::readFieldMapCurrentEqualizer, could not open file ");
1066  G4Exception("LBNFMagneticFieldPolyconeHorn::readFieldMapCurrentEqualizer", " ", RunMustBeAborted, msg.c_str());
1067  }
1068  char *pTmp1 = (char*) &fCurrentEqualizerLongAbsLength;
1069  fInDat.read(pTmp1, sizeof(double));
1070  char *pTmp2 = (char*) &fCurrentEqualizerQuadAmpl;
1071  fInDat.read(pTmp2, sizeof(double));
1072  char *pTmp = (char*) &fNumZPtsForCE;
1073  fInDat.read(pTmp, sizeof(unsigned int));
1074  pTmp = (char*) &fNumRPtsForCE;
1075  fInDat.read(pTmp, sizeof(unsigned int));
1076  pTmp = (char*) &fNumPhiPtsForCE;
1077  fInDat.read(pTmp, sizeof(unsigned int));
1078  size_t lTotMap = 0;
1079  pTmp = (char*) &lTotMap;
1080  fInDat.read(pTmp, sizeof(size_t));
1081  std::cerr << " LBNFMagneticFieldPolyconeHorn::readFieldMapCurrentEqualizer "
1082  << std::endl << " ...... Size of map in file "
1083  << lTotMap << " Grid " << fNumZPtsForCE << " / " << fNumRPtsForCE << " / " << fNumPhiPtsForCE << std::endl;
1084  for (size_t i=0; i!= lTotMap; i++) {
1085  unsigned int ii = 0;
1086  pTmp = (char*) &ii;
1087  fInDat.read(pTmp, sizeof(unsigned int));
1088  float bb[2];
1089  pTmp = (char*) &bb[0];
1090  fInDat.read(pTmp, 2*sizeof(float));
1091  fField3DMapCurrentEqualizer.emplace(ii, std::pair<float, float>(bb[0], bb[1]));
1092  }
1095  fField3DMapCurrentEqualizerPhiStep = (M_PI/2.)/(fNumPhiPtsForCE-1); // Only one quadrant..
1098  for (unsigned int iZ = 0; iZ != fNumZPtsForCE; iZ++) {
1099 // std::cerr << " At Z index " << iZ << std::endl;
1101  double radIC=0.;
1102  double radOC=0.;
1103  this->fillHornPolygonRadii(z, &radIC, &radOC);
1104  fField3DMapCurrentEqualizerRadSqAtZ.push_back(radOC*radOC);
1105  double stepRadial = (fOuterRadius*fOuterRadius - radOC*radOC)/(fNumRPtsForCE-1);
1106  fField3DMapCurrentEqualizerRadSqRStepAtZ.push_back(stepRadial);
1107  }
1108  fInDat.close();
1109  this->dumpField();
1110  std::cerr << " And quit !. " << std::endl; exit(2);
1111 
1112 }
std::vector< double > fField3DMapCurrentEqualizerRadSqRStepAtZ
void msg(const char *fmt,...)
Definition: message.cpp:107
std::string string
Definition: nybbler.cc:12
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:45
double z
QString read()
void fillHornPolygonRadii(double z, double *rIn, double *rOut) const
std::vector< double > fField3DMapCurrentEqualizerRadSqAtZ
std::map< unsigned int, std::pair< float, float > > fField3DMapCurrentEqualizer
QTextStream & endl(QTextStream &s)
void LBNFMagneticFieldPolyconeHorn::SetCurrentEqualizerLongAbsLength ( double  v)
inline
void LBNFMagneticFieldPolyconeHorn::SetCurrentEqualizerOctAmpl ( double  v)
inline
void LBNFMagneticFieldPolyconeHorn::SetCurrentEqualizerQuadAmpl ( double  v)
inline
void LBNFMagneticFieldPolyconeHorn::SetDeltaEccentricityIO ( G4double  f)
inline
void LBNFMagneticFieldPolyconeHorn::SetDeltaEllipticityI ( G4double  f)
inline
void LBNFMagneticFieldPolyconeHorn::SetEffectiveLength ( double  z)
inline
void LBNFMagneticFieldPolyconeHorn::SetFileNameFieldMapForCE ( std::string  s)
inline

Definition at line 141 of file LBNFMagneticFieldPolyconeHorn.hh.

static QCString * s
Definition: config.cpp:1042
void LBNFMagneticFieldPolyconeHorn::SetHornCurrent ( G4double  ihorn)
inline
void LBNFMagneticFieldPolyconeHorn::SetSkinDepthInnerRad ( G4double  f)
inline
void LBNFMagneticFieldPolyconeHorn::SetZShiftDrawingCoordinate ( double  z)
inline
void LBNFMagneticFieldPolyconeHorn::TestDivergence ( int  opt) const

Definition at line 585 of file LBNFMagneticFieldPolyconeHorn.cc.

585  {
586 //
587 // Test that it satisfy Maxwell equation, div B = 0
588 //
589 // Since we compute in polar coordinate system, do it Cartesian..
590 //
591  G4ThreeVector dir;
592  double pos[3];
593  size_t iPtZSel = fRadsInnerC.size()/2;
594  pos[2] = fZDCBegin[iPtZSel];
595  double radIC=0.;
596  double radOC=0.;
597  radOC += 1.5*CLHEP::mm;
598  this->fillHornPolygonRadii(pos[2], &radIC, &radOC);
599  std::string fNameOut;
600  switch (opt) {
601  case 0:
602  dir = G4ThreeVector(std::sqrt(1.0-0.01), 0.1, 0.);
603  pos[0] = 1.1*radOC; pos[1] = 0.1;
604  fNameOut=std::string("./LBNFMagneticFieldPolyconeHorn_TestDivergence_X_v1.txt");
605  break;
606  case 1:
607  dir = G4ThreeVector(0.1, std::sqrt(1.0-0.01), 0.);
608  pos[1] = 1.1*radOC; pos[0] = 0.1;
609  fNameOut=std::string("./LBNFMagneticFieldPolyconeHorn_TestDivergence_Y_v1.txt");
610  break;
611  case 2:
612  dir = G4ThreeVector(0.480729, sqrt(1.0 - (0.480729*0.480729)), 0.);
613  pos[0] = 1.1*radIC/std::sqrt(2.); pos[1] = pos[0];
614  fNameOut=std::string("./LBNFMagneticFieldPolyconeHorn_TestDivergence_U_v1.txt");
615  break;
616  default:
617  std::cerr << "LBNFMagneticFieldPolyconeHorn::TestDivergence Valid switches so far are 0, 1 or 2" << std::endl;
618  exit(1);
619  }
620  std::ofstream fOut(fNameOut.c_str());
621  fOut << " x y r bx by b dbdx dbdy obnablab " << std::endl;
622  const double step = 0.002*CLHEP::mm;
623  double deltaMaxCart = 0.;
624  const double range = fOuterRadius - fRadsOuterC[iPtZSel]- 2.5*CLHEP::mm;
625  const int numPts = static_cast<int> (range/step);
626  std::cerr << " LBNFMagneticFieldPolyconeHorn::TestDivergence, number of pts "
627  << numPts << " Z location for scan " << pos[2] << " radii "
628  << radIC << " / " << fOuterRadius << std::endl;
629  double bFieldPrev[3]; double bField[3]; double posPrevious[3];
630  for (size_t kk=0; kk != 3; kk++) { posPrevious[kk] = pos[kk]; bFieldPrev[kk] = 0.; }
631  double dbVal[3]; dbVal[2] = 0.; // assume Bz = 0.
632  double bdlIntegral = 0.;
633  for (int iStep = 0; iStep != numPts; iStep++) {
634  this->GetFieldValue(pos, bField);
635  const double bNorm = std::sqrt( bField[0]*bField[0] + bField[1]*bField[1]);
636 
637  if (bNorm < 1.0e-10) {
638  for (size_t k=0; k!=3; k++) {
639  bFieldPrev[k] = 0.;
640  posPrevious[k] = pos[k];
641  pos[k] += step*dir[k];
642  }
643  continue;
644  }
645  bdlIntegral += bField[0]*step*dir[1] - bField[1]*step*dir[0];
646  const double phi = std::atan2(pos[1], pos[0]);
647  if (iStep != 0) {
648  dbVal[0] = std::cos(phi) * (bField[0] - bFieldPrev[0])/(pos[0] - posPrevious[0]);
649  dbVal[1] = std::sin(phi) * (bField[1] - bFieldPrev[1])/(pos[1] - posPrevious[1]);
650  const double dd = (1.0/bNorm)*(dbVal[0] + dbVal[1]);
651  fOut << " " << pos[0] << " " << pos[1] << " " << std::sqrt(pos[0]*pos[0] + pos[1]*pos[1])
652  << " " << bField[0]/CLHEP::tesla << " " << bField[1]/CLHEP::tesla
653  << " " << bNorm/CLHEP::tesla << " "
654  << dbVal[0]/bNorm << " " << dbVal[1]/bNorm << " " << dd << std::endl;
655  deltaMaxCart = std::max(std::abs(dd), deltaMaxCart);
656  }
657  for (size_t k=0; k!=3; k++) {
658  bFieldPrev[k] = bField[k];
659  posPrevious[k] = pos[k];
660  pos[k] += step*dir[k];
661  }
662  }
663  std::cerr << " LBNFMagneticFieldPolyconeHorn::TestDivergence, final max deviation (rel) "
664  << deltaMaxCart << " Integral bdl " << bdlIntegral/(CLHEP::tesla*CLHEP::meter) << std::endl;
665  fOut.close();
666 // std::cerr << " And quit for now " << std::endl; exit(2);
667 
668 }
std::string string
Definition: nybbler.cc:12
opt
Definition: train.py:196
virtual void GetFieldValue(const double Point[3], double *Bfield) const
T abs(T value)
static int max(int a, int b)
void fillHornPolygonRadii(double z, double *rIn, double *rOut) const
QTextStream & endl(QTextStream &s)
void LBNFMagneticFieldPolyconeHorn::TestEccentricityBerkeley ( ) const

Definition at line 1113 of file LBNFMagneticFieldPolyconeHorn.cc.

1113  {
1114 //
1115 // July 25 2017..
1116 //
1117 // Alberto M. suggested the following exercise: Let us take the algorithm in the GetFieldValue method,
1118 // fill in the radOC and radIC value such that it corresponds to the problem ??? (needs reference )
1119 //
1120  std::vector<double> Bfield(2, 0.);
1121  std::vector<double> BfieldB(2, 0.);
1122  const double radOC = 6.0*CLHEP::mm;
1123  const double radIC = 2.0*CLHEP::mm;
1124  const double aBer = radIC;
1125  const double deltaE = radIC;
1126  std::ofstream fOut("./TestEccentricityBerkelyV1.txt");
1127  fOut << " x y Bx By BxB ByB " << std::endl;
1128  const int numStepY = 50;
1129  const double stepY = 2*(radIC - 0.01)/numStepY;
1130  const int numStepX = 200;
1131  const double stepX = 3*radOC/numStepX;
1132  G4double current = fHornCurrent/CLHEP::ampere/1000.;
1133  const double magBField = current / (5./CLHEP::cm)/10*CLHEP::tesla; //B(kG)=i(kA)/[5*r(cm)], 1T=10kG
1134 // double magBField = current / (5.*r/CLHEP::cm)/10*CLHEP::tesla; //B(kG)=i(kA)/[5*r(cm)], 1T=10kG ..
1135 // from GetFieldValue
1136  const double magBFieldB = 2.0*M_PI*magBField; // adjusted.. Pretty sure the constant above is correct!.
1137  for (int iy =0; iy != numStepY+1; iy++) {
1138  const double y = (iy == numStepY) ? 0. : -radIC + 0.5*stepY + iy*stepY;
1139  // last loop around is for the test along the X axis
1140  for (int ix =0; ix != numStepX; ix++) {
1141  const double x = -1.5*radOC + 0.5*stepX + ix*stepX;
1142  const double r = std::sqrt(x*x + y*y);
1143  const double phi = std::atan2(y, x);
1144  // cloned from GetFieldValue..
1145 
1146  // Two Cartesian coordinate system, the first one, centered on Outer surface of the IC
1147  // The second one, translated by delta, say to the left, and with critical radius radIn
1148 // const double ITot = magBField * r; // Up to a constant.. We don't multiply by r, see above the
1149  const double ITot = magBField; // Up to a constant.. We don't multiply by r, see above the
1150  // definition of constant magBField..
1151  const double JTot = ITot/(radOC*radOC - radIC*radIC);
1152  const double BField1Phi = (r < radOC) ? ( JTot * r) : (JTot * radOC*radOC/ r);
1153  const double BField1X = -1.0*BField1Phi*std::sin(phi);
1154  const double BField1Y = BField1Phi*std::cos(phi);
1155  const double h1 = r * std::sin(phi);
1156 // const double l2 = fDeltaEccentricityIO + r*std::cos(phi);
1157  const double l2 = (-1.0*deltaE) + r*std::cos(phi); // sign convention on delta change..
1158  const double r2 = std::sqrt(l2*l2 + h1*h1); // with respect to the displaced inner radius.
1159  const double phi2 = std::atan2(h1, l2);
1160  const double BField2Phi = (r2 < radIC) ? ( JTot * r2) : (JTot * radIC*radIC/ r2);
1161  const double BField2X = -1.0*BField2Phi*std::sin(phi2);
1162  const double BField2Y = BField2Phi*std::cos(phi2);
1163  Bfield[0] = BField1X - BField2X;
1164  Bfield[1] = BField1Y - BField2Y;
1165 
1166  // Now the BerKeley soution..
1167  BfieldB[0] = 0.;
1168  BfieldB[1] = 0.;
1169  const double r1 = r2; // notation in the Berkeley book
1170  if (r1 < radIC) {
1171  BfieldB[1] = magBFieldB/ (16.0*M_PI*aBer);
1172  } else {
1173  // valid only along the X - axis
1174  if (iy == numStepY) {
1175  if (std::abs(x) > radOC) {
1176  BfieldB[1] = (8.0*x - 9.0*aBer)*magBFieldB/(16.0*M_PI*x*(x - aBer));
1177  } else if ((((2.0*aBer <= x) && (x <= radOC))) || (((-radOC <= x) && (x <= 0)))) {
1178  BfieldB[1] = (x*x -aBer*x -aBer*aBer)*magBFieldB/(16.0*M_PI*aBer*aBer*(x - aBer));
1179  } else {
1180  std::cerr << " Unexpected case in LBNFMagneticFieldPolyconeHorn::TestEccentricityBerkeley " <<
1181  " x " << x << " y " << y << " r1 " << r1 << " iy " << iy<< std::endl;
1182  exit(2);
1183  }
1184  }
1185  }
1186  fOut << " " << x << " " << y << " "
1187  << Bfield[0] << " " << Bfield[1] << " " << BfieldB[0] << " " << BfieldB[1] << std::endl;
1188  }
1189  }
1190  fOut.close();
1191  std::cerr << " And quit for now.. " << std::endl; exit(2);
1192 
1193 }
double y
T abs(T value)
static Entry * current
list x
Definition: train.py:276
QTextStream & endl(QTextStream &s)
void LBNFMagneticFieldPolyconeHorn::writeFieldMapCurrentEqualizer ( ) const

Definition at line 1022 of file LBNFMagneticFieldPolyconeHorn.cc.

1022  {
1023 
1024  std::ostringstream fNameOutStrStr;
1025  fNameOutStrStr << "./FieldMapCEQ_Horn_" << (hornNumber +1)
1026  << "_LAbs_" << static_cast<int>(fCurrentEqualizerLongAbsLength)
1027  << "_Quad_" << static_cast<int>(fCurrentEqualizerQuadAmpl)
1028  << "_NZ_" << fNumZPtsForCE << "_NR_" << fNumRPtsForCE
1029  << "_NP_" << fNumPhiPtsForCE << ".dat";
1030  std::string fNameOutStr(fNameOutStrStr.str());
1031  std::ofstream fOutDat (fNameOutStr.c_str(), std::ios::out | std::ios::binary);
1032  const char *pTmp1 = (const char*) &fCurrentEqualizerLongAbsLength;
1033  fOutDat.write(pTmp1, sizeof(double));
1034  const char *pTmp2 = (const char*) &fCurrentEqualizerQuadAmpl;
1035  fOutDat.write(pTmp2, sizeof(double));
1036  char *pTmp = (char*) &fNumZPtsForCE;
1037  fOutDat.write(pTmp, sizeof(unsigned int));
1038  pTmp = (char*) &fNumRPtsForCE;
1039  fOutDat.write(pTmp, sizeof(unsigned int));
1040  pTmp = (char*) &fNumPhiPtsForCE;
1041  fOutDat.write(pTmp, sizeof(unsigned int));
1042  size_t lTotMap = fField3DMapCurrentEqualizer.size();
1043  pTmp = (char*) &lTotMap;
1044  fOutDat.write(pTmp, sizeof(size_t));
1045  for (std::map<unsigned int, std::pair<float, float> >::const_iterator it = fField3DMapCurrentEqualizer.begin();
1046  it != fField3DMapCurrentEqualizer.end(); it++) {
1047  unsigned int ii = it->first;
1048  pTmp = (char*) &ii;
1049  fOutDat.write(pTmp, sizeof(unsigned int));
1050  float bb[2];
1051  bb[0] = it->second.first;
1052  bb[1] = it->second.second;
1053  pTmp = (char*) &bb[0];
1054  fOutDat.write(pTmp, 2*sizeof(float));
1055  }
1056  fOutDat.close();
1057 
1058 }
std::string string
Definition: nybbler.cc:12
std::map< unsigned int, std::pair< float, float > > fField3DMapCurrentEqualizer

Member Data Documentation

double LBNFMagneticFieldPolyconeHorn::fCurrentEqualizerLongAbsLength
private

Definition at line 45 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fCurrentEqualizerOctAmpl
private

Definition at line 50 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fCurrentEqualizerQuadAmpl
private

Definition at line 48 of file LBNFMagneticFieldPolyconeHorn.hh.

bool LBNFMagneticFieldPolyconeHorn::fDebugIsOn
mutableprivate

Definition at line 57 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fDeltaEccentricityIO
private

Definition at line 41 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fDeltaEllipticityI
private

Definition at line 43 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fEffectiveInnerRad
mutableprivate

Definition at line 58 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fEffectiveLength
private

Definition at line 34 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fEffectiveOuterRad
mutableprivate

Definition at line 59 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fEffectiveSkinDepthFact
mutableprivate

Definition at line 60 of file LBNFMagneticFieldPolyconeHorn.hh.

std::map<unsigned int, std::pair<float, float> > LBNFMagneticFieldPolyconeHorn::fField3DMapCurrentEqualizer
mutableprivate

Definition at line 77 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fField3DMapCurrentEqualizerPhiStep
mutableprivate

Definition at line 75 of file LBNFMagneticFieldPolyconeHorn.hh.

std::vector<double> LBNFMagneticFieldPolyconeHorn::fField3DMapCurrentEqualizerRadSqAtZ
mutableprivate

Definition at line 78 of file LBNFMagneticFieldPolyconeHorn.hh.

std::vector<double> LBNFMagneticFieldPolyconeHorn::fField3DMapCurrentEqualizerRadSqRStepAtZ
mutableprivate

Definition at line 79 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fField3DMapCurrentEqualizerZMin
mutableprivate

Definition at line 73 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fField3DMapCurrentEqualizerZStep
mutableprivate

Definition at line 74 of file LBNFMagneticFieldPolyconeHorn.hh.

std::string LBNFMagneticFieldPolyconeHorn::fFileNameFieldMapForCE
private

Definition at line 68 of file LBNFMagneticFieldPolyconeHorn.hh.

G4double LBNFMagneticFieldPolyconeHorn::fHornCurrent
private

Definition at line 27 of file LBNFMagneticFieldPolyconeHorn.hh.

bool LBNFMagneticFieldPolyconeHorn::fHornIsMisaligned
private

Definition at line 32 of file LBNFMagneticFieldPolyconeHorn.hh.

unsigned int LBNFMagneticFieldPolyconeHorn::fNumPhiPtsForCE
mutableprivate

Definition at line 71 of file LBNFMagneticFieldPolyconeHorn.hh.

unsigned int LBNFMagneticFieldPolyconeHorn::fNumRPtsForCE
mutableprivate

Definition at line 70 of file LBNFMagneticFieldPolyconeHorn.hh.

unsigned int LBNFMagneticFieldPolyconeHorn::fNumZPtsForCE
mutableprivate

Definition at line 69 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fOuterRadius
private

Definition at line 35 of file LBNFMagneticFieldPolyconeHorn.hh.

double LBNFMagneticFieldPolyconeHorn::fOuterRadiusEff
private

Definition at line 35 of file LBNFMagneticFieldPolyconeHorn.hh.

std::ofstream LBNFMagneticFieldPolyconeHorn::fOutTraj
mutableprivate

Definition at line 53 of file LBNFMagneticFieldPolyconeHorn.hh.

std::vector<double> LBNFMagneticFieldPolyconeHorn::fRadsInnerC
private

Definition at line 30 of file LBNFMagneticFieldPolyconeHorn.hh.

std::vector<double> LBNFMagneticFieldPolyconeHorn::fRadsOuterC
private

Definition at line 31 of file LBNFMagneticFieldPolyconeHorn.hh.

G4RotationMatrix LBNFMagneticFieldPolyconeHorn::fRotMatrixHornContainer
private

Definition at line 33 of file LBNFMagneticFieldPolyconeHorn.hh.

std::vector<double> LBNFMagneticFieldPolyconeHorn::fShift
private

Definition at line 64 of file LBNFMagneticFieldPolyconeHorn.hh.

std::vector<double> LBNFMagneticFieldPolyconeHorn::fShiftSlope
private

Definition at line 65 of file LBNFMagneticFieldPolyconeHorn.hh.

G4double LBNFMagneticFieldPolyconeHorn::fSkinDepth
private

Definition at line 38 of file LBNFMagneticFieldPolyconeHorn.hh.

G4double LBNFMagneticFieldPolyconeHorn::fSkinDepthIIRInv
private

Definition at line 40 of file LBNFMagneticFieldPolyconeHorn.hh.

G4double LBNFMagneticFieldPolyconeHorn::fSkinDepthInnerRad
private

Definition at line 39 of file LBNFMagneticFieldPolyconeHorn.hh.

std::vector<double> LBNFMagneticFieldPolyconeHorn::fZDCBegin
private

Definition at line 29 of file LBNFMagneticFieldPolyconeHorn.hh.

G4double LBNFMagneticFieldPolyconeHorn::fZShiftDrawingCoordinate
mutableprivate

Definition at line 66 of file LBNFMagneticFieldPolyconeHorn.hh.

size_t LBNFMagneticFieldPolyconeHorn::hornNumber
private

Definition at line 26 of file LBNFMagneticFieldPolyconeHorn.hh.


The documentation for this class was generated from the following files: