File indexing completed on 2025-04-10 08:06:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "ParserChemReaction.hh"
0030
0031 #include "G4SystemOfUnits.hh"
0032
0033 #include <fstream>
0034
0035 namespace scavenger
0036 {
0037
0038
0039
0040 void ParserChemReaction::ReplaceString(G4String& aString, const G4String& from, const G4String& to)
0041 {
0042 if (G4StrUtil::contains(aString, from)) {
0043 size_t startPosition = 0;
0044 while ((startPosition = aString.find(from, startPosition)) != std::string::npos) {
0045 aString.replace(startPosition, from.length(), to);
0046 startPosition += to.length();
0047 }
0048 }
0049 }
0050
0051
0052
0053 void ParserChemReaction::ImplementReaction(const G4String& reactant1, const G4String& reactant2,
0054 const std::vector<G4String>& product,
0055 const G4double& reactionRate, const G4String& type)
0056 {
0057 if (type == "I") {
0058 fListReactant1[0].push_back(reactant1);
0059 fListReactant2[0].push_back(reactant2);
0060 fListProduct[0].push_back(product);
0061 fListRate[0].push_back(reactionRate);
0062 }
0063 else if (type == "II") {
0064 fListReactant1[1].push_back(reactant1);
0065 fListReactant2[1].push_back(reactant2);
0066 fListProduct[1].push_back(product);
0067 fListRate[1].push_back(reactionRate);
0068 }
0069 else if (type == "III") {
0070 fListReactant1[2].push_back(reactant1);
0071 fListReactant2[2].push_back(reactant2);
0072 fListProduct[2].push_back(product);
0073 fListRate[2].push_back(reactionRate);
0074 }
0075 else if (type == "IV") {
0076 fListReactant1[3].push_back(reactant1);
0077 fListReactant2[3].push_back(reactant2);
0078 fListProduct[3].push_back(product);
0079 fListRate[3].push_back(reactionRate);
0080 }
0081 else if (type == "VI") {
0082 fListReactant1[4].push_back(reactant1);
0083 fListReactant2[4].push_back(reactant2);
0084 fListProduct[4].push_back(product);
0085 fListRate[4].push_back(reactionRate);
0086 }
0087 }
0088
0089
0090
0091 void ParserChemReaction::ReadReaction(const G4String& reactionString,
0092 std::vector<G4String>& reactant,
0093 std::vector<G4String>& product, G4double& reactionRate)
0094 {
0095 reactant.clear();
0096 product.clear();
0097
0098 G4bool readReaction = true;
0099 G4bool readReactant = true;
0100 G4bool readProduct = false;
0101 G4bool readRate = false;
0102
0103 std::stringstream aStream;
0104 aStream << reactionString;
0105
0106 while (!aStream.eof() && readReaction) {
0107 G4String aString;
0108 aStream >> aString;
0109
0110 if (G4StrUtil::contains(aString, "#")) {
0111 readReaction = false;
0112 }
0113 else if (readReactant) {
0114 if (aString == G4String("->")) {
0115 readReactant = false;
0116 readProduct = true;
0117 }
0118 else if (aString != G4String("+")) {
0119 ReplaceString(aString, G4String("+"), G4String("p"));
0120 ReplaceString(aString, G4String("-"), G4String("m"));
0121
0122 if (reactant.size() < 2) {
0123 reactant.push_back(aString);
0124 }
0125 }
0126 }
0127 else if (readProduct) {
0128 if (aString == G4String(",")) {
0129 readProduct = false;
0130 readRate = true;
0131 }
0132 else if (aString != G4String("+") && !G4StrUtil::contains(aString, "[")
0133 && !G4StrUtil::contains(aString, "]"))
0134 {
0135 ReplaceString(aString, G4String("+"), G4String("p"));
0136 ReplaceString(aString, G4String("-"), G4String("m"));
0137 product.push_back(aString);
0138 }
0139 }
0140 else if (readRate) {
0141 std::stringstream aStreamTmp;
0142 aStreamTmp << aString;
0143 aStreamTmp >> reactionRate;
0144
0145 if (reactant.size() == 1) {
0146
0147 reactionRate *= (1 * 1 / s);
0148 }
0149 else {
0150 reactionRate *= (1e-3 * m3 / (mole * s));
0151 }
0152
0153 readRate = false;
0154 readReaction = false;
0155 }
0156 }
0157
0158
0159 if (reactant.size() == 1) {
0160 reactant.emplace_back("NoneM");
0161 }
0162 }
0163
0164
0165
0166 G4double ParserChemReaction::GetScavengerConcentration(const G4String& name)
0167 {
0168 G4double concentration = -1.;
0169
0170 std::map<G4String, G4double>::iterator it;
0171 it = fReservoirConcentrationMap.find(name);
0172
0173 if (it != fReservoirConcentrationMap.end()) {
0174 concentration = it->second;
0175 }
0176 else {
0177 G4ExceptionDescription exception;
0178 exception << "Scavenger is not defined: "
0179 << "reaction will not be registered!";
0180 G4Exception("ParserChemReaction::GetScavengerConcentration", "parchem01", JustWarning,
0181 exception);
0182 }
0183
0184 return concentration;
0185 }
0186
0187
0188
0189 void ParserChemReaction::ReadReservoir(const G4String& reservoirString)
0190 {
0191 G4double concentration = 0.;
0192 G4String name = "";
0193
0194 G4bool readScavenger = true;
0195 G4bool readName = false;
0196 G4bool readConcentration = false;
0197
0198 std::stringstream aStream;
0199 aStream << reservoirString;
0200
0201 while (!aStream.eof() && readScavenger) {
0202 G4String aString;
0203 aStream >> aString;
0204
0205 if (G4StrUtil::contains(aString, "#")) {
0206 readScavenger = false;
0207 }
0208 else if (aString == G4String("scavenger:")) {
0209 readName = true;
0210 }
0211 else if (readName) {
0212 name = G4String(aString);
0213 ReplaceString(name, G4String("+"), G4String("p"));
0214 ReplaceString(name, G4String("-"), G4String("m"));
0215
0216 readName = false;
0217 readConcentration = true;
0218 }
0219 else if (readConcentration) {
0220 std::stringstream aStreamTmp;
0221 aStreamTmp << aString;
0222 aStreamTmp >> concentration;
0223 concentration *= (mole / (1e-3 * m3));
0224 readConcentration = false;
0225 readScavenger = false;
0226 }
0227 }
0228
0229 if (concentration > 0.) {
0230 if (fReservoirConcentrationMap.count(name) < 1) {
0231 fReservoirConcentrationMap[name] = concentration;
0232 }
0233 else {
0234 G4ExceptionDescription exception;
0235 exception << "Scavenger already defined previously:\n"
0236 << "scavenger will not be registered!";
0237 G4Exception("ParserChemReaction::ReadReservoir", "parchem02", JustWarning, exception);
0238 }
0239 }
0240 else {
0241 G4ExceptionDescription exception;
0242 exception << "Null or negative scavenger concentration:\n"
0243 << "scavenger will not be registered!";
0244 G4Exception("ParserChemReaction::ReadReservoir", "parchem03", JustWarning, exception);
0245 }
0246 }
0247
0248
0249
0250 void ParserChemReaction::AddReaction(const G4String& reactionString, const G4String& type)
0251 {
0252 std::vector<G4String> reactant;
0253 std::vector<G4String> product;
0254 G4double reactionRate = -1;
0255
0256 G4bool reservoir = false;
0257
0258 if (type == "VI") {
0259 reservoir = true;
0260 }
0261
0262 ReadReaction(reactionString, reactant, product, reactionRate);
0263
0264 if (!reactant.empty() && (reactionRate <= 0)) {
0265 G4ExceptionDescription exception;
0266 exception << "Null or negative reaction rate: "
0267 << "reaction will not be registered!";
0268 G4Exception("ParserChemReaction::AddReaction", "parchem04", JustWarning, exception);
0269 return;
0270 }
0271
0272 G4double concentration;
0273
0274 if (reservoir && (reactant.size() >= 2)) {
0275 if (G4StrUtil::contains(reactant[0], "[") && G4StrUtil::contains(reactant[0], "]")) {
0276 ReplaceString(reactant[0], G4String("["), G4String(""));
0277 ReplaceString(reactant[0], G4String("]"), G4String(""));
0278
0279 concentration = GetScavengerConcentration(reactant[0]);
0280
0281 if (concentration != -1) {
0282 reactionRate *= concentration;
0283 reactant[0].append("(B)");
0284 ImplementReaction(reactant[1], reactant[0], product, reactionRate, type);
0285 }
0286 }
0287 else if (G4StrUtil::contains(reactant[1], "[") && G4StrUtil::contains(reactant[1], "]")) {
0288 ReplaceString(reactant[1], G4String("["), G4String(""));
0289 ReplaceString(reactant[1], G4String("]"), G4String(""));
0290
0291 concentration = GetScavengerConcentration(reactant[1]);
0292
0293 if (concentration != -1) {
0294 reactionRate *= concentration;
0295 reactant[1].append("(B)");
0296 ImplementReaction(reactant[0], reactant[1], product, reactionRate, type);
0297 }
0298 }
0299 else if (reactant[1] == "NoneM") {
0300
0301 ImplementReaction(reactant[0], reactant[1], product, reactionRate, type);
0302 }
0303 else {
0304 G4ExceptionDescription exception;
0305 exception << "Missing or unsuitable square brackets:\n"
0306 << "reaction will not be registered.\n"
0307 << "Verify the writing of chemical reactions!";
0308 G4Exception("ParserChemReaction::AddReaction", "parchem05", JustWarning, exception);
0309 }
0310 }
0311 else if (reactant.size() >= 2) {
0312 if (!G4StrUtil::contains(reactant[0], "[") && !G4StrUtil::contains(reactant[0], "]")
0313 && !G4StrUtil::contains(reactant[1], "[") && !G4StrUtil::contains(reactant[1], "]")
0314 && (reactant[1] != "NoneM"))
0315 {
0316 ImplementReaction(reactant[0], reactant[1], product, reactionRate, type);
0317 }
0318 else if (reactant[1] == "NoneM") {
0319 G4ExceptionDescription exception;
0320 exception << "Unsuitable reaction type: "
0321 << "reaction will not be registered.\n"
0322 << "For first-order reaction, use reaction type 6.";
0323 G4Exception("ParserChemReaction::AddReaction", "parchem06", JustWarning, exception);
0324 }
0325 else {
0326 G4ExceptionDescription exception;
0327 exception << "Unsuitable square brackets: "
0328 << "reaction will not be registered.\n"
0329 << "Verify the writing of chemical reactions!";
0330 G4Exception("ParserChemReaction::AddReaction", "parchem07", JustWarning, exception);
0331 }
0332 }
0333 }
0334
0335
0336
0337 void ParserChemReaction::ReadReactionFile(const G4String& fileName)
0338 {
0339 G4String line;
0340 std::ifstream myFile(fileName);
0341
0342 if (myFile.is_open()) {
0343 while (getline(myFile, line)) {
0344 if (G4StrUtil::contains(line, "type_1")) {
0345 AddReaction(line, "I");
0346 }
0347 else if (G4StrUtil::contains(line, "type_2")) {
0348 AddReaction(line, "II");
0349 }
0350 else if (G4StrUtil::contains(line, "type_3")) {
0351 AddReaction(line, "III");
0352 }
0353 else if (G4StrUtil::contains(line, "type_4")) {
0354 AddReaction(line, "IV");
0355 }
0356 else if (G4StrUtil::contains(line, "type_6")) {
0357 AddReaction(line, "VI");
0358 }
0359 else if (G4StrUtil::contains(line, "scavenger:")) {
0360 ReadReservoir(line);
0361 }
0362 else if (!G4StrUtil::contains(line, "#") && !line.empty()) {
0363 G4ExceptionDescription exception;
0364 exception << "Unknown declaration: "
0365 << "reaction or scavenger will not be registered.\n"
0366 << "Verify the writing of chemical reactions or scavengers!";
0367 G4Exception("ParserChemReaction::ReadReactionFile", "parchem08", JustWarning, exception);
0368 }
0369 }
0370
0371 myFile.close();
0372 }
0373 else {
0374 G4ExceptionDescription exception;
0375 exception << "Chemical reaction file not found.";
0376 G4Exception("ParserChemReaction::ReadReactionFile", "parchem09", JustWarning, exception);
0377 }
0378 }
0379
0380
0381
0382 }