Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-10 08:06:46

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file scavenger/src/ParserChemReaction.cc
0027 /// \brief Implementation of the scavenger::ParserChemReaction class
0028 
0029 #include "ParserChemReaction.hh"
0030 
0031 #include "G4SystemOfUnits.hh"
0032 
0033 #include <fstream>
0034 
0035 namespace scavenger
0036 {
0037 
0038 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
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         // For first-order reactions
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   // For first-order reactions
0159   if (reactant.size() == 1) {
0160     reactant.emplace_back("NoneM");
0161   }
0162 }
0163 
0164 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
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       // First-order reaction
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
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 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0381 
0382 }  // namespace scavenger