Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id: G4MoleculeCounter.cc 65022 2012-11-12 16:43:12Z gcosmo $ 26 // 27 // 27 << 28 #include "G4MoleculeCounter.hh" 28 #include "G4MoleculeCounter.hh" 29 << 30 #include "G4MolecularConfiguration.hh" << 31 #include "G4MoleculeDefinition.hh" << 32 #include "G4MoleculeTable.hh" << 33 #include "G4Scheduler.hh" // TODO: remove this << 34 #include "G4SystemOfUnits.hh" << 35 #include "G4UIcommand.hh" 29 #include "G4UIcommand.hh" 36 #include "G4UnitsTable.hh" 30 #include "G4UnitsTable.hh" 37 << 38 #include <iomanip> 31 #include <iomanip> 39 #include <memory> << 40 32 41 using namespace std; << 33 double compDoubleWithPrecision::fPrecision = 5e-13; 42 34 43 namespace G4{ << 35 G4MoleculeCounter::G4MoleculeCounter() 44 namespace MoleculeCounter { << 45 << 46 bool TimePrecision::operator()(const double& a << 47 { 36 { 48 if (std::fabs(a - b) < fPrecision) << 37 fUse = FALSE; 49 { << 38 fVerbose = 0 ; 50 return false; << 51 } << 52 << 53 return a < b; << 54 } 39 } 55 40 56 G4ThreadLocal double TimePrecision::fPrecision << 41 G4MoleculeCounter* G4MoleculeCounter::fpInstance = 0; 57 } << 58 } << 59 42 60 //-------------------------------------------- << 43 G4MoleculeCounter* G4MoleculeCounter::GetMoleculeCounter() 61 G4MoleculeCounter* G4MoleculeCounter::Instance << 62 { 44 { 63 if (fpInstance == nullptr) << 45 if(!fpInstance) 64 { << 65 fpInstance = new G4MoleculeCounter(); 46 fpInstance = new G4MoleculeCounter(); 66 } << 67 return dynamic_cast<G4MoleculeCounter*>(fp << 68 } << 69 << 70 //-------------------------------------------- << 71 47 72 G4MoleculeCounter::G4MoleculeCounter() << 48 return fpInstance; 73 { << 74 fVerbose = 0; << 75 fCheckTimeIsConsistentWithScheduler = true << 76 } 49 } 77 50 78 //-------------------------------------------- << 51 void G4MoleculeCounter::DeleteInstance() 79 << 80 G4MoleculeCounter::~G4MoleculeCounter() = defa << 81 << 82 //-------------------------------------------- << 83 << 84 void G4MoleculeCounter::Initialize() << 85 { 52 { 86 auto mol_iterator = G4MoleculeTable::Insta << 53 if(fpInstance) 87 while ((mol_iterator)()) << 88 { 54 { 89 if (!IsRegistered(mol_iterator.value() << 55 delete fpInstance; 90 { << 56 fpInstance = 0; 91 continue; << 92 } << 93 << 94 fCounterMap[mol_iterator.value()]; // << 95 } 57 } 96 } 58 } 97 59 98 //-------------------------------------------- << 60 void G4MoleculeCounter::AddAMoleculeAtTime(const G4Molecule& molecule, G4double time) 99 << 100 void G4MoleculeCounter::SetTimeSlice(double ti << 101 { 61 { 102 G4::MoleculeCounter::TimePrecision::fPreci << 62 if(fVerbose > 1) 103 } << 104 << 105 //-------------------------------------------- << 106 << 107 G4bool G4MoleculeCounter::SearchTimeMap(Reacta << 108 { << 109 if (fpLastSearch == nullptr) << 110 { 63 { 111 fpLastSearch = std::make_unique<Search << 64 G4cout<<"G4MoleculeCounter::AddAMoleculeAtTime : "<< molecule.GetName() 112 } << 65 << " at time : " << G4BestUnit(time, "Time") <<G4endl; 113 else << 114 { << 115 if (fpLastSearch->fLowerBoundSet && << 116 fpLastSearch->fLastMoleculeSearche << 117 { << 118 return true; << 119 } << 120 } 66 } 121 67 122 auto mol_it = fCounterMap.find(molecule); << 68 if(fDontRegister[molecule.GetDefinition()]) return ; 123 fpLastSearch->fLastMoleculeSearched = mol_ << 124 69 125 if (mol_it != fCounterMap.end()) << 70 // G4double pstime = time/picosecond; 126 { << 71 // 127 fpLastSearch->fLowerBoundTime = fpLast << 72 // G4double fractpart=-1, intpart=-1; 128 .end(); << 73 // fractpart = modf (pstime , &intpart); 129 fpLastSearch->fLowerBoundSet = true; << 74 // 130 } << 75 // if(pstime<10.1) 131 else << 76 // { >> 77 // fractpart *= 10 ; >> 78 // fractpart = floor(fractpart)/10; >> 79 // pstime = intpart+fractpart; >> 80 // } >> 81 // >> 82 // else >> 83 // { >> 84 // pstime = intpart; >> 85 // } >> 86 // time = pstime*picosecond ; >> 87 >> 88 if(fVerbose) 132 { 89 { 133 fpLastSearch->fLowerBoundSet = false; << 90 G4cout<<"-------------------------"<<G4endl ; >> 91 G4cout << "G4MoleculeCounter::AddAMoleculeAtTime " << G4endl; >> 92 G4cout<<"!! Molecule = " << molecule.GetName() << G4endl; >> 93 G4cout<<"!! At Time = "<< G4BestUnit(time, "Time") <<G4endl; 134 } 94 } 135 95 136 return false; << 96 CounterMapType::iterator counterMap_i = fCounterMap.find(molecule) ; 137 } << 138 97 139 //-------------------------------------------- << 98 if(counterMap_i == fCounterMap.end()) 140 << 141 int G4MoleculeCounter::SearchUpperBoundTime(do << 142 bo << 143 { << 144 auto mol_it = fpLastSearch->fLastMoleculeS << 145 if (mol_it == fCounterMap.end()) << 146 { 99 { 147 return 0; << 100 if(fVerbose) G4cout << " !! ***** Map is empty " << G4endl; >> 101 fCounterMap[molecule][time] = 1; 148 } 102 } 149 << 103 else if(counterMap_i->second.empty()) 150 NbMoleculeAgainstTime& timeMap = mol_it->s << 151 if (timeMap.empty()) << 152 { 104 { 153 return 0; << 105 if(fVerbose) G4cout << " !! ***** Map is empty " << G4endl; >> 106 counterMap_i->second[time] = 1; 154 } 107 } 155 << 108 else 156 if (sameTypeOfMolecule) << 157 { 109 { 158 if (fpLastSearch->fLowerBoundSet && fp << 110 NbMoleculeAgainstTime::iterator end = counterMap_i->second.end(); >> 111 end--; >> 112 >> 113 if(fVerbose) >> 114 G4cout<<"!! End Time = "<< G4BestUnit(end->first, "Time") <<G4endl; >> 115 >> 116 if(end->first <= time) 159 { 117 { 160 if (fpLastSearch->fLowerBoundTime- << 118 counterMap_i->second[time]=end->second + 1; 161 { << 119 } 162 auto upperToLast = fpLastSearc << 120 else 163 upperToLast++; << 121 { >> 122 NbMoleculeAgainstTime::iterator it = counterMap_i->second.lower_bound(time); 164 123 165 if (upperToLast == timeMap.end << 124 while(it->first > time && it!=counterMap_i->second.begin()) 166 { << 125 { 167 return fpLastSearch->fLowe << 126 if(fVerbose) 168 } << 127 G4cout<<"!! ********** Is going back!!!!"<<G4endl; 169 << 128 it--; 170 if (upperToLast->first > time) << 171 { << 172 return fpLastSearch->fLowe << 173 } << 174 } 129 } 175 } << 176 } << 177 130 178 auto up_time_it = timeMap.upper_bound(time << 131 if(it==counterMap_i->second.begin() && it->first > time) >> 132 { >> 133 if(fVerbose) >> 134 G4cout<<"!! ********** Illegal !!!!"<<G4endl; >> 135 return ; >> 136 } 179 137 180 if (up_time_it == timeMap.end()) << 138 if(fVerbose) 181 { << 139 { 182 auto last_time = timeMap.rbegin(); << 140 G4cout<<"!! PREVIOUS NB = "<< it->second <<G4endl; 183 return last_time->second; << 141 G4cout<<"!! PREVIOUS TIME = "<< G4BestUnit(it->first,"Time") <<G4endl; 184 } << 142 } 185 if (up_time_it == timeMap.begin()) << 143 counterMap_i->second[time]=it->second + 1; 186 { << 144 } 187 return 0; << 188 } 145 } 189 146 190 up_time_it--; << 147 if(fVerbose) 191 << 148 G4cout<<"!! NB = "<< fCounterMap[molecule][time]<<G4endl; 192 fpLastSearch->fLowerBoundTime = up_time_it << 193 fpLastSearch->fLowerBoundSet = true; << 194 << 195 return fpLastSearch->fLowerBoundTime->seco << 196 } 149 } 197 150 198 //-------------------------------------------- << 151 void G4MoleculeCounter::RemoveAMoleculeAtTime(const G4Molecule& molecule, G4double time) 199 << 200 int G4MoleculeCounter::GetNMoleculesAtTime(Rea << 201 dou << 202 { << 203 G4bool sameTypeOfMolecule = SearchTimeMap( << 204 return SearchUpperBoundTime(time, sameType << 205 } << 206 << 207 //-------------------------------------------- << 208 << 209 void G4MoleculeCounter::AddAMoleculeAtTime(Rea << 210 G4d << 211 con << 212 int << 213 { 152 { 214 if (fDontRegister[molecule->GetDefinition( << 153 if(fVerbose > 1) 215 { 154 { 216 return; << 155 G4cout<<"-------------------------"<<G4endl ; >> 156 G4cout<<"G4MoleculeCounter::RemoveAMoleculeAtTime : "<< molecule.GetName() >> 157 << " at time : " << G4BestUnit(time,"Time") <<G4endl; >> 158 G4cout<<"-------------------------"<<G4endl ; 217 } 159 } 218 160 219 if (fVerbose != 0) << 161 if(fDontRegister[molecule.GetDefinition()]) return ; 220 { << 221 G4cout << "G4MoleculeCounter::AddAMole << 222 << " at time : " << G4BestUnit( << 223 } << 224 162 225 auto counterMap_i = fCounterMap.find(molec << 163 NbMoleculeAgainstTime& nbMolPerTime = fCounterMap[molecule]; 226 164 227 if (counterMap_i == fCounterMap.end()) << 165 if(nbMolPerTime.empty()) 228 { 166 { 229 fCounterMap[molecule][time] = number; << 167 molecule.PrintState(); 230 } << 168 G4String errMsg = "You are trying to remove molecule " 231 else if (counterMap_i->second.empty()) << 169 + molecule.GetName() 232 { << 170 +" from the counter while this kind of molecules has not been registered yet"; 233 counterMap_i->second[time] = number; << 171 G4Exception("G4MoleculeCounter::RemoveAMoleculeAtTime","",FatalErrorInArgument, errMsg); >> 172 >> 173 return; 234 } 174 } 235 else 175 else 236 { 176 { 237 auto end = counterMap_i->second.rbegin << 177 NbMoleculeAgainstTime::iterator it ; 238 178 239 if (end->first <= time || << 179 if(nbMolPerTime.size() == 1) 240 fabs(end->first - time) <= G4::Mol << 241 // Case 1 = new time comes after l << 242 // Case 2 = new time is about the << 243 { 180 { 244 double newValue = end->second + nu << 181 it = nbMolPerTime.begin() ; 245 counterMap_i->second[time] = newVa << 182 if(fVerbose) >> 183 G4cout << "!! fCounterMap[molecule].size() == 1" << G4endl; 246 } 184 } 247 else 185 else 248 { 186 { 249 // if(fabs(time - G4Scheduler << 187 it = nbMolPerTime.lower_bound(time); 250 // G4Scheduler::Instance() << 251 { << 252 G4ExceptionDescription errMsg; << 253 errMsg << "Time of species " << 254 << molecule->GetName() << 255 << G4BestUnit(time, "Ti << 256 << " global time is " << 257 << G4BestUnit(G4Schedul << 258 << G4endl; << 259 G4Exception("G4MoleculeCounter << 260 "TIME_DONT_MATCH", << 261 FatalException, er << 262 } << 263 } 188 } 264 } << 265 } << 266 189 267 //-------------------------------------------- << 190 if(it==nbMolPerTime.end()) 268 << 191 { 269 void G4MoleculeCounter::RemoveAMoleculeAtTime( << 192 if(fVerbose) 270 << 193 G4cout << " ********** NO ITERATOR !!!!!!!!! " << G4endl; 271 << 194 it--; 272 << 273 { << 274 if (fDontRegister[pMolecule->GetDefinition << 275 { << 276 return; << 277 } << 278 195 279 if (fVerbose != 0) << 196 if(time<it->first) 280 { << 197 { 281 G4cout << "G4MoleculeCounter::RemoveAM << 198 G4String errMsg = "There was no "+ molecule.GetName() 282 << pMolecule->GetName() << " at << 199 + " record at the time or even before the time asked"; 283 << G4endl; << 200 G4Exception("G4MoleculeCounter::RemoveAMoleculeAtTime","",FatalErrorInArgument, errMsg); 284 } << 201 } >> 202 } 285 203 286 if (fCheckTimeIsConsistentWithScheduler) << 204 if(fVerbose) 287 { << 288 if (fabs(time - G4Scheduler::Instance( << 289 G4Scheduler::Instance()->GetTimeTo << 290 { 205 { 291 G4ExceptionDescription errMsg; << 206 // G4cout << "G4MoleculeCounter::RemoveAMoleculeAtTime " << G4endl; 292 errMsg << "Time of species " << 207 G4cout<<"!! Molecule = " << molecule.GetName() << G4endl; 293 << pMolecule->GetName() << << 208 G4cout<<"!! At Time = "<< G4BestUnit(time,"Time") <<G4endl; 294 << G4BestUnit(time, "Time") << 209 G4cout<<"!! PREVIOUS TIME = "<< G4BestUnit(it->first,"Time")<<G4endl; 295 << " global time is " << 210 G4cout<<"!! PREVIOUS Nb = "<< it->second <<G4endl; 296 << G4BestUnit(G4Scheduler:: << 211 } 297 << G4endl; << 212 298 G4Exception("G4MoleculeCounter::Re << 213 // If valgrind problem on the line below, it means that the pointer "it" 299 "TIME_DONT_MATCH", << 214 // points nowhere 300 FatalException, errMsg << 215 if(nbMolPerTime.value_comp()(*it, *nbMolPerTime.begin())) >> 216 { >> 217 if(fVerbose) >> 218 G4cout<<"!! ***** In value_comp ... " << G4endl; >> 219 it++; >> 220 if(time<it->first) >> 221 { >> 222 G4String errMsg = "There was no "+ molecule.GetName() >> 223 + " record at the time or even before the time asked"; >> 224 G4Exception("G4MoleculeCounter::RemoveAMoleculeAtTime","",FatalErrorInArgument, errMsg); >> 225 } 301 } 226 } 302 } << 303 << 304 NbMoleculeAgainstTime& nbMolPerTime = fCou << 305 227 306 if (nbMolPerTime.empty()) << 228 while(it->first - time > compDoubleWithPrecision::fPrecision && it!=nbMolPerTime.begin()) 307 { << 229 { 308 pMolecule->PrintState(); << 230 if(fVerbose) 309 Dump(); << 231 { 310 G4String errMsg = << 232 G4cout<<"!! ***** Is going back!!!!"<<G4endl; 311 "You are trying to remove mole << 233 G4cout<<"!! PREVIOUS TIME = "<< G4BestUnit(it-> first,"Time") <<G4endl; 312 " from the counter while this << 234 } 313 G4Exception("G4MoleculeCounter::Remove << 235 it--; 314 FatalErrorInArgument, errM << 236 } 315 << 316 return; << 317 } << 318 << 319 auto it = nbMolPerTime.rbegin(); << 320 237 321 if (it == nbMolPerTime.rend()) << 238 if(it==nbMolPerTime.begin() && it->first > time) 322 { << 239 { 323 it--; << 240 if(fVerbose) >> 241 G4cout<<"!! ********** Illegal !!!!"<<G4endl; >> 242 return ; >> 243 } 324 244 325 G4String errMsg = << 245 if(fVerbose) 326 "There was no " + pMolecule->G << 246 { 327 G4Exception("G4MoleculeCounter::Remove << 247 G4cout<<"!! PREVIOUS NB = "<< (*it).second <<G4endl; 328 FatalErrorInArgument, errM << 248 G4cout<<"!! PREVIOUS TIME = "<< G4BestUnit(it->first,"Time")<<G4endl; >> 249 } >> 250 nbMolPerTime[time]=it->second - 1; 329 } 251 } 330 << 252 if(fVerbose) 331 if (time - it->first < -G4::MoleculeCounte << 332 { 253 { 333 Dump(); << 254 G4cout<<"!! NB = "<< nbMolPerTime[time]<<G4endl; 334 G4ExceptionDescription errMsg; << 335 errMsg << "Is time going back?? " << p << 336 << " is being removed at time " << 337 << " while last recorded time w << 338 << G4BestUnit(it->first, "Time" << 339 G4Exception("G4MoleculeCounter::Remove << 340 "RETURN_TO_THE_FUTUR", << 341 FatalErrorInArgument, << 342 errMsg); << 343 } 255 } 344 << 345 double finalN = it->second - number; << 346 << 347 if (finalN < 0) << 348 { << 349 Dump(); << 350 G4ExceptionDescription errMsg; << 351 errMsg << "After removal of " << numbe << 352 << pMolecule->GetName() << " th << 353 << G4BestUnit(time, "Time") << << 354 << " Global time is " << 355 << G4BestUnit(G4Scheduler::Inst << 356 << ". Previous selected time is << 357 << G4BestUnit(it->first, "Time" << 358 << G4endl; << 359 G4Exception("G4MoleculeCounter::Remove << 360 "N_INF_0", << 361 FatalException, errMsg); << 362 } << 363 << 364 nbMolPerTime[time] = finalN; << 365 } 256 } 366 257 367 //-------------------------------------------- << 258 std::auto_ptr<vector<G4Molecule> > G4MoleculeCounter::GetRecordedMolecules() 368 << 369 G4MoleculeCounter::RecordedMolecules G4Molecul << 370 { 259 { 371 if (fVerbose > 1) << 260 if(fVerbose > 1) 372 { 261 { 373 G4cout << "Entering in G4MoleculeCount << 262 G4cout<<"Entering in G4MoleculeCounter::RecordMolecules"<<G4endl; 374 } 263 } 375 264 376 RecordedMolecules output(new ReactantList( << 265 CounterMapType::iterator it; >> 266 std::auto_ptr< vector<G4Molecule> > output (new vector<G4Molecule>) ; 377 267 378 for (const auto & it : fCounterMap) << 268 for(it = fCounterMap.begin() ; it != fCounterMap.end() ; it++) 379 { 269 { 380 output->push_back(it.first); << 270 output->push_back((*it).first); 381 } 271 } 382 return output; 272 return output; 383 } << 384 << 385 //-------------------------------------------- << 386 << 387 RecordedTimes G4MoleculeCounter::GetRecordedTi << 388 { << 389 RecordedTimes output(new std::set<G4double << 390 << 391 for(const auto& it : fCounterMap) << 392 { << 393 for(const auto& it2 : it.second) << 394 { << 395 //time = it2->first; << 396 output->insert(it2.first); << 397 } << 398 } << 399 << 400 return output; << 401 } << 402 << 403 //-------------------------------------------- << 404 << 405 // >>DEV<< << 406 //void G4MoleculeCounter::SignalReceiver(G4Spe << 407 // size_ << 408 // int / << 409 // G4Spe << 410 // int d << 411 //{ << 412 // switch(speciesChange) << 413 // { << 414 // case G4SpeciesInCM::eAdd: << 415 // AddAMoleculeAtTime(G4MoleculeTable::In << 416 // G4Scheduler::Instan << 417 // diff); << 418 // break; << 419 // case G4SpeciesInCM::eRemove: << 420 // RemoveAMoleculeAtTime(G4MoleculeTable: << 421 // G4Scheduler::Instan << 422 // diff); << 423 // break; << 424 // } << 425 //} << 426 << 427 //-------------------------------------------- << 428 << 429 void G4MoleculeCounter::Dump() << 430 { << 431 for (const auto& it : fCounterMap) << 432 { << 433 auto pReactant = it.first; << 434 << 435 G4cout << " --- > For " << pReactant-> << 436 << 437 for (const auto& it2 : it.second) << 438 { << 439 G4cout << " " << G4BestUnit(it2.fi << 440 << " " << it2.second << << 441 } << 442 } << 443 } << 444 << 445 //-------------------------------------------- << 446 << 447 void G4MoleculeCounter::ResetCounter() << 448 { << 449 if (fVerbose != 0) << 450 { << 451 G4cout << " ---> G4MoleculeCounter::Re << 452 } << 453 fCounterMap.clear(); << 454 fpLastSearch.reset(nullptr); << 455 } << 456 << 457 //-------------------------------------------- << 458 << 459 const NbMoleculeAgainstTime& G4MoleculeCounter << 460 { << 461 return fCounterMap[molecule]; << 462 } << 463 << 464 //-------------------------------------------- << 465 << 466 void G4MoleculeCounter::SetVerbose(G4int level << 467 { << 468 fVerbose = level; << 469 } << 470 << 471 //-------------------------------------------- << 472 << 473 G4int G4MoleculeCounter::GetVerbose() << 474 { << 475 return fVerbose; << 476 } << 477 << 478 //-------------------------------------------- << 479 << 480 void G4MoleculeCounter::DontRegister(const G4M << 481 { << 482 fDontRegister[molDef] = true; << 483 } << 484 << 485 //-------------------------------------------- << 486 << 487 bool G4MoleculeCounter::IsRegistered(const G4M << 488 { << 489 return fDontRegister.find(molDef) == fDont << 490 } << 491 << 492 //-------------------------------------------- << 493 << 494 void G4MoleculeCounter::RegisterAll() << 495 { << 496 fDontRegister.clear(); << 497 } << 498 << 499 G4bool G4MoleculeCounter::IsTimeCheckedForCons << 500 { << 501 return fCheckTimeIsConsistentWithScheduler << 502 } << 503 << 504 void G4MoleculeCounter::CheckTimeForConsistenc << 505 { << 506 fCheckTimeIsConsistentWithScheduler = flag << 507 } 273 } 508 274 509 275