00001 #include "BDSGlobalConstants.hh"
00002
00003 #include "mySectorBend.hh"
00004 #include "G4Box.hh"
00005 #include "G4Torus.hh"
00006 #include "G4IntersectionSolid.hh"
00007 #include "G4VisAttributes.hh"
00008 #include "G4LogicalVolume.hh"
00009 #include "G4VPhysicalVolume.hh"
00010 #include "G4UserLimits.hh"
00011 #include "G4TransportationManager.hh"
00012 #include "G4PropagatorInField.hh"
00013 #include "G4SubtractionSolid.hh"
00014
00015 #include <map>
00016
00017 const int DEBUG = 0;
00018
00019
00020
00021 typedef std::map<G4String,int> LogVolCountMap;
00022 extern LogVolCountMap* LogVolCount;
00023
00024 typedef std::map<G4String,G4LogicalVolume*> LogVolMap;
00025 extern LogVolMap* LogVol;
00026
00027 extern BDSMaterials* theMaterials;
00028 extern G4RotationMatrix* RotY90;
00029 extern G4RotationMatrix* RotX90;
00030
00031
00032
00033 mySectorBend::mySectorBend(G4String aName,G4double aLength,
00034 G4double bpRad,G4double FeRad,
00035 G4double bField, G4double angle, G4double outR,
00036 G4double tilt, G4double bGrad,
00037 G4String aMaterial, G4int nSegments):
00038 BDSMultipole(aName,aLength,bpRad,FeRad,SetVisAttributes(),aMaterial,0,0,angle)
00039 {
00040
00041 if (outR==0)
00042 SetOuterRadius(BDSGlobals->GetComponentBoxSize()/2);
00043 else
00044 SetOuterRadius(outR);
00045 itsTilt = tilt;
00046 itsBField = bField;
00047 itsBGrad = bGrad;
00048
00049 itsType="sbend";
00050
00051 if (!(*LogVolCount)[itsName] )
00052 {
00053 BuildSBMarkerLogicalVolume();
00054
00055 BuildSBBeampipe();
00056
00057 BuildBPFieldAndStepper();
00058
00059 BuildBPFieldMgr(itsStepper,itsMagField);
00060
00061 BuildSBOuterLogicalVolume();
00062
00063 SetMultipleSensitiveVolumes(itsBeampipeLogicalVolume);
00064 SetMultipleSensitiveVolumes(itsOuterLogicalVolume);
00065
00066 if(BDSGlobals->GetIncludeIronMagFields())
00067 {
00068 G4double polePos[4];
00069 G4double Bfield[3];
00070
00071 polePos[0]=0.;
00072 polePos[1]=BDSGlobals->GetMagnetPoleRadius();
00073 polePos[2]=0.;
00074 polePos[0]=-999.;
00075
00076
00077 itsMagField->GetFieldValue(polePos,Bfield);
00078 G4double BFldIron=
00079 sqrt(Bfield[0]*Bfield[0]+Bfield[1]*Bfield[1])*
00080 BDSGlobals->GetMagnetPoleSize()/
00081 (BDSGlobals->GetComponentBoxSize()/2-
00082 BDSGlobals->GetMagnetPoleRadius());
00083
00084
00085 BFldIron/=2.;
00086
00087
00088 }
00089
00090
00091
00092 G4VisAttributes* VisAtt =
00093 new G4VisAttributes(G4Colour(0., 0., 0));
00094 VisAtt->SetForceSolid(true);
00095 itsInnerBPLogicalVolume->SetVisAttributes(VisAtt);
00096
00097 G4VisAttributes* VisAtt1 =
00098 new G4VisAttributes(G4Colour(0.1, 0.1, 0.1));
00099 VisAtt1->SetForceSolid(true);
00100 itsBeampipeLogicalVolume->SetVisAttributes(VisAtt1);
00101
00102 G4VisAttributes* VisAtt2 =
00103 new G4VisAttributes(G4Colour(0., 0., 1.));
00104 VisAtt2->SetForceSolid(true);
00105 itsOuterLogicalVolume->SetVisAttributes(VisAtt2);
00106
00107
00108 (*LogVolCount)[itsName]=1;
00109 (*LogVol)[itsName]=itsMarkerLogicalVolume;
00110 }
00111 else
00112 {
00113 (*LogVolCount)[itsName]++;
00114 if(BDSGlobals->GetSynchRadOn()&& BDSGlobals->GetSynchRescale())
00115 {
00116
00117
00118
00119 itsName+=BDSGlobals->StringFromInt((*LogVolCount)[itsName]);
00120
00121 BuildSBMarkerLogicalVolume();
00122
00123 BuildSBBeampipe();
00124
00125 BuildBPFieldAndStepper();
00126
00127 BuildBPFieldMgr(itsStepper,itsMagField);
00128
00129 BuildSBOuterLogicalVolume();
00130
00131 SetMultipleSensitiveVolumes(itsBeampipeLogicalVolume);
00132 SetMultipleSensitiveVolumes(itsOuterLogicalVolume);
00133
00134
00135 G4VisAttributes* VisAtt =
00136 new G4VisAttributes(G4Colour(0., 0., 0));
00137 VisAtt->SetForceSolid(true);
00138 itsInnerBPLogicalVolume->SetVisAttributes(VisAtt);
00139
00140 G4VisAttributes* VisAtt1 =
00141 new G4VisAttributes(G4Colour(0.1, 0.1, 0.1));
00142 VisAtt1->SetForceSolid(true);
00143 itsBeampipeLogicalVolume->SetVisAttributes(VisAtt1);
00144
00145 G4VisAttributes* VisAtt2 =
00146 new G4VisAttributes(G4Colour(0., 0., 1.));
00147 VisAtt2->SetForceSolid(true);
00148 itsOuterLogicalVolume->SetVisAttributes(VisAtt2);
00149
00150
00151 (*LogVol)[itsName]=itsMarkerLogicalVolume;
00152 }
00153 else
00154 {
00155 itsMarkerLogicalVolume=(*LogVol)[itsName];
00156 }
00157 }
00158 }
00159
00160 void mySectorBend::SynchRescale(G4double factor)
00161 {
00162 itsStepper->SetBGrad(itsBGrad*factor);
00163 itsStepper->SetBField(-itsBField*factor);
00164
00165
00166 if(DEBUG) G4cout << "Sbend " << itsName << " has been scaled" << G4endl;
00167 }
00168
00169 G4VisAttributes* mySectorBend::SetVisAttributes()
00170 {
00171 itsVisAttributes=new G4VisAttributes(G4Colour(0,1,1));
00172 return itsVisAttributes;
00173 }
00174
00175
00176 void mySectorBend::BuildBPFieldAndStepper()
00177 {
00178
00179 G4ThreeVector Bfield(0.,-itsBField,0.);
00180 itsMagField=new BDSSbendMagField(Bfield,itsLength,itsAngle);
00181
00182 itsEqRhs=new G4Mag_UsualEqRhs(itsMagField);
00183
00184 itsStepper = new myQuadStepper(itsEqRhs);
00185 itsStepper->SetBField(-itsBField);
00186 itsStepper->SetBGrad(itsBGrad);
00187
00188 BuildBPFieldMgr(itsStepper,itsMagField);
00189
00190 itsBeampipeLogicalVolume->SetFieldManager(BDSGlobals->GetZeroFieldManager(),false);
00191 itsInnerBPLogicalVolume->SetFieldManager(itsBPFieldMgr,false);
00192
00193 }
00194
00195
00196 void mySectorBend::BuildSBMarkerLogicalVolume()
00197 {
00198
00199 G4double rho = itsLength/fabs(itsAngle);
00200
00201 itsMarkerLogicalVolume=
00202 new G4LogicalVolume(new G4Torus(itsName+"_marker",
00203 0,
00204 itsOuterR,
00205 rho,
00206 0,
00207 fabs(itsAngle)),
00208 theMaterials->GetMaterial("Vacuum"),
00209 itsName+"_marker");
00210
00211 itsMarkerUserLimits = new G4UserLimits(DBL_MAX,DBL_MAX,DBL_MAX);
00212 itsMarkerUserLimits->SetMaxAllowedStep(itsLength);
00213 itsMarkerLogicalVolume->SetUserLimits(itsMarkerUserLimits);
00214 }
00215
00216
00217
00218 void mySectorBend::BuildSBBeampipe()
00219 {
00220
00221
00222
00223
00224
00225 G4double rho = itsLength/fabs(itsAngle);
00226
00227
00228
00229 G4double bpThickness = BDSGlobals->GetBeampipeThickness();
00230 G4Torus *pipeTube = new G4Torus(itsName+"_pipe_outer",
00231 itsBpRadius-bpThickness,
00232 itsBpRadius,
00233 rho,
00234 0,
00235 fabs(itsAngle) );
00236
00237
00238 G4Torus *pipeInner = new G4Torus(itsName+"_pipe_inner",
00239 0,
00240 itsBpRadius-bpThickness,
00241 rho,
00242 0,
00243 fabs(itsAngle) );
00244
00245
00246
00247
00248
00249
00250
00251 G4Material *material = theMaterials->GetMaterial( BDSGlobals->GetPipeMaterialName());
00252
00253 itsBeampipeLogicalVolume=
00254 new G4LogicalVolume(pipeTube,
00255 material,
00256 itsName+"_bmp_logical");
00257
00258 itsInnerBPLogicalVolume=
00259 new G4LogicalVolume(pipeInner,
00260 theMaterials->GetMaterial("Vacuum"),
00261 itsName+"_bmp_Inner_log");
00262
00263
00264
00265
00266
00267
00268 G4VPhysicalVolume* PhysiInner;
00269 PhysiInner =
00270 new G4PVPlacement(
00271 0,
00272 0,
00273 itsInnerBPLogicalVolume,
00274 itsName+"_InnerBmp",
00275 itsMarkerLogicalVolume,
00276 false,
00277 0);
00278
00279 G4VPhysicalVolume* PhysiComp;
00280 PhysiComp =
00281 new G4PVPlacement(
00282 0,
00283 0,
00284 itsBeampipeLogicalVolume,
00285 itsName+"_bmp",
00286 itsMarkerLogicalVolume,
00287 false,
00288 0);
00289
00290 itsBeampipeUserLimits =
00291 new G4UserLimits("beampipe cuts",DBL_MAX,DBL_MAX,DBL_MAX,
00292 BDSGlobals->GetThresholdCutCharged());
00293
00294 itsInnerBeampipeUserLimits =
00295 new G4UserLimits("inner beampipe cuts",DBL_MAX,DBL_MAX,DBL_MAX,
00296 BDSGlobals->GetThresholdCutCharged());
00297
00298
00299
00300
00301
00302
00303
00304 itsBeampipeUserLimits->SetMaxAllowedStep(itsLength);
00305 itsBeampipeLogicalVolume->SetUserLimits(itsBeampipeUserLimits);
00306
00307 itsInnerBeampipeUserLimits->SetMaxAllowedStep(itsLength);
00308 itsInnerBPLogicalVolume->SetUserLimits(itsInnerBeampipeUserLimits);
00309
00310
00311 itsMarkerLogicalVolume->
00312 SetFieldManager(BDSGlobals->GetZeroFieldManager(),false);
00313
00314 }
00315
00316 void mySectorBend::BuildSBOuterLogicalVolume(G4bool OuterMaterialIsVacuum)
00317 {
00318
00319 G4double rho = itsLength/fabs(itsAngle);
00320
00321
00322
00323
00324
00325
00326
00327
00328 G4Material* material;
00329 if(itsMaterial != "") material = theMaterials->GetMaterial(itsMaterial);
00330 else material = theMaterials->GetMaterial("Iron");
00331
00332 if(OuterMaterialIsVacuum)
00333 {
00334 itsOuterLogicalVolume=
00335 new G4LogicalVolume(new G4Torus(itsName+"_solid",
00336 itsInnerIronRadius,
00337 itsOuterR,
00338 rho,
00339 0,
00340 fabs(itsAngle) ),
00341 theMaterials->GetMaterial("Vacuum"),
00342 itsName+"_outer");
00343 }
00344
00345 if(!OuterMaterialIsVacuum)
00346 {
00347 itsOuterLogicalVolume=
00348 new G4LogicalVolume(new G4Torus(itsName+"_solid",
00349 itsInnerIronRadius,
00350 itsOuterR,
00351 rho,
00352 0,
00353 fabs(itsAngle) ),
00354 material,
00355 itsName+"_outer");
00356 }
00357
00358 G4VPhysicalVolume* itsPhysiComp;
00359 itsPhysiComp =
00360 new G4PVPlacement(
00361 0,
00362 0,
00363 itsOuterLogicalVolume,
00364 itsName+"_solid",
00365 itsMarkerLogicalVolume,
00366 false,
00367 0);
00368
00369 itsOuterUserLimits =
00370 new G4UserLimits("multipole cut",itsLength,DBL_MAX,DBL_MAX,
00371 BDSGlobals->GetThresholdCutCharged());
00372
00373 itsOuterLogicalVolume->SetUserLimits(itsOuterUserLimits);
00374
00375 }
00376
00377 mySectorBend::~mySectorBend()
00378 {
00379 delete itsVisAttributes;
00380 delete itsMarkerLogicalVolume;
00381 delete itsOuterLogicalVolume;
00382 delete itsPhysiComp;
00383 delete itsMagField;
00384 delete itsEqRhs;
00385 delete itsStepper;
00386 }