Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VUserMoleculeCounter< TIndex > Class Template Referenceabstract

#include <G4VUserMoleculeCounter.hh>

Inheritance diagram for G4VUserMoleculeCounter< TIndex >:

Classes

Public Member Functions

 G4VUserMoleculeCounter ()
 G4VUserMoleculeCounter (G4String, MoleculeCounterType=MoleculeCounterType::Other)
 ~G4VUserMoleculeCounter () override=default
void Initialize () final
void InitializeUser () override=0
void ResetCounter () override
void Dump () const override
void DumpCounterMapIndices () const override
void AbsorbCounter (const G4VMoleculeCounterInternalBase *) override
std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndexBuildIndex (const G4Track *) const override=0
std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndexBuildIndex (const G4Track *, const G4StepPoint *) const override=0
std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndexBuildSimpleIndex (const G4MolecularConfiguration *) const override=0
void AddMolecule (std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndex >, G4double, G4int=1) override
void RemoveMolecule (std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndex >, G4double, G4int=1) override
std::set< const G4MolecularConfiguration * > GetRecordedMolecules () const override
std::set< G4doubleGetRecordedTimes () const override
void SchedulerFinalizedTracking () override
const std::map< TIndex, InnerCounterMapType > & GetCounterMap () const
std::vector< TIndex > GetMapIndices () const
virtual G4int GetNbMoleculesAtTime (const TIndex &, G4double) const
virtual G4int GetNbMoleculesAtTime (Search &, const TIndex &, G4double) const
virtual std::vector< G4intGetNbMoleculesAtTimes (const TIndex &, const std::vector< G4double > &) const
Public Member Functions inherited from G4VMoleculeCounter
 ~G4VMoleculeCounter () override=default
virtual void AddMolecule (std::unique_ptr< G4VMoleculeCounterIndex >, G4double, G4int=1)=0
virtual void RemoveMolecule (std::unique_ptr< G4VMoleculeCounterIndex >, G4double, G4int=1)=0
MoleculeCounterType GetType () const
G4bool GetSensitiveToStepping () const
void SetSensitiveToStepping (G4bool=true)
G4bool GetNegativeCountsAreFatal () const
void IgnoreMolecule (const G4MoleculeDefinition *)
void IgnoreReactant (const G4MolecularConfiguration *)
void RegisterAll ()
G4bool IsReactantIgnored (const G4MoleculeDefinition *) const
G4bool IsReactantIgnored (const G4MolecularConfiguration *) const
Public Member Functions inherited from G4VMoleculeCounterInternalBase
virtual ~G4VMoleculeCounterInternalBase ()=default
G4int GetId () const
void SetManagedId (G4int)
G4int GetManagedId () const
const G4StringGetName () const
G4int GetVerbose () const
void SetVerbose (G4int)
G4double GetActiveLowerBound () const
void SetActiveLowerBound (G4double, G4bool=true)
G4double GetActiveUpperBound () const
void SetActiveUpperBound (G4double, G4bool=true)
G4bool GetActiveLowerBoundInclusive () const
G4bool GetActiveUpperBoundInclusive () const
G4bool IsTimeBelowLowerBound (G4double) const
G4bool IsTimeAboveUpperBound (G4double) const
G4bool IsActiveAtGlobalTime (G4double) const
G4bool GetCheckTimeConsistencyWithScheduler () const
void SetCheckTimeConsistencyWithScheduler (G4bool=true)
G4bool GetCheckRecordedTimeConsistency () const
void SetCheckRecordedTimeConsistency (G4bool=true)
const G4MoleculeCounterTimeComparerGetTimeComparer () const
void SetTimeComparer (const G4MoleculeCounterTimeComparer &)

Protected Member Functions

G4bool SearchIndexUpdated (Search &, const TIndex &) const
G4int SearchUpperBoundTime (Search &, G4double, G4bool) const
Protected Member Functions inherited from G4VMoleculeCounter
void SetNegativeCountsAreFatal (G4bool)

Protected Attributes

std::map< TIndex, InnerCounterMapTypefCounterMap {}
std::map< TIndex, G4intfShadowCounterMap {}
Protected Attributes inherited from G4VMoleculeCounter
MoleculeCounterType fType {MoleculeCounterType::Other}
G4bool fSensitiveToStepping {false}
G4bool fNegativeCountsAreFatal {true}
std::set< const G4MoleculeDefinition * > fIgnoredMolecules {}
std::set< const G4MolecularConfiguration * > fIgnoredReactants {}
Protected Attributes inherited from G4VMoleculeCounterInternalBase
G4bool fIsInitialized {false}
G4int fId
G4int fManagedId {-1}
G4String fName {}
G4int fVerbose {0}
G4double fActiveLowerBound {0}
G4double fActiveUpperBound {std::numeric_limits<G4double>::max()}
G4bool fActiveLowerBoundInclusive {true}
G4bool fActiveUpperBoundInclusive {true}
G4bool fCheckTimeIsConsistentWithScheduler {true}
G4bool fCheckRecordedTimesAreConsistent {true}
G4MoleculeCounterTimeComparer fTimeComparer {}

Additional Inherited Members

Public Types inherited from G4VMoleculeCounter
enum  MoleculeCounterType { Other , Basic , Mesoscopic }
Static Public Member Functions inherited from G4VMoleculeCounterInternalBase
static void SetFixedTimePrecision (G4double)

Detailed Description

template<class TIndex>
class G4VUserMoleculeCounter< TIndex >

Definition at line 41 of file G4VUserMoleculeCounter.hh.

Constructor & Destructor Documentation

◆ G4VUserMoleculeCounter() [1/2]

template<typename T>
G4VUserMoleculeCounter< T >::G4VUserMoleculeCounter ( )

Definition at line 108 of file G4VUserMoleculeCounter.hh.

Referenced by AbsorbCounter().

◆ G4VUserMoleculeCounter() [2/2]

template<typename T>
G4VUserMoleculeCounter< T >::G4VUserMoleculeCounter ( G4String name,
MoleculeCounterType type = MoleculeCounterType::Other )

◆ ~G4VUserMoleculeCounter()

template<class TIndex>
G4VUserMoleculeCounter< TIndex >::~G4VUserMoleculeCounter ( )
overridedefault

Member Function Documentation

◆ AbsorbCounter()

template<typename TIndex>
void G4VUserMoleculeCounter< TIndex >::AbsorbCounter ( const G4VMoleculeCounterInternalBase * pCounterBase)
overridevirtual

Implements G4VMoleculeCounterInternalBase.

Definition at line 707 of file G4VUserMoleculeCounter.hh.

708{
709 if (pCounterBase == nullptr) {
711 errMsg << "Could not cast the pointer to type G4VUserMoleculeCounter<"
713 << "Because the pointer is nullptr!" << G4endl;
714 G4Exception(G4String("G4VUserMoleculeCounter<"
715 + G4::MoleculeCounter::GetTemplateTypeName<TIndex>() + ">::AbsorbCounter"),
716 "BAD_REFERENCE", FatalException, errMsg);
717 }
718
720
721 if (pCounter == nullptr) {
723 errMsg << "Could not cast the pointer to type G4VUserMoleculeCounter<"
725 << "Because the objects aren't of the same type!" << G4endl;
726 G4Exception(G4String("G4VUserMoleculeCounter<"
727 + G4::MoleculeCounter::GetTemplateTypeName<TIndex>() + ">::AbsorbCounter"),
728 "BAD_REFERENCE", FatalException, errMsg);
729 }
730
731 if (pCounter->GetType() != GetType()) {
733 errMsg << "You are trying to absorb a counter with different type!" << G4endl;
734 G4Exception(G4String("G4VUserMoleculeCounter<"
735 + G4::MoleculeCounter::GetTemplateTypeName<TIndex>() + ">::AbsorbCounter"),
736 "TYPE_DIFF", JustWarning, errMsg);
737 }
738
739 for (auto const& worker_it : pCounter->GetCounterMap()) {
740 auto [master_it, indexIsNew] =
741 fCounterMap.emplace(worker_it.first, InnerCounterMapType{fTimeComparer});
742
744 for (auto const& [time, number] : worker_it.second) {
747
748 if (master_it->second.empty()) {
749 master_it->second.emplace(time, currentNumber);
750 }
751 else { // at least one element exists, so we can try to find the closest key
753 auto [it, _] = master_it->second.emplace(time, it_closest->second);
754 do {
755 it->second += currentNumber;
756 } while (++it != master_it->second.end());
757 }
758 }
759 }
760}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
MoleculeCounterType GetType() const
std::map< TIndex, InnerCounterMapType > fCounterMap
const std::map< TIndex, InnerCounterMapType > & GetCounterMap() const
std::map< TKey, TValue, TComp >::iterator FindClosestEntryForKey(std::map< TKey, TValue, TComp > &map, TKey key)

◆ AddMolecule()

template<typename TIndex>
void G4VUserMoleculeCounter< TIndex >::AddMolecule ( std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndex > pIndex,
G4double time,
G4int number = 1 )
override

Definition at line 163 of file G4VUserMoleculeCounter.hh.

165{
166 const TIndex* mapIndex = dynamic_cast<TIndex*>(pIndex.get());
167
168 if(mapIndex == nullptr)
169 {
171 errMsg << "mapIndex is not found "<< G4endl;
172 G4Exception(G4String("G4VUserMoleculeCounter<"
174 "mapIndex == nullptr", FatalException, errMsg);
175 }else{
176 if (G4::MoleculeCounter::Contains(fIgnoredMolecules, mapIndex->GetMolecule()->GetDefinition())
178 {
179 return;
180 }
181
185 {
187 errMsg << "Time of species " << mapIndex->GetMolecule()->GetName() << " is "
188 << G4BestUnit(time, "Time") << "while the global time is "
190 G4Exception(G4String("G4VUserMoleculeCounter<"
192 "TIME_DONT_MATCH", FatalException, errMsg);
193 }
194
196 if (fVerbose > 3) {
197 G4cout << "G4VUserMoleculeCounter<" << G4::MoleculeCounter::GetTemplateTypeName<TIndex>()
198 << ">(" << GetName() << ")::AddMolecule : " << mapIndex->GetMolecule()->GetName()
199 << " at time : " << G4BestUnit(time, "Time") << G4endl;
200 G4cout << ":: [IsTimeAboveUpperBound] Skipping since IsTimeAboveUpperBound == true"
201 << G4endl;
202 }
203 return;
204 }
205 else if (IsTimeBelowLowerBound(time)) {
206 // put into shadow counter
207 auto [it, indexIsNew] = fShadowCounterMap.emplace(*mapIndex, number);
208 if (!indexIsNew) it->second += number;
209 if (fVerbose > 3) {
210 G4cout << ":: [IsTimeBelowLowerBound] Adding " << mapIndex->GetInfo()
211 << " shadow count: " << it->second - number << " + " << number << G4endl;
212 }
213 return;
214 }
215
216 if (fVerbose > 1) {
217 G4cout << "G4VUserMoleculeCounter<" << G4::MoleculeCounter::GetTemplateTypeName<TIndex>()
218 << ">(" << GetName() << ")::AddMolecule : " << mapIndex->GetMolecule()->GetName()
219 << " at time : " << G4BestUnit(time, "Time") << G4endl;
220 }
221
222 // within time bounds && not-ignored molecule
223 // -> continue
224
227
228 if (it_shadow != fShadowCounterMap.end()) {
229 // entry found in shadow counter
230 if (indexIsNew) {
231 // mapIndex is new, initialize with shadow counter
232 it->second[fActiveLowerBound] = it_shadow->second;
233 }
234 else {
235 // mapIndex existed, we need to add the shadow count to it
236 // this happens if we are in a subsequent event and have just crossed over the lower
237 // activity bound the counter has then already entries from the previous event
240 std::tie(it_time, timeIsNew) = it->second.emplace(fActiveLowerBound, 0);
241 do {
242 it_time->second += it_shadow->second;
243 } while (++it_time != it->second.end());
244 }
245 // either way, remove the shadow count
247 }
248
249 // map for index existed (and was not empty)
251 // can only do consistency check if the counters are cleared for each event (= chem run)
252 {
253 auto end = it->second.rbegin();
254 auto init_n = end == it->second.rend() ? 0 : end->second;
255
256 auto [it_time, timeIsNew] = it->second.emplace(time, init_n);
257 it_time->second += number;
258
260 && !(end->first <= time
261 || std::fabs(end->first - time) <= fTimeComparer.GetPrecisionAtTime(time)))
262 // Case 1 = new time comes after last recorded data
263 // Case 2 = new time is about the same as the last recorded one
264 {
266 errMsg << "Time of species " << mapIndex->GetMolecule()->GetName() << " is "
267 << G4BestUnit(time, "Time") << "while the global time is "
269 << "(last counter time: " << G4BestUnit(end->first, "Time") << ")" << G4endl;
270 G4Exception(G4String("G4VUserMoleculeCounter<"
272 + ">::AddMolecule"),
273 "TIME_DONT_MATCH", FatalException, errMsg);
274 }
275 }
276 else // counters are not (automatically) reset by manager
277 {
278 // since counters are not cleared after chemical run (i.e., after event)
279 // there will already be numbers in the map, so...
280 // (1) find the closest time
281 // (2) emplace entry using closest value as init + number
282 // (3) add number to all "future" entries as well
283 if (it->second.empty()) {
284 it->second.emplace(time, number);
285 }
286 else { // at least one element exists, so we can try to find the closest key
288 auto [it_time, _] = it->second.emplace(time, it_closest->second);
289 do {
290 it_time->second += number;
291 } while (++it_time != it->second.end());
292 }
293 }
294 }
295}
#define G4BestUnit(a, b)
std::set< const G4MoleculeDefinition * > fIgnoredMolecules
std::set< const G4MolecularConfiguration * > fIgnoredReactants
std::map< TIndex, G4int > fShadowCounterMap

◆ BuildIndex() [1/2]

template<class TIndex>
std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndex > G4VUserMoleculeCounter< TIndex >::BuildIndex ( const G4Track * ) const
overridepure virtual

Implements G4VMoleculeCounter.

Implemented in G4MoleculeCounter.

Referenced by BuildIndex(), and BuildIndex().

◆ BuildIndex() [2/2]

template<class TIndex>
std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndex > G4VUserMoleculeCounter< TIndex >::BuildIndex ( const G4Track * ,
const G4StepPoint *  ) const
overridepure virtual

Implements G4VMoleculeCounter.

◆ BuildSimpleIndex()

template<class TIndex>
std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndex > G4VUserMoleculeCounter< TIndex >::BuildSimpleIndex ( const G4MolecularConfiguration * ) const
overridepure virtual

Implements G4VMoleculeCounter.

Implemented in G4MoleculeCounter.

Referenced by BuildSimpleIndex().

◆ Dump()

template<typename T>
void G4VUserMoleculeCounter< T >::Dump ( ) const
overridevirtual

Implements G4VMoleculeCounterInternalBase.

Definition at line 604 of file G4VUserMoleculeCounter.hh.

605{
608}
void DumpCounterMapIndices() const override
void DumpCounterMapContents(const std::map< T, InnerCounterMapType > &map, G4bool includeEmpty=false)

Referenced by RemoveMolecule().

◆ DumpCounterMapIndices()

template<typename T>
void G4VUserMoleculeCounter< T >::DumpCounterMapIndices ( ) const
overridevirtual

Implements G4VMoleculeCounterInternalBase.

Definition at line 611 of file G4VUserMoleculeCounter.hh.

612{
614}
void DumpCounterMapIndices(const std::map< T, InnerCounterMapType > &map, G4bool includeEmpty=false)

Referenced by Dump().

◆ GetCounterMap()

template<class TIndex>
const std::map< TIndex, InnerCounterMapType > & G4VUserMoleculeCounter< TIndex >::GetCounterMap ( ) const
inline

Definition at line 81 of file G4VUserMoleculeCounter.hh.

81{ return fCounterMap; }

◆ GetMapIndices()

template<typename TIndex>
std::vector< TIndex > G4VUserMoleculeCounter< TIndex >::GetMapIndices ( ) const

Definition at line 570 of file G4VUserMoleculeCounter.hh.

571{
572 if (fVerbose > 2) {
573 G4cout << "Entering in G4VUserMoleculeCounter::GetMapIndices" << G4endl;
574 }
576}
const std::vector< T > GetMapIndices(const std::map< T, U > &_map)

◆ GetNbMoleculesAtTime() [1/2]

template<typename TIndex>
G4int G4VUserMoleculeCounter< TIndex >::GetNbMoleculesAtTime ( const TIndex & index,
G4double time ) const
virtual

Definition at line 130 of file G4VUserMoleculeCounter.hh.

131{
132 Search search = {};
134}
virtual G4int GetNbMoleculesAtTime(const TIndex &, G4double) const

Referenced by GetNbMoleculesAtTime(), and GetNbMoleculesAtTimes().

◆ GetNbMoleculesAtTime() [2/2]

template<typename TIndex>
G4int G4VUserMoleculeCounter< TIndex >::GetNbMoleculesAtTime ( Search & search,
const TIndex & index,
G4double time ) const
virtual

Definition at line 139 of file G4VUserMoleculeCounter.hh.

141{
144}
G4int SearchUpperBoundTime(Search &, G4double, G4bool) const
G4bool SearchIndexUpdated(Search &, const TIndex &) const

◆ GetNbMoleculesAtTimes()

template<typename TIndex>
std::vector< G4int > G4VUserMoleculeCounter< TIndex >::GetNbMoleculesAtTimes ( const TIndex & index,
const std::vector< G4double > & times ) const
virtual

Definition at line 150 of file G4VUserMoleculeCounter.hh.

152{
153 Search search = {};
155 for (auto time : times)
157 return counts;
158}

◆ GetRecordedMolecules()

template<typename T>
std::set< const G4MolecularConfiguration * > G4VUserMoleculeCounter< T >::GetRecordedMolecules ( ) const
overridevirtual

Implements G4VMoleculeCounter.

Definition at line 581 of file G4VUserMoleculeCounter.hh.

582{
583 if (fVerbose > 2) {
584 G4cout << "Entering in G4MoleculeCounter::RecordMolecules" << G4endl;
585 }
587 for (const auto& it : fCounterMap) {
588 output.insert(it.first.GetMolecule());
589 }
590 return output;
591}

◆ GetRecordedTimes()

template<typename T>
std::set< G4double > G4VUserMoleculeCounter< T >::GetRecordedTimes ( ) const
overridevirtual

Implements G4VMoleculeCounter.

Definition at line 596 of file G4VUserMoleculeCounter.hh.

597{
599}
std::set< G4double > GetRecordedTimes(const std::map< T, InnerCounterMapType > &map)

◆ Initialize()

template<typename TIndex>
void G4VUserMoleculeCounter< TIndex >::Initialize ( )
finalvirtual

Implements G4VMoleculeCounterInternalBase.

Definition at line 121 of file G4VUserMoleculeCounter.hh.

◆ InitializeUser()

template<class TIndex>
void G4VUserMoleculeCounter< TIndex >::InitializeUser ( )
overridepure virtual

Implements G4VMoleculeCounterInternalBase.

Implemented in G4MoleculeCounter.

Referenced by Initialize(), and InitializeUser().

◆ RemoveMolecule()

template<typename TIndex>
void G4VUserMoleculeCounter< TIndex >::RemoveMolecule ( std::unique_ptr< G4VMoleculeCounter::G4VMoleculeCounterIndex > pIndex,
G4double time,
G4int number = 1 )
override

Definition at line 300 of file G4VUserMoleculeCounter.hh.

302{
303 const TIndex* mapIndex = dynamic_cast<TIndex*>(pIndex.get());
304
305 if(mapIndex == nullptr)
306 {
308 errMsg << "mapIndex is not found "<< G4endl;
309 G4Exception(G4String("G4VUserMoleculeCounter<"
311 "mapIndex == nullptr", FatalException, errMsg);
312 }else{
313 if (G4::MoleculeCounter::Contains(fIgnoredMolecules, mapIndex->GetMolecule()->GetDefinition())
315 {
316 return;
317 }
318
322 {
324 errMsg << "Time of species " << mapIndex->GetMolecule()->GetName() << " is "
325 << G4BestUnit(time, "Time") << "while the global time is "
327 G4Exception(G4String("G4VUserMoleculeCounter<"
329 + ">::RemoveMolecule"),
330 "TIME_DONT_MATCH", FatalException, errMsg);
331 }
332
334 auto it = fShadowCounterMap.find(*mapIndex);
335 if (it == fShadowCounterMap.end()) {
337 errMsg << "There was no " << mapIndex->GetMolecule()->GetName()
338 << " recorded at the time or even before the time asked" << G4endl;
339 G4Exception(G4String("G4VUserMoleculeCounter<"
341 + ">::RemoveMolecule"),
343 }
344 else {
345 if (fVerbose > 3) {
346 G4cout << ":: [IsTimeBelowLowerBound] Removing " << mapIndex->GetInfo()
347 << " shadow count: " << it->second << " - " << number << G4endl;
348 }
349 it->second -= number;
350 return;
351 }
352 }
353 else if (IsTimeAboveUpperBound(time)) {
354 // if the "active" counter was not filled, add the shadow counter to it at the lower bound
355 // only needed for remove since remove will always be called at the end when the molecule is
356 // destroyed
358 if (indexIsNew || it->second.empty()) {
360 if (it_shadow != fShadowCounterMap.end()) {
361 it->second[fActiveLowerBound] = it_shadow->second;
362 if (fVerbose > 3) {
363 G4cout << ":: [IsTimeAboveUpperBound] Set " << mapIndex->GetInfo()
364 << " Map[ActiveLowerBound] with shadow count:" << it_shadow->second << G4endl;
365 }
367 }
368 else if (fVerbose > 3) {
369 G4cout << ":: [IsTimeAboveUpperBound] Not updating with shadow count since"
370 " no shadow count was found!"
371 << G4endl;
372 }
373 }
374 else if (fVerbose > 3) {
375 G4cout << ":: [IsTimeAboveUpperBound] Not updating with shadow count"
376 " since it already exists "
377 << G4endl;
378 }
379 return;
380 }
381
382 if (fVerbose > 2) {
383 G4cout << "G4VUserMoleculeCounter<" << G4::MoleculeCounter::GetTemplateTypeName<TIndex>()
384 << ">(" << GetName() << ")::RemoveMolecule : " << mapIndex->GetMolecule()->GetName()
385 << " at time : " << G4BestUnit(time, "Time") << G4endl;
386 }
387
388 // within time bounds && not-ignored molecule
389 // -> continue
390
392 auto it = fCounterMap.find(*mapIndex);
393
394 if (it_shadow != fShadowCounterMap.end()) {
395 // entry found in shadow counter
396 if (it == fCounterMap.end()) {
397 // no mapIndex found, initialize with shadow counter
398 G4bool indexIsNew = false;
401 if (!indexIsNew) {
403 errMsg << "We tried to emplace the index after it was found to not exist, but now it "
404 "says it existed!?"
405 << G4endl;
406 G4Exception(G4String("G4VUserMoleculeCounter<"
408 + ">::RemoveMolecule"),
409 "NONSENSICAL", FatalErrorInArgument, errMsg);
410 }
411 it->second[fActiveLowerBound] = it_shadow->second;
412 }
413 else { // it != fCounterMap.end()
414 // mapIndex exists, we need to add the shadow count to it
415 // this happens if we are in a subsequent event and have just crossed over the lower
416 // activity bound the counter has then already entries from the previous event
417 auto [it_time, _] = it->second.emplace(fActiveLowerBound, 0);
418 do {
419 it_time->second += it_shadow->second;
420 } while (++it_time != it->second.end());
421 }
422
423 // either way, remove the shadow count
425
426 // if (it_shadow != fShadowCounterMap.end()) {
427 // G4bool indexIsNew = false;
428 // // auto [it_, indexIsNew] = fCounterMap.emplace(*mapIndex,
429 // // InnerCounterMapType{fTimeComparer});
430 // std::tie(it, indexIsNew) = fCounterMap.emplace(*mapIndex,
431 // InnerCounterMapType{fTimeComparer}); if (!indexIsNew) {
432 // G4ExceptionDescription errMsg;
433 // errMsg << "We tried to emplace the index after it was found to not exist, but now it
434 // "
435 // "says it existed!?"
436 // << G4endl;
437 // G4Exception(G4String("G4VUserMoleculeCounter<"
438 // + G4::MoleculeCounter::GetTemplateTypeName<TIndex>()
439 // + ">::RemoveMolecule"),
440 // "NONSENSICAL", FatalErrorInArgument, errMsg);
441 // }
442 // it->second[fActiveLowerBound] = it_shadow->second;
443 // // it = it_;
444 // if (fVerbose > 3) {
445 // G4cout << ":: Initialize " << mapIndex->GetInfo()
446 // << " Map[ActiveLowerBound] with shadow count:" << it_shadow->second <<
447 // G4endl;
448 // }
449 // fShadowCounterMap.erase(it_shadow);
450 // }
451 }
452
455 G4bool isNewTime = false;
456 G4double oldTime = 0;
457
459 auto end = nbMolPerTime.rbegin(); // get last entry
460 oldTime = end->first;
461
462 // CHECK: no molecules have been recorded for this index
463 if (end == nbMolPerTime.rend()) {
464 if (fVerbose > 2) {
465 mapIndex->GetMolecule()->PrintState();
466 Dump();
467 }
469 errMsg << "There was no " << mapIndex->GetMolecule()->GetName()
470 << " recorded at the time or even before the time asked" << G4endl;
471 G4Exception("G4VUserMoleculeCounter::RemoveMolecule", "", FatalErrorInArgument, errMsg);
472 }
473 // CHECK: current time is less (by more than counter precision) than the most recently
474 // recorded index
476 && time - end->first < -fTimeComparer.GetPrecisionAtTime(time))
477 {
478 if (fVerbose > 2) {
479 mapIndex->GetMolecule()->PrintState();
480 Dump();
481 }
483 errMsg << "Is time going back?? " << mapIndex->GetMolecule()->GetName()
484 << " is being removed at time " << G4BestUnit(time, "Time")
485 << "while last recorded time was " << G4BestUnit(end->first, "Time") << ".";
486 G4Exception("G4VUserMoleculeCounter::RemoveMolecule", "RETURN_TO_THE_FUTUR",
488 }
489 std::tie(it_time, isNewTime) = nbMolPerTime.emplace(time, end->second);
490 // auto oldNumber = it_time->second;
491 it_time->second -= number;
492 // if (time > 0.001)
493 // G4cout << "(t=" << time << ")=" << number << " | old_it(t=" << it_time->first
494 // << ") = " << oldNumber << " | timeIsNew=" << isNewTime
495 // << " | new_it(t=" << it_time->first << ") = " << it_time->second << G4endl;
496 }
497 else {
498 // since counters are not cleared after chemical run (i.e., after event)
499 // there will already be numbers in the map, so...
500 // (1) find the closest time
501 // (2) emplace entry using closest value as init - number
502 // (3) remove number from all "future" entries as well
505 auto _it = it_time;
506 do {
507 _it->second -= number;
508 } while (++_it != it->second.end());
509 }
510
511 // Check that count at new time is >= 0
512 // This currently throws tons of errors for non-basic counters.
513 // auto it_time = nbMolPerTime.find(time);
514 if (it_time == nbMolPerTime.end() || it_time->second < 0) {
515 if (fVerbose > 2) Dump();
517 errMsg << "After removal of " << number << " species of "
518 << mapIndex->GetMolecule()->GetName() << " the final number at time "
519 << G4BestUnit(time, "Time") << " is less than zero and so not valid."
520 << "\nIndex was :" << mapIndex->GetInfo() << "\nGlobal time is "
522 << "\nPrevious selected time is " << G4BestUnit(oldTime, "Time") << G4endl;
524 G4Exception(G4String("G4VUserMoleculeCounter<"
526 + ">::RemoveMolecule"),
527 "N_INF_0", FatalException, errMsg);
528 }
529 else if (fVerbose > 0) {
530 G4Exception(G4String("G4VUserMoleculeCounter<"
532 + ">::RemoveMolecule"),
533 "N_INF_0", JustWarning, errMsg);
534 }
535 }
536 }
537}

◆ ResetCounter()

template<typename T>
void G4VUserMoleculeCounter< T >::ResetCounter ( )
overridevirtual

Implements G4VMoleculeCounterInternalBase.

Definition at line 619 of file G4VUserMoleculeCounter.hh.

620{
621 if (fVerbose > 1) {
622 G4cout << "G4VUserMoleculeCounter<" << G4::MoleculeCounter::GetTemplateTypeName<T>() << ">("
623 << GetName() << ")::ResetCounter" << G4endl;
624 }
625 fCounterMap.clear();
626}

◆ SchedulerFinalizedTracking()

template<typename TIndex>
void G4VUserMoleculeCounter< TIndex >::SchedulerFinalizedTracking ( )
overridevirtual

Implements G4VMoleculeCounter.

Definition at line 542 of file G4VUserMoleculeCounter.hh.

543{
544 // Add record to fCounterMap for each fShadowCounterMap index unless they exist already
545 for (auto& it_shadow : fShadowCounterMap) {
546 auto [it, indexIsNew] =
547 fCounterMap.emplace(it_shadow.first, InnerCounterMapType{fTimeComparer});
548 if (indexIsNew || it->second.empty()) {
549 it->second[fActiveLowerBound] = it_shadow.second;
550 if (fVerbose > 3) {
551 G4cout << "G4VUserMoleculeCounter<" << G4::MoleculeCounter::GetTemplateTypeName<TIndex>()
552 << ">(" << GetName() << ")::SchedulerEndedTracking : " << "setting map index '"
553 << it_shadow.first.GetInfo() << "' from shadow counter to n = " << it_shadow.second
554 << G4endl;
555 }
556 }
557 else if (fVerbose > 2) {
558 G4cout << "G4VUserMoleculeCounter<" << G4::MoleculeCounter::GetTemplateTypeName<TIndex>()
559 << ">(" << GetName() << ")::SchedulerEndedTracking : "
560 << "encountered dangling shadow counter iterator for index '"
561 << it_shadow.first.GetInfo() << "'" << G4endl;
562 }
563 }
564 fShadowCounterMap.clear();
565}

◆ SearchIndexUpdated()

template<typename TIndex>
G4bool G4VUserMoleculeCounter< TIndex >::SearchIndexUpdated ( Search & search,
const TIndex & index ) const
protected

Definition at line 631 of file G4VUserMoleculeCounter.hh.

632{
633 if (search.fLowerBoundSet && !(search.fLastIndexSearched->first < index)
635 {
636 return true;
637 }
638
639 auto mol_it = fCounterMap.find(index);
640 search.fLastIndexSearched = mol_it;
641
642 if (mol_it != fCounterMap.end()) {
643 search.fLowerBoundTime = search.fLastIndexSearched->second.end();
644 search.fLowerBoundSet = true;
645 }
646 else {
647 search.fLowerBoundSet = false;
648 }
649
650 return false;
651}

Referenced by GetNbMoleculesAtTime().

◆ SearchUpperBoundTime()

template<typename T>
G4int G4VUserMoleculeCounter< T >::SearchUpperBoundTime ( Search & search,
G4double time,
G4bool sameIndex ) const
protected

Definition at line 656 of file G4VUserMoleculeCounter.hh.

658{
659 auto mol_it = search.fLastIndexSearched;
660 if (mol_it == fCounterMap.end()) {
661 return 0;
662 }
663
664 InnerCounterMapType const& timeMap = mol_it->second;
665 if (timeMap.empty()) {
666 return 0;
667 }
668
669 if (sameIndex) {
670 if (search.fLowerBoundSet && search.fLowerBoundTime != timeMap.end()) {
671 if (search.fLowerBoundTime->first < time) {
672 auto upperToLast = search.fLowerBoundTime;
673 upperToLast++;
674
675 if (upperToLast == timeMap.end()) {
676 return search.fLowerBoundTime->second;
677 }
678
679 if (upperToLast->first > time) {
680 return search.fLowerBoundTime->second;
681 }
682 }
683 }
684 }
685
686 auto up_time_it = timeMap.upper_bound(time);
687
688 if (up_time_it == timeMap.end()) {
689 auto last_time = timeMap.rbegin();
690 return last_time->second;
691 }
692 if (up_time_it == timeMap.begin()) {
693 return 0;
694 }
695
696 up_time_it--;
697
698 search.fLowerBoundTime = up_time_it;
699 search.fLowerBoundSet = true;
700
701 return search.fLowerBoundTime->second;
702}

Referenced by GetNbMoleculesAtTime().

Member Data Documentation

◆ fCounterMap

◆ fShadowCounterMap

template<class TIndex>
std::map<TIndex, G4int> G4VUserMoleculeCounter< TIndex >::fShadowCounterMap {}
protected

Definition at line 78 of file G4VUserMoleculeCounter.hh.

78{};

Referenced by AddMolecule(), RemoveMolecule(), and SchedulerFinalizedTracking().


The documentation for this class was generated from the following file: