46 : fpChemistryInfo(pChemistryInfo), fIsInitialized(false), fCounterAgainstTime(false), fVerbose(0)
59 if (fpChemistryInfo->
size() == 0) {
60 G4cout <<
"G4DNAScavengerMaterial existed but empty" <<
G4endl;
63 fIsInitialized =
true;
70 if (fH2O == matConf) {
72 exceptionDescription <<
"matConf : " << matConf->
GetName();
73 G4Exception(
"G4DNAScavengerMaterial::GetNumberMoleculePerVolumeUnitForMaterialConf",
77 auto iter = fScavengerTable.find(matConf);
78 if (iter == fScavengerTable.end()) {
82 if (iter->second >= 1) {
83 return (floor)(iter->second);
93 if (fH2O == matConf || fH3Op == matConf ||
104 fScavengerTable[matConf]--;
105 if (fScavengerTable[matConf] < 0)
110 if (fCounterAgainstTime) {
120 if (fH2O == matConf || fH3Op == matConf ||
128 auto it = fScavengerTable.find(matConf);
129 if (it == fScavengerTable.end())
133 fScavengerTable[matConf]++;
135 if (fCounterAgainstTime) {
143 auto iter = fpChemistryInfo->
begin();
144 G4cout <<
"**************************************************************" <<
G4endl;
145 for (; iter != fpChemistryInfo->
end(); iter++) {
146 auto containedConf = iter->first;
148 auto concentration = fScavengerTable[containedConf] / (Avogadro * pConfinedBox->Volume());
149 G4cout <<
"Scavenger:" << containedConf->GetName() <<
" : "
150 << concentration / 1.0e-6 <<
" (M) with : "
151 << fScavengerTable[containedConf] <<
" (molecules)"
152 <<
"in: " << pConfinedBox->Volume() / (um * um * um) <<
" (um3)" <<
G4endl;
153 if (fScavengerTable[containedConf] < 1) {
154 G4cout <<
"!!!!!!!!!!!!! this molecule has less one molecule for "
163 G4cout <<
"**************************************************************" <<
G4endl;
168 if (fpChemistryInfo ==
nullptr) {
172 if (fpChemistryInfo->
size() == 0) {
176 fScavengerTable.clear();
178 fpLastSearch.reset(
nullptr);
181 auto iter = fpChemistryInfo->
begin();
182 for (; iter != fpChemistryInfo->
end(); iter++) {
183 auto containedConf = iter->first;
184 auto concentration = iter->second;
185 fScavengerTable[containedConf] = floor(Avogadro * concentration * pConfinedBox->Volume());
186 fCounterMap[containedConf][1 * picosecond] =
187 floor(Avogadro * concentration * pConfinedBox->Volume());
200 G4cout <<
"G4DNAScavengerMaterial::AddAMoleculeAtTime : " << molecule->
GetName()
204 auto counterMap_i = fCounterMap.find(molecule);
206 if (counterMap_i == fCounterMap.end()) {
207 fCounterMap[molecule][time] = number;
209 else if (counterMap_i->second.empty()) {
210 counterMap_i->second[time] = number;
213 auto end = counterMap_i->second.rbegin();
215 if (
end->first <= time
218 counterMap_i->second[time] = newValue;
219 if (newValue != (floor)(fScavengerTable[molecule]))
221 G4String errMsg =
"You are trying to add wrong molecule ";
236 auto it_ = nbMolPerTime.rbegin();
237 G4cout <<
"G4DNAScavengerMaterial::RemoveAMoleculeAtTime : " << pMolecule->
GetName()
240 <<
" form : " << it_->second <<
G4endl;
243 if (nbMolPerTime.empty()) {
245 G4String errMsg =
"You are trying to remove molecule " +
247 " from the counter while this kind of molecules has not "
248 "been registered yet";
254 auto it = nbMolPerTime.rbegin();
256 if (it == nbMolPerTime.rend()) {
260 +
" recorded at the time or even before the time asked";
264 G4double finalN = it->second - number;
268 G4cout <<
"fScavengerTable : " << pMolecule->
GetName() <<
" : " << (fScavengerTable[pMolecule])
272 errMsg <<
"After removal of " << number <<
" species of "
273 <<
" " << it->second <<
" " << pMolecule->
GetName() <<
" the final number at time "
274 <<
G4BestUnit(time,
"Time") <<
" is less than zero and so not valid." <<
G4endl;
276 <<
". Previous selected time is " <<
G4BestUnit(it->first,
"Time") <<
G4endl;
279 nbMolPerTime[time] = finalN;
281 if (finalN != (floor)(fScavengerTable[pMolecule]))
290 auto V = pConfinedBox->
Volume();
291 for (
const auto& it : fCounterMap) {
292 auto pReactant = it.first;
294 G4cout <<
" --- > For " << pReactant->GetName() <<
G4endl;
296 for (
const auto& it2 : it.second) {
298 << it2.second / (Avogadro * V * 1.0e-6 ) <<
G4endl;
305 if (!fCounterAgainstTime) {
314 errMsg <<
"N molecules not valid < 0 : " << molecule->
GetName() <<
" N : " << output <<
G4endl;
322 if (fpLastSearch ==
nullptr) {
323 fpLastSearch = std::make_unique<Search>();
326 if (fpLastSearch->fLowerBoundSet && fpLastSearch->fLastMoleculeSearched->first == molecule) {
331 auto mol_it = fCounterMap.find(molecule);
332 fpLastSearch->fLastMoleculeSearched = mol_it;
334 if (mol_it != fCounterMap.end()) {
335 fpLastSearch->fLowerBoundTime = fpLastSearch->fLastMoleculeSearched->second.end();
336 fpLastSearch->fLowerBoundSet =
true;
339 fpLastSearch->fLowerBoundSet =
false;
349 auto mol_it = fpLastSearch->fLastMoleculeSearched;
350 if (mol_it == fCounterMap.end()) {
355 if (timeMap.empty()) {
359 if (sameTypeOfMolecule) {
360 if (fpLastSearch->fLowerBoundSet && fpLastSearch->fLowerBoundTime != timeMap.end()) {
361 if (fpLastSearch->fLowerBoundTime->first < time) {
362 auto upperToLast = fpLastSearch->fLowerBoundTime;
365 if (upperToLast == timeMap.end()) {
366 return fpLastSearch->fLowerBoundTime->second;
369 if (upperToLast->first > time) {
370 return fpLastSearch->fLowerBoundTime->second;
376 auto up_time_it = timeMap.upper_bound(time);
378 if (up_time_it == timeMap.end()) {
379 auto last_time = timeMap.rbegin();
380 return last_time->second;
382 if (up_time_it == timeMap.begin()) {
388 fpLastSearch->fLowerBoundTime = up_time_it;
389 fpLastSearch->fLowerBoundSet =
true;
391 return fpLastSearch->fLowerBoundTime->second;
394void G4DNAScavengerMaterial::WaterEquilibrium()
398 fScavengerTable[fHOm] = (kw / ((
G4double)fScavengerTable[fH3Op] / convertFactor)) * convertFactor;
406 fScavengerTable[fH3Op] = floor(Avogadro * std::pow(10, -ph) * volume / liter);
407 fScavengerTable[fHOm] = floor(Avogadro * std::pow(10, -(14 - ph)) * volume / liter);
413 G4double Cion = (
G4double)fScavengerTable[fH3Op] / (Avogadro * volumeInLiter);
417 if (fScavengerTable[fH3Op] < 0)
421 fScavengerTable[fH3Op] = 0;
423 if (fScavengerTable[fHOm] < 0)
427 fScavengerTable[fHOm] = 0;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
G4double GetNumberMoleculePerVolumeUnitForMaterialConf(MolType) const
MaterialMap::iterator end()
int64_t SearchUpperBoundTime(G4double time, G4bool sameTypeOfMolecule)
void ReduceNumberMoleculePerVolumeUnitForMaterialConf(MolType, G4double)
std::map< G4double, int64_t, G4::MoleculeCounter::TimePrecision > NbMoleculeInTime
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 G4String & GetName() const
static G4MoleculeTable * Instance()
static G4Scheduler * Instance()
std::map< MolType, double >::iterator begin()
G4DNABoundingBox * GetChemistryBoundary() const
std::map< MolType, double >::iterator end()
static G4ThreadLocal double fPrecision