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 /// \file scavenger/src/ParserChemReaction.cc 27 /// \brief Implementation of the scavenger::ParserChemReaction class 28 29 #include "ParserChemReaction.hh" 30 31 #include "G4SystemOfUnits.hh" 32 33 #include <fstream> 34 35 namespace scavenger 36 { 37 38 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo..... 39 40 void ParserChemReaction::ReplaceString(G4String& aString, const G4String& from, const G4String& to) 41 { 42 if (G4StrUtil::contains(aString, from)) { 43 size_t startPosition = 0; 44 while ((startPosition = aString.find(from, startPosition)) != std::string::npos) { 45 aString.replace(startPosition, from.length(), to); 46 startPosition += to.length(); 47 } 48 } 49 } 50 51 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 52 53 void ParserChemReaction::ImplementReaction(const G4String& reactant1, const G4String& reactant2, 54 const std::vector<G4String>& product, 55 const G4double& reactionRate, const G4String& type) 56 { 57 if (type == "I") { 58 fListReactant1[0].push_back(reactant1); 59 fListReactant2[0].push_back(reactant2); 60 fListProduct[0].push_back(product); 61 fListRate[0].push_back(reactionRate); 62 } 63 else if (type == "II") { 64 fListReactant1[1].push_back(reactant1); 65 fListReactant2[1].push_back(reactant2); 66 fListProduct[1].push_back(product); 67 fListRate[1].push_back(reactionRate); 68 } 69 else if (type == "III") { 70 fListReactant1[2].push_back(reactant1); 71 fListReactant2[2].push_back(reactant2); 72 fListProduct[2].push_back(product); 73 fListRate[2].push_back(reactionRate); 74 } 75 else if (type == "IV") { 76 fListReactant1[3].push_back(reactant1); 77 fListReactant2[3].push_back(reactant2); 78 fListProduct[3].push_back(product); 79 fListRate[3].push_back(reactionRate); 80 } 81 else if (type == "VI") { 82 fListReactant1[4].push_back(reactant1); 83 fListReactant2[4].push_back(reactant2); 84 fListProduct[4].push_back(product); 85 fListRate[4].push_back(reactionRate); 86 } 87 } 88 89 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 90 91 void ParserChemReaction::ReadReaction(const G4String& reactionString, 92 std::vector<G4String>& reactant, 93 std::vector<G4String>& product, G4double& reactionRate) 94 { 95 reactant.clear(); 96 product.clear(); 97 98 G4bool readReaction = true; 99 G4bool readReactant = true; 100 G4bool readProduct = false; 101 G4bool readRate = false; 102 103 std::stringstream aStream; 104 aStream << reactionString; 105 106 while (!aStream.eof() && readReaction) { 107 G4String aString; 108 aStream >> aString; 109 110 if (G4StrUtil::contains(aString, "#")) { 111 readReaction = false; 112 } 113 else if (readReactant) { 114 if (aString == G4String("->")) { 115 readReactant = false; 116 readProduct = true; 117 } 118 else if (aString != G4String("+")) { 119 ReplaceString(aString, G4String("+"), G4String("p")); 120 ReplaceString(aString, G4String("-"), G4String("m")); 121 122 if (reactant.size() < 2) { 123 reactant.push_back(aString); 124 } 125 } 126 } 127 else if (readProduct) { 128 if (aString == G4String(",")) { 129 readProduct = false; 130 readRate = true; 131 } 132 else if (aString != G4String("+") && !G4StrUtil::contains(aString, "[") 133 && !G4StrUtil::contains(aString, "]")) 134 { 135 ReplaceString(aString, G4String("+"), G4String("p")); 136 ReplaceString(aString, G4String("-"), G4String("m")); 137 product.push_back(aString); 138 } 139 } 140 else if (readRate) { 141 std::stringstream aStreamTmp; 142 aStreamTmp << aString; 143 aStreamTmp >> reactionRate; 144 145 if (reactant.size() == 1) { 146 // For first-order reactions 147 reactionRate *= (1 * 1 / s); 148 } 149 else { 150 reactionRate *= (1e-3 * m3 / (mole * s)); 151 } 152 153 readRate = false; 154 readReaction = false; 155 } 156 } 157 158 // For first-order reactions 159 if (reactant.size() == 1) { 160 reactant.emplace_back("NoneM"); 161 } 162 } 163 164 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 165 166 G4double ParserChemReaction::GetScavengerConcentration(const G4String& name) 167 { 168 G4double concentration = -1.; 169 170 std::map<G4String, G4double>::iterator it; 171 it = fReservoirConcentrationMap.find(name); 172 173 if (it != fReservoirConcentrationMap.end()) { 174 concentration = it->second; 175 } 176 else { 177 G4ExceptionDescription exception; 178 exception << "Scavenger is not defined: " 179 << "reaction will not be registered!"; 180 G4Exception("ParserChemReaction::GetScavengerConcentration", "parchem01", JustWarning, 181 exception); 182 } 183 184 return concentration; 185 } 186 187 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 188 189 void ParserChemReaction::ReadReservoir(const G4String& reservoirString) 190 { 191 G4double concentration = 0.; 192 G4String name = ""; 193 194 G4bool readScavenger = true; 195 G4bool readName = false; 196 G4bool readConcentration = false; 197 198 std::stringstream aStream; 199 aStream << reservoirString; 200 201 while (!aStream.eof() && readScavenger) { 202 G4String aString; 203 aStream >> aString; 204 205 if (G4StrUtil::contains(aString, "#")) { 206 readScavenger = false; 207 } 208 else if (aString == G4String("scavenger:")) { 209 readName = true; 210 } 211 else if (readName) { 212 name = G4String(aString); 213 ReplaceString(name, G4String("+"), G4String("p")); 214 ReplaceString(name, G4String("-"), G4String("m")); 215 216 readName = false; 217 readConcentration = true; 218 } 219 else if (readConcentration) { 220 std::stringstream aStreamTmp; 221 aStreamTmp << aString; 222 aStreamTmp >> concentration; 223 concentration *= (mole / (1e-3 * m3)); 224 readConcentration = false; 225 readScavenger = false; 226 } 227 } 228 229 if (concentration > 0.) { 230 if (fReservoirConcentrationMap.count(name) < 1) { 231 fReservoirConcentrationMap[name] = concentration; 232 } 233 else { 234 G4ExceptionDescription exception; 235 exception << "Scavenger already defined previously:\n" 236 << "scavenger will not be registered!"; 237 G4Exception("ParserChemReaction::ReadReservoir", "parchem02", JustWarning, exception); 238 } 239 } 240 else { 241 G4ExceptionDescription exception; 242 exception << "Null or negative scavenger concentration:\n" 243 << "scavenger will not be registered!"; 244 G4Exception("ParserChemReaction::ReadReservoir", "parchem03", JustWarning, exception); 245 } 246 } 247 248 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 249 250 void ParserChemReaction::AddReaction(const G4String& reactionString, const G4String& type) 251 { 252 std::vector<G4String> reactant; 253 std::vector<G4String> product; 254 G4double reactionRate = -1; 255 256 G4bool reservoir = false; 257 258 if (type == "VI") { 259 reservoir = true; 260 } 261 262 ReadReaction(reactionString, reactant, product, reactionRate); 263 264 if (!reactant.empty() && (reactionRate <= 0)) { 265 G4ExceptionDescription exception; 266 exception << "Null or negative reaction rate: " 267 << "reaction will not be registered!"; 268 G4Exception("ParserChemReaction::AddReaction", "parchem04", JustWarning, exception); 269 return; 270 } 271 272 G4double concentration; 273 274 if (reservoir && (reactant.size() >= 2)) { 275 if (G4StrUtil::contains(reactant[0], "[") && G4StrUtil::contains(reactant[0], "]")) { 276 ReplaceString(reactant[0], G4String("["), G4String("")); 277 ReplaceString(reactant[0], G4String("]"), G4String("")); 278 279 concentration = GetScavengerConcentration(reactant[0]); 280 281 if (concentration != -1) { 282 reactionRate *= concentration; 283 reactant[0].append("(B)"); 284 ImplementReaction(reactant[1], reactant[0], product, reactionRate, type); 285 } 286 } 287 else if (G4StrUtil::contains(reactant[1], "[") && G4StrUtil::contains(reactant[1], "]")) { 288 ReplaceString(reactant[1], G4String("["), G4String("")); 289 ReplaceString(reactant[1], G4String("]"), G4String("")); 290 291 concentration = GetScavengerConcentration(reactant[1]); 292 293 if (concentration != -1) { 294 reactionRate *= concentration; 295 reactant[1].append("(B)"); 296 ImplementReaction(reactant[0], reactant[1], product, reactionRate, type); 297 } 298 } 299 else if (reactant[1] == "NoneM") { 300 // First-order reaction 301 ImplementReaction(reactant[0], reactant[1], product, reactionRate, type); 302 } 303 else { 304 G4ExceptionDescription exception; 305 exception << "Missing or unsuitable square brackets:\n" 306 << "reaction will not be registered.\n" 307 << "Verify the writing of chemical reactions!"; 308 G4Exception("ParserChemReaction::AddReaction", "parchem05", JustWarning, exception); 309 } 310 } 311 else if (reactant.size() >= 2) { 312 if (!G4StrUtil::contains(reactant[0], "[") && !G4StrUtil::contains(reactant[0], "]") 313 && !G4StrUtil::contains(reactant[1], "[") && !G4StrUtil::contains(reactant[1], "]") 314 && (reactant[1] != "NoneM")) 315 { 316 ImplementReaction(reactant[0], reactant[1], product, reactionRate, type); 317 } 318 else if (reactant[1] == "NoneM") { 319 G4ExceptionDescription exception; 320 exception << "Unsuitable reaction type: " 321 << "reaction will not be registered.\n" 322 << "For first-order reaction, use reaction type 6."; 323 G4Exception("ParserChemReaction::AddReaction", "parchem06", JustWarning, exception); 324 } 325 else { 326 G4ExceptionDescription exception; 327 exception << "Unsuitable square brackets: " 328 << "reaction will not be registered.\n" 329 << "Verify the writing of chemical reactions!"; 330 G4Exception("ParserChemReaction::AddReaction", "parchem07", JustWarning, exception); 331 } 332 } 333 } 334 335 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 336 337 void ParserChemReaction::ReadReactionFile(const G4String& fileName) 338 { 339 G4String line; 340 std::ifstream myFile(fileName); 341 342 if (myFile.is_open()) { 343 while (getline(myFile, line)) { 344 if (G4StrUtil::contains(line, "type_1")) { 345 AddReaction(line, "I"); 346 } 347 else if (G4StrUtil::contains(line, "type_2")) { 348 AddReaction(line, "II"); 349 } 350 else if (G4StrUtil::contains(line, "type_3")) { 351 AddReaction(line, "III"); 352 } 353 else if (G4StrUtil::contains(line, "type_4")) { 354 AddReaction(line, "IV"); 355 } 356 else if (G4StrUtil::contains(line, "type_6")) { 357 AddReaction(line, "VI"); 358 } 359 else if (G4StrUtil::contains(line, "scavenger:")) { 360 ReadReservoir(line); 361 } 362 else if (!G4StrUtil::contains(line, "#") && !line.empty()) { 363 G4ExceptionDescription exception; 364 exception << "Unknown declaration: " 365 << "reaction or scavenger will not be registered.\n" 366 << "Verify the writing of chemical reactions or scavengers!"; 367 G4Exception("ParserChemReaction::ReadReactionFile", "parchem08", JustWarning, exception); 368 } 369 } 370 371 myFile.close(); 372 } 373 else { 374 G4ExceptionDescription exception; 375 exception << "Chemical reaction file not found."; 376 G4Exception("ParserChemReaction::ReadReactionFile", "parchem09", JustWarning, exception); 377 } 378 } 379 380 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 381 382 } // namespace scavenger