src/BDSQuadrupole.cc

00001 //  
00002 //   BDSIM, (C) 2001-2006 
00003 //   
00004 //   version 0.3
00005 //  
00006 //
00007 //
00008 //   Quadrupole class
00009 //
00010 //   History
00011 //
00012 //     21 Nov 2006 by Agapov,  v.0.3
00013 //     22 Mar 2005 by Agapov, Carter,  v.0.2
00014 //     x  x   2002 by Blair
00015 //
00016 //
00017 
00018 #include "BDSGlobalConstants.hh" 
00019 #include "BDSDebug.hh"
00020 
00021 #include "BDSQuadrupole.hh"
00022 #include "G4Box.hh"
00023 #include "G4Tubs.hh"
00024 #include "G4Trd.hh"
00025 #include "G4VisAttributes.hh"
00026 #include "G4LogicalVolume.hh"
00027 #include "G4VPhysicalVolume.hh"
00028 #include "G4UserLimits.hh"
00029 #include "G4TransportationManager.hh"
00030 #include "G4HelixMixedStepper.hh"
00031 #include "G4HelixImplicitEuler.hh"
00032 #include "G4SimpleRunge.hh"
00033 #include "G4CashKarpRKF45.hh"
00034 
00035 #include <map>
00036 
00037 
00038 //============================================================
00039 
00040 typedef std::map<G4String,int> LogVolCountMap;
00041 extern LogVolCountMap* LogVolCount;
00042 
00043 typedef std::map<G4String,G4LogicalVolume*> LogVolMap;
00044 extern LogVolMap* LogVol;
00045 
00046 extern G4RotationMatrix* RotY90;
00047 //============================================================
00048 
00049 BDSQuadrupole::BDSQuadrupole(G4String aName, G4double aLength, 
00050                              G4double bpRad, G4double FeRad,
00051                              G4double bGrad, G4double tilt, G4double outR,
00052                              std::list<G4double> blmLocZ, std::list<G4double> blmLocTheta,
00053                              G4String aTunnelMaterial, G4String aMaterial, G4String spec):
00054   BDSMultipole(aName, aLength, bpRad, FeRad, SetVisAttributes(), blmLocZ, blmLocTheta, aTunnelMaterial, aMaterial),
00055   itsBGrad(bGrad),
00056   itsStepper(NULL),itsMagField(NULL),itsEqRhs(NULL)
00057 {
00058 #ifdef DEBUG 
00059   G4cout<< __METHOD_NAME__ << "spec=" << spec << G4endl;
00060 #endif
00061   // get specific quadrupole type
00062   G4String qtype = getParameterValueString(spec, "type");
00063 #ifdef DEBUG 
00064   G4cout<< __METHOD_NAME__ << "qtype="<<qtype<<G4endl;
00065 #endif
00066 
00067   SetOuterRadius(outR);
00068   itsTilt=tilt;
00069   itsType="quad";
00070 
00071   if (!(*LogVolCount)[itsName])
00072     {
00073       //
00074       // build external volume
00075       // 
00076 #ifdef DEBUG
00077       G4cout<<"Building marker volume "<<G4endl;
00078 #endif
00079       BuildDefaultMarkerLogicalVolume();
00080 
00081       //
00082       //build tunnel
00083       //
00084       if(BDSGlobalConstants::Instance()->GetBuildTunnel()){
00085         BuildTunnel();
00086       }
00087      
00088       //
00089       // build beampipe (geometry + magnetic field)
00090       //
00091 #ifdef DEBUG
00092       G4cout<<"Building beam pipe field and stepper "<<G4endl;
00093 #endif
00094       BuildBPFieldAndStepper();
00095 #ifdef DEBUG 
00096       G4cout<<"Building beam pipe field manager "<<G4endl;
00097 #endif
00098       BuildBPFieldMgr(itsStepper,itsMagField);
00099 #ifdef DEBUG 
00100       G4cout<<"Building beam pipe "<<G4endl;
00101 #endif
00102       BuildBeampipe();
00103 
00104       //
00105       // build magnet (geometry + magnetic field)
00106       // according to quad type
00107       //
00108       if(qtype=="standard") 
00109         BuildOuterLogicalVolume(); // standard - quad with poles and pockets
00110       else if(qtype=="cylinder")  
00111         BuildDefaultOuterLogicalVolume(itsLength); // cylinder outer volume
00112       //BuildEllipticalOuterLogicalVolume(itsLength); // cylinder outer volume
00113       else //default - cylinder
00114         BuildDefaultOuterLogicalVolume(itsLength); // cylinder outer volume
00115       //BuildEllipticalOuterLogicalVolume(itsLength); // cylinder outer volume
00116 
00117       if(BDSGlobalConstants::Instance()->GetIncludeIronMagFields())
00118         {
00119           G4double polePos[4];
00120           G4double Bfield[3];
00121 
00122           //coordinate in GetFieldValue
00123           polePos[0]=-BDSGlobalConstants::Instance()->GetMagnetPoleRadius()*sin(pi/4);
00124           polePos[1]=BDSGlobalConstants::Instance()->GetMagnetPoleRadius()*cos(pi/4);
00125           polePos[2]=0.;
00126           polePos[3]=-999.;//flag to use polePos rather than local track
00127 
00128           itsMagField->GetFieldValue(polePos,Bfield);
00129           G4double BFldIron=
00130             sqrt(Bfield[0]*Bfield[0]+Bfield[1]*Bfield[1])*
00131             BDSGlobalConstants::Instance()->GetMagnetPoleSize()/
00132             (BDSGlobalConstants::Instance()->GetComponentBoxSize()/2-
00133              BDSGlobalConstants::Instance()->GetMagnetPoleRadius());
00134 
00135           // Magnetic flux from a pole is divided in two directions
00136           BFldIron/=2.;
00137 
00138           BuildOuterFieldManager(4, BFldIron,pi/4);
00139         }
00140       //Build the beam loss monitors
00141       BuildBLMs();
00142       //
00143       // define sensitive volumes for hit generation
00144       //
00145       if(BDSGlobalConstants::Instance()->GetSensitiveBeamPipe()){
00146         G4cout << "BDSQuadrupole.cc:> setting sensitive beam pipe" << G4endl;
00147         SetMultipleSensitiveVolumes(itsBeampipeLogicalVolume);
00148       }
00149       if(BDSGlobalConstants::Instance()->GetSensitiveComponents()){
00150         G4cout << "BDSQuadrupole.cc:> setting sensitive outer volume" << G4endl;
00151         SetMultipleSensitiveVolumes(itsOuterLogicalVolume);
00152       }
00153       //
00154       // set visualization attributes
00155       //
00156       itsVisAttributes=SetVisAttributes();
00157       itsVisAttributes->SetForceSolid(true);
00158       itsOuterLogicalVolume->SetVisAttributes(itsVisAttributes);
00159 
00160       //
00161       // append marker logical volume to volume map
00162       //
00163       (*LogVolCount)[itsName]=1;
00164       (*LogVol)[itsName]=itsMarkerLogicalVolume;
00165     }
00166   else
00167     {
00168       (*LogVolCount)[itsName]++;
00169       if(BDSGlobalConstants::Instance()->GetSynchRadOn()&& BDSGlobalConstants::Instance()->GetSynchRescale())
00170         {
00171           // with synchrotron radiation, the rescaled magnetic field
00172           // means elements with the same name must have different
00173           // logical volumes, because they have different fields
00174           itsName+=BDSGlobalConstants::Instance()->StringFromInt((*LogVolCount)[itsName]);
00175 
00176           //
00177           // build external volume
00178           // 
00179           BuildDefaultMarkerLogicalVolume();
00180 
00181           //
00182           // build beampipe (geometry + magnetic field)
00183           //
00184           BuildBPFieldAndStepper();
00185           BuildBPFieldMgr(itsStepper,itsMagField);
00186           BuildBeampipe();
00187 
00188           //
00189           // build magnet (geometry + magnetic field)
00190           // according to quad type
00191           //
00192           if(qtype=="standard") 
00193             BuildOuterLogicalVolume(); // standard - quad with poles and pockets
00194           else if(qtype=="cylinder")  
00195             BuildDefaultOuterLogicalVolume(itsLength); // cylinder outer volume
00196             //      BuildEllipticalOuterLogicalVolume(itsLength); // cylinder outer volume
00197           else //default
00198             BuildDefaultOuterLogicalVolume(itsLength); // cylinder outer volume
00199           //BuildEllipticalOuterLogicalVolume(itsLength); // cylinder outer volume
00200           if(BDSGlobalConstants::Instance()->GetIncludeIronMagFields())
00201             {
00202               G4double polePos[4];
00203               G4double Bfield[3];
00204               
00205               //coordinate in GetFieldValue
00206               polePos[0]=-BDSGlobalConstants::Instance()->GetMagnetPoleRadius()*sin(pi/4);
00207               polePos[1]=BDSGlobalConstants::Instance()->GetMagnetPoleRadius()*cos(pi/4);
00208               polePos[2]=0.;
00209               polePos[3]=-999.;//flag to use polePos rather than local track
00210 
00211               itsMagField->GetFieldValue(polePos,Bfield);
00212               G4double BFldIron=
00213                 sqrt(Bfield[0]*Bfield[0]+Bfield[1]*Bfield[1])*
00214                 BDSGlobalConstants::Instance()->GetMagnetPoleSize()/
00215                 (BDSGlobalConstants::Instance()->GetComponentBoxSize()/2-
00216                  BDSGlobalConstants::Instance()->GetMagnetPoleRadius());
00217 
00218               // Magnetic flux from a pole is divided in two directions
00219               BFldIron/=2.;
00220               
00221               BuildOuterFieldManager(4, BFldIron,pi/4);
00222             }
00223           //When is SynchRescale(factor) called?
00224 
00225           //
00226           // define sensitive volumes for hit generation
00227           //
00228           if(BDSGlobalConstants::Instance()->GetSensitiveBeamPipe()){
00229             G4cout << "BDSQuadrupole.cc:> setting sensitive beampipe 2" << G4endl;            
00230             SetMultipleSensitiveVolumes(itsBeampipeLogicalVolume);
00231           }
00232           if(BDSGlobalConstants::Instance()->GetSensitiveComponents()){
00233             G4cout << "BDSQuadrupole.cc:> setting sensitive outer volume 2" << G4endl;           
00234             SetMultipleSensitiveVolumes(itsOuterLogicalVolume);
00235           }
00236                   
00237           //
00238           // set visualization attributes
00239           //
00240           itsVisAttributes=SetVisAttributes();
00241           itsVisAttributes->SetForceSolid(true);
00242           itsOuterLogicalVolume->SetVisAttributes(itsVisAttributes);
00243           
00244           //
00245           // append marker logical volume to volume map
00246           //
00247           (*LogVol)[itsName]=itsMarkerLogicalVolume;
00248         }
00249       else
00250         {
00251           //
00252           // use already defined marker volume
00253           //
00254           itsMarkerLogicalVolume=(*LogVol)[itsName];
00255         }      
00256     }
00257 }
00258 
00259 void BDSQuadrupole::SynchRescale(G4double factor)
00260 {
00261   itsStepper->SetBGrad(factor*itsBGrad);
00262   itsMagField->SetBGrad(factor*itsBGrad);
00263 #ifdef DEBUG 
00264   G4cout << "Quad " << itsName << " has been scaled" << G4endl;
00265 #endif
00266 }
00267 
00268 G4VisAttributes* BDSQuadrupole::SetVisAttributes()
00269 {
00270   itsVisAttributes=new G4VisAttributes(G4Colour(1,0,0));
00271   return itsVisAttributes;
00272 }
00273 
00274 void BDSQuadrupole::BuildBPFieldAndStepper()
00275 {
00276   // set up the magnetic field and stepper
00277   itsMagField=new BDSQuadMagField(1*itsBGrad); //L Deacon checking sign of field 4/7/12
00278   itsEqRhs=new G4Mag_UsualEqRhs(itsMagField);
00279 
00280   itsStepper=new BDSQuadStepper(itsEqRhs);
00281   itsStepper->SetBGrad(itsBGrad);
00282 }
00283 
00284 void BDSQuadrupole::BuildOuterLogicalVolume()
00285 {
00286   G4double outerRadius = itsOuterR;
00287   if(itsOuterR==0) outerRadius = BDSGlobalConstants::Instance()->GetComponentBoxSize()/2;
00288 
00289   outerRadius = outerRadius/sqrt(2.0);
00290 
00291   itsOuterLogicalVolume=
00292     new G4LogicalVolume(new G4Tubs(itsName+"_outer_solid",
00293                                    itsInnerIronRadius,
00294                                    outerRadius * sqrt(2.0),
00295                                    itsLength/2,
00296                                    0,twopi*radian),
00297                         BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),
00298                         itsName+"_outer");
00299   
00300   // create one quadrant of the quadrupole
00301   G4LogicalVolume* lQuadrant = 
00302     new G4LogicalVolume(new G4Tubs(itsName+"_outer_solid",
00303                                    itsInnerIronRadius,
00304                                    outerRadius * sqrt(2.0),
00305                                    itsLength/2,
00306                                    0,pi/ 2 *radian),
00307                         BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),
00308                         itsName+"_outer");
00309   
00310   // pole 
00311   G4double poleR = itsBpRadius;
00312   G4double phiStart = -pi / 4;
00313   G4double dPhi = pi / 2;
00314 
00315   G4LogicalVolume* lPole = 
00316     new G4LogicalVolume(new G4Tubs(itsName+"_pole",
00317                                    0,
00318                                    poleR,
00319                                    itsLength/2,
00320                                    phiStart,
00321                                    dPhi),
00322                         BDSMaterials::Instance()->GetMaterial("Iron"),
00323                         itsName+"pole_outer");
00324 
00325   G4RotationMatrix* rotPole = new G4RotationMatrix;
00326   //rotPole = NULL;
00327   rotPole->rotateZ(3.*pi / 4.);
00328 
00329   G4double xPole = (poleR + itsBpRadius) / sqrt(2.0);
00330   G4double yPole = (poleR + itsBpRadius) / sqrt(2.0);
00331 
00332 
00333   G4VPhysicalVolume* itsPhysiQPole1;
00334   itsPhysiQPole1 = new G4PVPlacement(
00335                       rotPole,                      // rotation
00336                       G4ThreeVector(xPole,yPole,0), // its position
00337                       lPole,                        // its logical volume
00338                       itsName+"_solid",             // its name
00339                       lQuadrant,                    // its mother  volume
00340                       false,                        // no boolean operation
00341                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                       // copy number
00342   
00343 
00344   // color-coding for the pole
00345   G4VisAttributes* VisAtt = 
00346     new G4VisAttributes(G4Colour(1., 0., 0.));
00347   VisAtt->SetForceSolid(true);
00348   lPole->SetVisAttributes(VisAtt);
00349 
00350 
00351   // yoke pieces
00352   G4double rYoke = outerRadius - poleR - itsBpRadius + poleR * cos(dPhi / 2);
00353 
00354   if(rYoke > 0 ) // place yoke
00355     {
00356 
00357       // random ...
00358       G4double rYoke1 =  outerRadius; // outer length
00359       G4double rYoke2 =  itsBpRadius;  // inner length 
00360 
00361       G4LogicalVolume* lYoke1 = 
00362         new G4LogicalVolume(new G4Trd(itsName+"_yoke1",
00363                                       rYoke1 / 2,
00364                                       rYoke2 / 2,
00365                                       itsLength/2,
00366                                       itsLength/2,
00367                                       rYoke/2),
00368                             BDSMaterials::Instance()->GetMaterial("Iron"),
00369                             itsName+"yoke_outer1");
00370 
00371       G4RotationMatrix* rotYoke = new G4RotationMatrix;
00372       //rotYoke = NULL;
00373       rotYoke->rotateX( - pi / 2.);
00374       rotYoke->rotateY(  pi / 4.);
00375 
00376       G4double xYoke = (poleR - poleR * cos(dPhi / 2) + itsBpRadius + rYoke/2) / sqrt(2.0);
00377       G4double yYoke = (poleR - poleR * cos(dPhi / 2) + itsBpRadius + rYoke/2) / sqrt(2.0);
00378 
00379 
00380       G4VPhysicalVolume* itsPhysiQYoke1;
00381       itsPhysiQYoke1 = new G4PVPlacement(
00382                           rotYoke,                      // rotation
00383                           G4ThreeVector(xYoke,yYoke,0), // its position
00384                           lYoke1,                       // its logical volume
00385                           itsName+"_yoke_solid",        // its name
00386                           lQuadrant,                    // its mother volume
00387                           false,                        // no boolean operation
00388                           0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                           // copy number
00389       SetMultiplePhysicalVolumes(itsPhysiQYoke1);
00390 
00391       // color-coding 
00392       G4VisAttributes* VisAtt1 = 
00393         new G4VisAttributes(G4Colour(1., 0., 0.4));
00394       VisAtt1->SetForceSolid(true);
00395       lYoke1->SetVisAttributes(VisAtt1);
00396     }
00397   else
00398     {
00399       G4cerr<<"Not enough place for yoke..."<<G4endl;
00400     }
00401 
00402 
00403   // put all quadrants in the outer volume
00404 
00405  
00406   G4VPhysicalVolume* itsPhysiQuadrant1;
00407   itsPhysiQuadrant1 = new G4PVPlacement(
00408                                         (G4RotationMatrix*)0,                  // rotation
00409                                         (G4ThreeVector)0,                     // its position
00410                                         lQuadrant,             // its logical volume
00411                                         itsName+"_solid",      // its name
00412                                         itsOuterLogicalVolume, // its mother volume
00413                                         false,                 // no boolean operation
00414                                         0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                    // copy number
00415 
00416 
00417   G4RotationMatrix* rotQ2= new  G4RotationMatrix;
00418   rotQ2->rotateZ( pi / 2.);
00419 
00420   G4VPhysicalVolume* itsPhysiQuadrant2;
00421   itsPhysiQuadrant2 = new G4PVPlacement(
00422                       rotQ2,                 // rotation
00423                       (G4ThreeVector)0,                     // its position
00424                       lQuadrant,             // its logical volume
00425                       itsName+"_solid",      // its name
00426                       itsOuterLogicalVolume, // its mother volume
00427                       false,                 // no boolean operation
00428                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                    // copy number
00429 
00430   G4RotationMatrix* rotQ3= new  G4RotationMatrix;
00431   rotQ3->rotateZ( pi );
00432   
00433   G4VPhysicalVolume* itsPhysiQuadrant3;
00434   itsPhysiQuadrant3 = new G4PVPlacement(
00435                       rotQ3,                 // rotation
00436                       (G4ThreeVector)0,                     // its position
00437                       lQuadrant,             // its logical volume
00438                       itsName+"_solid",      // its name
00439                       itsOuterLogicalVolume, // its mother volume
00440                       false,                 // no boolean operation
00441                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                    // copy number
00442 
00443 
00444   G4RotationMatrix* rotQ4= new  G4RotationMatrix;
00445   rotQ4->rotateZ( 3. * pi / 2.);
00446   
00447   G4VPhysicalVolume* itsPhysiQuadrant4;
00448   itsPhysiQuadrant4 = new G4PVPlacement(
00449                       rotQ4,                  // rotation
00450                       (G4ThreeVector)0,                      // its position
00451                       lQuadrant,              // its logical volume
00452                       itsName+"_solid",       // its name
00453                       itsOuterLogicalVolume,  // its mother volume
00454                       false,                  // no boolean operation
00455                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                     // copy number
00456 
00457 
00458   //rotQ->rotateZ( pi / 4.);
00459 
00460 
00461   // insert the outer volume into the marker volume
00462   itsPhysiComp = 
00463     new G4PVPlacement(
00464                       (G4RotationMatrix*)0,                      // no rotation
00465                       (G4ThreeVector)0,                      // its position
00466                       itsOuterLogicalVolume,  // its logical volume
00467                       itsName+"_outer_phys",  // its name
00468                       itsMarkerLogicalVolume, // its mother  volume
00469                       false,                  // no boolean operation
00470                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                     // copy number
00471   
00472   SetMultiplePhysicalVolumes(itsPhysiQPole1);
00473   SetMultiplePhysicalVolumes(itsPhysiQuadrant1);
00474   SetMultiplePhysicalVolumes(itsPhysiQuadrant2);
00475   SetMultiplePhysicalVolumes(itsPhysiQuadrant3);
00476   SetMultiplePhysicalVolumes(itsPhysiQuadrant4);
00477   SetMultiplePhysicalVolumes(itsPhysiComp);
00478 #ifndef NOUSERLIMITS
00479   itsOuterUserLimits =
00480     new G4UserLimits("quadrupole cut",itsLength,DBL_MAX,BDSGlobalConstants::Instance()->GetMaxTime(),
00481                      BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00482   itsOuterLogicalVolume->SetUserLimits(itsOuterUserLimits);
00483 #endif
00484 }
00485 
00486 /*
00487 void BDSQuadrupole::BuildOuterLogicalVolume()
00488 {
00489   G4double outerRadius = itsOuterR;
00490   if(itsOuterR==0) outerRadius = BDSGlobalConstants::Instance()->GetComponentBoxSize()/2;
00491 
00492   // compute sagitta:
00493   // why???? 
00494   // angle is always 0 for quadrupole (see BDSDetectorConstruction.cc)
00495   // and no bending is taken into account in the quadrupole stepper!
00496 
00497   G4double sagitta=0.;
00498 
00499   if(itsNSegments>1)
00500     {
00501       sagitta=itsLength/itsAngle*(1.-cos(itsAngle/2.));
00502     }
00503   
00504   // marker volume
00505   itsOuterLogicalVolume=
00506     new G4LogicalVolume(new G4Tubs(itsName+"_outer_solid",
00507                                    itsInnerIronRadius+sagitta,
00508                                    outerRadius * sqrt(2.0),
00509                                    itsLength/2,
00510                                    0,twopi*radian),
00511                         BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),
00512                         itsName+"_outer");
00513   
00514   // create one quadrant of the quadrupole
00515   G4LogicalVolume* lQuadrant = 
00516     new G4LogicalVolume(new G4Tubs(itsName+"_solid",
00517                                    itsInnerIronRadius+sagitta,
00518                                    outerRadius * sqrt(2.0),
00519                                    itsLength/2,
00520                                    0,pi/ 2 *radian),
00521                         BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->GetVacuumMaterial()),
00522                         itsName+"_outer");
00523   
00524   // pole 
00525   G4double poleR = itsBpRadius;
00526   G4double phiStart = -pi / 4;
00527   G4double dPhi = pi / 2;
00528 
00529   G4LogicalVolume* lPole = 
00530     new G4LogicalVolume(new G4Tubs(itsName+"_pole",
00531                                    0,
00532                                    poleR,
00533                                    itsLength/2,
00534                                    phiStart,
00535                                    dPhi),
00536                         BDSMaterials::Instance()->GetMaterial("Iron"),
00537                         itsName+"pole_outer");
00538 
00539   G4RotationMatrix* rotPole = new G4RotationMatrix;
00540   //rotPole = NULL;
00541   rotPole->rotateZ(3.*pi / 4.);
00542 
00543   G4double xPole = (poleR + itsBpRadius) / sqrt(2.0);
00544   G4double yPole = (poleR + itsBpRadius) / sqrt(2.0);
00545 
00546 
00547   G4VPhysicalVolume* itsPhysiQPole1;
00548   itsPhysiQPole1 = new G4PVPlacement(
00549                       rotPole,                      // rotation
00550                       G4ThreeVector(xPole,yPole,0), // its position
00551                       lPole,                        // its logical volume
00552                       itsName+"_solid",             // its name
00553                       lQuadrant,                    // its mother  volume
00554                       false,                        // no boolean operation
00555                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                       // copy number
00556   
00557   // color-coding for the pole
00558   G4VisAttributes* VisAtt = 
00559     new G4VisAttributes(G4Colour(1., 0., 0.));
00560   VisAtt->SetForceSolid(true);
00561   lPole->SetVisAttributes(VisAtt);
00562 
00563 
00564   // yoke pieces
00565   G4double rYoke = itsOuterR - poleR - itsBpRadius + poleR * cos(dPhi / 2);
00566 
00567   if(rYoke > 0 ) // place yoke
00568     {
00569 
00570       // random ...
00571       G4double rYoke1 =  itsOuterR; // outer length
00572       G4double rYoke2 =  itsBpRadius;  // inner length 
00573 
00574       G4LogicalVolume* lYoke1 = 
00575         new G4LogicalVolume(new G4Trd(itsName+"_yoke1",
00576                                       rYoke1 / 2,
00577                                       rYoke2 / 2,
00578                                       itsLength/2,
00579                                       itsLength/2,
00580                                       rYoke/2),
00581                             BDSMaterials::Instance()->GetMaterial("Iron"),
00582                             itsName+"yoke_outer1");
00583 
00584       G4RotationMatrix* rotYoke = new G4RotationMatrix;
00585       //rotYoke = NULL;
00586       rotYoke->rotateX( - pi / 2.);
00587       rotYoke->rotateY(  pi / 4.);
00588 
00589       G4double xYoke = (poleR - poleR * cos(dPhi / 2) + itsBpRadius + rYoke/2) / sqrt(2.0);
00590       G4double yYoke = (poleR - poleR * cos(dPhi / 2) + itsBpRadius + rYoke/2) / sqrt(2.0);
00591 
00592 
00593       G4VPhysicalVolume* itsPhysiQYoke1;
00594       itsPhysiQYoke1 = new G4PVPlacement(
00595                           rotYoke,                      // rotation
00596                           G4ThreeVector(xYoke,yYoke,0), // its position
00597                           lYoke1,                       // its logical volume
00598                           itsName+"_yoke_solid",        // its name
00599                           lQuadrant,                    // its mother volume
00600                           false,                        // no boolean operation
00601                           0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                           // copy number
00602       SetMultiplePhysicalVolumes(itsPhysiQYoke1);
00603 
00604       // color-coding 
00605       G4VisAttributes* VisAtt1 = 
00606         new G4VisAttributes(G4Colour(1., 0., 0.4));
00607       VisAtt1->SetForceSolid(true);
00608       lYoke1->SetVisAttributes(VisAtt1);
00609     }
00610   else
00611     {
00612       G4cerr<<"Not enough place for yoke..."<<G4endl;
00613     }
00614 
00615 
00616   // put all quadrants in the outer volume
00617 
00618  
00619   G4VPhysicalVolume* itsPhysiQuadrant1;
00620   itsPhysiQuadrant1 = new G4PVPlacement(
00621                       NULL,                  // rotation
00622                       (G4ThreeVector)0,                     // its position
00623                       lQuadrant,             // its logical volume
00624                       itsName+"_solid",      // its name
00625                       itsOuterLogicalVolume, // its mother volume
00626                       false,                 // no boolean operation
00627                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                    // copy number
00628 
00629   G4RotationMatrix* rotQ2= new  G4RotationMatrix;
00630   rotQ2->rotateZ( pi / 2.);
00631 
00632   G4VPhysicalVolume* itsPhysiQuadrant2;
00633   itsPhysiQuadrant2 = new G4PVPlacement(
00634                       rotQ2,                 // rotation
00635                       (G4ThreeVector)0,                     // its position
00636                       lQuadrant,             // its logical volume
00637                       itsName+"_solid",      // its name
00638                       itsOuterLogicalVolume, // its mother volume
00639                       false,                 // no boolean operation
00640                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                    // copy number
00641 
00642   G4RotationMatrix* rotQ3= new  G4RotationMatrix;
00643   rotQ3->rotateZ( pi );
00644   
00645   G4VPhysicalVolume* itsPhysiQuadrant3;
00646   itsPhysiQuadrant3 = new G4PVPlacement(
00647                       rotQ3,                 // rotation
00648                       (G4ThreeVector)0,                     // its position
00649                       lQuadrant,             // its logical volume
00650                       itsName+"_solid",      // its name
00651                       itsOuterLogicalVolume, // its mother volume
00652                       false,                 // no boolean operation
00653                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                    // copy number
00654 
00655 
00656   G4RotationMatrix* rotQ4= new  G4RotationMatrix;
00657   rotQ4->rotateZ( 3. * pi / 2.);
00658   
00659   G4VPhysicalVolume* itsPhysiQuadrant4;
00660   itsPhysiQuadrant4 = new G4PVPlacement(
00661                       rotQ4,                  // rotation
00662                       (G4ThreeVector)0,                      // its position
00663                       lQuadrant,              // its logical volume
00664                       itsName+"_solid",       // its name
00665                       itsOuterLogicalVolume,  // its mother volume
00666                       false,                  // no boolean operation
00667                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                     // copy number
00668 
00669 
00670   //rotQ->rotateZ( pi / 4.);
00671 
00672 
00673   // insert the outer volume into the marker volume
00674 
00675   G4RotationMatrix* Rot=NULL;
00676   if(itsAngle!=0) Rot=RotY90;
00677   
00678   itsPhysiComp = new G4PVPlacement(
00679                       Rot,                    // rotation
00680                       (G4ThreeVector)0,                      // its position
00681                       itsOuterLogicalVolume,  // its logical volume
00682                       itsName+"_solid",       // its name
00683                       itsMarkerLogicalVolume, // its mother  volume
00684                       false,                  // no boolean operation
00685                       0, BDSGlobalConstants::Instance()->GetCheckOverlaps());                     // copy number
00686   
00687   SetMultiplePhysicalVolumes(itsPhysiQPole1);
00688   SetMultiplePhysicalVolumes(itsPhysiQuadrant1);
00689   SetMultiplePhysicalVolumes(itsPhysiQuadrant2);
00690   SetMultiplePhysicalVolumes(itsPhysiQuadrant3);
00691   SetMultiplePhysicalVolumes(itsPhysiQuadrant4);
00692   SetMultiplePhysicalVolumes(itsPhysiComp);
00693   #ifndef NOUSERLIMITS
00694   itsOuterUserLimits =
00695   new G4UserLimits("quadrupole cut",itsLength,DBL_MAX,BDSGlobalConstants::Instance()->GetMaxTime(),
00696   BDSGlobalConstants::Instance()->GetThresholdCutCharged());
00697   itsOuterLogicalVolume->SetUserLimits(itsOuterUserLimits);
00698   #endif
00699 }
00700 */
00701 
00702 BDSQuadrupole::~BDSQuadrupole()
00703 {
00704   delete itsVisAttributes;
00705   delete itsMagField;
00706   delete itsEqRhs;
00707   delete itsStepper;
00708 }

Generated on 27 Aug 2013 for BDSIM by  doxygen 1.4.7