47 , fpChemistryInfo(pChemistryInfo)
48 , fIsInitialized(false)
49 , fCounterAgainstTime(false)
64 if(fpChemistryInfo->
size() == 0)
66 G4cout <<
"G4DNAScavengerMaterial existed but empty" <<
G4endl;
69 fIsInitialized =
true;
79 exceptionDescription <<
"matConf : "<<matConf->
GetName();
80 G4Exception(
"G4DNAScavengerMaterial::GetNumberMoleculePerVolumeUnitForMaterialConf",
"G4DNAScavengerMaterial001",
84 auto iter = fScavengerTable.find(matConf);
85 if(iter == fScavengerTable.end())
93 return (floor)(iter->second);
119 fScavengerTable[matConf]--;
120 if(fScavengerTable[matConf] < 0)
125 if(fCounterAgainstTime)
146 auto it = fScavengerTable.find(matConf);
147 if(it == fScavengerTable.end())
151 fScavengerTable[matConf]++;
153 if(fCounterAgainstTime)
162 auto iter = fpChemistryInfo->
begin();
163 G4cout <<
"**************************************************************"
165 for(; iter != fpChemistryInfo->
end(); iter++)
167 auto containedConf = iter->first;
170 fScavengerTable[containedConf] / (Avogadro * pConfinedBox->Volume());
171 G4cout <<
"Scavenger:" << containedConf->GetName() <<
" : "
172 << concentration / 1.0e-6 <<
" (M) with : "
173 << fScavengerTable[containedConf] <<
" (molecules)"
174 <<
"in: " << pConfinedBox->Volume() / (um * um * um) <<
" (um3)"
176 if(fScavengerTable[containedConf] < 1)
178 G4cout <<
"!!!!!!!!!!!!! this molecule has less one molecule for "
188 G4cout <<
"**************************************************************"
194 if(fpChemistryInfo ==
nullptr)
199 if(fpChemistryInfo->
size() == 0)
204 fScavengerTable.clear();
206 fpLastSearch.reset(
nullptr);
209 auto iter = fpChemistryInfo->
begin();
210 for(; iter != fpChemistryInfo->
end(); iter++)
212 auto containedConf = iter->first;
213 auto concentration = iter->second;
214 fScavengerTable[containedConf] =
215 floor(Avogadro * concentration * pConfinedBox->Volume());
216 fCounterMap[containedConf][1 * picosecond] =
217 floor(Avogadro * concentration * pConfinedBox->Volume());
230 G4cout <<
"G4DNAScavengerMaterial::AddAMoleculeAtTime : "
235 auto counterMap_i = fCounterMap.find(molecule);
237 if(counterMap_i == fCounterMap.end())
239 fCounterMap[molecule][time] = number;
241 else if(counterMap_i->second.empty())
243 counterMap_i->second[time] = number;
247 auto end = counterMap_i->second.rbegin();
249 if(
end->first <= time || fabs(
end->first - time) <=
253 counterMap_i->second[time] = newValue;
254 if(newValue != (floor)(fScavengerTable[molecule]))
256 G4String errMsg =
"You are trying to add wrong molecule ";
275 auto it_ = nbMolPerTime.rbegin();
276 G4cout <<
"G4DNAScavengerMaterial::RemoveAMoleculeAtTime : "
279 <<
" form : " << it_->second <<
G4endl;
282 if(nbMolPerTime.empty())
285 G4String errMsg =
"You are trying to remove molecule " +
287 " from the counter while this kind of molecules has not "
288 "been registered yet";
289 G4Exception(
"G4DNAScavengerMaterial::RemoveAMoleculeAtTime",
"",
296 auto it = nbMolPerTime.rbegin();
298 if(it == nbMolPerTime.rend())
303 " recorded at the time or even before the time asked";
304 G4Exception(
"G4DNAScavengerMaterial::RemoveAMoleculeAtTime",
"",
308 G4double finalN = it->second - number;
313 G4cout <<
"fScavengerTable : " << pMolecule->
GetName() <<
" : "
314 << (fScavengerTable[pMolecule]) <<
G4endl;
317 errMsg <<
"After removal of " << number <<
" species of "
318 <<
" " << it->second <<
" " << pMolecule->
GetName()
319 <<
" the final number at time " <<
G4BestUnit(time,
"Time")
320 <<
" is less than zero and so not valid." <<
G4endl;
321 G4cout <<
" Global time is "
323 <<
". Previous selected time is " <<
G4BestUnit(it->first,
"Time")
325 G4Exception(
"G4DNAScavengerMaterial::RemoveAMoleculeAtTime",
"N_INF_0",
328 nbMolPerTime[time] = finalN;
330 if(finalN != (floor)(fScavengerTable[pMolecule]))
340 auto V = pConfinedBox->
Volume();
341 for(
const auto& it : fCounterMap)
343 auto pReactant = it.first;
345 G4cout <<
" --- > For " << pReactant->GetName() <<
G4endl;
347 for(
const auto& it2 : it.second)
350 << it2.second / (Avogadro * V * 1.0e-6 ) <<
G4endl;
357 if(!fCounterAgainstTime)
368 errMsg <<
"N molecules not valid < 0 : "<<
370 G4Exception(
"G4DNAScavengerMaterial::GetNMoleculesAtTime",
"",
378 if(fpLastSearch ==
nullptr)
380 fpLastSearch = std::make_unique<Search>();
384 if(fpLastSearch->fLowerBoundSet &&
385 fpLastSearch->fLastMoleculeSearched->first == molecule)
391 auto mol_it = fCounterMap.find(molecule);
392 fpLastSearch->fLastMoleculeSearched = mol_it;
394 if(mol_it != fCounterMap.end())
396 fpLastSearch->fLowerBoundTime =
397 fpLastSearch->fLastMoleculeSearched->second.end();
398 fpLastSearch->fLowerBoundSet =
true;
402 fpLastSearch->fLowerBoundSet =
false;
411 G4bool sameTypeOfMolecule)
413 auto mol_it = fpLastSearch->fLastMoleculeSearched;
414 if(mol_it == fCounterMap.end())
425 if(sameTypeOfMolecule)
427 if(fpLastSearch->fLowerBoundSet &&
428 fpLastSearch->fLowerBoundTime != timeMap.end())
430 if(fpLastSearch->fLowerBoundTime->first < time)
432 auto upperToLast = fpLastSearch->fLowerBoundTime;
435 if(upperToLast == timeMap.end())
437 return fpLastSearch->fLowerBoundTime->second;
440 if(upperToLast->first > time)
442 return fpLastSearch->fLowerBoundTime->second;
448 auto up_time_it = timeMap.upper_bound(time);
450 if(up_time_it == timeMap.end())
452 auto last_time = timeMap.rbegin();
453 return last_time->second;
455 if(up_time_it == timeMap.begin())
462 fpLastSearch->fLowerBoundTime = up_time_it;
463 fpLastSearch->fLowerBoundSet =
true;
465 return fpLastSearch->fLowerBoundTime->second;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
std::map< G4double, int64_t, G4::MoleculeCounter::TimePrecision > NbMoleculeInTime
G4double GetNumberMoleculePerVolumeUnitForMaterialConf(MolType) const
MaterialMap::iterator end()
int64_t SearchUpperBoundTime(G4double time, G4bool sameTypeOfMolecule)
void ReduceNumberMoleculePerVolumeUnitForMaterialConf(MolType, G4double)
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