46 : fpChemistryInfo(pChemistryInfo), fIsInitialized(false), fCounterAgainstTime(false), fVerbose(0)
59 if (fpChemistryInfo->size() == 0) {
60 G4cout <<
"G4DNAScavengerMaterial existed but empty" <<
G4endl;
64 fEquilibriumProcesses.emplace(
65 std::make_pair(6, std::make_unique<G4ChemEquilibrium>(6, 10 * CLHEP::us)));
66 fEquilibriumProcesses.emplace(
67 std::make_pair(7, std::make_unique<G4ChemEquilibrium>(7, 10 * CLHEP::us)));
68 fEquilibriumProcesses.emplace(
69 std::make_pair(8, std::make_unique<G4ChemEquilibrium>(8, 10 * CLHEP::us)));
70 for(
auto& it : fEquilibriumProcesses)
72 it.second->Initialize();
73 it.second->SetVerbose(fVerbose);
76 fIsInitialized =
true;
83 if (fH2O == matConf) {
87 auto iter = fScavengerTable.find(matConf);
88 if (iter == fScavengerTable.end()) {
92 if (iter->second >= 1) {
93 return (floor)(iter->second);
103 if (fH2O == matConf || fH3Op == matConf ||
114 fScavengerTable[matConf]--;
115 if (fScavengerTable[matConf] < 0)
120 if (fCounterAgainstTime) {
130 if (fH2O == matConf || fH3Op == matConf ||
138 auto it = fScavengerTable.find(matConf);
139 if (it == fScavengerTable.end())
143 fScavengerTable[matConf]++;
145 if (fCounterAgainstTime) {
152 auto pConfinedBox = fpChemistryInfo->GetChemistryBoundary();
153 auto iter = fpChemistryInfo->begin();
154 G4cout <<
"**************************************************************" <<
G4endl;
155 for (; iter != fpChemistryInfo->end(); iter++) {
156 auto containedConf = iter->first;
158 auto concentration = fScavengerTable[containedConf] / (Avogadro * pConfinedBox->Volume());
159 G4cout <<
"Scavenger:" << containedConf->GetName() <<
" : "
160 << concentration / 1.0e-6 <<
" (M) with : "
161 << fScavengerTable[containedConf] <<
" (molecules)"
162 <<
"in: " << pConfinedBox->Volume() / (um * um * um) <<
" (um3)" <<
G4endl;
163 if (fScavengerTable[containedConf] < 1) {
164 G4cout <<
"!!!!!!!!!!!!! this molecule has less one molecule for "
173 G4cout <<
"**************************************************************" <<
G4endl;
178 if (fpChemistryInfo ==
nullptr) {
182 if (fpChemistryInfo->size() == 0) {
188 fScavengerTable.clear();
190 fpLastSearch.reset(
nullptr);
192 auto pConfinedBox = fpChemistryInfo->GetChemistryBoundary();
193 auto iter = fpChemistryInfo->begin();
194 for (; iter != fpChemistryInfo->end(); iter++) {
195 auto containedConf = iter->first;
196 auto concentration = iter->second;
197 fScavengerTable[containedConf] = floor(Avogadro * concentration * pConfinedBox->Volume());
198 fCounterMap[containedConf][1 * picosecond] =
199 floor(Avogadro * concentration * pConfinedBox->Volume());
212 G4cout <<
"G4DNAScavengerMaterial::AddAMoleculeAtTime : " << molecule->
GetName()
216 auto counterMap_i = fCounterMap.find(molecule);
218 if (counterMap_i == fCounterMap.end()) {
219 fCounterMap[molecule][time] = number;
221 else if (counterMap_i->second.empty()) {
222 counterMap_i->second[time] = number;
225 auto end = counterMap_i->second.rbegin();
227 if (
end->first <= time
230 counterMap_i->second[time] = newValue;
231 if (newValue != (floor)(fScavengerTable[molecule]))
233 G4String errMsg =
"You are trying to add wrong molecule : ";
234 G4cout<<
" newValue : "<<newValue<<
" " << molecule->GetName()
236 <<
" with number : " << number
237 <<
" (floor)(fScavengerTable[molecule]) : "<<(floor)(fScavengerTable[molecule])
238 <<
" and the final number is not valid." <<
G4endl;
253 auto it_ = nbMolPerTime.rbegin();
254 G4cout <<
"G4DNAScavengerMaterial::RemoveAMoleculeAtTime : " << pMolecule->
GetName()
257 <<
" form : " << it_->second <<
G4endl;
260 if (nbMolPerTime.empty()) {
262 G4String errMsg =
"You are trying to remove molecule " +
264 " from the counter while this kind of molecules has not "
265 "been registered yet";
271 auto it = nbMolPerTime.rbegin();
273 if (it == nbMolPerTime.rend()) {
277 +
" recorded at the time or even before the time asked";
281 G4double finalN = it->second - number;
285 G4cout <<
"fScavengerTable : " << pMolecule->
GetName() <<
" : " << (fScavengerTable[pMolecule])
289 errMsg <<
"After removal of " << number <<
" species of "
290 <<
" " << it->second <<
" " << pMolecule->
GetName() <<
" the final number at time "
291 <<
G4BestUnit(time,
"Time") <<
" is less than zero and so not valid." <<
G4endl;
293 <<
". Previous selected time is " <<
G4BestUnit(it->first,
"Time") <<
G4endl;
296 nbMolPerTime[time] = finalN;
298 if (finalN != (floor)(fScavengerTable[pMolecule]))
306 auto pConfinedBox = fpChemistryInfo->GetChemistryBoundary();
307 auto V = pConfinedBox->Volume();
308 for (
const auto& it : fCounterMap) {
309 auto pReactant = it.first;
311 G4cout <<
" --- > For " << pReactant->GetName() <<
G4endl;
313 for (
const auto& it2 : it.second) {
315 << it2.second / (Avogadro * V * 1.0e-6 ) <<
G4endl;
322 if (!fCounterAgainstTime) {
331 errMsg <<
"N molecules not valid < 0 : " << molecule->
GetName() <<
" N : " << output <<
G4endl;
339 if (fpLastSearch ==
nullptr) {
340 fpLastSearch = std::make_unique<Search>();
343 if (fpLastSearch->fLowerBoundSet && fpLastSearch->fLastMoleculeSearched->first == molecule) {
348 auto mol_it = fCounterMap.find(molecule);
349 fpLastSearch->fLastMoleculeSearched = mol_it;
351 if (mol_it != fCounterMap.end()) {
352 fpLastSearch->fLowerBoundTime = fpLastSearch->fLastMoleculeSearched->second.end();
353 fpLastSearch->fLowerBoundSet =
true;
356 fpLastSearch->fLowerBoundSet =
false;
366 auto mol_it = fpLastSearch->fLastMoleculeSearched;
367 if (mol_it == fCounterMap.end()) {
372 if (timeMap.empty()) {
376 if (sameTypeOfMolecule) {
377 if (fpLastSearch->fLowerBoundSet && fpLastSearch->fLowerBoundTime != timeMap.end()) {
378 if (fpLastSearch->fLowerBoundTime->first < time) {
379 auto upperToLast = fpLastSearch->fLowerBoundTime;
382 if (upperToLast == timeMap.end()) {
383 return fpLastSearch->fLowerBoundTime->second;
386 if (upperToLast->first > time) {
387 return fpLastSearch->fLowerBoundTime->second;
393 auto up_time_it = timeMap.upper_bound(time);
395 if (up_time_it == timeMap.end()) {
396 auto last_time = timeMap.rbegin();
397 return last_time->second;
399 if (up_time_it == timeMap.begin()) {
405 fpLastSearch->fLowerBoundTime = up_time_it;
406 fpLastSearch->fLowerBoundSet =
true;
408 return fpLastSearch->fLowerBoundTime->second;
411void G4DNAScavengerMaterial::WaterEquilibrium()
415 fScavengerTable[fHOm] = (kw / ((
G4double)fScavengerTable[fH3Op] / convertFactor)) * convertFactor;
422 auto volume = fpChemistryInfo->GetChemistryBoundary()->Volume();
423 fScavengerTable[fH3Op] = floor(Avogadro * std::pow(10, -ph) * volume / liter);
424 fScavengerTable[fHOm] = floor(Avogadro * std::pow(10, -(14 - ph)) * volume / liter);
429 G4double volumeInLiter = fpChemistryInfo->GetChemistryBoundary()->Volume() / liter;
430 G4double Cion = (
G4double)fScavengerTable[fH3Op] / (Avogadro * volumeInLiter);
434 if (fScavengerTable[fH3Op] < 0)
438 fScavengerTable[fH3Op] = 0;
440 if (fScavengerTable[fHOm] < 0)
444 fScavengerTable[fHOm] = 0;
452 for(
auto& it : fEquilibriumProcesses)
454 it.second->SetGlobalTime(time);
455 it.second->SetEquilibrium(pReaction);
456 if(it.second->IsStatusChanged())
return true;
463 for(
auto& it : fEquilibriumProcesses)
471 auto reaction = fEquilibriumProcesses.find(reactionType);
472 if(reaction == fEquilibriumProcesses.end())
477 return (reaction->second->GetEquilibriumStatus());
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
G4double GetNumberMoleculePerVolumeUnitForMaterialConf(MolType) const
MaterialMap::iterator end()
G4bool IsEquilibrium(const G4int &reactionType) const
int64_t SearchUpperBoundTime(G4double time, G4bool sameTypeOfMolecule)
G4bool SetEquilibrium(const G4DNAMolecularReactionData *pReaction, G4double time)
std::map< G4double, int64_t, G4::MoleculeCounter::FixedTimeComparer > NbMoleculeInTime
void ReduceNumberMoleculePerVolumeUnitForMaterialConf(MolType, G4double)
void SetpH(const G4int &ph)
void AddAMoleculeAtTime(MolType, G4double time, const G4ThreeVector *position=nullptr, G4int number=1)
G4bool find(MolType type)
int64_t GetNMoleculesAtTime(MolType molecule, G4double time)
void AddNumberMoleculePerVolumeUnitForMaterialConf(MolType, G4double)
G4DNAScavengerMaterial()=default
G4bool SearchTimeMap(MolType molecule)
void RemoveAMoleculeAtTime(MolType, G4double time, const G4ThreeVector *position=nullptr, G4int number=1)
const G4MolecularConfiguration * MolType
const G4String & GetName() const
static G4Scheduler * Instance()
G4DNABoundingBox * GetChemistryBoundary() const
static G4ThreadLocal G4double fPrecision