Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-06-01 07:06:34

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4SolidStore implementation
0027 //
0028 // 10.07.95, P.Kent, G.Cosmo
0029 // --------------------------------------------------------------------
0030 
0031 #include "globals.hh"
0032 #include "G4SolidStore.hh"
0033 #include "G4GeometryManager.hh"
0034 
0035 #include "G4AutoLock.hh"
0036 
0037 namespace
0038 {
0039   G4Mutex mapMutex = G4MUTEX_INITIALIZER;
0040 }
0041 
0042 // ***************************************************************************
0043 // Static class variables
0044 // ***************************************************************************
0045 //
0046 G4SolidStore* G4SolidStore::fgInstance = nullptr;
0047 G4ThreadLocal G4VStoreNotifier* G4SolidStore::fgNotifier = nullptr;
0048 G4ThreadLocal G4bool G4SolidStore::locked = false;
0049 
0050 // ***************************************************************************
0051 // Protected constructor: Construct underlying container with
0052 // initial size of 100 entries
0053 // ***************************************************************************
0054 //
0055 G4SolidStore::G4SolidStore()
0056   : std::vector<G4VSolid*>()
0057 {
0058   reserve(100);
0059 }
0060 
0061 // ***************************************************************************
0062 // Destructor
0063 // ***************************************************************************
0064 //
0065 G4SolidStore::~G4SolidStore() 
0066 {
0067   Clean();
0068 }
0069 
0070 // ***************************************************************************
0071 // Delete all elements from the store
0072 // ***************************************************************************
0073 //
0074 void G4SolidStore::Clean()
0075 {
0076   // Do nothing if geometry is closed
0077   //
0078   if (G4GeometryManager::IsGeometryClosed())
0079   {
0080     G4cout << "WARNING - Attempt to delete the solid store"
0081            << " while geometry closed !" << G4endl;
0082     return;
0083   }
0084 
0085   // Locks store for deletion of solids. De-registration will be
0086   // performed at this stage. G4VSolids will not de-register themselves.
0087   //
0088   locked = true;  
0089 
0090   std::size_t i = 0;
0091   G4SolidStore* store = GetInstance();
0092 
0093 #ifdef G4GEOMETRY_VOXELDEBUG
0094   G4cout << "Deleting Solids ... ";
0095 #endif
0096 
0097   for(auto pos=store->cbegin(); pos!=store->cend(); ++pos)
0098   {
0099     if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
0100     delete *pos; ++i;
0101   }
0102 
0103 #ifdef G4GEOMETRY_VOXELDEBUG
0104   if (store->size() < i-1)
0105     { G4cout << "No solids deleted. Already deleted by user ?" << G4endl; }
0106   else
0107     { G4cout << i-1 << " solids deleted !" << G4endl; }
0108 #endif
0109 
0110   store->bmap.clear(); store->mvalid = false;
0111   locked = false;
0112   store->clear();
0113 }
0114 
0115 // ***************************************************************************
0116 // Associate user notifier to the store
0117 // ***************************************************************************
0118 //
0119 void G4SolidStore::SetNotifier(G4VStoreNotifier* pNotifier)
0120 {
0121   GetInstance();
0122   fgNotifier = pNotifier;
0123 }
0124 
0125 // ***************************************************************************
0126 // Bring contents of internal map up to date and reset validity flag
0127 // ***************************************************************************
0128 //
0129 void G4SolidStore::UpdateMap()
0130 {
0131   G4AutoLock l(&mapMutex);  // to avoid thread contention at initialisation
0132   if (mvalid) return;
0133   bmap.clear();
0134   for(auto pos=GetInstance()->cbegin(); pos!=GetInstance()->cend(); ++pos)
0135   {
0136     const G4String& sol_name = (*pos)->GetName();
0137     auto it = bmap.find(sol_name);
0138     if (it != bmap.cend())
0139     {
0140       it->second.push_back(*pos);
0141     }
0142     else
0143     {
0144       std::vector<G4VSolid*> sol_vec { *pos };
0145       bmap.insert(std::make_pair(sol_name, sol_vec));
0146     }
0147   }
0148   mvalid = true;
0149   l.unlock();
0150 }
0151 
0152 // ***************************************************************************
0153 // Add Solid to container
0154 // ***************************************************************************
0155 //
0156 void G4SolidStore::Register(G4VSolid* pSolid)
0157 {
0158   G4SolidStore* store = GetInstance();
0159   store->push_back(pSolid);
0160   const G4String& sol_name = pSolid->GetName();
0161   auto it = store->bmap.find(sol_name);
0162   if (it != store->bmap.cend())
0163   {
0164     it->second.push_back(pSolid);
0165   }
0166   else
0167   {
0168     std::vector<G4VSolid*> sol_vec { pSolid };
0169     store->bmap.insert(std::make_pair(sol_name, sol_vec));
0170   }
0171   if (fgNotifier) { fgNotifier->NotifyRegistration(); }
0172   store->mvalid = true;
0173 }
0174 
0175 // ***************************************************************************
0176 // Remove Solid from container
0177 // ***************************************************************************
0178 //
0179 void G4SolidStore::DeRegister(G4VSolid* pSolid)
0180 {
0181   G4SolidStore* store = GetInstance();
0182   if (!locked)    // Do not de-register if locked !
0183   {
0184     if (fgNotifier != nullptr) { fgNotifier->NotifyDeRegistration(); }
0185     for (auto i=store->crbegin(); i!=store->crend(); ++i)
0186     {
0187       if (**i==*pSolid)
0188       {
0189         store->erase(std::next(i).base());
0190         store->mvalid = false;
0191         break;
0192       }
0193     }
0194     const G4String& sol_name = pSolid->GetName();
0195     auto it = store->bmap.find(sol_name);
0196     if (it != store->bmap.cend())
0197     {
0198       if (it->second.size() > 1)
0199       {
0200         for (auto i=it->second.cbegin(); i!=it->second.cend(); ++i)
0201         {
0202           if (**i==*pSolid)
0203           {
0204             it->second.erase(i);
0205             break;
0206           }
0207         }
0208       }
0209       else
0210       {
0211         store->bmap.erase(it);
0212       }
0213     }
0214   }
0215 }
0216 
0217 // ***************************************************************************
0218 // Retrieve the first or last solid pointer in the container having that name
0219 // ***************************************************************************
0220 //
0221 G4VSolid* G4SolidStore::GetSolid(const G4String& name, G4bool verbose,
0222                                  G4bool reverseSearch) const
0223 {
0224   G4SolidStore* store = GetInstance();
0225   if (!store->mvalid)  { store->UpdateMap(); }
0226   auto pos = store->bmap.find(name);
0227   if(pos != store->bmap.cend())
0228   {
0229     if ((verbose) && (pos->second.size()>1))
0230     {
0231       std::ostringstream message;
0232       message << "There exists more than ONE solid in store named: "
0233               << name << "!" << G4endl
0234               << "Returning the first found.";
0235       G4Exception("G4SolidStore::GetSolid()",
0236                   "GeomMgt1001", JustWarning, message);
0237     }
0238     if(reverseSearch)
0239     {
0240       return pos->second[pos->second.size()-1];
0241     }
0242     else
0243     {
0244       return pos->second[0];
0245     }
0246   }
0247   if (verbose)
0248   {
0249     std::ostringstream message;
0250     message << "Solid " << name << " not found in store !" << G4endl
0251             << "Returning NULL pointer.";
0252     G4Exception("G4SolidStore::GetSolid()",
0253                 "GeomMgt1001", JustWarning, message);
0254   }
0255   return nullptr;
0256 }
0257 
0258 // ***************************************************************************
0259 // Return ptr to Store, setting if necessary
0260 // ***************************************************************************
0261 //
0262 G4SolidStore* G4SolidStore::GetInstance()
0263 {
0264   static G4SolidStore worldStore;
0265   if (fgInstance == nullptr)
0266   {
0267     fgInstance = &worldStore;
0268   }
0269   return fgInstance;
0270 }