Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // 27 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr) 28 // 29 // WARNING : This class is released as a prototype. 30 // It might strongly evolve or even disapear in the next releases. 31 // 32 // History: 33 // ----------- 34 // 10 Oct 2011 M.Karamitros created 35 // 36 // ------------------------------------------------------------------- 37 38 #include <iomanip> 39 40 #include "G4DNAMolecularReactionTable.hh" 41 #include "G4PhysicalConstants.hh" 42 #include "G4SystemOfUnits.hh" 43 #include "G4UIcommand.hh" 44 #include "G4VDNAReactionModel.hh" 45 #include "G4MoleculeHandleManager.hh" 46 #include "G4MoleculeTable.hh" 47 #include "G4MolecularConfiguration.hh" 48 #include "G4ReactionTableMessenger.hh" 49 #include "G4IosFlagsSaver.hh" 50 #include "G4Exp.hh" 51 52 using namespace std; 53 54 G4DNAMolecularReactionTable* G4DNAMolecularReactionTable::fpInstance(nullptr); 55 56 G4DNAMolecularReactionData::G4DNAMolecularReactionData() 57 : fpReactant1(nullptr) 58 , fpReactant2(nullptr) 59 , fObservedReactionRate(0.) 60 , fActivationRate(0.) 61 , fDiffusionRate(0.) 62 , fOnsagerRadius(0.) 63 , fReactionRadius(0.) 64 , fEffectiveReactionRadius(0.) 65 , fProbability(0.) 66 , fType(0) 67 , fReactionID(0) 68 { 69 } 70 71 G4DNAMolecularReactionData::G4DNAMolecularReactionData(G4double reactionRate, 72 Reactant* pReactant1, 73 Reactant* pReactant2) 74 : fpReactant1(pReactant1) 75 , fpReactant2(pReactant2) 76 , fObservedReactionRate(reactionRate) 77 , fActivationRate(0.) 78 , fDiffusionRate(0.) 79 , fOnsagerRadius(0.) 80 , fReactionRadius(0.) 81 , fEffectiveReactionRadius(0.) 82 , fProbability(0.) 83 , fType(0) 84 , fReactionID(0) 85 { 86 ComputeEffectiveRadius(); 87 } 88 89 G4DNAMolecularReactionData::G4DNAMolecularReactionData(G4double reactionRate, 90 const G4String& reactant1, 91 const G4String& reactant2) 92 : fpReactant1(nullptr) 93 , fpReactant2(nullptr) 94 , fObservedReactionRate(reactionRate) 95 , fActivationRate(0.) 96 , fDiffusionRate(0.) 97 , fOnsagerRadius(0.) 98 , fReactionRadius(0.) 99 , fEffectiveReactionRadius(0.) 100 , fProbability(0.) 101 , fType(0) 102 , fReactionID(0) 103 { 104 SetReactant1(reactant1); 105 SetReactant2(reactant2); 106 ComputeEffectiveRadius(); 107 } 108 109 G4DNAMolecularReactionData::~G4DNAMolecularReactionData() 110 { 111 fProducts.clear(); 112 } 113 114 void G4DNAMolecularReactionData::ComputeEffectiveRadius() 115 { 116 G4double sumDiffCoeff = 0.; 117 118 if (fpReactant1 == fpReactant2) 119 { 120 sumDiffCoeff = fpReactant1->GetDiffusionCoefficient(); 121 fEffectiveReactionRadius = fObservedReactionRate / (4. * CLHEP::pi * sumDiffCoeff * CLHEP::Avogadro); 122 } 123 else 124 { 125 sumDiffCoeff = fpReactant1->GetDiffusionCoefficient() 126 + fpReactant2->GetDiffusionCoefficient(); 127 fEffectiveReactionRadius = fObservedReactionRate / (4. * CLHEP::pi * sumDiffCoeff * CLHEP::Avogadro); 128 } 129 130 fReactionID = 0; 131 fReactionRadius = fEffectiveReactionRadius; 132 fOnsagerRadius = (fpReactant1->GetCharge() * fpReactant2->GetCharge())/(4*pi*epsilon0*k_Boltzmann) / (293.15 * 80.1) ; 133 fProbability = 1; 134 135 } 136 137 int G4DNAMolecularReactionData::GetReactionID() const 138 { 139 return fReactionID; 140 } 141 142 void G4DNAMolecularReactionData::SetReactionID(int ID) 143 { 144 fReactionID = ID; 145 } 146 147 void G4DNAMolecularReactionData::SetReactant1(Reactant* pReactive) 148 { 149 fpReactant1 = pReactive; 150 } 151 152 void G4DNAMolecularReactionData::SetReactant2(Reactant* pReactive) 153 { 154 fpReactant2 = pReactive; 155 } 156 157 void G4DNAMolecularReactionData::SetReactants(Reactant* pReactant1, 158 Reactant* pReactant2) 159 { 160 fpReactant1 = pReactant1; 161 fpReactant2 = pReactant2; 162 } 163 164 void G4DNAMolecularReactionData::AddProduct(Reactant* pMolecule) 165 { 166 fProducts.push_back(pMolecule); 167 } 168 169 G4int G4DNAMolecularReactionData::GetNbProducts() const 170 { 171 return (G4int)fProducts.size(); 172 } 173 174 G4DNAMolecularReactionData::Reactant* G4DNAMolecularReactionData::GetProduct(G4int i) const 175 { 176 return fProducts[i]; 177 } 178 179 const G4DNAMolecularReactionData::ReactionProducts* G4DNAMolecularReactionData::GetProducts() const 180 { 181 return &fProducts; 182 } 183 184 void G4DNAMolecularReactionData::RemoveProducts() 185 { 186 fProducts.clear(); 187 } 188 189 void G4DNAMolecularReactionData::SetReactant1(const G4String& reactive) 190 { 191 fpReactant1 = G4MoleculeTable::Instance()->GetConfiguration(reactive); 192 } 193 void G4DNAMolecularReactionData::SetReactant2(const G4String& reactive) 194 { 195 fpReactant2 = G4MoleculeTable::Instance()->GetConfiguration(reactive); 196 } 197 void G4DNAMolecularReactionData::SetReactants(const G4String& reactant1, 198 const G4String& reactant2) 199 { 200 fpReactant1 = G4MoleculeTable::Instance()->GetConfiguration(reactant1); 201 fpReactant2 = G4MoleculeTable::Instance()->GetConfiguration(reactant2); 202 } 203 204 G4DNAMolecularReactionData::ReactantPair G4DNAMolecularReactionData::GetReactants() 205 { 206 return std::make_pair(fpReactant1, fpReactant2); 207 } 208 209 G4DNAMolecularReactionData::Reactant* G4DNAMolecularReactionData::GetReactant1() const 210 { 211 return fpReactant1; 212 } 213 214 G4DNAMolecularReactionData::Reactant* G4DNAMolecularReactionData::GetReactant2() const 215 { 216 return fpReactant2; 217 } 218 219 void G4DNAMolecularReactionData::SetObservedReactionRateConstant(G4double rate) 220 { 221 fObservedReactionRate = rate; 222 } 223 224 G4double G4DNAMolecularReactionData::GetObservedReactionRateConstant() const 225 { 226 return fObservedReactionRate; 227 } 228 229 G4double G4DNAMolecularReactionData::GetActivationRateConstant() const 230 { 231 return fActivationRate; 232 } 233 234 G4double G4DNAMolecularReactionData::GetDiffusionRateConstant() const 235 { 236 return fDiffusionRate; 237 } 238 239 void G4DNAMolecularReactionData::SetReactionRadius(G4double radius) 240 { 241 fReactionRadius = radius; 242 fEffectiveReactionRadius = -fOnsagerRadius / (1-exp(fOnsagerRadius / fReactionRadius)); 243 } 244 245 G4double G4DNAMolecularReactionData::GetReactionRadius() const 246 { 247 return fReactionRadius; 248 } 249 250 void G4DNAMolecularReactionData::SetEffectiveReactionRadius(G4double radius) 251 { 252 fEffectiveReactionRadius = radius; 253 } 254 255 G4double G4DNAMolecularReactionData::GetEffectiveReactionRadius() const 256 { 257 return fEffectiveReactionRadius; 258 } 259 260 G4double G4DNAMolecularReactionData::GetOnsagerRadius() const 261 { 262 return fOnsagerRadius; 263 } 264 265 G4double G4DNAMolecularReactionData::GetProbability() const 266 { 267 return fProbability; 268 } 269 270 void G4DNAMolecularReactionData::SetProbability(G4double prob) 271 { 272 fProbability = prob; 273 } 274 275 void G4DNAMolecularReactionData::SetReactionType(G4int type) 276 { 277 G4double sumDiffCoeff = 0.; 278 279 if(type == 1) 280 { 281 282 sumDiffCoeff = fpReactant1->GetDiffusionCoefficient() + 283 fpReactant2->GetDiffusionCoefficient(); 284 285 fReactionRadius = fpReactant1->GetVanDerVaalsRadius() + 286 fpReactant2->GetVanDerVaalsRadius(); 287 288 G4double Rs = 0.29 * nm; 289 if(fOnsagerRadius == 0) // Type II 290 { 291 fEffectiveReactionRadius = fReactionRadius; 292 fDiffusionRate = 4 * pi * sumDiffCoeff * fReactionRadius * Avogadro; 293 if (fpReactant1 == fpReactant2) fDiffusionRate/=2; 294 fActivationRate = fDiffusionRate * fObservedReactionRate / (fDiffusionRate - fObservedReactionRate); 295 fProbability = Rs / (Rs + (fDiffusionRate / fActivationRate) * (fReactionRadius + Rs)); 296 297 }else{ // Type IV 298 fEffectiveReactionRadius = -fOnsagerRadius/(1-exp(fOnsagerRadius/fReactionRadius)); 299 fDiffusionRate = 4 * pi * sumDiffCoeff * fEffectiveReactionRadius * Avogadro; 300 if (fpReactant1 == fpReactant2) fDiffusionRate/=2; 301 302 fActivationRate = fDiffusionRate * fObservedReactionRate / (fDiffusionRate - fObservedReactionRate); 303 fProbability = Rs / (Rs + (fDiffusionRate / fActivationRate) * (fEffectiveReactionRadius + Rs)); 304 } 305 } 306 307 fType = type; 308 } 309 310 G4int G4DNAMolecularReactionData::GetReactionType() const 311 { 312 return fType; 313 } 314 315 void G4DNAMolecularReactionData::AddProduct(const G4String& molecule) 316 { 317 fProducts.push_back(G4MoleculeTable::Instance()->GetConfiguration(molecule)); 318 } 319 320 double G4DNAMolecularReactionData::PolynomialParam(double temp_K, std::vector<double> P) 321 { 322 double inv_temp = 1. / temp_K; 323 324 return pow(10, 325 P[0] + P[1] * inv_temp + P[2] * pow(inv_temp, 2) 326 + P[3] * pow(inv_temp, 3) + P[4] * pow(inv_temp, 4)) 327 * (1e-3 * CLHEP::m3 / (CLHEP::mole * CLHEP::s)); 328 } 329 330 double G4DNAMolecularReactionData::ArrehniusParam(double temp_K, std::vector<double> P) 331 { 332 return P[0] * G4Exp(P[1] / temp_K)* 333 (1e-3 * CLHEP::m3 / (CLHEP::mole * CLHEP::s)); 334 } 335 336 double G4DNAMolecularReactionData::ScaledParameterization(double temp_K, 337 double temp_init, 338 double rateCste_init) 339 { 340 double D0 = G4MolecularConfiguration::DiffCoeffWater(temp_init); 341 double Df = G4MolecularConfiguration::DiffCoeffWater(temp_K); 342 return Df * rateCste_init / D0; 343 } 344 345 //============================================================================== 346 // REACTION TABLE 347 //============================================================================== 348 349 G4DNAMolecularReactionTable* G4DNAMolecularReactionTable::GetReactionTable() 350 { 351 if (fpInstance == nullptr) 352 { 353 fpInstance = new G4DNAMolecularReactionTable(); 354 } 355 return fpInstance; 356 } 357 358 //_____________________________________________________________________________________ 359 360 G4DNAMolecularReactionTable* G4DNAMolecularReactionTable::Instance() 361 { 362 if (fpInstance == nullptr) 363 { 364 fpInstance = new G4DNAMolecularReactionTable(); 365 } 366 return fpInstance; 367 } 368 369 //_____________________________________________________________________________________ 370 371 void G4DNAMolecularReactionTable::DeleteInstance() 372 { 373 374 375 delete fpInstance; 376 377 fpInstance = nullptr; 378 } 379 380 //_____________________________________________________________________________________ 381 382 G4DNAMolecularReactionTable::G4DNAMolecularReactionTable() 383 : 384 fpMessenger(new G4ReactionTableMessenger(this)) 385 { 386 } 387 388 G4DNAMolecularReactionTable::~G4DNAMolecularReactionTable() = default; 389 390 void G4DNAMolecularReactionTable::SetReaction(G4DNAMolecularReactionData* pReactionData) 391 { 392 const auto pReactant1 = pReactionData->GetReactant1(); 393 const auto pReactant2 = pReactionData->GetReactant2(); 394 395 fReactionData[pReactant1][pReactant2] = pReactionData; 396 fReactantsMV[pReactant1].push_back(pReactant2); 397 fReactionDataMV[pReactant1].push_back(pReactionData); 398 399 if (pReactant1 != pReactant2) 400 { 401 fReactionData[pReactant2][pReactant1] = pReactionData; 402 fReactantsMV[pReactant2].push_back(pReactant1); 403 fReactionDataMV[pReactant2].push_back(pReactionData); 404 } 405 406 fVectorOfReactionData.emplace_back(pReactionData); 407 pReactionData->SetReactionID((G4int)fVectorOfReactionData.size()); 408 } 409 410 //_____________________________________________________________________________________ 411 412 void G4DNAMolecularReactionTable::SetReaction(G4double reactionRate, 413 Reactant* pReactant1, 414 Reactant* pReactant2) 415 { 416 auto reactionData = new G4DNAMolecularReactionData(reactionRate, pReactant1, pReactant2); 417 SetReaction(reactionData); 418 } 419 420 //_____________________________________________________________________________________ 421 422 void G4DNAMolecularReactionTable::PrintTable(G4VDNAReactionModel* pReactionModel) 423 { 424 // Print Reactions and Interaction radius for jump step = 3ps 425 426 G4IosFlagsSaver iosfs(G4cout); 427 428 if ((pReactionModel != nullptr) && ((pReactionModel->GetReactionTable()) == nullptr)) 429 { 430 pReactionModel->SetReactionTable(this); 431 } 432 433 ReactivesMV::iterator itReactives; 434 435 std::map<Reactant*, std::map<Reactant*, G4bool>> alreadyPrint; 436 437 G4cout << "Number of chemical species involved in reactions = " 438 << fReactantsMV.size() << G4endl; 439 440 std::size_t nbPrintable = fReactantsMV.size() * fReactantsMV.size(); 441 442 auto outputReaction = new G4String[nbPrintable]; 443 auto outputReactionRate = new G4String[nbPrintable]; 444 auto outputRange = new G4String[nbPrintable]; 445 G4int n = 0; 446 447 for (itReactives = fReactantsMV.begin(); itReactives != fReactantsMV.end(); 448 ++itReactives) 449 { 450 auto moleculeA = (Reactant*)itReactives->first; 451 const vector<Reactant*>* reactivesVector = CanReactWith(moleculeA); 452 453 if (pReactionModel != nullptr) pReactionModel->InitialiseToPrint(moleculeA); 454 455 auto nbReactants = (G4int)fReactantsMV[itReactives->first].size(); 456 457 for (G4int iReact = 0; iReact < nbReactants; iReact++) 458 { 459 auto moleculeB = (Reactant*)(*reactivesVector)[iReact]; 460 461 Data* reactionData = fReactionData[moleculeA][moleculeB]; 462 463 //----------------------------------------------------------- 464 // Name of the reaction 465 if (!alreadyPrint[moleculeA][moleculeB]) 466 { 467 outputReaction[n] = moleculeA->GetName() + " + " + moleculeB->GetName(); 468 469 G4int nbProducts = reactionData->GetNbProducts(); 470 471 if (nbProducts != 0) 472 { 473 outputReaction[n] += " -> " + reactionData->GetProduct(0)->GetName(); 474 475 for (G4int j = 1; j < nbProducts; j++) 476 { 477 outputReaction[n] += " + " + reactionData->GetProduct(j)->GetName(); 478 } 479 } 480 else 481 { 482 outputReaction[n] += " -> No product"; 483 } 484 485 //----------------------------------------------------------- 486 // Interaction Rate 487 outputReactionRate[n] = G4UIcommand::ConvertToString( 488 reactionData->GetObservedReactionRateConstant() / (1e-3 * m3 / (mole * s))); 489 490 //----------------------------------------------------------- 491 // Calculation of the Interaction Range 492 G4double interactionRange = -1; 493 if (pReactionModel != nullptr) interactionRange = 494 pReactionModel->GetReactionRadius(iReact); 495 496 if (interactionRange != -1) 497 { 498 outputRange[n] = G4UIcommand::ConvertToString( 499 interactionRange / nanometer); 500 } 501 else 502 { 503 outputRange[n] = ""; 504 } 505 506 alreadyPrint[moleculeB][moleculeA] = TRUE; 507 n++; 508 } 509 } 510 } 511 // G4cout<<"Number of possible reactions: "<< n << G4endl; 512 513 //////////////////////////////////////////////////////////////////// 514 // Tableau dynamique en fonction du nombre de caractere maximal dans 515 // chaque colonne 516 //////////////////////////////////////////////////////////////////// 517 518 G4int maxlengthOutputReaction = -1; 519 G4int maxlengthOutputReactionRate = -1; 520 521 for (G4int i = 0; i < n; ++i) 522 { 523 if (maxlengthOutputReaction < (G4int)outputReaction[i].length()) 524 { 525 maxlengthOutputReaction = (G4int)outputReaction[i].length(); 526 } 527 if (maxlengthOutputReactionRate < (G4int)outputReactionRate[i].length()) 528 { 529 maxlengthOutputReactionRate = (G4int)outputReactionRate[i].length(); 530 } 531 } 532 533 maxlengthOutputReaction += 2; 534 maxlengthOutputReactionRate += 2; 535 536 if (maxlengthOutputReaction < 10) maxlengthOutputReaction = 10; 537 if (maxlengthOutputReactionRate < 30) maxlengthOutputReactionRate = 30; 538 539 G4String* title; 540 541 if (pReactionModel != nullptr) title = new G4String[3]; 542 else title = new G4String[2]; 543 544 title[0] = "Reaction"; 545 title[1] = "Reaction Rate [dm3/(mol*s)]"; 546 547 if (pReactionModel != nullptr) title[2] = 548 "Interaction Range for chosen reaction model [nm]"; 549 550 G4cout << setfill(' ') << setw(maxlengthOutputReaction) << left << title[0] 551 << setw(maxlengthOutputReactionRate) << left << title[1]; 552 553 if (pReactionModel != nullptr) G4cout << setw(2) << left << title[2]; 554 555 G4cout << G4endl; 556 557 G4cout.fill('-'); 558 if (pReactionModel != nullptr) G4cout.width( 559 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2 560 + (G4int)title[2].length()); 561 else G4cout.width(maxlengthOutputReaction + 2 + maxlengthOutputReactionRate); 562 G4cout << "-" << G4endl; 563 G4cout.fill(' '); 564 565 for (G4int i = 0; i < n; i++) 566 { 567 G4cout << setw(maxlengthOutputReaction) << left << outputReaction[i] 568 << setw(maxlengthOutputReactionRate) << left 569 << outputReactionRate[i]; 570 571 if (pReactionModel != nullptr) G4cout << setw(2) << left << outputRange[i]; 572 573 G4cout << G4endl; 574 575 G4cout.fill('-'); 576 if (pReactionModel != nullptr) G4cout.width( 577 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate + 2 578 + (G4int)title[2].length()); 579 else G4cout.width( 580 maxlengthOutputReaction + 2 + maxlengthOutputReactionRate); 581 G4cout << "-" << G4endl; 582 G4cout.fill(' '); 583 } 584 585 delete[] title; 586 delete[] outputReaction; 587 delete[] outputReactionRate; 588 delete[] outputRange; 589 } 590 591 //______________________________________________________________________________ 592 // Get/Set methods 593 594 G4VDNAMolecularGeometry* G4DNAMolecularReactionTable::GetGeometry() const 595 { 596 return fGeometry; 597 } 598 599 G4DNAMolecularReactionTable::Data* 600 G4DNAMolecularReactionTable::GetReactionData(Reactant* pReactant1, 601 Reactant* pReactant2) const 602 { 603 if (fReactionData.empty()) 604 { 605 G4String errMsg = "No reaction table was implemented"; 606 G4Exception("G4MolecularInteractionTable::GetReactionData", "", 607 FatalErrorInArgument, errMsg); 608 } 609 610 auto it1 = fReactionData.find(pReactant1); 611 612 if (it1 == fReactionData.end()) 613 { 614 G4String errMsg = 615 "No reaction table was implemented for this molecule Definition : " + pReactant1 616 ->GetName(); 617 G4Exception("G4MolecularInteractionTable::GetReactionData", "", 618 FatalErrorInArgument, errMsg); 619 // Though the above is Fatal and will terminate program, put return in to quieten Coverity 620 return nullptr; 621 } 622 623 auto it2 = it1->second.find(pReactant2); 624 625 if (it2 == it1->second.end()) 626 { 627 G4cout << "Name : " << pReactant2->GetName() << G4endl; 628 G4String errMsg = "No reaction table was implemented for this molecule : " 629 + pReactant2->GetName(); 630 G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg); 631 } 632 633 return (it2->second); 634 } 635 636 const G4DNAMolecularReactionTable::ReactionDataMap& G4DNAMolecularReactionTable::GetAllReactionData() 637 { 638 return fReactionData; 639 } 640 641 G4DNAMolecularReactionTable::DataList G4DNAMolecularReactionTable::GetVectorOfReactionData() 642 { 643 DataList dataList; 644 645 for (const auto& pData : fVectorOfReactionData) 646 { 647 dataList.emplace_back(pData.get()); 648 } 649 650 return dataList; 651 } 652 653 //______________________________________________________________________________ 654 655 const G4DNAMolecularReactionTable::ReactantList* 656 G4DNAMolecularReactionTable::CanReactWith(Reactant* pMolecule) const 657 { 658 if (fReactantsMV.empty()) 659 { 660 G4String errMsg = "No reaction table was implemented"; 661 G4Exception("G4MolecularInteractionTable::CanReactWith", "", 662 FatalErrorInArgument, errMsg); 663 return nullptr; 664 } 665 666 auto itReactivesMap = fReactantsMV.find(pMolecule); 667 668 if (itReactivesMap == fReactantsMV.end()) 669 { 670 #ifdef G4VERBOSE 671 if (fVerbose) 672 { 673 G4String errMsg = "No reaction table was implemented for this molecule : " 674 + pMolecule->GetName(); 675 // G4Exception("G4MolecularInteractionTable::CanReactWith","",FatalErrorInArgument, errMsg); 676 G4cout << "--- G4MolecularInteractionTable::GetReactionData ---" << G4endl; 677 G4cout << errMsg << G4endl; 678 } 679 #endif 680 return nullptr; 681 } 682 683 if (fVerbose) 684 { 685 G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl; 686 G4cout << "You are checking reactants for : " << pMolecule->GetName() << G4endl; 687 G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl; 688 689 auto itProductsVector = itReactivesMap->second.cbegin(); 690 691 for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++) 692 { 693 G4cout << (*itProductsVector)->GetName() << G4endl; 694 } 695 } 696 return &(itReactivesMap->second); 697 } 698 699 //______________________________________________________________________________ 700 701 const G4DNAMolecularReactionTable::SpecificDataList* 702 G4DNAMolecularReactionTable::GetReativesNData(const G4MolecularConfiguration* molecule) const 703 { 704 if (fReactionData.empty()) 705 { 706 G4String errMsg = "No reaction table was implemented"; 707 G4Exception("G4MolecularInteractionTable::CanInteractWith", "", 708 FatalErrorInArgument, errMsg); 709 } 710 711 auto itReactivesMap = fReactionData.find(molecule); 712 713 if (itReactivesMap == fReactionData.end()) 714 { 715 return nullptr; 716 } 717 718 if (fVerbose) 719 { 720 G4cout << " G4MolecularInteractionTable::CanReactWith :" << G4endl; 721 G4cout << "You are checking reactants for : " << molecule->GetName() << G4endl; 722 G4cout << " the number of reactants is : " << itReactivesMap->second.size() << G4endl; 723 724 auto itProductsVector = itReactivesMap->second.begin(); 725 726 for (; itProductsVector != itReactivesMap->second.end(); itProductsVector++) 727 { 728 G4cout << itProductsVector->first->GetName() << G4endl; 729 } 730 } 731 return &(itReactivesMap->second); 732 } 733 734 //______________________________________________________________________________ 735 736 const G4DNAMolecularReactionTable::DataList* 737 G4DNAMolecularReactionTable::GetReactionData(const G4MolecularConfiguration* molecule) const 738 { 739 if (fReactionDataMV.empty()) 740 { 741 G4String errMsg = "No reaction table was implemented"; 742 G4Exception("G4MolecularInteractionTable::CanInteractWith", "", 743 FatalErrorInArgument, errMsg); 744 } 745 auto it = fReactionDataMV.find(molecule); 746 747 if (it == fReactionDataMV.end()) 748 { 749 G4String errMsg = "No reaction table was implemented for this molecule Definition : " 750 + molecule->GetName(); 751 G4Exception("G4MolecularInteractionTable::GetReactionData", "", FatalErrorInArgument, errMsg); 752 // Though the above is Fatal and will terminate program, put return in to quieten Coverity 753 return nullptr; 754 } 755 756 return &(it->second); 757 } 758 759 //______________________________________________________________________________ 760 761 G4DNAMolecularReactionTable::Data* G4DNAMolecularReactionTable::GetReactionData(const G4String& mol1, 762 const G4String& mol2) const 763 { 764 const auto pConf1 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol1); 765 const auto pConf2 = G4MoleculeTable::GetMoleculeTable()->GetConfiguration(mol2); 766 return GetReactionData(pConf1, pConf2); 767 } 768 769 //______________________________________________________________________________ 770 771 void 772 G4DNAMolecularReactionData::SetPolynomialParameterization(const std::vector<double>& P) 773 { 774 fRateParam = std::bind(PolynomialParam, std::placeholders::_1, P); 775 } 776 777 //______________________________________________________________________________ 778 779 void G4DNAMolecularReactionData::SetArrehniusParameterization(double A0, 780 double E_R) 781 { 782 std::vector<double> P = { A0, E_R }; 783 fRateParam = std::bind(ArrehniusParam, std::placeholders::_1, P); 784 } 785 786 //______________________________________________________________________________ 787 788 void G4DNAMolecularReactionData::SetScaledParameterization(double temperature_K, 789 double rateCste) 790 { 791 fRateParam = std::bind(ScaledParameterization, 792 std::placeholders::_1, 793 temperature_K, 794 rateCste); 795 } 796 797 //______________________________________________________________________________ 798 799 void G4DNAMolecularReactionTable::ScaleReactionRateForNewTemperature(double temp_K) 800 { 801 for (const auto& pData : fVectorOfReactionData) 802 { 803 const_cast<G4DNAMolecularReactionData*>(pData.get())->ScaleForNewTemperature(temp_K); 804 } 805 } 806 807 //______________________________________________________________________________ 808 809 void G4DNAMolecularReactionData::ScaleForNewTemperature(double temp_K) 810 { 811 if (fRateParam) 812 { 813 SetObservedReactionRateConstant(fRateParam(temp_K)); 814 } 815 } 816 817 //______________________________________________________________________________ 818 819 G4DNAMolecularReactionTable::Data* 820 G4DNAMolecularReactionTable::GetReaction(int reactionID) const 821 { 822 for (auto& pData : fVectorOfReactionData) 823 { 824 if (pData->GetReactionID() == reactionID) 825 { 826 return pData.get(); 827 } 828 } 829 return nullptr; 830 } 831 832 size_t G4DNAMolecularReactionTable::GetNReactions() const 833 { 834 return fVectorOfReactionData.size(); 835 } 836 837 void G4DNAMolecularReactionTable::Reset() 838 { 839 fReactionData.clear(); 840 fReactantsMV.clear(); 841 fReactionDataMV.clear(); 842 fVectorOfReactionData.clear(); 843 } 844