File indexing completed on 2024-06-01 07:06:34
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
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
0044
0045
0046 G4SolidStore* G4SolidStore::fgInstance = nullptr;
0047 G4ThreadLocal G4VStoreNotifier* G4SolidStore::fgNotifier = nullptr;
0048 G4ThreadLocal G4bool G4SolidStore::locked = false;
0049
0050
0051
0052
0053
0054
0055 G4SolidStore::G4SolidStore()
0056 : std::vector<G4VSolid*>()
0057 {
0058 reserve(100);
0059 }
0060
0061
0062
0063
0064
0065 G4SolidStore::~G4SolidStore()
0066 {
0067 Clean();
0068 }
0069
0070
0071
0072
0073
0074 void G4SolidStore::Clean()
0075 {
0076
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
0086
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
0117
0118
0119 void G4SolidStore::SetNotifier(G4VStoreNotifier* pNotifier)
0120 {
0121 GetInstance();
0122 fgNotifier = pNotifier;
0123 }
0124
0125
0126
0127
0128
0129 void G4SolidStore::UpdateMap()
0130 {
0131 G4AutoLock l(&mapMutex);
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
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
0177
0178
0179 void G4SolidStore::DeRegister(G4VSolid* pSolid)
0180 {
0181 G4SolidStore* store = GetInstance();
0182 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
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
0260
0261
0262 G4SolidStore* G4SolidStore::GetInstance()
0263 {
0264 static G4SolidStore worldStore;
0265 if (fgInstance == nullptr)
0266 {
0267 fgInstance = &worldStore;
0268 }
0269 return fgInstance;
0270 }