GCC Code Coverage Report


Directory: ./
File: include/interaction.hpp
Date: 2025-11-05 16:49:12
Exec Total Coverage
Lines: 46 48 95.8%
Functions: 5 5 100.0%
Branches: 14 16 87.5%

Line Branch Exec Source
1 #pragma once
2
3 #include <yaml-cpp/yaml.h>
4
5 #include "cells.hpp"
6 #include "particle.hpp"
7 #include "potentials.hpp"
8 #include "system.hpp"
9
10 class Cells;
11
12 class Interaction {
13 public:
14 System *system;
15 std::vector<Particle> &particles;
16 std::vector<External *> externals;
17 Internal *internal;
18 bool allDoE;
19 bool allDoF;
20
21 Interaction(System *system, const YAML::Node &config);
22 virtual ~Interaction();
23
24 virtual double iteratePairs(Particle &p, PairFunction &func) = 0;
25 virtual double iterateTriples(Particle &p, TripleFunction &func) = 0;
26 virtual double iteratePairs(PairFunction &func, bool newton3, bool parallel = true) = 0;
27 virtual double iterateTriples(TripleFunction &func, bool newton3, bool parallel = true) = 0;
28
29 virtual void
30 2225 updateParticleMeta(Particle &p,
31 2225 ParticleUpdateType particleUpdateType = ParticleUpdateType::MOVE) {}
32 16 virtual void updateMeta() {}
33
34 23844 double external(Particle &p) {
35 23844 p.Eext = 0.;
36
2/2
✓ Branch 0 taken 8948 times.
✓ Branch 1 taken 23844 times.
32792 for (External *e : externals) {
37 8948 p.Eext += (*e)(p);
38 }
39 23844 return p.Eext;
40 }
41
42 virtual double
43 4945 updateParticleState(Particle &p,
44 ParticleUpdateType particleUpdateType = ParticleUpdateType::MOVE) {
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4945 times.
4945 if (internal->needsGather()) {
46 throw std::runtime_error("Interactions that need gathering cannot use updateParticleState");
47 }
48 4945 updateParticleMeta(p, particleUpdateType);
49 4945 double E = 0.;
50 4945 E = external(p);
51 4945 bool newton3Restore = internal->newton3;
52 4945 internal->newton3 = false;
53 4945 E += iteratePairs(p, *internal);
54
2/2
✓ Branch 0 taken 2977 times.
✓ Branch 1 taken 1968 times.
4945 if (internal->threebody()) {
55 2977 E += iterateTriples(p, *internal);
56 }
57 4945 internal->newton3 = newton3Restore;
58 4945 return E;
59 }
60
61 4778 virtual void updateState() {
62 4778 updateMeta();
63 4778 int n = particles.size();
64 4778 bool newton3 = internal->newton3;
65 4778 double Eext = 0.;
66 4778 #pragma omp parallel for reduction(+ : Eext)
67 for (int i = 0; i < n; ++i) {
68 Particle &pi = particles[i];
69 Eext += external(pi);
70 }
71 4778 double Eint = 0.;
72 4778 internal->reset();
73 4778 Eint += iteratePairs(*internal, newton3);
74
2/2
✓ Branch 0 taken 654 times.
✓ Branch 1 taken 4124 times.
4778 if (internal->needsGather()) {
75 654 internal->gather = true;
76 654 double Egather = 0.;
77 654 #pragma omp parallel for reduction(+ : Egather)
78 for (int i = 0; i < n; ++i) {
79 Egather += (*internal)(particles[i]);
80 }
81
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 654 times.
654 if (!newton3) {
82 // There is no double counting in this term, so compensate for the correction below
83 Egather *= 2;
84 }
85 654 Eint += Egather;
86 654 Eint += iteratePairs(*internal, newton3);
87 654 internal->gather = false;
88 }
89
2/2
✓ Branch 0 taken 689 times.
✓ Branch 1 taken 4089 times.
4778 if (internal->threebody()) {
90 689 double Etriples = iterateTriples(*internal, newton3);
91
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 680 times.
689 if (!newton3) {
92 // There is no double counting in this term, so compensate for the correction below
93 9 Etriples *= 2;
94 }
95 689 Eint += Etriples;
96 }
97
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4762 times.
4778 if (!newton3) {
98 // Account for double counting in energy
99 16 Eint *= 0.5;
100 }
101 4778 system->E = Eext + Eint;
102 4778 }
103 };
104
105 class AllInteraction : public Interaction {
106 public:
107 AllInteraction(System *system, const YAML::Node &config);
108
109 double iteratePairs(Particle &p, PairFunction &func);
110 double iterateTriples(Particle &p, TripleFunction &func);
111 double iteratePairs(PairFunction &func, bool newton3, bool parallel = true);
112 double iterateTriples(TripleFunction &func, bool newton3, bool parallel = true);
113 };
114
115 class CellNeighborInteraction : public Interaction {
116 double doCell(Cell &c, PairFunction &func, bool newton3);
117 double doCell(Cell &c, TripleFunction &func, bool newton3);
118 template <typename T> double iterate(T &func, bool newton3, bool parallel);
119
120 public:
121 ArrayI cellCount;
122 Vec cellL;
123 Cells cells;
124
125 CellNeighborInteraction(System *system, const YAML::Node &config);
126
127 double iteratePairs(Particle &p, PairFunction &func);
128 double iterateTriples(Particle &p, TripleFunction &func);
129 double iteratePairs(PairFunction &func, bool newton3, bool parallel = true);
130 double iterateTriples(TripleFunction &func, bool newton3, bool parallel = true);
131
132 void updateParticleMeta(Particle &p,
133 ParticleUpdateType particleUpdateType = ParticleUpdateType::MOVE);
134 void updateMeta();
135 };
136
137 class InteractionFactory {
138 public:
139 static Interaction *create(System *system, const YAML::Node &config);
140 };
141