Peano 4
Loading...
Searching...
No Matches
TracingAPI.cpp
Go to the documentation of this file.
1#include "TracingAPI.h"
2
3#include <ranges>
4
6
7
8#if !defined(AssignmentChecks) and !defined(noAssignmentChecks) and PeanoDebug>0
9#define AssignmentChecks
10#endif
11
12
13
14
15
16namespace {
17 tarch::logging::Log _log("toolbox::particles::assignmentchecks");
18
20} // namespace
21
22
24 particleName(particleName__),
25 particleX(particleX__) {}
26
28
30 return (particleName == rhs.particleName) and tarch::la::equals(particleX, rhs.particleX, Precision);
31}
32
34 if ( *this==rhs ) {
35 return false;
36 }
37 if (particleName < rhs.particleName) {
38 return true;
39 }
40 if (particleName > rhs.particleName) {
41 return false;
42 }
43 for (int d = 0; d < Dimensions; d++) {
44 if (particleX(d)<rhs.particleX(d)) {
45 return true;
46 }
47 if (particleX(d)>rhs.particleX(d)) {
48 return false;
49 }
50 }
51 assertion3( false, toString(), rhs.toString(), "cannot happen" );
52 return false;
53}
54
55
56std::string toolbox::particles::assignmentchecks::internal::ParticleIdentifier::toString() const { return "(" + particleName + "," + ::toString(particleX) + ")"; }
57
58
60 Type type_,
61 bool isLocal_,
62 const tarch::la::Vector<Dimensions,
63 double>& vertexX_,
65 int treeId_,
66 const std::string& trace_
67):
68 type(type_),
69 isLocal(isLocal_),
70 vertexX(vertexX_),
71 previousParticleX(0.0),
72 vertexH(vertexH_),
73 treeId(treeId_),
74 trace(trace_) {
76}
77
79 Type type_,
80 bool isLocal_,
81 int treeId_,
82 const std::string& trace_
83):
84 type(type_),
85 isLocal(isLocal_),
86 vertexX(tarch::la::Vector<Dimensions, double>(0.0)),
87 previousParticleX(0.0),
88 vertexH(tarch::la::Vector<Dimensions, double>(0.0)),
89 treeId(treeId_),
90 trace(trace_) {
92}
93
95 type(type_),
96 isLocal(false),
97 vertexX(tarch::la::Vector<Dimensions, double>(0.0)),
98 previousParticleX(0.0),
99 vertexH(tarch::la::Vector<Dimensions, double>(0.0)),
100 treeId(-1),
101 trace( "no-trace" ){
103}
104
106 Type type_,
107 const tarch::la::Vector<Dimensions, double>& previousVertexX_,
108 int treeId_,
109 const std::string& trace_
110):
111 type(type_),
112 isLocal(true),
113 vertexX(tarch::la::Vector<Dimensions, double>(0.0)),
114 previousParticleX(previousVertexX_),
115 vertexH(tarch::la::Vector<Dimensions, double>(0.0)),
116 treeId(treeId_),
117 trace(trace_) {
119}
120
122 std::ostringstream msg;
123
124 msg << "(";
125 switch (type) {
126 case Type::AssignToSieveSet:
127 msg << "assign-to-sieve-set" << ",local=" << isLocal << ",tree=" << treeId << ",trace=" << trace;
128 break;
129 case Type::AssignToVertex:
130 msg << "assign-to-vertex" << ",local=" << isLocal << ",x=" << vertexX << ",h=" << vertexH << ",tree=" << treeId << ",trace=" << trace;
131 break;
132 case Type::Erase:
133 msg << "erase" << ",local=" << isLocal << ",tree=" << treeId << ",trace=" << trace;
134 break;
135 case Type::DetachFromVertex:
136 msg << "detach-from-vertex" << ",local=" << isLocal << ",x=" << vertexX << ",h=" << vertexH << ",tree=" << treeId << ",trace=" << trace;
137 break;
138 case Type::NotFound:
139 msg << "not-found";
140 break;
141 case Type::MoveWhileAssociatedToVertex:
142 msg << "moved-while-associated-to-vertex" << "," << previousParticleX << "->x_new,tree=" << treeId << ",trace=" << trace;
143 break;
144 };
145 msg << ")";
146
147 return msg.str();
148}
149
150
152 _meshSweepName(meshSweepName) {}
153
154
156 return _meshSweepName;
157}
158
159
161 const std::string& particleName,
163 double searchTolerance
164) {
165 ParticleIdentifier result(particleName, particleX);
166
167 if (searchTolerance>0.0) {
169 auto currentSnapshot = _data.crbegin();
170 while (currentSnapshot != _data.crend()) {
171 for (const auto& eventsForOneParticle: *currentSnapshot) {
172 // use floating-point aware comparison operator
173 if (
174 eventsForOneParticle.first.particleName==result.particleName
175 and
176 tarch::la::equals(eventsForOneParticle.first.particleX, result.particleX, searchTolerance)
177 ) {
178 logDebug(
179 "createParticleIdentifier()",
180 "found entry for " << particleX << " given tolerance of " << searchTolerance << ": will copy data over bit-wisely which biases identifier by "
181 << (eventsForOneParticle.first.particleX - result.particleX)
182 );
183 // This is a bit-wise copy and biases the result towards an
184 // existing entry.
185 result = eventsForOneParticle.first;
186 assertion(currentSnapshot->count(result) > 0);
187 return result;
188 }
189 }
190 currentSnapshot++;
191 }
192 }
193
194 return result;
195}
196
197
199 _maxParticleSnapshotsToKeepTrackOf( maxParticleSnapshotsToKeepTrackOf ) {
200 _data.push_back(MeshSweepData("initial"));
201};
202
203
205 logInfo("startMeshSweep()", "finish old mesh sweep with " << _data.rbegin()->size() << " event(s) and start new one for " << meshSweepName );
207 _data.push_back(MeshSweepData(meshSweepName));
208};
209
210
214
215
216
219
220 bool hasEliminated = true;
221
222 while (hasEliminated) {
223 removeEmptyDatabaseSnapshots();
224
225 hasEliminated = false;
226 auto lastSnapshot = _data.rbegin();
227
228 auto particleTrajectory = lastSnapshot->begin();
229 while (particleTrajectory != lastSnapshot->end() and not hasEliminated) {
230 if (
231 particleTrajectory->second.back().type == Event::Type::MoveWhileAssociatedToVertex
232 or
233 particleTrajectory->second.back().type == Event::Type::AssignToVertex
234 or
235 not particleTrajectory->second.back().isLocal
236 ) {
237 removeTrajectory(
238 particleTrajectory->first,
239 particleTrajectory->second.back().treeId
240 );
241 hasEliminated = true;
242 }
243 else {
244 particleTrajectory++;
245 }
246 }
247
248 if (lastSnapshot->empty()) {
249 _data.pop_back();
250 hasEliminated = true;
251 }
252 }
253}
254
255
257 auto snapshot = _data.begin();
258 int currentSnapshot = 0;
259 while (snapshot!=_data.end()) {
260 auto trajectory = snapshot->begin();
261 while (trajectory!=snapshot->end()) {
262 if (trajectory->second.empty()) {
263 logDebug( "removeEmptyDatabaseSnapshots()", "removed entry for particle " << trajectory->first.toString() );
264 trajectory = snapshot->erase(trajectory);
265 }
266 else {
267 trajectory++;
268 }
269 }
270 snapshot++;
271 }
272
273
274 snapshot = _data.begin();
275 const int size = _data.size();
276 while (snapshot!=_data.end()) {
277 if (snapshot->empty() and currentSnapshot<size-1) {
278 logDebug( "removeEmptyDatabaseSnapshots()", "removed whole snapshot as it was empty" );
279 snapshot = _data.erase(snapshot);
280 }
281 else {
282 snapshot++;
283 }
284 currentSnapshot++;
285 }
286}
287
288
290 const ParticleIdentifier& identifier,
291 int spacetreeId,
292 int firstNRecentEntriesToSkip
293) {
294 assertion( spacetreeId>=0 );
295
296 auto currentSnapshot = _data.rbegin();
297 std::advance( currentSnapshot, firstNRecentEntriesToSkip );
298
299 while (currentSnapshot != _data.rend()) {
300 MeshSweepData& meshSweepData = *currentSnapshot;
301
302 if (meshSweepData.count(identifier) > 0) {
303 auto historyEventIterator = meshSweepData.at(identifier).rbegin();
304 while (historyEventIterator != meshSweepData.at(identifier).rend()) {
305 if (
306 historyEventIterator->treeId == spacetreeId
307 and
308 historyEventIterator->type == Event::Type::MoveWhileAssociatedToVertex
309 ) {
310 ParticleIdentifier previousIdentifier = identifier;
311 previousIdentifier.particleX = historyEventIterator->previousParticleX;
312 logDebug( "removeTrajectory(...)", "first erase historic data of " << previousIdentifier.toString() << " due to " << historyEventIterator->toString() );
313 removeTrajectory(previousIdentifier, spacetreeId, firstNRecentEntriesToSkip);
314 }
315 historyEventIterator++;
316 }
317
318 auto forwardEventIterator = meshSweepData.at(identifier).begin();
319 while (forwardEventIterator != meshSweepData.at(identifier).end()) {
320 if ( forwardEventIterator->treeId == spacetreeId ) {
321 logDebug( "removeTrajectory(...)", "erase event " << forwardEventIterator->toString() );
322 forwardEventIterator = meshSweepData[identifier].erase(forwardEventIterator);
323 }
324 else {
325 forwardEventIterator++;
326 }
327 }
328 }
329 currentSnapshot++;
330 firstNRecentEntriesToSkip++;
331 }
332}
333
334
335std::pair< toolbox::particles::assignmentchecks::internal::Event, toolbox::particles::assignmentchecks::internal::ParticleIdentifier > toolbox::particles::assignmentchecks::internal::Database::getEntry(
336 const ParticleIdentifier& identifier,
337 int spacetreeId,
338 int firstNRecentEntriesToSkip
339) {
341
342 auto currentSnapshot = _data.crbegin();
343
344 std::advance( currentSnapshot, firstNRecentEntriesToSkip );
345
346 while (currentSnapshot != _data.crend()) {
347 const MeshSweepData& meshSweepData = *currentSnapshot;
348
349 if (meshSweepData.count(identifier) > 0) {
350 auto event = meshSweepData.at(identifier).crbegin();
351 while (event != meshSweepData.at(identifier).crend()) {
352 bool treeIsAFit = event->treeId == spacetreeId
353 or spacetreeId==AnyTree;
354 if (
355 event->type == Event::Type::Erase
356 and
357 treeIsAFit
358 ) {
359 return { Event(Event::Type::NotFound), identifier };
360 }
361 else if (
363 and
364 treeIsAFit
365 and
366 firstNRecentEntriesToSkip!=DoNotFollowParticleMovementsInDatabase
367 ) {
368 const ParticleIdentifier previousIdentifier = _database.createParticleIdentifier(identifier.particleName, event->previousParticleX);
370 not (previousIdentifier==identifier),
371 previousIdentifier.toString(),
372 identifier.toString(),
373 event->toString()
374 );
375 logDebug( "getEntry()", "rerun with " << previousIdentifier.toString() << " distilled from " << identifier.toString() << " on iteration " << firstNRecentEntriesToSkip );
376 return getEntry(previousIdentifier, spacetreeId, firstNRecentEntriesToSkip);
377 }
378 else if (event->type != Event::Type::Erase and treeIsAFit) {
379 return { *event, identifier };
380 }
381 event++;
382 }
383 }
384 currentSnapshot++;
385 firstNRecentEntriesToSkip++;
386 }
387
388 return { Event(Event::Type::NotFound), identifier };
389}
390
391
394
395 std::ostringstream msg;
396
397 int snapshotCounter = 0;
398 for (auto& snapshot: _data) {
399 msg << std::endl << "sweep #" << snapshotCounter << " (" << snapshot.getName() << "):";
400 for (const auto& identifier: snapshot) {
401 msg << std::endl << "- " << identifier.first.toString() << ": ";
402 bool firstEntry = false;
403 for (const auto& event : identifier.second) {
404 if (firstEntry) {
405 firstEntry = true;
406 }
407 else {
408 msg << "->";
409 }
410 msg << event.toString();
411 }
412 }
413 snapshotCounter++;
414 }
415
416 return msg.str();
417}
418
419
422
423 int result = 0;
424 for (auto& p: _data) {
425 result += p.count(identifier);
426 }
427 return result;
428}
429
432
433 std::ostringstream msg;
434 if (not _data.empty()) {
435 const auto& lastMeshSnapshot = *_data.crbegin();
436 msg << "#" << (_data.size()-1) << "(" << lastMeshSnapshot.getName() << "):";
437 for (const auto& particleTrace: lastMeshSnapshot ) {
438 msg << std::endl << "-" << particleTrace.first.toString() << ": ";
439 for (const auto& event: particleTrace.second) {
440 msg << event.toString();
441 }
442 }
443 }
444 return msg.str();
445}
446
449
450 std::ostringstream msg;
451 msg << std::endl
452 << "============================" << std::endl
453 << identifier.toString() << std::endl
454 << "============================";
455 int snapshot = _data.size()-1;
456
457 bool hasPredecessor = false;
458 ParticleIdentifier predecessor(identifier);
459 auto p = _data.crbegin();
460
461 while (p!=_data.crend()) {
462 if ((*p).count(identifier) > 0) {
463 msg << std::endl << "sweep #" << snapshot << " (" << p->getName() << "):";
464 bool firstEntry = false;
465 for (const auto& event : p->at(identifier)) {
466 if (not firstEntry) {
467 firstEntry = true;
468 } else {
469 msg << "->";
470 }
471 msg << event.toString();
472 if (event.type==Event::Type::MoveWhileAssociatedToVertex and hasPredecessor) {
473 msg << " [particle has been moved on multiple ranks - only one taken into account]";
474 }
475 else if (event.type==Event::Type::MoveWhileAssociatedToVertex and not hasPredecessor) {
476 hasPredecessor = true;
477 predecessor = _database.createParticleIdentifier( predecessor.particleName, event.previousParticleX );
478 }
479 }
480 }
481 snapshot--;
482 p++;
483 }
484
485 if (hasPredecessor) {
486 return msg.str() + particleHistory(predecessor);
487 }
488 else return msg.str();
489}
490
493
494 assertion(not _data.empty());
495 MeshSweepData& snapshot = *_data.rbegin();
496 if (snapshot.count(identifier) == 0) {
497 snapshot.insert(std::pair<ParticleIdentifier, ParticleEvents>(identifier, ParticleEvents()));
498 logDebug( "addEvent(...)", "add new particle history thread in this snapshot for " << identifier.toString() );
499 }
500
501 // We first have to push it. Otherwise, the susequent getEntry() won't work.
502 snapshot[identifier].push_back(event);
503
504 if ( event.type == Event::Type::AssignToVertex and _data.size() > _maxParticleSnapshotsToKeepTrackOf ) {
505 removeTrajectory( identifier, event.treeId );
506 removeEmptyDatabaseSnapshots();
507
508 // re-add element
509 if (snapshot.count(identifier) == 0) {
510 snapshot.insert(std::pair<ParticleIdentifier, ParticleEvents>(identifier, ParticleEvents()));
511 logDebug( "addEvent(...)", "re-add particle history in this snapshot for " << identifier.toString() );
512 }
513 snapshot[identifier].push_back(event);
514 }
515 if ( event.type == Event::Type::MoveWhileAssociatedToVertex and _data.size() > _maxParticleSnapshotsToKeepTrackOf ) {
516 lock.free();
517
518 auto rootEntryOfLatestTrajectory = getEntry(identifier, event.treeId);
520 rootEntryOfLatestTrajectory.first.type!=Event::Type::NotFound,
521 rootEntryOfLatestTrajectory.first.toString(),
522 rootEntryOfLatestTrajectory.second.toString(),
523 event.toString(),
524 identifier.toString()
525 );
526
527 Event substituteEntryForTrajectory(
529 rootEntryOfLatestTrajectory.second.particleX,
530 event.treeId,
531 "substitute-for-whole-trajectory"
532 );
533 rootEntryOfLatestTrajectory.first.trace = "substitute-trajectory-start-from-original-point-" + ::toString( rootEntryOfLatestTrajectory.second.particleX );
534
535
536 lock.lock();
537 removeTrajectory( identifier, event.treeId);
538 removeEmptyDatabaseSnapshots();
539
540 // re-add element
541 if (snapshot.count(identifier) == 0) {
542 snapshot.insert(std::pair<ParticleIdentifier, ParticleEvents>(identifier, ParticleEvents()));
543 logDebug( "addEvent(...)", "re-add particle history in this snapshot for " << identifier.toString() );
544 }
545 snapshot[rootEntryOfLatestTrajectory.second].push_back(rootEntryOfLatestTrajectory.first);
546 snapshot[identifier].push_back(substituteEntryForTrajectory);
547 }
548}
549
550
551#if defined(AssignmentChecks)
552
554 const std::string& meshSweepName
555) {
556 _database.startMeshSweep( meshSweepName );
557}
558
559
561 const std::string& particleName,
563 bool isLocal,
564 int treeId,
565 const std::string& trace
566) {
567 logTraceInWith4Arguments("eraseParticle(...)", particleName, particleX, isLocal, treeId );
568
569 internal::ParticleIdentifier identifier = _database.createParticleIdentifier(particleName, particleX);
570 internal::Event event(internal::Event::Type::Erase, isLocal, treeId, trace);
571
572 internal::Event previousLocalParticle = _database.getEntry(identifier, treeId).first;
574 previousLocalParticle.type==internal::Event::Type::DetachFromVertex,
575 identifier.toString(),
576 event.toString(),
577 previousLocalParticle.toString(),
578 treeId,
579 _database.particleHistory(identifier)
580 );
581
582 _database.addEvent(identifier, event);
583 logTraceOut("eraseParticle(...)" );
584}
585
586
587
589 const std::string& particleName,
591 bool isLocal,
594 int treeId,
595 const std::string& trace,
596 bool particleIsNew
597) {
598 logTraceInWith6Arguments( "assignParticleToVertex(...)", particleName, particleX, isLocal, vertexX, vertexH, treeId );
599
600 constexpr bool checkNewParticles = false;
601
602 if ((not checkNewParticles) and particleIsNew) {
603 internal::ParticleIdentifier identifier = _database.createParticleIdentifier(particleName, particleX, 0.0);
604 internal::Event event(internal::Event::Type::AssignToVertex, isLocal, vertexX, vertexH, treeId, trace);
605
606 _database.addEvent(identifier, event);
607 }
608 else {
609 internal::ParticleIdentifier identifier = _database.createParticleIdentifier(particleName, particleX);
610 internal::Event event(internal::Event::Type::AssignToVertex, isLocal, vertexX, vertexH, treeId, trace);
611
612 #if PeanoDebug>0
613 internal::Event previousEvent = _database.getEntry(identifier, treeId).first;
614
615 const bool isDropping = previousEvent.type == internal::Event::Type::DetachFromVertex and tarch::la::allGreater( previousEvent.vertexH, vertexH );
616 const bool isLifting = previousEvent.type == internal::Event::Type::DetachFromVertex and tarch::la::allSmaller( previousEvent.vertexH, vertexH );
617 const bool isDroppingFromSieveSet = previousEvent.type == internal::Event::Type::AssignToSieveSet;
618 #endif
619
620 if (isLocal) {
622 previousEvent.type == internal::Event::Type::NotFound
623 or
624 isDroppingFromSieveSet
625 or
626 (isLifting and previousEvent.isLocal)
627 or
628 (isDropping and previousEvent.isLocal)
629 or
630 (previousEvent.type == internal::Event::Type::DetachFromVertex and not previousEvent.isLocal),
631 identifier.toString(),
632 event.toString(),
633 previousEvent.toString(),
634 treeId,
635 _database.getNumberOfSnapshots(),
636 trace,
637 _database.particleHistory(identifier)
638 );
640 _database.getEntry(identifier, treeId).first.type == internal::Event::Type::NotFound
641 or
642 isLifting or isDropping or isDroppingFromSieveSet
643 or
644 tarch::la::equals(previousEvent.vertexX, vertexX),
645 identifier.toString(),
646 event.toString(),
647 previousEvent.toString(),
648 trace,
649 _database.particleHistory(identifier)
650 );
652 _database.getEntry(identifier, treeId).first.type == internal::Event::Type::NotFound
653 or
654 isLifting or isDropping or isDroppingFromSieveSet
655 or
656 tarch::la::equals(previousEvent.vertexH, vertexH),
657 identifier.toString(),
658 event.toString(),
659 previousEvent.toString(),
660 trace,
661 _database.particleHistory(identifier)
662 );
663 }
664 else {
666 (previousEvent.type == internal::Event::Type::NotFound)
667 or
668 isDroppingFromSieveSet
669 or
670 (isDropping and not previousEvent.isLocal)
671 or
672 (previousEvent.type == internal::Event::Type::DetachFromVertex and previousEvent.isLocal),
673 identifier.toString(),
674 event.toString(),
675 previousEvent.toString(),
676 treeId,
677 _database.getNumberOfSnapshots(),
678 trace,
679 _database.particleHistory(identifier)
680 );
681 }
682
683 _database.addEvent(identifier, event);
684 }
685 logTraceOut( "assignParticleToVertex(...)" );
686}
687
688
690 const std::string& particleName,
691 const tarch::la::Vector<Dimensions, double>& oldParticleX,
692 const tarch::la::Vector<Dimensions, double>& newParticleX,
693 int treeId,
694 const std::string& trace
695) {
696 logTraceInWith3Arguments( "moveParticle(...)", particleName, oldParticleX, newParticleX );
697
698 if (not tarch::la::equals(oldParticleX, newParticleX, internal::ParticleIdentifier::Precision)) {
699 internal::ParticleIdentifier newIdentifier = _database.createParticleIdentifier(particleName, newParticleX);
700 internal::ParticleIdentifier oldIdentifier = _database.createParticleIdentifier(particleName, oldParticleX, internal::ParticleIdentifier::Precision * 4.0);
701 if (
702 newIdentifier != oldIdentifier
703 ) {
704 internal::Event newEvent(internal::Event::Type::MoveWhileAssociatedToVertex, oldIdentifier.particleX, treeId, trace );
705
706 #if PeanoDebug>0
707 internal::Event previousEvent = _database.getEntry(oldIdentifier, treeId ).first;
708 internal::Event existingNewEventOnAnyTree = _database.getEntry(newIdentifier, internal::Database::AnyTree ).first;
709 internal::Event existingNewEventOnLocalTree = _database.getEntry(newIdentifier, treeId ).first;
710 #endif
711
712 const std::string errorMessage0 = R"(
713=============
714Explanation
715=============
716The tracer has been informed of a particle movement. When it tried to bookmark
717the particle with its new position, it found out that there is already a
718particle registered at this place. It seems that a particle overlaps with
719another one.
720
721This might mean that there is actually a particle here, but could also result
722from two other situations:
723
724- We trace position updates one after the other. If particle A takes the
725 position of a particle B, we might simply not have updated B yet.
726- We trace position updates only if positions have changed significantly.
727 Significantly here is formalised via
728
729 toolbox::particles::assignmentchecks::internal::ParticleIdentifier::Precision
730
731 That is, if particles are closer together than this delta, we do not write
732 logs into our database. This ensures that the database is not filled with
733 tiny update entries.
734
735As the tracing cannot handle either situation, we are left with two options.
736We can dramatically reduce Precision at the cost of a higher overhead.
737Alternatively, it might be appropriate to check the time step sizes
738employed: If particles move too fast, the probability that A ends up at a
739position just previously held by B (which is not yet updated) is higher.
740
741)";
743 existingNewEventOnLocalTree.type == internal::Event::Type::NotFound,
744 oldIdentifier.toString(),
745 newIdentifier.toString(),
746 previousEvent.toString(),
747 newEvent.toString(),
748 existingNewEventOnLocalTree.toString(),
749 existingNewEventOnAnyTree.toString(),
750 _database.getNumberOfSnapshots(),
751 treeId,
752 trace,
754 _database.totalEntries(newIdentifier),
755 _database.particleHistory(newIdentifier),
756 errorMessage0
757 );
758 const std::string errorMessage1 = R"(
759=============
760Explanation
761=============
762The tracer has been informed of a particle movement. When it tried to bookmark
763the particle with its new position, it found out that there is already a
764particle registered at this place. That is fine, as particles might be held
765redundantly on different trees - either as halo copies or as they sit exactly
766on the face between two subdomains.
767
768If that happens, they however have to be tied to the same vertex in the domain
769although the vertex might be replicated on a different tree. Alternatively, the
770other rank might already have moved it and come to the conclusion that it has
771to be assigned to the sieve set. The present tree is not there yet, i.e. is
772just about to move it, but will eventually also raise its particle to the
773sieve set.
774)";
776 existingNewEventOnAnyTree.type == internal::Event::Type::NotFound
777 or
778 existingNewEventOnAnyTree.type == internal::Event::Type::AssignToSieveSet
779 or
780 (
781 existingNewEventOnAnyTree.type == internal::Event::Type::AssignToVertex
782 and
783 existingNewEventOnAnyTree.vertexX == previousEvent.vertexX
784 and
785 existingNewEventOnAnyTree.vertexH == previousEvent.vertexH
786 ),
787 oldIdentifier.toString(),
788 newIdentifier.toString(),
789 previousEvent.toString(),
790 newEvent.toString(),
791 existingNewEventOnLocalTree.toString(),
792 existingNewEventOnAnyTree.toString(),
793 _database.getNumberOfSnapshots(),
794 treeId,
795 trace,
797 _database.totalEntries(newIdentifier),
798 _database.particleHistory(newIdentifier),
799 errorMessage1
800 );
802 previousEvent.type == internal::Event::Type::AssignToVertex,
803 oldIdentifier.toString(),
804 previousEvent.toString(),
805 newIdentifier.toString(),
806 newEvent.toString(),
807 _database.getNumberOfSnapshots(),
808 treeId,
809 trace,
810 _database.totalEntries(oldIdentifier),
811 _database.particleHistory(oldIdentifier)
812 );
813
814 _database.addEvent(newIdentifier, newEvent);
815 }
816 }
817
818 logTraceOut( "moveParticle(...)" );
819}
820
821
823 const std::string& particleName,
825 bool isLocal,
828 int treeId,
829 const std::string& trace
830) {
831 logTraceInWith6Arguments( "detachParticleFromVertex(...)", particleName, particleX, isLocal, vertexX, vertexH, treeId );
832
833 internal::ParticleIdentifier identifier = _database.createParticleIdentifier(particleName, particleX);
834 internal::Event event{internal::Event::Type::DetachFromVertex, isLocal, vertexX, vertexH, treeId, trace};
835
836 #if PeanoDebug>0
837 internal::Event previousEvent = _database.getEntry(identifier, treeId).first;
838 #endif
839
841 previousEvent.type == internal::Event::Type::AssignToVertex,
842 identifier.toString(),
843 event.toString(),
844 previousEvent.toString(),
845 treeId,
846 _database.getNumberOfSnapshots(),
847 trace,
848 _database.particleHistory(identifier)
849 );
851 tarch::la::equals(previousEvent.vertexX, vertexX),
852 identifier.toString(),
853 event.toString(),
854 previousEvent.toString(),
855 treeId,
856 _database.getNumberOfSnapshots(),
857 trace,
858 _database.particleHistory(identifier)
859 );
861 tarch::la::equals(previousEvent.vertexH, vertexH),
862 identifier.toString(),
863 event.toString(),
864 previousEvent.toString(),
865 treeId,
866 trace,
867 _database.particleHistory(identifier)
868 );
869
870 _database.addEvent(identifier, event);
871 logTraceOut( "detachParticleFromVertex(...)" );
872}
873
874
876 const std::string& particleName, const tarch::la::Vector<Dimensions, double>& particleX, bool isLocal,
877 int treeId,
878 const std::string& trace
879) {
880 logTraceInWith4Arguments( "assignParticleToSieveSet(...)", particleName, particleX, isLocal, treeId );
881
882 logDebug("assignParticleToSieveSet()", "assign " << particleName << " particle at " << particleX << " to global sieve set on tree " << treeId);
883
884 internal::ParticleIdentifier identifier = _database.createParticleIdentifier(particleName, particleX);
885 internal::Event event{internal::Event::Type::AssignToSieveSet, isLocal, treeId, trace};
886
887 #if PeanoDebug>0
888 internal::Event previousEvent = _database.getEntry(identifier, treeId).first;
889 #endif
890
892 previousEvent.type == internal::Event::Type::DetachFromVertex,
893 identifier.toString(),
894 event.toString(), previousEvent.toString(),
895 treeId, _database.particleHistory(identifier)
896 );
897
898 _database.addEvent(identifier, event);
899 logTraceOut( "assignParticleToSieveSet(...)" );
900}
901
902
904 _database.eliminateExistingParticles();
905}
906
907
909 if (_database.getNumberOfSnapshots()!=0) {
910 logInfo( "ensureDatabaseIsEmpty()", "database still holds " << _database.getNumberOfSnapshots() << " snapshots" );
911 logError( "ensureDatabaseIsEmpty()", _database.toString() );
912 assertion(false);
913 exit(-1);
914 }
915}
916
917#else
918
919void toolbox::particles::assignmentchecks::startMeshSweep(const std::string& meshSweepName) {}
920
922 const std::string& particleName, const tarch::la::Vector<Dimensions, double>& particleX, bool isLocal, int treeId,
923 const std::string& trace
924) {}
925
927 const std::string& particleName,
929 bool isLocal,
932 int treeId,
933 const std::string& trace,
934 bool particleIsNew
935) {}
936
938 const std::string& particleName,
940 bool isLocal,
943 int treeId,
944 const std::string& trace
945) {}
946
948 const std::string& particleName, const tarch::la::Vector<Dimensions, double>& particleX, bool isLocal, int treeId, const std::string& trace
949) {}
950
952 const std::string& particleName,
953 const tarch::la::Vector<Dimensions, double>& oldParticleX,
954 const tarch::la::Vector<Dimensions, double>& newParticleX,
955 int treeId,
956 const std::string& trace
957) {}
958
960
964
965#endif
966
967
971
972
#define assertion4(expr, param0, param1, param2, param3)
#define assertion13(expr, param0, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12)
#define assertion3(expr, param0, param1, param2)
#define assertion7(expr, param0, param1, param2, param3, param4, param5, param6)
#define assertion9(expr, param0, param1, param2, param3, param4, param5, param6, param7, param8)
#define assertion(expr)
#define assertion6(expr, param0, param1, param2, param3, param4, param5)
#define assertion5(expr, param0, param1, param2, param3, param4)
#define logError(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:464
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logTraceOut(methodName)
Definition Log.h:379
#define logTraceInWith4Arguments(methodName, argument0, argument1, argument2, argument3)
Definition Log.h:373
#define logTraceInWith3Arguments(methodName, argument0, argument1, argument2)
Definition Log.h:372
#define logTraceInWith6Arguments(methodName, argument0, argument1, argument2, argument3, argument4, argument5)
Definition Log.h:375
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:411
bool operator!=(const swift2::TaskNumber &lhs, const swift2::TaskNumber &rhs)
bool operator==(const swift2::TaskNumber &lhs, const swift2::TaskNumber &rhs)
Log Device.
Definition Log.h:516
Create a lock around a boolean semaphore region.
int getNumberOfSnapshots() const
Return number of snapshots.
std::string particleHistory(const ParticleIdentifier &identifier)
Print history of one particle.
int totalEntries(const ParticleIdentifier &identifier)
Count total number of entries for a particle.
void startMeshSweep(const std::string &meshSweepName)
Add a new snapshot for a new mesh sweep.
std::string toString()
Dump the whole database.
void eliminateExistingParticles()
Eliminate existing particles, so only those that are "forgotten" remain.
void addEvent(ParticleIdentifier identifier, const Event &event)
Add a new event to the database.
Database(int maxParticleSnapshotsToKeepTrackOf=16)
void removeTrajectory(const ParticleIdentifier &lastIdentifier, int spacetreeId, int firstNRecentEntriesToSkip=0)
Remove the particle trajectory that ends up in lastIdentifier.
ParticleIdentifier createParticleIdentifier(const std::string &particleName, const tarch::la::Vector< Dimensions, double > &particleX, double searchTolerance=ParticleIdentifier::Precision)
Create a particle identifier.
std::pair< Event, ParticleIdentifier > getEntry(const ParticleIdentifier &identifier, int spacetreeId, int firstNRecentEntriesToSkip=SearchWholeDatabase)
Return last entry matching identifier.
std::string toString(Filter filter)
Definition convert.cpp:170
bool allGreater(const Vector< Size, Scalar > &lhs, const Scalar &cmp, const Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
bool allSmaller(const Vector< Size, Scalar > &lhs, const Scalar &cmp, const Scalar tolerance=NUMERICAL_ZERO_DIFFERENCE)
bool equals(const Matrix< Rows, Cols, Scalar > &lhs, const Matrix< Rows, Cols, Scalar > &rhs, const Scalar &tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares to matrices on equality by means of a numerical accuracy.
Have to include this header, as I need access to the SYCL_EXTERNAL keyword.
Definition accelerator.h:17
void eraseParticle(const std::string &particleName, const tarch::la::Vector< Dimensions, double > &particleX, bool isLocal, int treeId, const std::string &trace)
Log that a particle is erased.
void eliminateExistingParticles()
Eliminate all "live" particles from database.
void assignParticleToSieveSet(const std::string &particleName, const tarch::la::Vector< Dimensions, double > &particleX, bool isLocal, int treeId, const std::string &trace)
Assign a particle to a sieve set.
void detachParticleFromVertex(const std::string &particleName, const tarch::la::Vector< Dimensions, double > &particleX, bool isLocal, const tarch::la::Vector< Dimensions, double > &vertexX, const tarch::la::Vector< Dimensions, double > &vertexH, int treeId, const std::string &trace)
Remove particle from vertex.
void moveParticle(const std::string &particleName, const tarch::la::Vector< Dimensions, double > &oldParticleX, const tarch::la::Vector< Dimensions, double > &newParticleX, int treeId, const std::string &trace)
Record the movement of a particle.
void ensureDatabaseIsEmpty()
Ensure that database is empty.
void assignParticleToVertex(const std::string &particleName, const tarch::la::Vector< Dimensions, double > &particleX, bool isLocal, const tarch::la::Vector< Dimensions, double > &vertexX, const tarch::la::Vector< Dimensions, double > &vertexH, int treeId, const std::string &trace, bool particleIsNew=false)
Assign a particle to a vertex.
void startMeshSweep(const std::string &meshSweepName)
Inform API that this is the end of a grid run-throuch.
tarch::logging::Log _log("examples::unittests")
Simple vector class.
Definition Vector.h:134
Event(Type type_, bool isLocal_, const tarch::la::Vector< Dimensions, double > &vertexX_, const tarch::la::Vector< Dimensions, double > &vertexH_, int treeId_, const std::string &trace_)
Construct an event which identifies a vertex assignment or the removal from a vertex.
Key for internal bookkeeping of vertex-particle association.
Definition TracingAPI.h:128
ParticleIdentifier(const std::string &particleName__, const tarch::la::Vector< Dimensions, double > &particleX__)
Never create a particle identifier manually.
bool numericalEquals(const ParticleIdentifier &rhs) const
Equals predicate.