Geant4 Cross Reference |
>> 1 // This code implementation is the intellectual property of >> 2 // the GEANT4 collaboration. 1 // 3 // 2 // ******************************************* << 4 // By copying, distributing or modifying the Program (or any work 3 // * License and Disclaimer << 5 // based on the Program) you indicate your acceptance of this statement, 4 // * << 6 // and all its terms. 5 // * The Geant4 software is copyright of th << 6 // * the Geant4 Collaboration. It is provided << 7 // * conditions of the Geant4 Software License << 8 // * LICENSE and available at http://cern.ch/ << 9 // * include a list of copyright holders. << 10 // * << 11 // * Neither the authors of this software syst << 12 // * institutes,nor the agencies providing fin << 13 // * work make any representation or warran << 14 // * regarding this software system or assum << 15 // * use. Please see the license in the file << 16 // * for the full disclaimer and the limitatio << 17 // * << 18 // * This code implementation is the result << 19 // * technical work of the GEANT4 collaboratio << 20 // * By using, copying, modifying or distri << 21 // * any work based on the software) you ag << 22 // * use in resulting scientific publicati << 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* << 25 // 7 // 26 // G4IonTable class implementation << 8 // $Id: G4IonTable.cc,v 1.22.4.6 1999/12/14 09:16:47 gunter Exp $ >> 9 // GEANT4 tag $Name: geant4-01-01 $ 27 // 10 // 28 // Author: H.Kurashige, 27 June 1998 << 11 // 29 // ------------------------------------------- << 12 // -------------------------------------------------------------- >> 13 // GEANT 4 class implementation file >> 14 // >> 15 // For information related to this code contact: >> 16 // CERN, IT Division, ASD Group >> 17 // History: first implementation, based on object model of >> 18 // 27 June 1998 H.Kurashige >> 19 // --------------------------------------------------------------- >> 20 // modified GetIon 02 Aug., 98 H.Kurashige >> 21 // added Remove() 06 Nov.,98 H.Kurashige >> 22 // use G4NucleiPropoerties to get nuceli Mass 17 Nov.,98 H.Kurashige >> 23 // use G4GenericIon for process List >> 24 // modify fomula of Ion mass 09 Dec., 98 H.Kurashige >> 25 // ----- >> 26 // Modified GetIon methods 17 Aug. 99 H.Kurashige >> 27 // New design using G4VIsotopeTable 5 Oct. 99 H.Kurashige 30 28 31 #include "G4IonTable.hh" << 32 29 33 #include "G4AutoDelete.hh" << 30 #include "G4IonTable.hh" 34 #include "G4HyperNucleiProperties.hh" << 35 #include "G4Ions.hh" << 36 #include "G4IsotopeProperty.hh" << 37 #include "G4MuonicAtom.hh" << 38 #include "G4MuonicAtomHelper.hh" << 39 #include "G4NucleiProperties.hh" << 40 #include "G4NuclideTable.hh" << 41 #include "G4ParticleTable.hh" 31 #include "G4ParticleTable.hh" 42 #include "G4PhysicalConstants.hh" << 32 #include "G4Ions.hh" 43 #include "G4StateManager.hh" << 44 #include "G4SystemOfUnits.hh" << 45 #include "G4Threading.hh" << 46 #include "G4UImanager.hh" 33 #include "G4UImanager.hh" >> 34 #include "G4NucleiProperties.hh" >> 35 >> 36 #include "G4IsotopeProperty.hh" 47 #include "G4VIsotopeTable.hh" 37 #include "G4VIsotopeTable.hh" 48 #include "G4ios.hh" << 49 38 50 #include <algorithm> << 39 #include "G4ios.hh" 51 #include <iomanip> << 40 #include "g4std/iostream" 52 #include <iostream> << 41 #include "g4std/iomanip" 53 #include <sstream> << 54 #include <vector> << 55 << 56 // It is very important for multithreaded Gean << 57 // particle table pointer and the ion table po << 58 // each worker thread hold its own copy of the << 59 // ion list. This implementation is equivalent << 60 // private. The two shadow ponters are used by << 61 // content from the master thread. << 62 // << 63 G4ThreadLocal G4IonTable::G4IonList* G4IonTabl << 64 G4ThreadLocal std::vector<G4VIsotopeTable*>* G << 65 G4IonTable::G4IonList* G4IonTable::fIonListSha << 66 std::vector<G4VIsotopeTable*>* G4IonTable::fIs << 67 << 68 namespace lightions << 69 { << 70 static const G4ParticleDefinition* p_proton = << 71 static const G4ParticleDefinition* p_deuteron << 72 static const G4ParticleDefinition* p_triton = << 73 static const G4ParticleDefinition* p_alpha = n << 74 static const G4ParticleDefinition* p_He3 = nul << 75 void Init() << 76 { << 77 if (p_proton != nullptr) return; << 78 p_proton = G4ParticleTable::GetParticleTable << 79 p_deuteron = G4ParticleTable::GetParticleTab << 80 p_triton = G4ParticleTable::GetParticleTable << 81 p_alpha = G4ParticleTable::GetParticleTable( << 82 p_He3 = G4ParticleTable::GetParticleTable()- << 83 } << 84 } // namespace lightions << 85 << 86 namespace antilightions << 87 { << 88 static const G4ParticleDefinition* p_proton = << 89 static const G4ParticleDefinition* p_deuteron << 90 static const G4ParticleDefinition* p_triton = << 91 static const G4ParticleDefinition* p_alpha = n << 92 static const G4ParticleDefinition* p_He3 = nul << 93 void Init() << 94 { << 95 if (p_proton != nullptr) return; << 96 p_proton = G4ParticleTable::GetParticleTable << 97 p_deuteron = G4ParticleTable::GetParticleTab << 98 p_triton = G4ParticleTable::GetParticleTable << 99 p_alpha = G4ParticleTable::GetParticleTable( << 100 p_He3 = G4ParticleTable::GetParticleTable()- << 101 } << 102 } // namespace antilightions << 103 42 104 #ifdef G4MULTITHREADED << 43 #include "g4std/strstream" 105 G4Mutex G4IonTable::ionTableMutex = G4MUTEX_IN << 106 #endif << 107 44 108 // ------------------------------------------- << 109 45 >> 46 //////////////////// 110 G4IonTable::G4IonTable() 47 G4IonTable::G4IonTable() 111 { 48 { 112 fIonList = new G4IonList(); 49 fIonList = new G4IonList(); 113 << 50 fIsotopeTable = 0; 114 // Set up the shadow pointer used by worker << 115 // << 116 if (fIonListShadow == nullptr) { << 117 fIonListShadow = fIonList; << 118 } << 119 << 120 fIsotopeTableList = new std::vector<G4VIsoto << 121 << 122 // Set up the shadow pointer used by worker << 123 // << 124 if (fIsotopeTableListShadow == nullptr) { << 125 fIsotopeTableListShadow = fIsotopeTableLis << 126 } << 127 << 128 PrepareNuclideTable(); << 129 RegisterIsotopeTable(pNuclideTable); << 130 } 51 } 131 52 >> 53 //////////////////// 132 G4IonTable::~G4IonTable() 54 G4IonTable::~G4IonTable() 133 { 55 { 134 // delete IsotopeTable if existing << 56 // delete IsotopeTable if exists 135 if (fIsotopeTableList != nullptr) { << 57 if (fIsotopeTable != 0) delete fIsotopeTable; 136 for (const auto fIsotopeTable : *fIsotopeT << 58 fIsotopeTable =0; 137 if (fIsotopeTable != G4NuclideTable::Get << 59 138 delete fIsotopeTable; << 60 if (fIonList ==0) return; 139 } << 61 140 } << 62 // delete ion objects 141 fIsotopeTableList->clear(); << 63 G4ParticleDefinition* particle; 142 delete fIsotopeTableList; << 64 #ifdef G4USE_STL 143 } << 65 G4IonList::reverse_iterator i; 144 fIsotopeTableList = nullptr; << 66 for (i = fIonList->rbegin(); i!= fIonList->rend(); ++i) { 145 << 67 particle = *i; 146 if (fIonList == nullptr) return; << 68 #else 147 << 69 G4int idx; 148 // remove all contents in the Ion List << 70 for (idx=(fIonList->entries()-1); idx >=0 ; idx--) { 149 // No need to delete here because all partic << 71 particle = (*fIonList)(idx); 150 fIonList->clear(); << 151 delete fIonList; << 152 fIonList = nullptr; << 153 } << 154 << 155 G4IonTable* G4IonTable::GetIonTable() << 156 { << 157 return G4ParticleTable::GetParticleTable()-> << 158 } << 159 << 160 // Used by each worker thread to copy the cont << 161 void G4IonTable::WorkerG4IonTable() << 162 { << 163 if (fIonList == nullptr) { << 164 fIonList = new G4IonList(); << 165 } << 166 else { << 167 fIonList->clear(); << 168 } << 169 << 170 for (const auto& it : *fIonListShadow) { << 171 fIonList->insert(it); << 172 } << 173 << 174 // Do not copy Isotope Table to Worker threa << 175 // << 176 if (fIsotopeTableList == nullptr) { << 177 fIsotopeTableList = new std::vector<G4VIso << 178 for (const auto i : *fIsotopeTableListShad << 179 fIsotopeTableList->push_back(i); << 180 } << 181 } << 182 } << 183 << 184 void G4IonTable::InitializeLightIons() << 185 { << 186 lightions::Init(); << 187 antilightions::Init(); << 188 } << 189 << 190 void G4IonTable::DestroyWorkerG4IonTable() << 191 { << 192 // delete IsotopeTable if existing << 193 if (fIsotopeTableList != nullptr) { << 194 for (auto fIsotopeTable : *fIsotopeTableLi << 195 if (fIsotopeTable != G4NuclideTable::Get << 196 delete fIsotopeTable; << 197 } << 198 } << 199 fIsotopeTableList->clear(); << 200 delete fIsotopeTableList; << 201 } << 202 fIsotopeTableList = nullptr; << 203 << 204 if (fIonList == nullptr) return; << 205 << 206 // remove all contents in the Ion List << 207 // No need to delete here because all partic << 208 fIonList->clear(); << 209 delete fIonList; << 210 fIonList = nullptr; << 211 } << 212 << 213 G4ParticleDefinition* G4IonTable::CreateIon(G4 << 214 G4 << 215 { << 216 G4ParticleDefinition* ion = nullptr; << 217 << 218 // check whether GenericIon has processes << 219 G4ParticleDefinition* genericIon = G4Particl << 220 G4ProcessManager* pman = nullptr; << 221 if (genericIon != nullptr) { << 222 pman = genericIon->GetProcessManager(); << 223 } << 224 if ((genericIon == nullptr) || (genericIon-> << 225 #ifdef G4VERBOSE << 226 if (GetVerboseLevel() > 1) { << 227 G4cout << "G4IonTable::CreateIon() : can << 228 << " Z =" << Z << " A = " << A < << 229 } << 230 #endif 72 #endif 231 G4Exception("G4IonTable::CreateIon()", "PA << 232 "Can not create ions because G << 233 return nullptr; << 234 } << 235 73 236 G4double life = 0.0; << 74 if ( !IsLightIon(particle) ) { 237 G4DecayTable* decayTable = nullptr; << 75 // delete if not static objects 238 G4bool stable = true; << 239 G4double mu = 0.0; << 240 G4double Eex = 0.0; << 241 G4int lvl = 0; << 242 G4int J = 0; << 243 << 244 const G4IsotopeProperty* fProperty = FindIso << 245 if (fProperty != nullptr) { << 246 Eex = fProperty->GetEnergy(); << 247 lvl = fProperty->GetIsomerLevel(); << 248 J = fProperty->GetiSpin(); << 249 life = fProperty->GetLifeTime(); << 250 mu = fProperty->GetMagneticMoment(); << 251 decayTable = fProperty->GetDecayTable(); << 252 stable = (life <= 0.) || (decayTable == nu << 253 lvl = fProperty->GetIsomerLevel(); << 254 if (lvl < 0) lvl = 9; << 255 } << 256 else { << 257 #ifdef G4VERBOSE 76 #ifdef G4VERBOSE 258 if (GetVerboseLevel() > 1) { << 77 G4String name; 259 G4ExceptionDescription ed; << 78 if (GetVerboseLevel()>1) { 260 ed << "G4IonTable::CreateIon(): G4Isotop << 79 G4cout << "G4IonTable:~IonTable() : delete ion of " ; 261 << " Z = " << Z << " A = " << A << " << 80 G4cout << particle->GetParticleName() << G4endl; 262 if (flb != G4Ions::G4FloatLevelBase::no_ << 263 ed << " FloatingLevel +" << G4Ions::Fl << 264 } 81 } 265 ed << ".\n" << 266 << " Physics quantities such as life << 267 G4Exception("G4IonTable::CreateIon()", " << 268 } << 269 #endif 82 #endif 270 // excitation energy << 83 delete particle; 271 Eex = E; << 272 // lvl is assigned to 9 temporarily << 273 if (Eex > 0.0) lvl = 9; << 274 } << 275 << 276 // Eex = G4NuclideTable::Round(Eex); << 277 if (Eex == 0.0) lvl = 0; << 278 // ion name << 279 G4String name = ""; << 280 /////////////if (lvl<9) name = GetIonName(Z, << 281 if (lvl == 0 && flb == G4Ions::G4FloatLevelB << 282 name = GetIonName(Z, A, lvl); << 283 else << 284 name = GetIonName(Z, A, Eex, flb); << 285 << 286 // PDG encoding << 287 G4int encoding = GetNucleusEncoding(Z, A, E, << 288 << 289 // PDG mass << 290 G4double mass = GetNucleusMass(Z, A) + Eex; << 291 << 292 // PDG charge is set to one of nucleus << 293 G4double charge = G4double(Z) * eplus; << 294 << 295 // create an ion << 296 // spin, parity, isospin values are fixed << 297 << 298 // Request lock for particle table accesses. << 299 // this critical region. << 300 // << 301 // clang-format off << 302 ion = new G4Ions( name, mass, << 303 J, +1, << 304 0, 0, << 305 "nucleus", 0, << 306 stable, life, << 307 "generic", 0, << 308 Eex, lvl << 309 // clang-format on << 310 << 311 // Release lock for particle table accesses. << 312 // << 313 ion->SetPDGMagneticMoment(mu); << 314 static_cast<G4Ions*>(ion)->SetFloatLevelBase << 315 << 316 // No Anti particle registered << 317 ion->SetAntiPDGEncoding(0); << 318 << 319 #ifdef G4VERBOSE << 320 if (GetVerboseLevel() > 1) { << 321 G4cout << "G4IonTable::CreateIon() : creat << 322 << " encoding=" << encoding; << 323 if (E > 0.0) { << 324 G4cout << " IsomerLVL=" << lvl << " exci << 325 } 84 } 326 G4cout << G4endl; << 327 } << 328 #endif << 329 << 330 // Add process manager to the ion << 331 AddProcessManager(ion); << 332 85 333 #ifdef G4MULTITHREADED << 334 // Fill decay channels if this method is inv << 335 if (G4Threading::IsWorkerThread()) { << 336 if (!stable && (decayTable != nullptr)) { << 337 G4int nCh = decayTable->entries(); << 338 for (G4int iCh = 0; iCh < nCh; ++iCh) { << 339 decayTable->GetDecayChannel(iCh)->GetD << 340 } << 341 } << 342 } 86 } 343 #endif << 344 87 345 return ion; << 88 // remove all contents in the Ion List 346 } << 89 fIonList->clear(); 347 90 348 G4ParticleDefinition* G4IonTable::CreateIon(G4 << 91 delete fIonList; 349 G4 << 92 fIonList =0; 350 { << 93 } 351 if (LL == 0) return CreateIon(Z, A, E, flb); << 352 94 353 // create hyper nucleus << 354 G4ParticleDefinition* ion = nullptr; << 355 95 356 // check whether GenericIon has processes << 96 //////////////////// 357 G4ParticleDefinition* genericIon = G4Particl << 97 // -- CreateIon method ------ 358 G4ProcessManager* pman = nullptr; << 98 //////////////////// 359 if (genericIon != nullptr) pman = genericIon << 99 G4ParticleDefinition* G4IonTable::CreateIon(G4int Z, G4int A, G4double E, G4int J) 360 if ((genericIon == nullptr) || (genericIon-> << 100 { >> 101 G4ParticleDefinition* ion=0; >> 102 >> 103 // get ion name >> 104 G4String name = GetIonName(Z, A, E); >> 105 if ( name(0) == '?') { 361 #ifdef G4VERBOSE 106 #ifdef G4VERBOSE 362 if (GetVerboseLevel() > 1) { << 107 if (GetVerboseLevel()>0) { 363 G4cout << "G4IonTable::CreateIon() : can << 108 G4cout << "G4IonTable::GetIon() : can not create ions " << G4endl; 364 << " Z =" << Z << " A = " << A < << 109 G4cout << " Z =" << Z << " A = " << A << G4endl; 365 } 110 } 366 #endif 111 #endif 367 G4Exception("G4IonTable::CreateIon()", "PA << 112 return 0; 368 "Can not create ions because G << 113 } 369 return nullptr; << 370 } << 371 114 372 G4int J = 0; << 115 G4double life = -1.0; 373 G4double life = 0.0; << 116 G4DecayTable* decayTable =0; 374 G4DecayTable* decayTable = nullptr; << 375 G4bool stable = true; << 376 << 377 // excitation energy << 378 // G4double Eex = G4NuclideTable::Round(E); << 379 G4double Eex = E; << 380 G4double mass = GetNucleusMass(Z, A, LL) + E << 381 G4int lvl = 0; << 382 // lvl is assigned to 9 temporarily << 383 if (Eex > 0.0) lvl = 9; << 384 117 385 // PDG encoding << 118 G4IsotopeProperty* fProperty = FindIsotope(Z, A, E, J); 386 G4int encoding = GetNucleusEncoding(Z, A, LL << 119 if (fProperty !=0 ){ 387 << 120 J = fProperty->GetiSpin(); 388 // PDG charge is set to one of nucleus << 121 E = fProperty->GetEnergy(); 389 G4double charge = G4double(Z) * eplus; << 122 life = fProperty->GetLifeTime(); >> 123 decayTable = fProperty->GetDecayTable(); >> 124 } 390 125 >> 126 G4double mass = GetNucleusMass(Z, A)+ E; >> 127 G4double charge = G4double(Z)*eplus; >> 128 391 // create an ion 129 // create an ion 392 // spin, parity, isospin values are fixed << 130 // spin, parity, isospin values are fixed 393 // 131 // 394 // get ion name << 395 G4String name = GetIonName(Z, A, LL, Eex, fl << 396 << 397 // clang-format off << 398 ion = new G4Ions( name, mass, 132 ion = new G4Ions( name, mass, 0.0*MeV, charge, 399 J, +1, << 133 J, +1, 0, 400 0, 0, << 134 0, 0, 0, 401 "nucleus", 0, << 135 "nucleus", 0, A, 0, 402 stable, life, << 136 true, life, decayTable); 403 "generic", 0, << 404 Eex, lvl << 405 // clang-format on << 406 << 407 // Release lock for particle table accesses << 408 << 409 G4double mu = 0.0; // magnetic moment << 410 ion->SetPDGMagneticMoment(mu); << 411 static_cast<G4Ions*>(ion)->SetFloatLevelBase << 412 << 413 // No Anti particle registered << 414 ion->SetAntiPDGEncoding(0); << 415 137 416 #ifdef G4VERBOSE 138 #ifdef G4VERBOSE 417 if (GetVerboseLevel() > 1) { << 139 if (GetVerboseLevel()>1) { 418 G4cout << "G4IonTable::CreateIon() : creat << 140 G4cout << "G4IonTable::GetIon() : create ion of " << name << G4endl; 419 << ", " << LL << " encoding=" << en << 141 } 420 if (E > 0.0) { << 421 G4cout << " IsomerLVL=" << lvl << " exci << 422 } << 423 G4cout << G4endl; << 424 } << 425 #endif 142 #endif 426 << 143 427 // Add process manager to the ion 144 // Add process manager to the ion 428 AddProcessManager(ion); << 145 AddProcessManager(name); 429 << 146 >> 147 // Set cut value same as "GenericIon" >> 148 SetCuts(ion); >> 149 >> 150 if (fProperty !=0) delete fProperty; 430 return ion; 151 return ion; 431 } 152 } 432 153 433 G4ParticleDefinition* G4IonTable::CreateIon(G4 << 154 //////////////////// >> 155 // -- GetIon methods ------ >> 156 //////////////////// >> 157 G4ParticleDefinition* G4IonTable::GetIon(G4int Z, G4int A, G4int J, G4int Q) 434 { 158 { 435 // always create an ion for any lvl << 159 return GetIon(Z, A); 436 return CreateIon(Z, A, 0.0, G4Ions::FloatLev << 437 } 160 } 438 161 439 G4ParticleDefinition* G4IonTable::CreateIon(G4 << 162 //////////////////// >> 163 G4ParticleDefinition* G4IonTable::GetIon(G4int Z, G4int A, G4int J) 440 { 164 { 441 return (LL == 0) ? CreateIon(Z, A, 0.0, G4Io << 165 return GetIon( Z, A, 0.0, J); 442 : CreateIon(Z, A, LL, 0.0, << 443 } << 444 << 445 G4ParticleDefinition* G4IonTable::GetIon(G4int << 446 { << 447 return GetIon(Z, A, 0.0, G4Ions::G4FloatLeve << 448 } << 449 << 450 G4ParticleDefinition* G4IonTable::GetIon(G4int << 451 { << 452 return (LL == 0) ? GetIon(Z, A, 0.0, G4Ions: << 453 : GetIon(Z, A, LL, 0.0, G4I << 454 } 166 } 455 167 >> 168 //////////////////// 456 G4ParticleDefinition* G4IonTable::GetIon(G4int 169 G4ParticleDefinition* G4IonTable::GetIon(G4int Z, G4int A, G4double E, G4int J) 457 { 170 { 458 return GetIon(Z, A, E, G4Ions::G4FloatLevelB << 171 if ( (A<1) || (Z>numberOfElements) || (Z<=0) || (J<0) || (E<0.0) ) { 459 } << 460 << 461 G4ParticleDefinition* G4IonTable::GetIon(G4int << 462 { << 463 return GetIon(Z, A, E, G4Ions::FloatLevelBas << 464 } << 465 << 466 G4ParticleDefinition* G4IonTable::GetIon(G4int << 467 G4int << 468 { << 469 if ((A < 1) || (Z <= 0) || (E < 0.0) || (A > << 470 #ifdef G4VERBOSE << 471 if (GetVerboseLevel() > 0) { << 472 G4cout << "G4IonTable::GetIon() : illega << 473 << " Z =" << Z << " A = " << A < << 474 } << 475 #endif << 476 return nullptr; << 477 } << 478 auto flb1 = flb; << 479 << 480 // Search ions with A, Z << 481 G4ParticleDefinition* ion = FindIon(Z, A, E, << 482 << 483 // find out ground state floating level << 484 if (ion == nullptr && E == 0.0) { << 485 const G4IsotopeProperty* fProperty = FindI << 486 if (nullptr != fProperty) { << 487 flb1 = fProperty->GetFloatLevelBase(); << 488 if (flb != flb1) { << 489 ion = FindIon(Z, A, E, flb1, J); << 490 } << 491 } << 492 } << 493 << 494 // create ion << 495 #ifdef G4MULTITHREADED << 496 if (ion == nullptr) { << 497 if (G4Threading::IsWorkerThread()) { << 498 G4MUTEXLOCK(&G4IonTable::ionTableMutex); << 499 ion = FindIonInMaster(Z, A, E, flb1, J); << 500 if (ion == nullptr) ion = CreateIon(Z, A << 501 InsertWorker(ion); << 502 G4MUTEXUNLOCK(&G4IonTable::ionTableMutex << 503 } << 504 else { << 505 ion = CreateIon(Z, A, E, flb1); << 506 } << 507 } << 508 #else << 509 if (ion == nullptr) ion = CreateIon(Z, A, E, << 510 #endif << 511 << 512 return ion; << 513 } << 514 << 515 G4ParticleDefinition* G4IonTable::GetIon(G4int << 516 { << 517 return GetIon(Z, A, LL, E, G4Ions::G4FloatLe << 518 } << 519 << 520 G4ParticleDefinition* G4IonTable::GetIon(G4int << 521 G4int << 522 { << 523 return GetIon(Z, A, LL, E, G4Ions::FloatLeve << 524 } << 525 << 526 G4ParticleDefinition* G4IonTable::GetIon(G4int << 527 G4Ion << 528 { << 529 if (LL == 0) return GetIon(Z, A, E, flb, J); << 530 << 531 if (A < 2 || Z < 0 || Z > A - LL || LL > A | << 532 #ifdef G4VERBOSE << 533 if (GetVerboseLevel() > 0) { << 534 G4cout << "G4IonTable::GetIon() : illega << 535 << " Z =" << Z << " A = " << A < << 536 } << 537 #endif << 538 return nullptr; << 539 } << 540 if (A == 2) { << 541 #ifdef G4VERBOSE 172 #ifdef G4VERBOSE 542 if (GetVerboseLevel() > 0) { << 173 if (GetVerboseLevel()>0) { 543 G4cout << "G4IonTable::GetIon() : No bou << 174 G4cout << "G4IonTable::GetIon() : illegal atomic number/mass" << G4endl; 544 << " Z =" << Z << " A = " << A < << 175 G4cout << " Z =" << Z << " A = " << A << " E = " << E/keV << G4endl; 545 } 176 } 546 #endif 177 #endif 547 return nullptr; << 178 G4Exception("G4IonTable::GetIon : illegal atomic number/mass "); 548 } 179 } 549 180 550 // Search ions with A, Z << 181 // Search ions with A, Z 551 G4ParticleDefinition* ion = FindIon(Z, A, LL << 182 G4ParticleDefinition* ion = FindIon(Z,A,E,J); 552 183 553 // create ion 184 // create ion 554 #ifdef G4MULTITHREADED << 185 if (ion == 0) { 555 if (ion == nullptr) { << 186 ion = CreateIon(Z, A, E, J); 556 if (G4Threading::IsWorkerThread()) { << 557 G4MUTEXLOCK(&G4IonTable::ionTableMutex); << 558 ion = FindIonInMaster(Z, A, LL, E, flb, << 559 if (ion == nullptr) ion = CreateIon(Z, A << 560 InsertWorker(ion); << 561 G4MUTEXUNLOCK(&G4IonTable::ionTableMutex << 562 } << 563 else { << 564 ion = CreateIon(Z, A, LL, E, flb); << 565 } << 566 } 187 } 567 #else << 568 if (ion == nullptr) ion = CreateIon(Z, A, LL << 569 #endif << 570 << 571 return ion; << 572 } << 573 188 574 G4ParticleDefinition* G4IonTable::GetIon(G4int << 189 return ion; 575 { << 576 G4int Z, A, LL, IsoLvl; << 577 G4double E; << 578 if (!GetNucleusByEncoding(encoding, Z, A, LL << 579 #ifdef G4VERBOSE << 580 if (GetVerboseLevel() > 0) { << 581 G4cout << "G4IonTable::GetIon() : illega << 582 << " CODE:" << encoding << G4endl << 583 } << 584 #endif << 585 G4Exception("G4IonTable::GetIon()", "PART1 << 586 return nullptr; << 587 } << 588 return GetIon(Z, A, LL, IsoLvl); << 589 } 190 } 590 191 >> 192 //////////////////// 591 G4ParticleDefinition* G4IonTable::FindIon(G4in 193 G4ParticleDefinition* G4IonTable::FindIon(G4int Z, G4int A, G4double E, G4int J) 592 { 194 { 593 return FindIon(Z, A, E, G4Ions::G4FloatLevel << 195 const G4double EnergyTorelance = 0.1 * keV; 594 } << 595 << 596 G4ParticleDefinition* G4IonTable::FindIon(G4in << 597 { << 598 return FindIon(Z, A, E, G4Ions::FloatLevelBa << 599 } << 600 196 601 G4ParticleDefinition* G4IonTable::FindIon(G4in << 197 if ( (A<1) || (Z>numberOfElements) || (Z<=0) || (J<0) || (E<0.0)) { 602 G4Io << 603 { << 604 if ((A < 1) || (Z <= 0) || (J < 0) || (E < 0 << 605 #ifdef G4VERBOSE 198 #ifdef G4VERBOSE 606 if (GetVerboseLevel() > 0) { << 199 if (GetVerboseLevel()>0) { 607 G4cout << "G4IonTable::FindIon(): illega << 200 G4cout << "G4IonTable::FindIon() : illegal atomic number/mass or excitation level " << G4endl; 608 << " or excitation level:" << G4e << 201 G4cout << " Z =" << Z << " A = " << A << " E = " << E/keV << G4endl; 609 << " E = " << E / keV << G4endl; << 610 } 202 } 611 #endif 203 #endif 612 G4Exception("G4IonTable::FindIon()", "PART << 204 return 0; 613 return nullptr; << 614 } 205 } 615 // Search ions with A, Z ,E 206 // Search ions with A, Z ,E 616 // !! J is omitted now !! << 207 // !! J is moitted now !! 617 const G4ParticleDefinition* ion = nullptr; << 208 G4ParticleDefinition* ion; 618 G4bool isFound = false; 209 G4bool isFound = false; 619 210 620 // check if light ion << 211 // -- loop over all particles in Ion table 621 ion = GetLightIon(Z, A); << 212 #ifdef G4USE_STL 622 if (ion != nullptr && E == 0.0) { << 213 G4IonList::iterator idx; 623 // light ion << 214 for (idx = fIonList->begin(); idx!= fIonList->end(); ++idx) { 624 isFound = true; << 215 ion = *idx; 625 } << 216 #else 626 else { << 217 G4int idx; 627 // -- loop over all particles in Ion table << 218 for (idx= 0; idx < fIonList->entries() ; ++idx) { 628 G4int encoding = GetNucleusEncoding(Z, A); << 219 ion = (*fIonList)(idx); 629 const G4ParticleDefinition* ion1 = nullptr << 630 for (auto i = fIonList->find(encoding); i << 631 ion = i->second; << 632 if ((ion->GetAtomicNumber() != Z) || (io << 633 // excitation level << 634 G4double anExcitaionEnergy = ((const G4I << 635 << 636 if (std::fabs(E - anExcitaionEnergy) < p << 637 if (nullptr == ion1) ion1 = ion; << 638 if (((const G4Ions*)(ion))->GetFloatLe << 639 isFound = true; << 640 break; << 641 } << 642 } << 643 } << 644 // rerun search on ground level without ch << 645 if (!isFound && E == 0.0 && nullptr != ion << 646 isFound = true; << 647 ion = ion1; << 648 } << 649 } << 650 << 651 if (isFound) { << 652 return const_cast<G4ParticleDefinition*>(i << 653 } << 654 << 655 return nullptr; << 656 } << 657 << 658 G4ParticleDefinition* G4IonTable::FindIon(G4in << 659 { << 660 return (LL == 0) ? FindIon(Z, A, E, G4Ions:: << 661 : FindIon(Z, A, LL, E, G4Io << 662 } << 663 << 664 G4ParticleDefinition* G4IonTable::FindIon(G4in << 665 G4in << 666 { << 667 return FindIon(Z, A, LL, E, G4Ions::FloatLev << 668 } << 669 << 670 G4ParticleDefinition* G4IonTable::FindIon(G4in << 671 G4Io << 672 { << 673 if (LL == 0) return FindIon(Z, A, E, flb, J) << 674 << 675 if (A < 2 || Z < 0 || Z > A - LL || LL > A | << 676 #ifdef G4VERBOSE << 677 if (GetVerboseLevel() > 0) { << 678 G4cout << "G4IonTable::FindIon(): illega << 679 << " or excitation level:" << G4e << 680 << " E = " << E / keV << G4endl; << 681 } << 682 #endif 220 #endif 683 G4Exception("G4IonTable::FindIon()", "PART << 684 return nullptr; << 685 } << 686 // Search ions with A, Z ,E << 687 // !! J is omitted now !! << 688 const G4ParticleDefinition* ion = nullptr; << 689 G4bool isFound = false; << 690 221 691 // -- loop over all particles in Ion table << 222 // Z = Atomic Number 692 G4int encoding = GetNucleusEncoding(Z, A, LL << 223 G4int anAtomicNumber = 0; 693 for (auto i = fIonList->find(encoding); i != << 224 // A = baryon number 694 ion = i->second; << 225 G4int anAtomicMass = 0; 695 if ((ion->GetAtomicNumber() != Z) || (ion- << 696 if (ion->GetQuarkContent(3) != LL) break; << 697 // excitation level 226 // excitation level 698 G4double anExcitaionEnergy = ((const G4Ion << 227 G4double anExcitaionEnergy =0.0; 699 if (std::fabs(E - anExcitaionEnergy) < pNu << 700 if (((const G4Ions*)(ion))->GetFloatLeve << 701 isFound = true; << 702 break; << 703 } << 704 } << 705 } << 706 << 707 if (isFound) { << 708 return const_cast<G4ParticleDefinition*>(i << 709 } << 710 << 711 return nullptr; << 712 } << 713 << 714 G4ParticleDefinition* G4IonTable::FindIon(G4in << 715 { << 716 return FindIon(Z, A, 0.0, G4Ions::FloatLevel << 717 } << 718 << 719 G4ParticleDefinition* G4IonTable::FindIon(G4in << 720 { << 721 return (LL == 0) ? FindIon(Z, A, 0.0, G4Ions << 722 : FindIon(Z, A, LL, 0.0, G4 << 723 } << 724 << 725 G4int G4IonTable::GetNucleusEncoding(G4int Z, << 726 { << 727 // PDG code for Ions << 728 // Nuclear codes are given as 10-digit numbe << 729 // For a nucleus consisting of np protons an << 730 // A = np + nn and Z = np. << 731 // I gives the isomer level, with I = 0 corr << 732 // to the ground state and I >0 to excitatio << 733 << 734 if (Z == 1 && A == 1 && E == 0.0) return 221 << 735 << 736 G4int encoding = 1000000000; << 737 encoding += Z * 10000; << 738 encoding += A * 10; << 739 if (lvl > 0 && lvl < 10) << 740 encoding += lvl; // isomer level << 741 else if (E > 0.0) << 742 encoding += 9; // isomer level << 743 << 744 return encoding; << 745 } << 746 << 747 G4int G4IonTable::GetNucleusEncoding(G4int Z, << 748 { << 749 // Get PDG code for Hyper-Nucleus Ions << 750 // Nuclear codes are given as 10-digit numbe << 751 // For a nucleus consisting of np protons an << 752 // A = np + nn +nlambda and Z = np. << 753 // LL = nlambda << 754 // I gives the isomer level, with I = 0 corr << 755 // to the ground state and I >0 to excitatio << 756 << 757 G4int encoding = GetNucleusEncoding(Z, A, E, << 758 if (LL == 0) return encoding; << 759 encoding += LL * 10000000; << 760 if (Z == 1 && A == 1 && E == 0.0) encoding = << 761 << 762 return encoding; << 763 } << 764 << 765 G4bool G4IonTable::GetNucleusByEncoding(G4int << 766 { << 767 if (encoding <= 0) return false; // anti pa << 768 << 769 if (encoding == 2212) // proton << 770 { << 771 Z = 1; << 772 A = 1; << 773 E = 0.0; << 774 lvl = 0; << 775 return true; << 776 } << 777 << 778 encoding -= 1000000000; << 779 Z = encoding / 10000; << 780 encoding -= 10000 * Z; << 781 A = encoding / 10; << 782 lvl = encoding % 10; << 783 return true; << 784 } << 785 << 786 G4bool G4IonTable::GetNucleusByEncoding(G4int << 787 G4int& << 788 { << 789 if (encoding <= 0) return false; // anti pa << 790 << 791 if (encoding == 3122) // Lambda << 792 { << 793 Z = 1; << 794 A = 1; << 795 LL = 1; << 796 E = 0.0; << 797 lvl = 0; << 798 return true; << 799 } << 800 << 801 if (encoding % 10 != 0) { << 802 // !!!not supported for excitation states << 803 return false; << 804 } << 805 if (encoding < 1000000000) { << 806 // anti particle << 807 return false; << 808 } << 809 228 810 encoding -= 1000000000; << 229 if ( IsLightIon(ion) ) { 811 LL = encoding / 10000000; << 230 anAtomicNumber = int(ion->GetPDGCharge()/eplus); 812 encoding -= 10000000 * LL; << 231 anAtomicMass = ion->GetBaryonNumber(); 813 Z = encoding / 10000; << 232 anExcitaionEnergy = 0.0; 814 encoding -= 10000 * Z; << 233 815 A = encoding / 10; << 234 } else { 816 lvl = encoding % 10; << 235 anAtomicNumber = ((const G4Ions*)(ion))->GetAtomicNumber(); 817 return true; << 236 anAtomicMass = ((const G4Ions*)(ion))->GetAtomicMass(); 818 } << 237 anExcitaionEnergy = ((const G4Ions*)(ion))->GetExcitationEnergy(); 819 << 238 } 820 G4String G4IonTable::GetIonName(G4int Z, G4int << 239 821 G4Ions::G4Floa << 240 if ( (A == anAtomicMass) && 822 { << 241 (Z == anAtomicNumber ) && 823 G4String name = GetIonName(Z, A, 0); << 242 ( abs(E - anExcitaionEnergy ) < EnergyTorelance ) ) { 824 << 243 isFound = true; 825 // Excited energy or floating level << 244 break; 826 if (E > 0 || flb != G4Ions::G4FloatLevelBase << 827 std::ostringstream os; << 828 os.setf(std::ios::fixed); << 829 os.precision(3); << 830 // Excited nucleus << 831 os << '[' << E / keV; << 832 if (flb != G4Ions::G4FloatLevelBase::no_Fl << 833 os << G4Ions::FloatLevelBaseChar(flb); << 834 } 245 } 835 os << ']'; << 836 name += os.str(); << 837 } 246 } 838 247 839 return name; << 248 if ( isFound ){ 840 } << 249 return ion; 841 << 250 } else { 842 G4String G4IonTable::GetIonName(G4int Z, G4int << 251 return 0; 843 G4Ions::G4Floa << 844 { << 845 if (LL == 0) return GetIonName(Z, A, E, flb) << 846 G4String name = ""; << 847 for (G4int i = 0; i < LL; ++i) { << 848 name += "L"; << 849 } 252 } 850 name += GetIonName(Z, A, E, flb); << 851 return name; << 852 } 253 } 853 254 854 G4String G4IonTable::GetIonName(G4int Z, G4int << 255 ///////////////// 855 { << 256 G4String G4IonTable::GetIonName(G4int Z, G4int A, G4double E) const 856 std::ostringstream os; << 257 { 857 << 258 G4String name; 858 // Atomic number << 259 if ( (0< Z) && (Z <=numberOfElements) ) { 859 if ((0 < Z) && (Z <= numberOfElements)) { << 260 name = elementName[Z-1]; 860 os << elementName[Z - 1]; << 261 } else { 861 } << 262 return "?"; 862 else { << 263 } 863 os << "E" << Z << "-"; << 264 char val[50]; 864 } << 265 G4std::ostrstream os(val,50); 865 // Atomic Mass << 266 os.setf(G4std::ios::fixed); 866 os << A; << 267 os << A << '[' << G4std::setprecision(1) << E/keV << ']' << '\0'; 867 << 268 name += val; 868 if (lvl > 0) { << 869 // Isomer level for Excited nucelus << 870 os << '[' << lvl << ']'; << 871 } << 872 G4String name = os.str(); << 873 return name; 269 return name; 874 } 270 } 875 271 876 G4String G4IonTable::GetIonName(G4int Z, G4int << 877 { << 878 if (LL == 0) return GetIonName(Z, A, lvl); << 879 G4String name = ""; << 880 for (G4int i = 0; i < LL; ++i) { << 881 name += "L"; << 882 } << 883 name += GetIonName(Z, A, lvl); << 884 return name; << 885 } << 886 272 887 G4bool G4IonTable::IsIon(const G4ParticleDefin << 273 ///////////////// >> 274 G4bool G4IonTable::IsIon(G4ParticleDefinition* particle) 888 { 275 { 889 // Return true if the particle is ion << 276 // return true if the particle is ion 890 static const G4String nucleus("nucleus"); << 891 static const G4String proton("proton"); << 892 << 893 // Neutron is not ion << 894 if ((particle->GetAtomicMass() > 0) && (part << 895 return particle->GetBaryonNumber() > 0; << 896 } << 897 277 898 // Particles derived from G4Ions << 278 // particles derived from G4VIon and G4Ions 899 if (particle->GetParticleType() == nucleus) << 279 G4bool value = (particle->GetParticleType() == "nucleus"); 900 280 901 // Proton (Hydrogen nucleus) << 281 // proton (Hydrogen nucleus) 902 if (particle->GetParticleName() == proton) r << 282 value = value || (particle->GetParticleName() == "proton"); 903 283 904 return false; << 284 return value; 905 } 285 } 906 286 907 G4bool G4IonTable::IsAntiIon(const G4ParticleD << 287 ///////////////// >> 288 G4bool G4IonTable::IsLightIon(G4ParticleDefinition* particle) const 908 { 289 { 909 // Return true if the particle is ion << 290 // return true if the particle is pre-defined ion 910 static const G4String anti_nucleus("anti_nuc << 291 G4String name = particle->GetParticleName(); 911 static const G4String anti_proton("anti_prot << 912 << 913 // Anti_neutron is not ion << 914 if ((particle->GetAtomicMass() > 0) && (part << 915 return particle->GetBaryonNumber() < 0; << 916 } << 917 << 918 // Particles derived from G4Ions << 919 if (particle->GetParticleType() == anti_nucl << 920 292 921 // Anti_proton (Anti_Hydrogen nucleus) << 293 G4bool value = (name == "proton"); 922 if (particle->GetParticleName() == anti_prot << 294 value = value || (name == "neutron"); 923 << 295 value = value || (name == "alpha"); 924 return false; << 296 value = value || (name == "deuteron"); 925 } << 297 value = value || (name == "triton") ; 926 << 298 value = value || (name == "He3"); 927 G4bool G4IonTable::IsLightIon(const G4Particle << 299 value = value || (name == "GenericIon") ; 928 { << 300 929 static const std::string names[] = {"proton" << 301 return value; 930 << 302 } 931 // Return true if the particle is pre-define << 932 return std::find(names, names + 5, (particle << 933 } << 934 << 935 G4bool G4IonTable::IsLightAntiIon(const G4Part << 936 { << 937 static const std::string names[] = {"anti_pr << 938 "anti_He << 939 << 940 // Return true if the particle is pre-define << 941 return std::find(names, names + 5, (particle << 942 } << 943 303 >> 304 ///////////////// 944 G4ParticleDefinition* G4IonTable::GetLightIon( 305 G4ParticleDefinition* G4IonTable::GetLightIon(G4int Z, G4int A) const 945 { 306 { 946 // Returns pointer to pre-defined ions << 307 // returns pointer to pre-defined ions 947 const G4ParticleDefinition* ion = nullptr; << 948 if ((Z <= 2)) { << 949 #ifndef G4MULTITHREADED << 950 // In sequential use lazy-initialization << 951 lightions::Init(); << 952 #endif << 953 if ((Z == 1) && (A == 1)) { << 954 ion = lightions::p_proton; << 955 } << 956 else if ((Z == 1) && (A == 2)) { << 957 ion = lightions::p_deuteron; << 958 } << 959 else if ((Z == 1) && (A == 3)) { << 960 ion = lightions::p_triton; << 961 } << 962 else if ((Z == 2) && (A == 4)) { << 963 ion = lightions::p_alpha; << 964 } << 965 else if ((Z == 2) && (A == 3)) { << 966 ion = lightions::p_He3; << 967 } << 968 } << 969 return const_cast<G4ParticleDefinition*>(ion << 970 } << 971 308 972 G4ParticleDefinition* G4IonTable::GetLightAnti << 309 G4ParticleDefinition* ion=0; 973 { << 310 G4double mass; 974 // Returns pointer to pre-defined ions << 311 if ( (Z<=2) ) { 975 const G4ParticleDefinition* ion = nullptr; << 312 if ( (Z==1)&&(A==1) ) { 976 if ((Z <= 2)) { << 313 ion = G4ParticleTable::GetParticleTable()->FindParticle("proton"); // proton 977 #ifndef G4MULTITHREADED << 314 978 // In sequential use lazy-initialization << 315 } else if ( (Z==0)&&(A==1) ) { 979 antilightions::Init(); << 316 ion = G4ParticleTable::GetParticleTable()->FindParticle("neutron"); // neutron 980 #endif << 317 } else if ( (Z==1)&&(A==2) ) { 981 if ((Z == 1) && (A == 1)) { << 318 ion = G4ParticleTable::GetParticleTable()->FindParticle("deuteron"); // deuteron 982 ion = antilightions::p_proton; << 319 } else if ( (Z==1)&&(A==3) ) { 983 } << 320 ion = G4ParticleTable::GetParticleTable()->FindParticle("triton"); // tritoon 984 else if ((Z == 1) && (A == 2)) { << 321 } else if ( (Z==2)&&(A==4) ) { 985 ion = antilightions::p_deuteron; << 322 ion = G4ParticleTable::GetParticleTable()->FindParticle("alpha"); // alpha 986 } << 323 987 else if ((Z == 1) && (A == 3)) { << 324 } else if ( (Z==2)&&(A==3) ) { 988 ion = antilightions::p_triton; << 325 ion = G4ParticleTable::GetParticleTable()->FindParticle("He3"); // He3 989 } << 990 else if ((Z == 2) && (A == 4)) { << 991 ion = antilightions::p_alpha; << 992 } << 993 else if ((Z == 2) && (A == 3)) { << 994 ion = antilightions::p_He3; << 995 } 326 } 996 } 327 } 997 return const_cast<G4ParticleDefinition*>(ion << 328 return ion; 998 } 329 } 999 330 1000 G4double G4IonTable::GetNucleusMass(G4int Z, << 331 ///////////////// >> 332 // -- GetNucleusMass/GetIonMass --- >> 333 ///////////////// >> 334 G4double G4IonTable::GetNucleusMass(G4int Z, G4int A) const 1001 { 335 { 1002 if ((A < 1) || (Z < 0) || (LL < 0) || (lvl << 336 if ( (A<1) || (Z>numberOfElements) || (Z<0)) { 1003 #ifdef G4VERBOSE 337 #ifdef G4VERBOSE 1004 if (GetVerboseLevel() > 0) { << 338 if (GetVerboseLevel()>0) { 1005 G4cout << "G4IonTable::GetNucleusMass() << 339 G4cout << "G4IonTable::GetNucleusMass() : illegal atomic number/mass " << G4endl; 1006 << " Z =" << Z << " A = " << A << 340 G4cout << " Z =" << Z << " A = " << A << G4endl; 1007 } 341 } 1008 #endif 342 #endif 1009 G4Exception("G4IonTable::GetNucleusMass() << 343 G4Exception("G4IonTable::GetNucleusMass() : illegal atomic number/mass "); 1010 "illegal atomic number/mass") << 1011 return -1.0; << 1012 } 344 } 1013 345 >> 346 // calculate nucleus mass >> 347 G4ParticleDefinition* ion=GetLightIon(Z, A); 1014 G4double mass; 348 G4double mass; 1015 if (LL == 0) { << 1016 // calculate nucleus mass << 1017 const G4ParticleDefinition* ion = GetLigh << 1018 349 1019 if (ion != nullptr) { << 350 if (ion!=0) { 1020 mass = ion->GetPDGMass(); << 351 mass = ion->GetPDGMass(); 1021 } << 352 1022 else { << 353 } else { 1023 // Use G4NucleiProperties::GetNuclearMa << 354 1024 mass = G4NucleiProperties::GetNuclearMa << 355 // use G4NucleiProperties::GetNuclearMass 1025 } << 356 mass = G4NucleiProperties::GetNuclearMass(A, Z); 1026 357 1027 // Isomer << 1028 if (lvl > 0) { << 1029 // -- loop over all particles in Ion ta << 1030 G4int encoding = GetNucleusEncoding(Z, << 1031 G4bool isFound = false; << 1032 for (auto i = fIonList->find(encoding); << 1033 ion = i->second; << 1034 if ((ion->GetAtomicNumber() != Z) || << 1035 // Excitation level << 1036 if (((const G4Ions*)(ion))->GetIsomer << 1037 isFound = true; << 1038 break; << 1039 } << 1040 } << 1041 if (isFound) { << 1042 // Return existing isomer mass << 1043 mass = ion->GetPDGMass(); << 1044 } << 1045 else { << 1046 // Find isomer from IsotopeTable << 1047 const G4IsotopeProperty* fProperty = << 1048 if (fProperty != nullptr) mass += fPr << 1049 } << 1050 } << 1051 } << 1052 else { << 1053 mass = G4HyperNucleiProperties::GetNuclea << 1054 } 358 } >> 359 1055 return mass; 360 return mass; 1056 } 361 } 1057 362 1058 G4double G4IonTable::GetIsomerMass(G4int Z, G << 363 ////////////////// >> 364 G4double G4IonTable::GetIonMass(G4int Z, G4int A) const 1059 { 365 { 1060 return GetNucleusMass(Z, A, 0, lvl); << 366 return GetNucleusMass(Z,A); 1061 } 367 } 1062 368 1063 G4double G4IonTable::GetIonMass(G4int Z, G4in << 1064 { << 1065 return GetNucleusMass(Z, A, LL, lvl); << 1066 } << 1067 369 1068 void G4IonTable::clear() << 370 ///////////////// >> 371 // -- Methods for handling conatiner --- >> 372 ///////////////// >> 373 void G4IonTable::Insert(G4ParticleDefinition* particle) 1069 { 374 { 1070 if (G4ParticleTable::GetParticleTable()->Ge << 375 if (IsIon(particle)) { 1071 G4Exception("G4IonTable::clear()", "PART1 << 376 #ifdef G4USE_STL 1072 "No effects because readyToUs << 377 fIonList->push_back(particle); 1073 return; << 378 #else 1074 } << 379 fIonList->insert(particle); 1075 << 1076 #ifdef G4VERBOSE << 1077 if (GetVerboseLevel() > 2) { << 1078 G4cout << "G4IonTable::Clear() : number o << 1079 G4cout << fIonList->size() << G4endl; << 1080 } << 1081 #endif 380 #endif 1082 fIonList->clear(); << 381 } else { >> 382 //#ifdef G4VERBOSE >> 383 //if (GetVerboseLevel()>0) { >> 384 // G4cout << "G4IonTable::Insert :" << particle->GetParticleName() ; >> 385 // G4cout << " is not ions" << G4endl; >> 386 //} >> 387 //#endif >> 388 } 1083 } 389 } 1084 390 1085 void G4IonTable::Insert(const G4ParticleDefin << 391 ///////////////// >> 392 void G4IonTable::Remove(G4ParticleDefinition* particle) 1086 { 393 { 1087 if (!IsIon(particle)) return; << 394 if (IsIon(particle)) { 1088 if (Contains(particle)) return; << 395 #ifdef G4USE_STL 1089 << 396 G4IonList::iterator idx; 1090 G4int Z = particle->GetAtomicNumber(); << 397 for (idx = fIonList->begin(); idx!= fIonList->end(); ++idx) { 1091 G4int A = particle->GetAtomicMass(); << 398 if ( particle == *idx) { 1092 G4int LL = particle->GetQuarkContent(3); / << 399 fIonList->erase(idx); 1093 G4int encoding = GetNucleusEncoding(Z, A, L << 1094 << 1095 // Register the ion with its encoding of th << 1096 fIonListShadow->insert(std::pair<const G4in << 1097 } << 1098 << 1099 void G4IonTable::InsertWorker(const G4Particl << 1100 { << 1101 if (particle == nullptr) return; << 1102 << 1103 G4int Z = particle->GetAtomicNumber(); << 1104 G4int A = particle->GetAtomicMass(); << 1105 G4int LL = particle->GetQuarkContent(3); / << 1106 G4int encoding = GetNucleusEncoding(Z, A, L << 1107 G4bool found = false; << 1108 if (encoding != 0) { << 1109 for (auto i = fIonList->find(encoding); i << 1110 if (particle == i->second) { << 1111 found = true; << 1112 break; << 1113 } 400 } 1114 } 401 } 1115 } << 402 #else 1116 if (found) return; << 403 fIonList->remove(particle); 1117 << 1118 // Register the ion with its encoding of th << 1119 fIonList->insert(std::pair<const G4int, con << 1120 } << 1121 << 1122 void G4IonTable::Remove(const G4ParticleDefin << 1123 { << 1124 if (particle == nullptr) return; << 1125 #ifdef G4MULTITHREADED << 1126 if (G4Threading::IsWorkerThread()) { << 1127 G4ExceptionDescription ed; << 1128 ed << "Request of removing " << particle- << 1129 << " is ignored as it is invoked from << 1130 G4Exception("G4IonTable::Remove()", "PART << 1131 return; << 1132 } << 1133 #endif 404 #endif 1134 if (G4ParticleTable::GetParticleTable()->Ge << 1135 G4StateManager* pStateManager = G4StateMa << 1136 G4ApplicationState currentState = pStateM << 1137 if (currentState != G4State_PreInit) { << 1138 G4String msg = "Request of removing "; << 1139 msg += particle->GetParticleName(); << 1140 msg += " has No effects other than Pre_ << 1141 G4Exception("G4IonTable::Remove()", "PA << 1142 return; << 1143 } << 1144 405 >> 406 } else { 1145 #ifdef G4VERBOSE 407 #ifdef G4VERBOSE 1146 if (GetVerboseLevel() > 0) { << 408 if (GetVerboseLevel()>0) { 1147 G4cout << particle->GetParticleName() < << 409 G4cout << "G4IonTable::Remove :" << particle->GetParticleName() ; >> 410 G4cout << " is not ions" << G4endl; 1148 } 411 } 1149 #endif 412 #endif 1150 } 413 } 1151 414 1152 if (IsIon(particle)) { << 1153 G4int Z = particle->GetAtomicNumber(); << 1154 G4int A = particle->GetAtomicMass(); << 1155 G4int LL = particle->GetQuarkContent(3); << 1156 G4int encoding = GetNucleusEncoding(Z, A, << 1157 if (encoding != 0) { << 1158 for (auto i = fIonListShadow->find(enco << 1159 if (particle == i->second) { << 1160 fIonListShadow->erase(i); << 1161 break; << 1162 } << 1163 } << 1164 } << 1165 } << 1166 else { << 1167 #ifdef G4VERBOSE << 1168 if (GetVerboseLevel() > 1) { << 1169 G4cout << "G4IonTable::Remove :" << par << 1170 } << 1171 #endif << 1172 } << 1173 } 415 } 1174 416 1175 void G4IonTable::DumpTable(const G4String& pa << 417 >> 418 >> 419 ///////////////// >> 420 // -- Dump Information >> 421 ///////////////// >> 422 void G4IonTable::DumpTable(const G4String &particle_name) const 1176 { 423 { 1177 const G4ParticleDefinition* ion; << 424 G4ParticleDefinition* ion; 1178 for (const auto& idx : *fIonList) { << 425 #ifdef G4USE_STL 1179 ion = idx.second; << 426 G4IonList::iterator idx; 1180 if ((particle_name == "ALL") || (particle << 427 for (idx = fIonList->begin(); idx!= fIonList->end(); ++idx) { >> 428 ion = *idx; >> 429 #else >> 430 for (G4int idx= 0; idx < fIonList->entries() ; idx++) { >> 431 ion = (*fIonList)(idx); >> 432 #endif >> 433 if (( particle_name == "ALL" ) || (particle_name == "all")){ 1181 ion->DumpTable(); 434 ion->DumpTable(); 1182 } << 435 } else if ( particle_name == ion->GetParticleName() ) { 1183 else if (particle_name == ion->GetParticl << 1184 ion->DumpTable(); 436 ion->DumpTable(); 1185 } 437 } 1186 } 438 } 1187 } 439 } 1188 440 1189 // ------------------------------------------ << 441 ///////////////// 1190 // << 442 const G4String G4IonTable::elementName[] = { 1191 // clang-format off << 1192 const G4String G4IonTable::elementName[] = << 1193 { << 1194 "H", 443 "H", "He", 1195 "Li", "Be", 444 "Li", "Be", "B", "C", "N", "O", "F", "Ne", 1196 "Na", "Mg", 445 "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", 1197 "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe 446 "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", 1198 "Rb", "Sr", "Y", "Zr", "Nb", "Mo","Tc", "Ru 447 "Rb", "Sr", "Y", "Zr", "Nb", "Mo","Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", 1199 "Cs", "Ba", 448 "Cs", "Ba", 1200 "La", "Ce", "Pr", "Nd", "Pm", " 449 "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", 1201 "Hf", "Ta", "W", "Re", "Os 450 "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", 1202 "Fr", "Ra", 451 "Fr", "Ra", 1203 "Ac", "Th", "Pa", "U", "Np", " 452 "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", 1204 "Rf", "Db", "Sg", "Bh", "Hs", " << 453 "Db", "Jl", "Rf", "Bh", "Hn", "Mt", "Xa" >> 454 1205 }; 455 }; 1206 // clang-format on << 1207 456 >> 457 >> 458 ///////////////// 1208 G4int G4IonTable::GetVerboseLevel() const 459 G4int G4IonTable::GetVerboseLevel() const 1209 { 460 { 1210 return G4ParticleTable::GetParticleTable()- 461 return G4ParticleTable::GetParticleTable()->GetVerboseLevel(); 1211 } 462 } 1212 463 1213 void G4IonTable::AddProcessManager(G4Particle << 464 ///////////////// >> 465 void G4IonTable::AddProcessManager(const G4String& name) 1214 { 466 { 1215 if (ion->IsGeneralIon()) { << 467 // create command string for addProcManager 1216 // Check whether GenericIon has processes << 468 char cmdAdd[60]; 1217 G4ParticleDefinition* genericIon = G4Part << 469 G4std::ostrstream osAdd(cmdAdd,60); 1218 << 470 osAdd << "/run/particle/addProcManager "<< name << '\0'; 1219 G4ProcessManager* pman = nullptr; << 1220 if (genericIon != nullptr) pman = generic << 1221 if ((genericIon == nullptr) || (genericIo << 1222 { << 1223 G4String msg = "G4IonTable::AddProcessM << 1224 msg += ion->GetParticleName(); << 1225 msg += "\n because GenericIon is not av << 1226 G4Exception("G4IonTable::AddProcessMana << 1227 return; << 1228 } << 1229 471 1230 ion->SetParticleDefinitionID(genericIon-> << 472 // set /control/verbose 0 1231 } << 473 G4int tempVerboseLevel = G4UImanager::GetUIpointer()->GetVerboseLevel(); 1232 else { << 474 G4UImanager::GetUIpointer()->SetVerboseLevel(0); 1233 // Is this a MuonicAtom ? << 1234 auto muatom = dynamic_cast<G4MuonicAtom*> << 1235 << 1236 if (muatom != nullptr) { << 1237 #ifdef G4VERBOSE << 1238 if (GetVerboseLevel() > 1) { << 1239 G4cout << "G4IonTable::AddProcessMana << 1240 << "MuonicAtom dynamic_cast su << 1241 } << 1242 #endif << 1243 // Check whether GenericMuonicAtom has << 1244 G4ParticleDefinition* genericMA = G4Par << 1245 475 1246 G4ProcessManager* pman = nullptr; << 476 // issue /run/particle/addProcManage 1247 if (genericMA != nullptr) pman = generi << 477 G4UImanager::GetUIpointer()->ApplyCommand(cmdAdd); 1248 if ((genericMA == nullptr) || (genericM << 1249 { << 1250 G4String msg = "G4IonTable::AddProces << 1251 msg += ion->GetParticleName(); << 1252 msg += "\n because GenericMuonicAtom << 1253 G4Exception("G4IonTable::AddProcessMa << 1254 return; << 1255 } << 1256 478 1257 ion->SetParticleDefinitionID(genericMA- << 479 // retreive /control/verbose 1258 } << 480 G4UImanager::GetUIpointer()->SetVerboseLevel(tempVerboseLevel); 1259 else { << 1260 G4String msg = "G4IonTable::AddProcessM << 1261 msg += ion->GetParticleName(); << 1262 msg += "\n because of unsupported parti << 1263 G4Exception("G4IonTable::AddProcessMana << 1264 return; << 1265 } << 1266 } << 1267 return; << 1268 } 481 } 1269 << 482 1270 void G4IonTable::RegisterIsotopeTable(G4VIsot << 483 ///////////////// >> 484 void G4IonTable::SetCuts(G4ParticleDefinition* ion) 1271 { 485 { 1272 // check duplication << 486 // Set cut value same as "GenericIon" 1273 G4String name = table->GetName(); << 487 G4ParticleDefinition* genericIon=G4ParticleTable::GetParticleTable()->FindParticle("GenericIon"); 1274 for (const auto fIsotopeTable : *fIsotopeTa << 488 if (genericIon == 0) { 1275 if (name == fIsotopeTable->GetName()) ret << 489 G4Exception("G4IonTable::SetCuts : GenericIon is not defined !!"); 1276 } << 490 } 1277 // register << 1278 fIsotopeTableList->push_back(table); << 1279 } << 1280 << 1281 G4VIsotopeTable* G4IonTable::GetIsotopeTable( << 1282 { << 1283 G4VIsotopeTable* fIsotopeTable = nullptr; << 1284 if (index < fIsotopeTableList->size()) { << 1285 fIsotopeTable = (*fIsotopeTableList)[inde << 1286 } << 1287 return fIsotopeTable; << 1288 } << 1289 << 1290 G4IsotopeProperty* G4IonTable::FindIsotope(G4 << 1291 G4 << 1292 { << 1293 if (fIsotopeTableList == nullptr) return nu << 1294 if (fIsotopeTableList->empty()) return null << 1295 << 1296 G4IsotopeProperty* property = nullptr; << 1297 << 1298 for (std::size_t i = 0; i < fIsotopeTableLi << 1299 G4VIsotopeTable* fIsotopeTable = (*fIsoto << 1300 property = fIsotopeTable->GetIsotope(Z, A << 1301 if (property != nullptr) break; << 1302 } << 1303 << 1304 return property; << 1305 } << 1306 << 1307 G4IsotopeProperty* G4IonTable::FindIsotope(G4 << 1308 { << 1309 if (fIsotopeTableList == nullptr) return nu << 1310 if (fIsotopeTableList->empty()) return null << 1311 << 1312 G4IsotopeProperty* property = nullptr; << 1313 << 1314 // iterate << 1315 for (std::size_t i = 0; i < fIsotopeTableLi << 1316 G4VIsotopeTable* fIsotopeTable = (*fIsoto << 1317 property = fIsotopeTable->GetIsotope(Z, A << 1318 if (property != nullptr) break; << 1319 } << 1320 << 1321 return property; << 1322 } << 1323 << 1324 void G4IonTable::CreateAllIon() << 1325 { << 1326 PreloadNuclide(); << 1327 } << 1328 491 1329 void G4IonTable::CreateAllIsomer() << 492 if (genericIon->GetEnergyCuts() != 0) { 1330 { << 493 ion->SetCuts( genericIon->GetLengthCuts()); 1331 PreloadNuclide(); << 494 #ifdef G4VERBOSE 1332 } << 495 if (GetVerboseLevel()> 1) { 1333 << 496 G4cout << "G4IonTable::GetIon() : cut value ="; 1334 void G4IonTable::PrepareNuclideTable() << 497 G4cout << genericIon->GetLengthCuts()/mm << "[mm]" <<G4endl; 1335 { << 498 } 1336 if (pNuclideTable == nullptr) pNuclideTable << 499 #endif 1337 } << 1338 500 1339 void G4IonTable::PreloadNuclide() << 501 G4String name = ion->GetParticleName(); 1340 { << 1341 if (isIsomerCreated || !G4Threading::IsMult << 1342 502 1343 pNuclideTable->GenerateNuclide(); << 503 // Build Physics Tables for the ion >> 504 // create command string for buildPhysicsTable >> 505 char cmdBld[60]; >> 506 G4std::ostrstream osBld(cmdBld,60); >> 507 osBld << "/run/particle/buildPhysicsTable "<< name << '\0'; >> 508 >> 509 // set /control/verbose 0 >> 510 G4int tempVerboseLevel = G4UImanager::GetUIpointer()->GetVerboseLevel(); >> 511 G4UImanager::GetUIpointer()->SetVerboseLevel(0); 1344 512 1345 for (std::size_t i = 0; i != pNuclideTable- << 513 // issue /run/particle/buildPhysicsTable 1346 const G4IsotopeProperty* fProperty = pNuc << 514 G4UImanager::GetUIpointer()->ApplyCommand(cmdBld); 1347 G4int Z = fProperty->GetAtomicNumber(); << 1348 G4int A = fProperty->GetAtomicMass(); << 1349 G4double Eex = fProperty->GetEnergy(); << 1350 GetIon(Z, A, Eex); << 1351 } << 1352 515 1353 isIsomerCreated = true; << 516 // retreive /control/verbose 1354 } << 517 G4UImanager::GetUIpointer()->SetVerboseLevel(tempVerboseLevel); 1355 518 1356 G4ParticleDefinition* G4IonTable::GetParticle << 519 } else { 1357 { << 1358 if ((index >= 0) && (index < Entries())) { << 1359 auto idx = fIonList->cbegin(); << 1360 G4int counter = 0; << 1361 while (idx != fIonList->cend()) // Loop << 1362 { << 1363 if (counter == index) { << 1364 return const_cast<G4ParticleDefinitio << 1365 } << 1366 ++counter; << 1367 ++idx; << 1368 } << 1369 } << 1370 #ifdef G4VERBOSE 520 #ifdef G4VERBOSE 1371 if (GetVerboseLevel() > 1) { << 521 if (GetVerboseLevel()> 1) { 1372 G4cout << " G4IonTable::GetParticle" << 522 G4cout << "G4IonTable::GetIon() : "; 1373 << " invalid index (=" << index << << 523 G4cout << " cut value of GenericIon has not be defined yet"; 1374 << " entries = " << Entries() << G << 524 } 1375 } << 525 #endif 1376 #endif << 1377 return nullptr; << 1378 } << 1379 526 1380 G4bool G4IonTable::Contains(const G4ParticleD << 1381 { << 1382 if (!IsIon(particle)) return false; << 1383 << 1384 G4int Z = particle->GetAtomicNumber(); << 1385 G4int A = particle->GetAtomicMass(); << 1386 G4int LL = particle->GetQuarkContent(3); / << 1387 G4int encoding = GetNucleusEncoding(Z, A, L << 1388 G4bool found = false; << 1389 if (encoding != 0) { << 1390 for (auto i = fIonListShadow->find(encodi << 1391 if (particle == i->second) { << 1392 found = true; << 1393 break; << 1394 } << 1395 } << 1396 } 527 } 1397 return found; << 1398 } << 1399 << 1400 G4int G4IonTable::Entries() const << 1401 { << 1402 return (G4int)fIonList->size(); << 1403 } 528 } 1404 529 1405 G4int G4IonTable::size() const << 530 //////////////////// >> 531 void G4IonTable::RegisterIsotopeTable(G4VIsotopeTable* table) 1406 { 532 { 1407 return (G4int)fIonList->size(); << 533 fIsotopeTable = table; 1408 } 534 } 1409 535 1410 G4ParticleDefinition* G4IonTable::FindIonInMa << 536 //////////////////// 1411 << 537 G4VIsotopeTable* G4IonTable::GetIsotopeTable() const 1412 { 538 { 1413 // Search ions with A, Z ,E << 539 return fIsotopeTable; 1414 // !! J is omitted now !! << 1415 const G4ParticleDefinition* ion = nullptr; << 1416 G4bool isFound = false; << 1417 << 1418 // -- loop over all particles in Ion table << 1419 G4int encoding = GetNucleusEncoding(Z, A); << 1420 for (auto i = fIonListShadow->find(encoding << 1421 ion = i->second; << 1422 if ((ion->GetAtomicNumber() != Z) || (ion << 1423 // excitation level << 1424 G4double anExcitaionEnergy = ((const G4Io << 1425 if (std::fabs(E - anExcitaionEnergy) < pN << 1426 if (((const G4Ions*)(ion))->GetFloatLev << 1427 isFound = true; << 1428 break; << 1429 } << 1430 } << 1431 } << 1432 << 1433 if (isFound) { << 1434 return const_cast<G4ParticleDefinition*>( << 1435 } << 1436 << 1437 return nullptr; << 1438 } 540 } 1439 541 1440 G4ParticleDefinition* G4IonTable::FindIonInMa << 1441 << 1442 { << 1443 if (LL == 0) return FindIon(Z, A, E, flb, J << 1444 << 1445 // Search ions with A, Z ,E << 1446 // !! J is omitted now !! << 1447 const G4ParticleDefinition* ion = nullptr; << 1448 G4bool isFound = false; << 1449 << 1450 // -- loop over all particles in Ion table << 1451 G4int encoding = GetNucleusEncoding(Z, A, L << 1452 for (auto i = fIonListShadow->find(encoding << 1453 ion = i->second; << 1454 if ((ion->GetAtomicNumber() != Z) || (ion << 1455 if (ion->GetQuarkContent(3) != LL) break; << 1456 // Excitation level << 1457 G4double anExcitaionEnergy = ((const G4Io << 1458 if (std::fabs(E - anExcitaionEnergy) < pN << 1459 if (((const G4Ions*)(ion))->GetFloatLev << 1460 isFound = true; << 1461 break; << 1462 } << 1463 } << 1464 } << 1465 << 1466 if (isFound) { << 1467 return const_cast<G4ParticleDefinition*>( << 1468 } << 1469 << 1470 return nullptr; << 1471 } << 1472 542 1473 G4ParticleDefinition* G4IonTable::FindIonInMa << 543 //////////////////// >> 544 G4IsotopeProperty* G4IonTable::FindIsotope(G4int Z, G4int A, G4double E, G4int J) 1474 { 545 { 1475 // Search ions with A, Z ,E << 546 G4IsotopeProperty* fProperty = new G4IsotopeProperty(); 1476 // !! J is omitted now !! << 1477 const G4ParticleDefinition* ion = nullptr; << 1478 G4bool isFound = false; << 1479 << 1480 // -- loop over all particles in Ion table << 1481 G4int encoding = GetNucleusEncoding(Z, A); << 1482 for (auto i = fIonListShadow->find(encoding << 1483 ion = i->second; << 1484 if ((ion->GetAtomicNumber() != Z) || (ion << 1485 // Excitation level << 1486 if (((const G4Ions*)(ion))->GetIsomerLeve << 1487 isFound = true; << 1488 break; << 1489 } << 1490 } << 1491 547 1492 if (isFound) { << 548 // Set Isotope Property 1493 return const_cast<G4ParticleDefinition*>( << 549 fProperty->SetAtomicNumber(Z); >> 550 fProperty->SetAtomicMass(A); >> 551 fProperty->SetEnergy(E); >> 552 fProperty->SetiSpin(J); >> 553 fProperty->SetLifeTime(-1.0); >> 554 fProperty->SetDecayTable(0); >> 555 >> 556 if (fIsotopeTable ==0) return 0; >> 557 >> 558 // ask IsotopeTable >> 559 if (fIsotopeTable->FindIsotope(fProperty)) { >> 560 return fProperty; >> 561 } else { >> 562 delete fProperty; >> 563 return 0; 1494 } 564 } 1495 << 1496 return nullptr; << 1497 } 565 } 1498 566 1499 G4ParticleDefinition* G4IonTable::FindIonInMa << 1500 { << 1501 if (LL == 0) return FindIon(Z, A, lvl); << 1502 << 1503 // Search ions with A, Z ,E, lvl << 1504 const G4ParticleDefinition* ion = nullptr; << 1505 G4bool isFound = false; << 1506 << 1507 // -- loop over all particles in Ion table << 1508 G4int encoding = GetNucleusEncoding(Z, A, L << 1509 for (auto i = fIonListShadow->find(encoding << 1510 ion = i->second; << 1511 if ((ion->GetAtomicNumber() != Z) || (ion << 1512 if (ion->GetQuarkContent(3) != LL) break; << 1513 // excitation level << 1514 if (((const G4Ions*)(ion))->GetIsomerLeve << 1515 isFound = true; << 1516 break; << 1517 } << 1518 } << 1519 567 1520 if (isFound) { << 1521 return const_cast<G4ParticleDefinition*>( << 1522 } << 1523 568 1524 return nullptr; << 1525 } << 1526 569 1527 G4double G4IonTable::GetLifeTime(const G4Part << 1528 { << 1529 if ((particle->IsGeneralIon()) && (pNuclide << 1530 G4Exception("G4IonTable::GetLifeTime()", << 1531 "Method is invoked before G4I << 1532 return 0.; << 1533 } << 1534 return particle->GetPDGLifeTime(); << 1535 } << 1536 570 1537 G4double G4IonTable::GetLifeTime(G4int Z, G4i << 1538 { << 1539 return GetLifeTime(Z, A, E, G4Ions::FloatLe << 1540 } << 1541 571 1542 G4double G4IonTable::GetLifeTime(G4int Z, G4i << 1543 { << 1544 G4double life = -1001.0; << 1545 const G4IsotopeProperty* fProperty = FindIs << 1546 if (fProperty != nullptr) life = fProperty- << 1547 return life; << 1548 } << 1549 572 1550 G4ParticleDefinition* G4IonTable::GetMuonicAt << 1551 { << 1552 if (base == nullptr || !IsIon(base)) { << 1553 G4Exception("G4IonTable::GetMuonicAtom()" << 1554 "Constructor argument is not << 1555 return nullptr; << 1556 } << 1557 573 1558 // We're assuming here that we get a base t << 1559 // constructed and unexcited ... strip exci << 1560 // isomers from the encoding << 1561 << 1562 auto const Z = base->GetAtomicNumber(); << 1563 auto const A = base->GetAtomicMass(); << 1564 auto const baseenc = GetNucleusEncoding(Z, << 1565 auto const encoding = baseenc + 1000000000; << 1566 << 1567 // We have to do all the MT manipulations m << 1568 // convenience functions assume a G4Ions wi << 1569 // they recalculate the encoding from parti << 1570 // than using the carried member function v << 1571 // do operations on the base ion, rather th << 1572 // G4MuonicAtom << 1573 << 1574 auto i = fIonList->find(encoding); << 1575 if (i != fIonList->cend()) { << 1576 return const_cast<G4ParticleDefinition*>( << 1577 } << 1578 // not in threadlocal list; check global li << 1579 #ifdef G4MULTITHREADED << 1580 if (G4Threading::IsWorkerThread()) { << 1581 G4MUTEXLOCK(&G4IonTable::ionTableMutex); << 1582 i = fIonListShadow->find(encoding); << 1583 auto end = fIonListShadow->cend(); << 1584 G4MUTEXUNLOCK(&G4IonTable::ionTableMutex) << 1585 if (i != end) { << 1586 // we found it, stuff it into the threa << 1587 fIonList->insert(*i); << 1588 // and then return it ... << 1589 return const_cast<G4ParticleDefinition* << 1590 } << 1591 } << 1592 #endif << 1593 574 1594 // not found in either list; create and pot << 1595 auto const name = "Mu" + GetIonName(Z, A); << 1596 575 1597 G4MuonicAtom* muatom = G4MuonicAtomHelper:: << 1598 576 1599 // Not sure this is doing the right thing.. << 1600 AddProcessManager(muatom); << 1601 577 1602 // Now, we have to push the muatom into the << 1603 // first, recheck global list, in case anot << 1604 // before us and created this same muatom << 1605 << 1606 #ifdef G4MULTITHREADED << 1607 if (G4Threading::IsWorkerThread()) { << 1608 G4MUTEXLOCK(&G4IonTable::ionTableMutex); << 1609 // first, we need to make sure it hasn't << 1610 // other thread << 1611 auto j = fIonListShadow->find(encoding); << 1612 if (j != fIonListShadow->cend()) { << 1613 // oops ... someone else built a copy w << 1614 // cleanup our instantiation, and take << 1615 // the global list << 1616 delete muatom; << 1617 muatom = const_cast<G4MuonicAtom*>(stat << 1618 } << 1619 else { << 1620 // otherwise, push onto the global list << 1621 fIonListShadow->insert(std::make_pair(e << 1622 } << 1623 G4MUTEXUNLOCK(&G4IonTable::ionTableMutex) << 1624 } << 1625 #endif << 1626 // in either case, push onto the the thread << 1627 fIonList->insert(std::make_pair(encoding, m << 1628 578 1629 return muatom; << 1630 } << 1631 579 1632 G4ParticleDefinition* G4IonTable::GetMuonicAt << 1633 { << 1634 // Need the cast because we need a G4Ions* << 1635 // function, but GetIon returns a G4Particl << 1636 auto base = static_cast<G4Ions const*>(GetI << 1637 return GetMuonicAtom(base); << 1638 } << 1639 580