GCC Code Coverage Report


Directory: ./
File: include/interaction.hpp
Date: 2025-02-03 10:58:24
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 2222 updateParticleMeta(Particle &p,
31 2222 ParticleUpdateType particleUpdateType = ParticleUpdateType::MOVE) {}
32 16 virtual void updateMeta() {}
33
34 22963 double external(Particle &p) {
35 22963 p.Eext = 0.;
36
2/2
✓ Branch 0 taken 8948 times.
✓ Branch 1 taken 22963 times.
31911 for (External *e : externals) {
37 8948 p.Eext += (*e)(p);
38 }
39 22963 return p.Eext;
40 }
41
42 virtual double
43 4946 updateParticleState(Particle &p,
44 ParticleUpdateType particleUpdateType = ParticleUpdateType::MOVE) {
45
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4946 times.
4946 if (internal->needsGather()) {
46 throw std::runtime_error("Interactions that need gathering cannot use updateParticleState");
47 }
48 4946 updateParticleMeta(p, particleUpdateType);
49 4946 double E = 0.;
50 4946 E = external(p);
51 4946 bool newton3Restore = internal->newton3;
52 4946 internal->newton3 = false;
53 4946 E += iteratePairs(p, *internal);
54
2/2
✓ Branch 0 taken 2977 times.
✓ Branch 1 taken 1969 times.
4946 if (internal->threebody()) {
55 2977 E += iterateTriples(p, *internal);
56 }
57 4946 internal->newton3 = newton3Restore;
58 4946 return E;
59 }
60
61 4484 virtual void updateState() {
62 4484 updateMeta();
63 4484 int n = particles.size();
64 4484 bool newton3 = internal->newton3;
65 4484 double Eext = 0.;
66 4484 #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 4484 double Eint = 0.;
72 4484 internal->reset();
73 4484 Eint += iteratePairs(*internal, newton3);
74
2/2
✓ Branch 0 taken 647 times.
✓ Branch 1 taken 3837 times.
4484 if (internal->needsGather()) {
75 647 internal->gather = true;
76 647 double Egather = 0.;
77 647 #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 647 times.
647 if (!newton3) {
82 // There is no double counting in this term, so compensate for the correction below
83 Egather *= 2;
84 }
85 647 Eint += Egather;
86 647 Eint += iteratePairs(*internal, newton3);
87 647 internal->gather = false;
88 }
89
2/2
✓ Branch 0 taken 679 times.
✓ Branch 1 taken 3805 times.
4484 if (internal->threebody()) {
90 679 double Etriples = iterateTriples(*internal, newton3);
91
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 670 times.
679 if (!newton3) {
92 // There is no double counting in this term, so compensate for the correction below
93 9 Etriples *= 2;
94 }
95 679 Eint += Etriples;
96 }
97
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4468 times.
4484 if (!newton3) {
98 // Account for double counting in energy
99 16 Eint *= 0.5;
100 }
101 4484 system->E = Eext + Eint;
102 4484 }
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