8 #include "G4VPhysicalVolume.hh" 10 #include "G4TransportationManager.hh" 13 #include "Randomize.hh" 24 fOuterRadiusEff(1.0e9),
25 fSkinDepth(4.1*
CLHEP::mm),
26 fSkinDepthInnerRad(1.0e10*
CLHEP::mm),
27 fSkinDepthIIRInv(
std::sqrt(2)/fSkinDepthInnerRad),
28 fDeltaEccentricityIO(0.),
29 fDeltaEllipticityI(0.),
43 double zzMinTmp = 1.0e20;
44 double zzMaxTmp = -1.0e20;
49 const double epsil = 0.050*CLHEP::mm;
50 for (
size_t k=0;
k != nPts;
k++) {
65 std::cerr <<
"LBNFMagneticFieldPolyconeHorn::LBNFMagneticFieldPolyconeHorn, CD HornA, fZShiftDrawingCoordinate " 72 std::cerr <<
" .... /Rin/Rout map, global coordinate system " <<
std::endl;
74 std::cerr <<
" " <<
k <<
" " 81 std::cerr <<
"LBNFMagneticFieldPolyconeHorn::LBNFMagneticFieldPolyconeHorn, CD HornB, fZShiftDrawingCoordinate " 87 std::cerr <<
" .... /Rin/Rout map, global coordinate system " <<
std::endl;
89 std::cerr <<
" " <<
k <<
" " 97 std::cerr <<
"LBNFMagneticFieldPolyconeHorn::LBNFMagneticFieldPolyconeHorn, CD HornC, fZShiftDrawingCoordinate " 103 std::cerr <<
" .... /Rin/Rout map, global coordinate system " <<
std::endl;
105 std::cerr <<
" " <<
k <<
" " 132 std::ostringstream hornIndexStrStr; hornIndexStrStr <<
hornNumber+1;
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 " 153 for (
size_t k=0;
k!=2;
k++) {
154 fShift[
k] = -0.50*(pUpLeft[
k] + pUpRight[
k]);
160 std::ostringstream aNameStrStr; aNameStrStr <<
"LBNFSimpleHorn" << (hornNumber+1) <<
"Container";
162 if (hornNumber == 0) namePlacedVol =
std::string(
"Horn1PolyM1");
164 aPlacementHandler->
Find(
"BFieldInitialization", namePlacedVol.c_str(),
"BFieldInitialization");
166 std::cerr <<
" Horn " << hornNumber+1 <<
" is misaligned " 197 for (
size_t k=0;
k!=3; ++
k) Bfield[
k] = 0.;
198 const double zGlobal = Point[2];
201 std::vector<double> ptTrans(3,0.);
202 for (
size_t k=0;
k != 2;
k++)
211 double bFieldFromMap[3];
212 ptTrans[2] = zGlobal;
214 Bfield[0] = bFieldFromMap[0];
215 Bfield[1] = bFieldFromMap[1];
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++) {
229 const double r = std::sqrt(ptTrans[0]*ptTrans[0] + ptTrans[1]*ptTrans[1]);
230 const double phi = std::atan2(Point[1], Point[0]);
234 double magBField = current / (5.*r/CLHEP::cm)/10*CLHEP::tesla;
238 if (doCurrentEqualizerCorr) {
239 double zFactAzi = 1.0e-6;
254 magBField *= (1.0 + factCE);
284 double dipoleAtInnerInner = 0.;
290 Bfield[1] = dipoleAtInnerInner;
295 if (r < radIC)
return;
309 double magFieldPhi = magBField;
310 double magFieldR = 0.;
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;
320 magFieldPhi *= factRInAlum;
333 double r12Fact = 1.0;
337 ptTrans[1]*ptTrans[1]);
340 double deltaMagFieldPhiEc = magBField * r12Fact * (
fDeltaEccentricityIO / rDelta) * std::cos(phi);
346 magFieldPhi = factRInAlum*(magBField - deltaMagFieldPhiEl - deltaMagFieldPhiEc);
347 magFieldR = factRInAlum*(magFieldREl + magFieldREc);
352 Bfield[0] = -magFieldPhi*ptTrans[1]/r + magFieldR*ptTrans[0]/
r;
353 Bfield[1] = magFieldPhi*ptTrans[0]/r + magFieldR*ptTrans[1]/
r;
360 const double ITot = magBField *
r;
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);
367 const double r2 = std::sqrt(l2*l2 + h1*h1);
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;
377 if (doCurrentEqualizerCorr) {
378 const double kOfPhiEQ =
385 Bfield[0] += (magFieldPhi*ptTrans[0]/
r) * kOfPhiEQ;
386 Bfield[1] += (magFieldPhi*ptTrans[1]/
r) * kOfPhiEQ;
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++) {
406 std::ostringstream fNameStr; fNameStr <<
"./FieldMapHornTmpV3" << (
hornNumber +1);
408 else fNameStr <<
".txt";
410 std::ofstream fOut(fName.c_str());
414 const double zStart = 2219.;
416 const double zEnd = 2219.0000001;
417 std::cerr <<
"LBNFMagneticFieldPolyconeHorn::dumpField .. fZShiftDrawingCoordinate " 419 <<
" Z start/end " << zStart <<
"/" << zEnd <<
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;
433 for (
int iZ=0; iZ !=numZStep; iZ++) {
434 double z = zStart + iZ*zStep;
436 const double zLocD = point[2];
437 double radIC = 0.;
double radOC = 0.;
439 double r = radIC - 0.25*CLHEP::mm;
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);
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;
456 fOut <<
" z zd x y r bphi br bx by " <<
std::endl;
460 const int numZStep = 1;
461 const int numRStep= 200;
462 const int numPhiStep= 100;
463 const double zStep = (zEnd-zStart)/numZStep;
465 const double rInit = 20.;
467 const double rMax = 50.0*CLHEP::mm;
469 const double rStep = (rMax - rInit)/numRStep;
470 for (
int iZ=0; iZ !=numZStep; iZ++) {
471 double z = zStart + iZ*zStep;
473 const double zLocD = point[2];
474 double radIC = 0.;
double radOC = 0.;
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);
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;
495 std::cerr <<
" And quit for now... " <<
std::endl; exit(2);
500 std::ostringstream fNameAStr;
501 fNameAStr <<
"./FieldMapHorn" << (
hornNumber +1)
504 fOut.open(fNameA.c_str());
507 const int numPhi = 10.;
508 const double stepPhi = (M_PI/2.) / numPhi;
513 const double zLoc = pos[2];
514 double radICAr=0.;
double radOCAr=0.;
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;
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);
527 fOut <<
" " << pos[0] <<
" " << pos[1] <<
" " << r <<
" " 528 << bField[0]/CLHEP::tesla <<
" " << bField[1]/CLHEP::tesla <<
std::endl;
536 std::ostringstream fNameBStr; fNameBStr <<
"./FieldMapHornCEQ_" << (
hornNumber +1) <<
"_Debug.txt";
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;
545 double radIC;
double radOC;
548 for (
int iZCE=0; iZCE != 10; iZCE++) {
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);
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);
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;
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;
597 radOC += 1.5*CLHEP::mm;
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");
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");
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");
617 std::cerr <<
"LBNFMagneticFieldPolyconeHorn::TestDivergence Valid switches so far are 0, 1 or 2" <<
std::endl;
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.;
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 " 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.;
632 double bdlIntegral = 0.;
633 for (
int iStep = 0; iStep != numPts; iStep++) {
635 const double bNorm = std::sqrt( bField[0]*bField[0] + bField[1]*bField[1]);
637 if (bNorm < 1.0e-10) {
638 for (
size_t k=0;
k!=3;
k++) {
640 posPrevious[
k] = pos[
k];
641 pos[
k] += step*dir[
k];
645 bdlIntegral += bField[0]*step*dir[1] - bField[1]*step*dir[0];
646 const double phi = std::atan2(pos[1], pos[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;
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];
663 std::cerr <<
" LBNFMagneticFieldPolyconeHorn::TestDivergence, final max deviation (rel) " 664 << deltaMaxCart <<
" Integral bdl " << bdlIntegral/(CLHEP::tesla*CLHEP::meter) << std::endl;
670 const double Point[3],
double *Bfield)
const {
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.;
677 const unsigned int iZ1 =
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 =
688 const unsigned int iPhi2 = (iPhi1 == (
fNumPhiPtsForCE-1)) ? 0 : (iPhi1 + 1);
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];
694 const double rSqZ2 = rSqRequested - fField3DMapCurrentEqualizerRadSqAtZ[iZ2];
695 if ((rSqZ1 < 0.) && (rSqZ2 < 0.))
return;
696 double radOCAtZ = 0.;
697 double radICAtZ = 0.;
698 if ((rSqZ1 < 0.) || (rSqZ2 < 0.)) {
700 if (rSqRequested < (radOCAtZ*radOCAtZ))
return;
703 const unsigned int iR2Z1 = (rSqZ1 < 0.) ? 0 : ((iR1Z1 == (
fNumRPtsForCE-1)) ? iR1Z1 : (iR1Z1 + 1));
705 const unsigned int iR2Z2 = (rSqZ2 < 0.) ? 0 : ((iR1Z2 == (
fNumRPtsForCE-1)) ? iR1Z2 : (iR1Z2 + 1));
708 if (
fDebugIsOn) std::cerr <<
" ..... RsQ, Z1 " << rSqZ1 <<
" at Z2 " << rSqZ2 <<
" indices " 709 << iR1Z1 <<
" / " << iR2Z1 <<
" / " << iR1Z2 <<
" / " << iR2Z2 <<
std::endl;
719 if (
fDebugIsOn) std::cerr <<
" ..... ii indices " << ii1 <<
" / " << ii2 <<
" / " << ii3 <<
" / " << ii4
721 double bxIz1 = 0.;
double byIz1 = 0.;
728 double bxIz2 = 0.;
double byIz2 = 0.;
729 if (((iR2Z1 == iR1Z1) || (iR2Z2 == iR1Z2)) && (iR1Z1 != 0) &&
730 (iR1Z2 != 0) && (iR2Z1 != 0) && (iR2Z2 != 0) ) {
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;
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;
759 Bfield[0] = (1.0 - v)*bxIz1 + v*bxIz2;
760 Bfield[1] = (1.0 - v)*byIz1 + v*byIz2;
762 if (
fDebugIsOn) std::cerr <<
" ....Phi/Z interpolation only. " 763 <<
" Bfield " << Bfield[0] <<
" / " << Bfield[1] <<
std::endl;
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);
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 ;
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;
796 if (
fDebugIsOn) std::cerr <<
" .... v " << v <<
" Bfield " << Bfield[0] <<
" / " << Bfield[1] <<
std::endl;
797 }
else if (rSqZ2 < 0.) {
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);
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 ;
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;
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;
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);
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 ;
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;
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);
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 ;
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;
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;
896 if (iQuadrant == 0)
return;
897 double bfQ[2]; bfQ[0] = Bfield[0]; bfQ[1] = Bfield[1];
898 switch (iQuadrant ) {
900 Bfield[0] = -bfQ[1]; Bfield[1] = bfQ[0];
break;
902 Bfield[0] = -bfQ[0]; Bfield[1] = -bfQ[1];
break;
904 Bfield[0] = bfQ[1]; Bfield[1] = -bfQ[0];
break;
917 if (
fDebugIsOn) std::cerr <<
" LBNFMagneticFieldPolyconeHorn::fill3DMapCurrentEqualizer, starting .. " <<
std::endl;
919 double magBField = current / (5./CLHEP::cm)/10*CLHEP::tesla;
929 const int numWires = 500;
930 const double phiWStep = 2.0*M_PI/numWires;
940 double zFactAzi = 1.0e-6;
953 const double factCE = std::exp(-1.0*
std::abs(zFactAzi));
955 std::cerr <<
" At z = " << z <<
"radIC " << radIC <<
" radOC " 956 << radOC <<
" zFactAzi " << factCE <<
" " << magBField <<
std::endl;
961 const double r = 1.0e-12 + sqrt(radOC*radOC + iR*stepRadial);
964 const double xP = r * std::cos(phi);
965 const double yP = r * std::sin(phi);
966 double bX = 0.;
double bY = 0.;
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));
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;
990 if (sumCurrent < 1.0e-10) { bX = 0.; bY = 0.; }
else {
991 bX *=magBField/sumCurrent; bY *= magBField/sumCurrent;
995 std::pair<float, float>(static_cast<float>(bX), static_cast<float>(bY)));
1024 std::ostringstream fNameOutStrStr;
1025 fNameOutStrStr <<
"./FieldMapCEQ_Horn_" << (
hornNumber +1)
1031 std::ofstream fOutDat (fNameOutStr.c_str(), std::ios::out | std::ios::binary);
1033 fOutDat.write(pTmp1,
sizeof(
double));
1035 fOutDat.write(pTmp2,
sizeof(
double));
1037 fOutDat.write(pTmp,
sizeof(
unsigned int));
1039 fOutDat.write(pTmp,
sizeof(
unsigned int));
1041 fOutDat.write(pTmp,
sizeof(
unsigned int));
1043 pTmp = (
char*) &lTotMap;
1044 fOutDat.write(pTmp,
sizeof(
size_t));
1047 unsigned int ii = it->first;
1049 fOutDat.write(pTmp,
sizeof(
unsigned int));
1051 bb[0] = it->second.first;
1052 bb[1] = it->second.second;
1053 pTmp = (
char*) &bb[0];
1054 fOutDat.write(pTmp, 2*
sizeof(
float));
1063 if (!fInDat.is_open()) {
1064 std::string msg(
" LBNFMagneticFieldPolyconeHorn::readFieldMapCurrentEqualizer, could not open file ");
1066 G4Exception(
"LBNFMagneticFieldPolyconeHorn::readFieldMapCurrentEqualizer",
" ", RunMustBeAborted, msg.c_str());
1069 fInDat.read(pTmp1,
sizeof(
double));
1071 fInDat.read(pTmp2,
sizeof(
double));
1073 fInDat.read(pTmp,
sizeof(
unsigned int));
1075 fInDat.read(pTmp,
sizeof(
unsigned int));
1077 fInDat.read(pTmp,
sizeof(
unsigned int));
1079 pTmp = (
char*) &lTotMap;
1080 fInDat.read(pTmp,
sizeof(
size_t));
1081 std::cerr <<
" LBNFMagneticFieldPolyconeHorn::readFieldMapCurrentEqualizer " 1082 <<
std::endl <<
" ...... Size of map in file " 1084 for (
size_t i=0;
i!= lTotMap;
i++) {
1085 unsigned int ii = 0;
1087 fInDat.
read(pTmp,
sizeof(
unsigned int));
1089 pTmp = (
char*) &bb[0];
1090 fInDat.read(pTmp, 2*
sizeof(
float));
1110 std::cerr <<
" And quit !. " <<
std::endl; exit(2);
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;
1133 const double magBField = current / (5./CLHEP::cm)/10*CLHEP::tesla;
1136 const double magBFieldB = 2.0*M_PI*magBField;
1137 for (
int iy =0; iy != numStepY+1; iy++) {
1138 const double y = (iy == numStepY) ? 0. : -radIC + 0.5*stepY + iy*stepY;
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);
1149 const double ITot = 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);
1157 const double l2 = (-1.0*deltaE) + r*std::cos(phi);
1158 const double r2 = std::sqrt(l2*l2 + h1*h1);
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;
1169 const double r1 = r2;
1171 BfieldB[1] = magBFieldB/ (16.0*M_PI*aBer);
1174 if (iy == numStepY) {
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));
1180 std::cerr <<
" Unexpected case in LBNFMagneticFieldPolyconeHorn::TestEccentricityBerkeley " <<
1181 " x " << x <<
" y " << y <<
" r1 " << r1 <<
" iy " << iy<<
std::endl;
1186 fOut <<
" " << x <<
" " << y <<
" " 1187 << Bfield[0] <<
" " << Bfield[1] <<
" " << BfieldB[0] <<
" " << BfieldB[1] <<
std::endl;
1191 std::cerr <<
" And quit for now.. " <<
std::endl; exit(2);
1196 std::cerr <<
" Closing Output Trajectory file in LBNFMagneticFieldPolyconeHorn " <<
std::endl;
G4double fZShiftDrawingCoordinate
std::vector< double > fField3DMapCurrentEqualizerRadSqRStepAtZ
void fillTrajectories(const double Point[3], double bx, double by) const
double fField3DMapCurrentEqualizerZStep
void msg(const char *fmt,...)
~LBNFMagneticFieldPolyconeHorn()
const LBNEVolumePlacementData * Find(const G4String &name, const char *motherName, const char *method) const
bool GetUseLBNFOptimConceptDesignHornB() const
double fCurrentEqualizerLongAbsLength
void writeFieldMapCurrentEqualizer() const
std::vector< LBNESurveyedPt >::const_iterator GetPoint(const std::string &aName) const
static LBNEVolumePlacements * Instance()
void getFieldFrom3DMapCurrentEqualizer(const double Point[3], double *Bfield) const
bool GetUseLBNFOptimConceptDesignHornC() const
std::vector< double > fRadsOuterC
std::vector< double > GetHornsPolyInnerConductorRadiiHornARev2() const
unsigned int fNumRPtsForCE
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
double GetHornsPolyInnerConductorZCoord(size_t iH, size_t numPts) const
G4RotationMatrix fRotMatrixHornContainer
bool GetUseLBNFOptimConceptDesignHornA() const
double GetHornParabolicRZCoord(size_t iH, size_t k) const
double GetThickICDRevisedHornB() const
G4RotationMatrix fRotation
virtual void GetFieldValue(const double Point[3], double *Bfield) const
double fEffectiveSkinDepthFact
unsigned int fNumPhiPtsForCE
double fCurrentEqualizerQuadAmpl
std::vector< double > fShiftSlope
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
std::string fFileNameFieldMapForCE
G4double fSkinDepthInnerRad
void TestDivergence(int opt) const
std::vector< double > fShift
void readFieldMapCurrentEqualizer() const
static int max(int a, int b)
bool IsHornPnParabolic(size_t numHorn) const
double getNormCurrDensityInnerC(double deltaR, double rOut) const
void TestEccentricityBerkeley() const
std::vector< double > fZDCBegin
std::vector< double > fRadsInnerC
void fillHornPolygonRadii(double z, double *rIn, double *rOut) const
int GetUseHornsPolyNumInnerPts(size_t i) const
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
std::vector< double > GetHornsPolyInnerConductorZsHornCRev2() const
double GetHornsPolyInnerConductorRadius(size_t iH, size_t numPts) const
double fEffectiveInnerRad
LBNFMagneticFieldPolyconeHorn(size_t iH)
std::vector< double > fField3DMapCurrentEqualizerRadSqAtZ
double fCurrentEqualizerOctAmpl
double GetThickICDRevisedHornC() const
unsigned int fNumZPtsForCE
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
double fDeltaEllipticityI
double fField3DMapCurrentEqualizerZMin
size_t GetHornParabolicNumInnerPts(size_t iH) const
double fEffectiveOuterRad
double fField3DMapCurrentEqualizerPhiStep
QTextStream & endl(QTextStream &s)
std::vector< double > GetHornsPolyInnerConductorZsHornBRev2() const
void fill3DMapCurrentEqualizer() const
double fDeltaEccentricityIO