Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 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 // 26 // 27 #include "G4DNAScavengerMaterial.hh" 28 29 #include "G4DNABoundingBox.hh" 30 #include "G4DNAMolecularMaterial.hh" 31 #include "G4MolecularConfiguration.hh" 32 #include "G4PhysicalConstants.hh" 33 #include "G4Scheduler.hh" 34 #include "G4StateManager.hh" 35 #include "G4SystemOfUnits.hh" 36 #include "G4UnitsTable.hh" 37 #include "G4VChemistryWorld.hh" 38 39 #include <memory> 40 41 using namespace std; 42 43 //-------------------------------------------- 44 45 G4DNAScavengerMaterial::G4DNAScavengerMaterial 46 : fpChemistryInfo(pChemistryInfo), fIsInitia 47 { 48 Initialize(); 49 } 50 51 //-------------------------------------------- 52 53 void G4DNAScavengerMaterial::Initialize() 54 { 55 if (fIsInitialized) { 56 return; 57 } 58 59 if (fpChemistryInfo->size() == 0) { 60 G4cout << "G4DNAScavengerMaterial existed 61 } 62 Reset(); 63 fIsInitialized = true; 64 } 65 66 G4double 67 G4DNAScavengerMaterial::GetNumberMoleculePerVo 68 { 69 // no change these molecules 70 if (fH2O == matConf) { 71 G4ExceptionDescription exceptionDescriptio 72 exceptionDescription << "matConf : " << ma 73 G4Exception("G4DNAScavengerMaterial::GetNu 74 "G4DNAScavengerMaterial001", F 75 } 76 77 auto iter = fScavengerTable.find(matConf); 78 if (iter == fScavengerTable.end()) { 79 return 0; 80 } 81 82 if (iter->second >= 1) { 83 return (floor)(iter->second); 84 } 85 86 return 0; 87 } 88 89 void G4DNAScavengerMaterial::ReduceNumberMolec 90 91 { 92 // no change these molecules 93 if (fH2O == matConf || fH3Op == matConf || 94 fHOm == matConf) 95 { 96 // G4cout<<"moletype : "<<matConf->GetName 97 // kobs is already counted these molecule 98 return; 99 } 100 if (!find(matConf)) // matConf must greater 101 { 102 return; 103 } 104 fScavengerTable[matConf]--; 105 if (fScavengerTable[matConf] < 0) // projec 106 { 107 assert(false); 108 } 109 110 if (fCounterAgainstTime) { 111 RemoveAMoleculeAtTime(matConf, time); 112 } 113 } 114 115 void G4DNAScavengerMaterial::AddNumberMolecule 116 117 { 118 // no change these molecules 119 120 if (fH2O == matConf || fH3Op == matConf || 121 G4MoleculeTable::Instance()->GetConfigur 122 { 123 // G4cout<<"moletype : "<<matConf->GetName 124 // kobs is already counted these molecule 125 return; 126 } 127 128 auto it = fScavengerTable.find(matConf); 129 if (it == fScavengerTable.end()) // matConf 130 { 131 return; 132 } 133 fScavengerTable[matConf]++; 134 135 if (fCounterAgainstTime) { 136 AddAMoleculeAtTime(matConf, time); 137 } 138 } 139 140 void G4DNAScavengerMaterial::PrintInfo() 141 { 142 auto pConfinedBox = fpChemistryInfo->GetChem 143 auto iter = fpChemistryInfo->begin(); 144 G4cout << "********************************* 145 for (; iter != fpChemistryInfo->end(); iter+ 146 auto containedConf = iter->first; 147 // auto concentration = iter->second; 148 auto concentration = fScavengerTable[conta 149 G4cout << "Scavenger:" << containedConf->G 150 << concentration / 1.0e-6 /*mm3 to 151 << fScavengerTable[containedConf] < 152 << "in: " << pConfinedBox->Volume() 153 if (fScavengerTable[containedConf] < 1) { 154 G4cout << "!!!!!!!!!!!!! this molecule h 155 "considered volume" 156 << G4endl; 157 // assert(false); 158 } 159 if (fVerbose != 0) { 160 Dump(); 161 } 162 } 163 G4cout << "********************************* 164 } 165 166 void G4DNAScavengerMaterial::Reset() 167 { 168 if (fpChemistryInfo == nullptr) { 169 return; 170 } 171 172 if (fpChemistryInfo->size() == 0) { 173 return; 174 } 175 176 fScavengerTable.clear(); 177 fCounterMap.clear(); 178 fpLastSearch.reset(nullptr); 179 180 auto pConfinedBox = fpChemistryInfo->GetChem 181 auto iter = fpChemistryInfo->begin(); 182 for (; iter != fpChemistryInfo->end(); iter+ 183 auto containedConf = iter->first; 184 auto concentration = iter->second; 185 fScavengerTable[containedConf] = floor(Avo 186 fCounterMap[containedConf][1 * picosecond] 187 floor(Avogadro * concentration * pConfin 188 } 189 if (fVerbose != 0) { 190 PrintInfo(); 191 } 192 } 193 194 //-------------------------------------------- 195 196 void G4DNAScavengerMaterial::AddAMoleculeAtTim 197 198 { 199 if (fVerbose != 0) { 200 G4cout << "G4DNAScavengerMaterial::AddAMol 201 << " at time : " << G4BestUnit(time 202 } 203 204 auto counterMap_i = fCounterMap.find(molecul 205 206 if (counterMap_i == fCounterMap.end()) { 207 fCounterMap[molecule][time] = number; 208 } 209 else if (counterMap_i->second.empty()) { 210 counterMap_i->second[time] = number; 211 } 212 else { 213 auto end = counterMap_i->second.rbegin(); 214 215 if (end->first <= time 216 || fabs(end->first - time) <= G4::Mole 217 G4double newValue = end->second + number 218 counterMap_i->second[time] = newValue; 219 if (newValue != (floor)(fScavengerTable[ 220 { 221 G4String errMsg = "You are trying to a 222 G4Exception("AddAMoleculeAtTime", "", 223 } 224 } 225 } 226 } 227 228 //-------------------------------------------- 229 230 void G4DNAScavengerMaterial::RemoveAMoleculeAt 231 232 { 233 NbMoleculeInTime& nbMolPerTime = fCounterMap 234 235 if (fVerbose != 0) { 236 auto it_ = nbMolPerTime.rbegin(); 237 G4cout << "G4DNAScavengerMaterial::RemoveA 238 << " at time : " << G4BestUnit(time 239 240 << " form : " << it_->second << G4e 241 } 242 243 if (nbMolPerTime.empty()) { 244 Dump(); 245 G4String errMsg = "You are trying to remov 246 pMolecule->GetName() + 247 " from the counter while 248 "been registered yet"; 249 G4Exception("G4DNAScavengerMaterial::Remov 250 251 return; 252 } 253 254 auto it = nbMolPerTime.rbegin(); 255 256 if (it == nbMolPerTime.rend()) { 257 it--; 258 259 G4String errMsg = "There was no " + pMolec 260 + " recorded at the time 261 G4Exception("G4DNAScavengerMaterial::Remov 262 } 263 264 G4double finalN = it->second - number; 265 if (finalN < 0) { 266 Dump(); 267 268 G4cout << "fScavengerTable : " << pMolecul 269 << G4endl; 270 271 G4ExceptionDescription errMsg; 272 errMsg << "After removal of " << number << 273 << " " << it->second << " " << pMol 274 << G4BestUnit(time, "Time") << " is 275 G4cout << " Global time is " << G4BestUnit 276 << ". Previous selected time is " < 277 G4Exception("G4DNAScavengerMaterial::Remov 278 } 279 nbMolPerTime[time] = finalN; 280 281 if (finalN != (floor)(fScavengerTable[pMolec 282 { 283 assert(false); 284 } 285 } 286 287 void G4DNAScavengerMaterial::Dump() 288 { 289 auto pConfinedBox = fpChemistryInfo->GetChem 290 auto V = pConfinedBox->Volume(); 291 for (const auto& it : fCounterMap) { 292 auto pReactant = it.first; 293 294 G4cout << " --- > For " << pReactant->GetN 295 296 for (const auto& it2 : it.second) { 297 G4cout << " " << G4BestUnit(it2.first, " 298 << it2.second / (Avogadro * V * 1 299 } 300 } 301 } 302 303 int64_t G4DNAScavengerMaterial::GetNMoleculesA 304 { 305 if (!fCounterAgainstTime) { 306 G4cout << "fCounterAgainstTime == false" < 307 assert(false); 308 } 309 310 G4bool sameTypeOfMolecule = SearchTimeMap(mo 311 auto output = SearchUpperBoundTime(time, sam 312 if (output < 0) { 313 G4ExceptionDescription errMsg; 314 errMsg << "N molecules not valid < 0 : " < 315 G4Exception("G4DNAScavengerMaterial::GetNM 316 } 317 return output; 318 } 319 320 G4bool G4DNAScavengerMaterial::SearchTimeMap(M 321 { 322 if (fpLastSearch == nullptr) { 323 fpLastSearch = std::make_unique<Search>(); 324 } 325 else { 326 if (fpLastSearch->fLowerBoundSet && fpLast 327 return true; 328 } 329 } 330 331 auto mol_it = fCounterMap.find(molecule); 332 fpLastSearch->fLastMoleculeSearched = mol_it 333 334 if (mol_it != fCounterMap.end()) { 335 fpLastSearch->fLowerBoundTime = fpLastSear 336 fpLastSearch->fLowerBoundSet = true; 337 } 338 else { 339 fpLastSearch->fLowerBoundSet = false; 340 } 341 342 return false; 343 } 344 345 //-------------------------------------------- 346 347 int64_t G4DNAScavengerMaterial::SearchUpperBou 348 { 349 auto mol_it = fpLastSearch->fLastMoleculeSea 350 if (mol_it == fCounterMap.end()) { 351 return 0; 352 } 353 354 NbMoleculeInTime& timeMap = mol_it->second; 355 if (timeMap.empty()) { 356 return 0; 357 } 358 359 if (sameTypeOfMolecule) { 360 if (fpLastSearch->fLowerBoundSet && fpLast 361 if (fpLastSearch->fLowerBoundTime->first 362 auto upperToLast = fpLastSearch->fLowe 363 upperToLast++; 364 365 if (upperToLast == timeMap.end()) { 366 return fpLastSearch->fLowerBoundTime 367 } 368 369 if (upperToLast->first > time) { 370 return fpLastSearch->fLowerBoundTime 371 } 372 } 373 } 374 } 375 376 auto up_time_it = timeMap.upper_bound(time); 377 378 if (up_time_it == timeMap.end()) { 379 auto last_time = timeMap.rbegin(); 380 return last_time->second; 381 } 382 if (up_time_it == timeMap.begin()) { 383 return 0; 384 } 385 386 up_time_it--; 387 388 fpLastSearch->fLowerBoundTime = up_time_it; 389 fpLastSearch->fLowerBoundSet = true; 390 391 return fpLastSearch->fLowerBoundTime->second 392 } 393 394 void G4DNAScavengerMaterial::WaterEquilibrium( 395 { 396 auto convertFactor = Avogadro * fpChemistryI 397 G4double kw = 1.01e-14; 398 fScavengerTable[fHOm] = (kw / ((G4double)fSc 399 G4cout << "pH : " << GetpH() << G4endl; 400 return; 401 } 402 403 void G4DNAScavengerMaterial::SetpH(const G4int 404 { 405 auto volume = fpChemistryInfo->GetChemistryB 406 fScavengerTable[fH3Op] = floor(Avogadro * st 407 fScavengerTable[fHOm] = floor(Avogadro * std 408 } 409 410 G4double G4DNAScavengerMaterial::GetpH() 411 { 412 G4double volumeInLiter = fpChemistryInfo->Ge 413 G4double Cion = (G4double)fScavengerTable[fH 414 G4double pH = std::log10(Cion); 415 // G4cout<<"OH- : "<<fScavengerTable[fHOm]<< 416 // "<<-pH<<G4endl; 417 if (fScavengerTable[fH3Op] < 0) // protect 418 { 419 G4Exception("G4DNAScavengerMaterial::GetpH 420 "H3O+ < 0"); 421 fScavengerTable[fH3Op] = 0; 422 } 423 if (fScavengerTable[fHOm] < 0) // protect m 424 { 425 G4Exception("G4DNAScavengerMaterial::GetpH 426 "HO- < 0"); 427 fScavengerTable[fHOm] = 0; 428 } 429 return -pH; 430 }