00001 #include "BDSGlobalConstants.hh"
00002 #include "BDSDebug.hh"
00003
00004 #include "BDSRBend.hh"
00005
00006 #include "BDSBeamPipe.hh"
00007 #include "BDSBeamPipeFactory.hh"
00008 #include "BDSBeamPipeInfo.hh"
00009 #include "BDSDipoleStepper.hh"
00010 #include "BDSMagnetOuterInfo.hh"
00011 #include "BDSMagnetType.hh"
00012 #include "BDSMaterials.hh"
00013 #include "BDSSbendMagField.hh"
00014 #include "BDSUtilities.hh"
00015
00016 #include "G4FieldManager.hh"
00017 #include "G4IntersectionSolid.hh"
00018 #include "G4LogicalVolume.hh"
00019 #include "G4Mag_EqRhs.hh"
00020 #include "G4PVPlacement.hh"
00021 #include "G4Tubs.hh"
00022 #include "G4CutTubs.hh"
00023 #include "G4UserLimits.hh"
00024 #include "G4VisAttributes.hh"
00025 #include "G4VPhysicalVolume.hh"
00026
00027 BDSRBend::BDSRBend(G4String name,
00028 G4double length,
00029 G4double bField,
00030 G4double bGrad,
00031 G4double angleIn,
00032 BDSBeamPipeInfo* beamPipeInfo,
00033 BDSMagnetOuterInfo magnetOuterInfo,
00034 BDSTiltOffset tiltOffset):
00035 BDSMagnet(BDSMagnetType::rectangularbend, name, length,
00036 beamPipeInfo, magnetOuterInfo, tiltOffset),
00037 itsBField(bField),
00038 itsBGrad(bGrad)
00039 {
00040 angle = angleIn;
00041 outerRadius = magnetOuterInfo.outerDiameter*0.5;
00042 CommonConstructor(length);
00043 }
00044
00045
00046 void BDSRBend::CommonConstructor(G4double aLength)
00047 {
00048
00049 chordLength = aLength;
00050
00051 orientation = BDS::CalculateOrientation(angle);
00052
00053
00054
00055
00056
00057 itsStraightSectionChord = outerRadius / (tan(0.5*fabs(angle)) + tan((0.5*CLHEP::pi) - (0.5*fabs(angle))) );
00058 itsMagFieldLength = chordLength - (2.0*itsStraightSectionChord);
00059 magnetXShift = orientation*itsStraightSectionChord*tan(0.5*fabs(angle));
00060 G4ThreeVector magpos = G4ThreeVector(magnetXShift, 0, 0);
00061 G4double dz = (itsMagFieldLength*0.5)+(itsStraightSectionChord*0.5);
00062 G4ThreeVector driftposstart = G4ThreeVector(0.5*magnetXShift, 0, -1*dz);
00063 G4ThreeVector driftposend = G4ThreeVector(0.5*magnetXShift, 0, dz);
00064 itsStraightSectionLength = itsStraightSectionChord / (cos(0.5*fabs(angle)));
00065
00066 G4double in_z = cos(0.5*fabs(angle));
00067 G4double in_x = sin(0.5*fabs(angle));
00068 inputface = G4ThreeVector(-orientation*in_x, 0.0, -1.0*in_z);
00069 outputface = G4ThreeVector(-orientation*in_x, 0.0, in_z);
00070
00071 #ifdef BDSDEBUG
00072 G4cout << __METHOD_NAME__ << "Angle = " << angle << G4endl;
00073 G4cout << __METHOD_NAME__ << "Straight section chord = " << itsStraightSectionChord << G4endl;
00074 G4cout << __METHOD_NAME__ << "Magnetic field length = " << itsMagFieldLength << G4endl;
00075 G4cout << __METHOD_NAME__ << "Straight section length = " << itsStraightSectionLength << G4endl;
00076 G4cout << __METHOD_NAME__ << "Straight section chord = " << itsStraightSectionChord << G4endl;
00077 G4cout << __METHOD_NAME__ << "Magnet shift in X = " << magnetXShift << G4endl;
00078 #endif
00079 }
00080
00081 void BDSRBend::Build()
00082 {
00083 BDSMagnet::Build();
00084 if(BDSGlobalConstants::Instance()->GetIncludeIronMagFields())
00085 {
00086 G4double polePos[4];
00087 G4double Bfield[3];
00088
00089
00090 polePos[0]=0.;
00091 polePos[1]=BDSGlobalConstants::Instance()->GetMagnetPoleRadius();
00092 polePos[2]=0.;
00093 polePos[3]=-999.;
00094
00095 itsMagField->GetFieldValue(polePos,Bfield);
00096 G4double BFldIron=
00097 sqrt(Bfield[0]*Bfield[0]+Bfield[1]*Bfield[1])*
00098 BDSGlobalConstants::Instance()->GetMagnetPoleSize()/
00099 (BDSGlobalConstants::Instance()->GetComponentBoxSize()/2-
00100 BDSGlobalConstants::Instance()->GetMagnetPoleRadius());
00101
00102
00103 BFldIron/=2.;
00104
00105 BuildOuterFieldManager(2, BFldIron,CLHEP::pi/2);
00106 }
00107 }
00108
00109 void BDSRBend::BuildBPFieldAndStepper()
00110 {
00111
00112 G4ThreeVector Bfield(0.,-itsBField,0.);
00113 G4double arclength = fabs(angle) * ((itsMagFieldLength*0.5) / sin(0.5*fabs(angle)));
00114 #ifdef BDSDEBUG
00115 G4cout << __METHOD_NAME__ << " calculated arclength in dipole field: " << arclength << G4endl;
00116 #endif
00117 itsMagField = new BDSSbendMagField(Bfield,arclength,angle);
00118 itsEqRhs = new G4Mag_UsualEqRhs(itsMagField);
00119
00120 BDSDipoleStepper* dipoleStepper = new BDSDipoleStepper(itsEqRhs);
00121 dipoleStepper->SetBField(-itsBField);
00122 dipoleStepper->SetBGrad(itsBGrad);
00123 itsStepper = dipoleStepper;
00124 }
00125
00126 void BDSRBend::BuildOuterVolume()
00127 {
00128
00129
00130
00131 G4double originalLength = chordLength;
00132 chordLength = itsMagFieldLength;
00133 BDSMagnet::BuildOuterVolume();
00134 chordLength = originalLength;
00135 }
00136
00137
00138 void BDSRBend::BuildBeampipe()
00139 {
00140 BDSBeamPipe* bpFirstBit =
00141 BDSBeamPipeFactory::Instance()->CreateBeamPipeAngledOut(beamPipeInfo->beamPipeType,
00142 name,
00143 itsStraightSectionLength,
00144 -angle*0.5,
00145 beamPipeInfo->aper1,
00146 beamPipeInfo->aper2,
00147 beamPipeInfo->aper3,
00148 beamPipeInfo->aper4,
00149 beamPipeInfo->vacuumMaterial,
00150 beamPipeInfo->beamPipeThickness,
00151 beamPipeInfo->beamPipeMaterial);
00152
00153 beampipe =
00154 BDSBeamPipeFactory::Instance()->CreateBeamPipe(beamPipeInfo->beamPipeType,
00155 name,
00156 itsMagFieldLength,
00157 beamPipeInfo->aper1,
00158 beamPipeInfo->aper2,
00159 beamPipeInfo->aper3,
00160 beamPipeInfo->aper4,
00161 beamPipeInfo->vacuumMaterial,
00162 beamPipeInfo->beamPipeThickness,
00163 beamPipeInfo->beamPipeMaterial);
00164
00165 BDSBeamPipe* bpLastBit =
00166 BDSBeamPipeFactory::Instance()->CreateBeamPipeAngledIn(beamPipeInfo->beamPipeType,
00167 name,
00168 itsStraightSectionLength,
00169 angle*0.5,
00170 beamPipeInfo->aper1,
00171 beamPipeInfo->aper2,
00172 beamPipeInfo->aper3,
00173 beamPipeInfo->aper4,
00174 beamPipeInfo->vacuumMaterial,
00175 beamPipeInfo->beamPipeThickness,
00176 beamPipeInfo->beamPipeMaterial);
00177
00178
00179
00180 G4double straightSectionCentralZ = (itsMagFieldLength*0.5) + (itsStraightSectionChord*0.5);
00181 G4RotationMatrix* straightStartRM = new G4RotationMatrix();
00182 straightStartRM->rotateY(angle*0.5);
00183 G4RotationMatrix* straightEndRM = new G4RotationMatrix();
00184 straightEndRM->rotateY(-angle*0.5);
00185 straightEndRM->rotateZ(CLHEP::pi);
00186 G4ThreeVector straightStartPos = G4ThreeVector(orientation*magnetXShift*0.5,0,-straightSectionCentralZ);
00187 G4ThreeVector straightEndPos = G4ThreeVector(orientation*magnetXShift*0.5,0,straightSectionCentralZ);
00188 G4ThreeVector magnetPos = G4ThreeVector(orientation*magnetXShift,0,0);
00189
00190 new G4PVPlacement(straightStartRM,
00191 straightStartPos,
00192 bpFirstBit->GetContainerLogicalVolume(),
00193 name+"_bp_start_phys",
00194 containerLogicalVolume,
00195 false,
00196 0,
00197 BDSGlobalConstants::Instance()->GetCheckOverlaps() );
00198
00199 new G4PVPlacement(0,
00200 magnetPos,
00201 beampipe->GetContainerLogicalVolume(),
00202 name+"_bp_phys",
00203 containerLogicalVolume,
00204 false,
00205 0,
00206 BDSGlobalConstants::Instance()->GetCheckOverlaps() );
00207
00208 new G4PVPlacement(straightEndRM,
00209 straightEndPos,
00210 bpLastBit->GetContainerLogicalVolume(),
00211 name+"_bp_end_phys",
00212 containerLogicalVolume,
00213 false,
00214 0,
00215 BDSGlobalConstants::Instance()->GetCheckOverlaps() );
00216
00217
00218
00219 beampipe->GetVacuumLogicalVolume()->SetFieldManager(itsBPFieldMgr,false);
00220 containerLogicalVolume->
00221 SetFieldManager(BDSGlobalConstants::Instance()->GetZeroFieldManager(),false);
00222
00223 RegisterLogicalVolumes(bpFirstBit->GetAllLogicalVolumes());
00224 RegisterLogicalVolumes(beampipe->GetAllLogicalVolumes());
00225 RegisterLogicalVolumes(bpLastBit->GetAllLogicalVolumes());
00226
00227
00228 if(BDSGlobalConstants::Instance()->GetSensitiveBeamPipe())
00229 {
00230 RegisterSensitiveVolumes(bpFirstBit->GetAllSensitiveVolumes());
00231 RegisterSensitiveVolumes(beampipe->GetAllSensitiveVolumes());
00232 RegisterSensitiveVolumes(bpLastBit->GetAllSensitiveVolumes());
00233 }
00234
00235 SetExtentX(beampipe->GetExtentX());
00236 SetExtentY(beampipe->GetExtentY());
00237 SetExtentZ(-chordLength*0.5,chordLength*0.5);
00238 }