G4PVParameterised.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // class G4PVParameterised
00031 //
00032 // Implementation
00033 //
00034 // ----------------------------------------------------------------------
00035 
00036 #include "G4PVParameterised.hh"
00037 #include "G4VPVParameterisation.hh"
00038 #include "G4AffineTransform.hh"
00039 #include "G4UnitsTable.hh"
00040 #include "G4VSolid.hh"
00041 #include "G4LogicalVolume.hh"
00042 
00043 // ----------------------------------------------------------------------
00044 // Constructor
00045 //
00046 G4PVParameterised::G4PVParameterised( const G4String& pName,
00047                                             G4LogicalVolume* pLogical,
00048                                             G4VPhysicalVolume* pMother,
00049                                       const EAxis pAxis,
00050                                       const G4int nReplicas,
00051                                             G4VPVParameterisation *pParam,
00052                                             G4bool pSurfChk )
00053   : G4PVReplica(pName, pLogical, pMother, pAxis, nReplicas, 0, 0),
00054     fparam(pParam)
00055 {
00056 #ifdef G4VERBOSE  
00057   if ((pMother) && (pMother->IsParameterised()))
00058   {
00059     std::ostringstream message, hint;
00060     message << "A parameterised volume is being placed" << G4endl
00061             << "inside another parameterised volume !";
00062     hint << "To make sure that no overlaps are generated," << G4endl
00063          << "you should verify the mother replicated shapes" << G4endl
00064          << "are of the same type and dimensions." << G4endl
00065          << "   Mother physical volume: " << pMother->GetName() << G4endl
00066          << "   Parameterised volume: " << pName << G4endl
00067          << "  (To switch this warning off, compile with G4_NO_VERBOSE)";
00068     G4Exception("G4PVParameterised::G4PVParameterised()", "GeomVol1002",
00069                 JustWarning, message, G4String(hint.str()));
00070   }
00071 #endif
00072   if (pSurfChk) { CheckOverlaps(); }
00073 }
00074 
00075 // ----------------------------------------------------------------------
00076 // Constructor
00077 //
00078 G4PVParameterised::G4PVParameterised( const G4String& pName,
00079                                             G4LogicalVolume* pLogical,
00080                                             G4LogicalVolume* pMotherLogical,
00081                                       const EAxis pAxis,
00082                                       const G4int nReplicas,
00083                                             G4VPVParameterisation *pParam,
00084                                             G4bool pSurfChk )
00085   : G4PVReplica(pName, pLogical, pMotherLogical, pAxis, nReplicas, 0, 0),
00086     fparam(pParam)
00087 {
00088   if (pSurfChk) { CheckOverlaps(); }
00089 }
00090 
00091 // ----------------------------------------------------------------------
00092 // Fake default constructor - sets only member data and allocates memory
00093 //                            for usage restricted to object persistency.
00094 //
00095 G4PVParameterised::G4PVParameterised( __void__& a )
00096   : G4PVReplica(a), fparam(0)
00097 {
00098 }
00099 
00100 // ----------------------------------------------------------------------
00101 // Destructor
00102 //
00103 G4PVParameterised::~G4PVParameterised()
00104 {
00105 }
00106 
00107 // ----------------------------------------------------------------------
00108 // GetParameterisation
00109 //
00110 G4VPVParameterisation* G4PVParameterised::GetParameterisation() const
00111 {
00112   return fparam;
00113 }
00114 
00115 // ----------------------------------------------------------------------
00116 // IsParameterised
00117 //
00118 G4bool G4PVParameterised::IsParameterised() const
00119 {
00120   return true;
00121 }
00122 
00123 // ----------------------------------------------------------------------
00124 // GetReplicationData
00125 //
00126 void G4PVParameterised::GetReplicationData( EAxis& axis,
00127                                             G4int& nReplicas,
00128                                             G4double& width,
00129                                             G4double& offset,
00130                                             G4bool& consuming) const
00131 {
00132   axis = faxis;
00133   nReplicas = fnReplicas;
00134   width = fwidth;
00135   offset = foffset;
00136   consuming = false;
00137 }
00138 
00139 // ----------------------------------------------------------------------
00140 // SetRegularStructureId
00141 //
00142 void  G4PVParameterised::SetRegularStructureId( G4int Code )
00143 {
00144   G4PVReplica::SetRegularStructureId( Code );
00145   // To undertake additional preparation, a derived volume must
00146   //   redefine this method, while calling also the above method.
00147 }
00148 
00149 
00150 // ----------------------------------------------------------------------
00151 // CheckOverlaps
00152 //
00153 G4bool
00154 G4PVParameterised::CheckOverlaps(G4int res, G4double tol, G4bool verbose)
00155 {
00156   if (res<=0) { return false; }
00157 
00158   G4VSolid *solidA = 0, *solidB = 0;
00159   G4LogicalVolume *motherLog = GetMotherLogical();
00160   G4VSolid *motherSolid = motherLog->GetSolid();
00161   std::vector<G4ThreeVector> points;
00162 
00163   if (verbose)
00164   {
00165     G4cout << "Checking overlaps for parameterised volume "
00166            << GetName() << " ... ";
00167   }
00168 
00169   for (G4int i=0; i<GetMultiplicity(); i++)
00170   {
00171     solidA = fparam->ComputeSolid(i, this);
00172     solidA->ComputeDimensions(fparam, i, this);
00173     fparam->ComputeTransformation(i, this);
00174 
00175     // Create the transformation from daughter to mother
00176     //
00177     G4AffineTransform Tm( GetRotation(), GetTranslation() );
00178 
00179     // Generate random points on surface according to the given resolution,
00180     // transform them to the mother's coordinate system and if no overlaps
00181     // with the mother volume, cache them in a vector for later use with
00182     // the daughters
00183     //
00184     for (G4int n=0; n<res; n++)
00185     {
00186       G4ThreeVector mp = Tm.TransformPoint(solidA->GetPointOnSurface());
00187 
00188       // Checking overlaps with the mother volume
00189       //
00190       if (motherSolid->Inside(mp)==kOutside)
00191       {
00192         G4double distin = motherSolid->DistanceToIn(mp);
00193         if (distin > tol)
00194         {
00195           std::ostringstream message;
00196           message << "Overlap with mother volume !" << G4endl
00197                   << "         Overlap is detected for volume "
00198                   << GetName() << ", parameterised instance: " << i << G4endl
00199                   << "          with its mother volume "
00200                   << motherLog->GetName() << G4endl
00201                   << "          at mother local point " << mp << ", "
00202                   << "overlapping by at least: "
00203                   << G4BestUnit(distin, "Length");
00204           G4Exception("G4PVParameterised::CheckOverlaps()",
00205                       "GeomVol1002", JustWarning, message);
00206           return true;
00207         }
00208       }
00209       points.push_back(mp);
00210     }
00211 
00212     // Checking overlaps with each other parameterised instance
00213     //
00214     std::vector<G4ThreeVector>::iterator pos;
00215     for (G4int j=i+1; j<GetMultiplicity(); j++)
00216     {
00217       solidB = fparam->ComputeSolid(j,this);
00218       solidB->ComputeDimensions(fparam, j, this);
00219       fparam->ComputeTransformation(j, this);
00220 
00221       // Create the transformation for daughter volume
00222       //
00223       G4AffineTransform Td( GetRotation(), GetTranslation() );
00224 
00225       for (pos=points.begin(); pos!=points.end(); pos++)
00226       {
00227         // Transform each point according to daughter's frame
00228         //
00229         G4ThreeVector md = Td.Inverse().TransformPoint(*pos);
00230 
00231         if (solidB->Inside(md)==kInside)
00232         {
00233           G4double distout = solidB->DistanceToOut(md);
00234           if (distout > tol)
00235           {
00236             std::ostringstream message;
00237             message << "Overlap within parameterised volumes !" << G4endl
00238                     << "          Overlap is detected for volume "
00239                     << GetName() << ", parameterised instance: " << i << G4endl
00240                     << "          with parameterised volume instance: " << j
00241                     << G4endl
00242                     << "          at local point " << md << ", "
00243                     << "overlapping by at least: "
00244                     << G4BestUnit(distout, "Length")
00245                     << ", related to volume instance: " << j << ".";
00246             G4Exception("G4PVParameterised::CheckOverlaps()",
00247                         "GeomVol1002", JustWarning, message);
00248             return true;
00249           }
00250         }
00251       }
00252     }
00253   }
00254   if (verbose)
00255   {
00256     G4cout << "OK! " << G4endl;
00257   }
00258 
00259   return false;
00260 }

Generated on Mon May 27 17:49:30 2013 for Geant4 by  doxygen 1.4.7