GCC Code Coverage Report


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