File indexing completed on 2025-02-23 09:22:10
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 #include "ChemistryWorld.hh"
0028
0029 #include "G4DNABoundingBox.hh"
0030 #include "G4DNAMolecularReactionTable.hh"
0031 #include "G4MoleculeTable.hh"
0032
0033
0034 ChemistryWorld::ChemistryWorld() : G4VChemistryWorld(), G4UImessenger()
0035 {
0036 fpChemWoldDir = std::make_unique<G4UIdirectory>("/UHDR/env/", false);
0037 fpChemWoldDir->SetGuidance("chemistry environment commands");
0038
0039 fpAddpH = std::make_unique<G4UIcmdWithADouble>("/UHDR/env/pH", this);
0040 fpAddpH->SetGuidance("Add pH for water.");
0041 fpAddpH->SetParameterName("pH", false);
0042 fpAddpH->SetToBeBroadcasted(false);
0043
0044 fpAddScavengerName = std::make_unique<G4UIcmdWithAString>("/UHDR/env/scavenger", this);
0045 fpAddScavengerName->SetToBeBroadcasted(false);
0046
0047 fpTargetVolume = std::make_unique<G4UIcmdWithADoubleAndUnit>("/UHDR/env/volume", this);
0048 fpTargetVolume->SetGuidance("Volume of water.");
0049 fpTargetVolume->SetParameterName("Volume", false);
0050 fpTargetVolume->AvailableForStates(G4State_PreInit);
0051 fpTargetVolume->SetToBeBroadcasted(false);
0052 }
0053
0054
0055 void ChemistryWorld::ConstructChemistryBoundary()
0056 {
0057 fHalfBox = 1.6 * um;
0058 std::initializer_list<G4double> l{fHalfBox, -fHalfBox, fHalfBox, -fHalfBox, fHalfBox, -fHalfBox};
0059 fpChemistryBoundary = std::make_unique<G4DNABoundingBox>(l);
0060 }
0061
0062
0063 void ChemistryWorld::SetNewValue(G4UIcommand* command, G4String newValue)
0064 {
0065 if (command == fpAddpH.get()) {
0066 fpH = fpAddpH->GetNewDoubleValue(newValue);
0067 ConstructChemistryComponents();
0068 }
0069 else if (command == fpAddScavengerName.get()) {
0070 std::istringstream iss(newValue);
0071 G4String species;
0072 iss >> species;
0073 auto scavengerConf = G4MoleculeTable::Instance()->GetConfiguration(species);
0074 G4double concentraion;
0075 iss >> concentraion;
0076 G4String unit;
0077 iss >> unit;
0078 if (unit == "M") {
0079 G4double ConcentrationInM = concentraion / (mole * liter);
0080 fpChemicalComponent[scavengerConf] = ConcentrationInM;
0081 }
0082 else if (unit == "mM") {
0083 G4double ConcentrationInM = concentraion / (mole * liter * 1e3);
0084 fpChemicalComponent[scavengerConf] = ConcentrationInM;
0085 }
0086 else if (unit == "uM") {
0087 G4double ConcentrationInM = concentraion / (mole * liter * 1e6);
0088 fpChemicalComponent[scavengerConf] = ConcentrationInM;
0089 }
0090 else if (unit == "%")
0091 {
0092 G4double ConcentrationInM = (concentraion / 100) * 0.0013 / (mole * liter);
0093 fpChemicalComponent[scavengerConf] = ConcentrationInM;
0094 }
0095 else {
0096 throw std::runtime_error("Unit should be in Molarity");
0097 }
0098 }
0099 else if (command == fpTargetVolume.get()) {
0100 fHalfBox = G4UIcmdWithADoubleAndUnit::GetNewDoubleValue(newValue);
0101 std::initializer_list<G4double> l{fHalfBox, -fHalfBox, fHalfBox,
0102 -fHalfBox, fHalfBox, -fHalfBox};
0103 fpChemistryBoundary = std::make_unique<G4DNABoundingBox>(l);
0104 }
0105 }
0106
0107
0108 void ChemistryWorld::ConstructChemistryComponents()
0109 {
0110 auto O2 = G4MoleculeTable::Instance()->GetConfiguration("O2");
0111 auto H2O = G4MoleculeTable::Instance()->GetConfiguration("H2O");
0112 auto H3Op = G4MoleculeTable::Instance()->GetConfiguration("H3Op(B)");
0113 auto OHm = G4MoleculeTable::Instance()->GetConfiguration("OHm(B)");
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 G4double pKw = 14;
0124 G4double waterMolarity = 55.3 / (mole * liter);
0125 fpChemicalComponent[H2O] = waterMolarity;
0126
0127 G4double H3OpBMolarity = std::pow(10, -fpH) / (mole * liter);
0128 fpChemicalComponent[H3Op] = H3OpBMolarity;
0129
0130 G4double OHmBMolarity = std::pow(10, -(pKw - fpH)) / (mole * liter);
0131 fpChemicalComponent[OHm] = OHmBMolarity;
0132
0133 G4double O2Molarity = (0. / 100) * 0.0013 / (mole * liter);
0134 fpChemicalComponent[O2] = O2Molarity;
0135 }
0136