votca 2024.2-dev
Loading...
Searching...
No Matches
nblistgrid_3body.cc
Go to the documentation of this file.
1/*
2 * Copyright 2009-2020 The VOTCA Development Team (http://www.votca.org)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18// Local VOTCA includes
20#include "votca/csg/topology.h"
21
22namespace votca {
23namespace csg {
24
25using namespace std;
26
28 BeadList &list3, bool do_exclusions) {
29
30 do_exclusions_ = do_exclusions;
31 if (list1.empty()) {
32 return;
33 }
34 if (list2.empty()) {
35 return;
36 }
37 if (list3.empty()) {
38 return;
39 }
40
41 // check if all bead lists "have" the same topology
42 assert(&(list1.getTopology()) == &(list2.getTopology()));
43 assert(&(list1.getTopology()) == &(list3.getTopology()));
44 assert(&(list2.getTopology()) == &(list3.getTopology()));
45 const Topology &top = list1.getTopology();
46
48
49 // Add all beads of list1 to beads1_
50 for (auto &iter : list1) {
51 getCell(iter->getPos()).beads1_.push_back(iter);
52 }
53
54 // Add all beads of list2 to beads2_
55 for (auto &iter : list2) {
56 getCell(iter->getPos()).beads2_.push_back(iter);
57 }
58
59 // Add all beads of list2 to beads3_
60 for (auto &iter : list3) {
61 getCell(iter->getPos()).beads3_.push_back(iter);
62 }
63
64 // loop over beads of list 1 again to get the correlations
65 for (auto &iter : list1) {
66 cell_t &cell = getCell(iter->getPos());
67 TestBead(top, cell, iter);
68 }
69}
70
72 bool do_exclusions) {
73 do_exclusions_ = do_exclusions;
74 if (list1.empty()) {
75 return;
76 }
77 if (list2.empty()) {
78 return;
79 }
80
81 // check if both bead lists "have" the same topology
82 assert(&(list1.getTopology()) == &(list2.getTopology()));
83 const Topology &top = list1.getTopology();
84
86
87 // Add all beads of list1 to beads1_
88 for (auto &bead : list1) {
89 getCell(bead->getPos()).beads1_.push_back(bead);
90 }
91
92 // Add all beads of list2 to beads2_
93 for (auto &bead : list2) {
94 getCell(bead->getPos()).beads2_.push_back(bead);
95 }
96
97 // In this case type2 and type3 are the same
98 for (auto &cell : grid_) {
99 cell.beads3_ = cell.beads2_;
100 }
101
102 // loop over beads of list 1 again to get the correlations
103 for (auto &bead : list1) {
104 cell_t &cell = getCell(bead->getPos());
105 TestBead(top, cell, bead);
106 }
107}
108
109void NBListGrid_3Body::Generate(BeadList &list, bool do_exclusions) {
110 do_exclusions_ = do_exclusions;
111 if (list.empty()) {
112 return;
113 }
114
115 const Topology &top = list.getTopology();
116
117 InitializeGrid(top.getBox());
118
119 // Add all beads of list to all! bead lists of the cell
120 for (auto &iter : list) {
121 getCell(iter->getPos()).beads1_.push_back(iter);
122 }
123
124 for (auto &cell : grid_) {
125 cell.beads2_ = cell.beads1_;
126 cell.beads3_ = cell.beads1_;
127 }
128
129 // loop over beads again to get the correlations (as all of the same type
130 // here)
131 for (auto &bead : list) {
132 cell_t &cell = getCell(bead->getPos());
133 TestBead(top, cell, bead);
134 }
135}
136
137void NBListGrid_3Body::InitializeGrid(const Eigen::Matrix3d &box) {
138 box_a_ = box.col(0);
139 box_b_ = box.col(1);
140 box_c_ = box.col(2);
141
142 // create plane normals
143 norm_a_ = box_b_.cross(box_c_);
144 norm_b_ = box_c_.cross(box_a_);
145 norm_c_ = box_a_.cross(box_b_);
146
147 norm_a_.normalize();
148 norm_b_.normalize();
149 norm_c_.normalize();
150
151 double la = box_a_.dot(norm_a_);
152 double lb = box_b_.dot(norm_b_);
153 double lc = box_c_.dot(norm_c_);
154
155 // calculate grid size, each grid has to be at least size of cut-off
156 box_Na_ = Index(std::max(std::abs(la / cutoff_), 1.0));
157 box_Nb_ = Index(std::max(std::abs(lb / cutoff_), 1.0));
158 box_Nc_ = Index(std::max(std::abs(lc / cutoff_), 1.0));
159
160 norm_a_ = norm_a_ / la * (double)box_Na_;
161 norm_b_ = norm_b_ / lb * (double)box_Nb_;
162 norm_c_ = norm_c_ / lc * (double)box_Nc_;
163
164 grid_.resize(box_Na_ * box_Nb_ * box_Nc_);
165
166 Index a1, a2, b1, b2, c1, c2;
167
168 a1 = b1 = c1 = -1;
169 a2 = b2 = c2 = 1;
170
171 if (box_Na_ < 3) {
172 a2 = 0;
173 }
174 if (box_Nb_ < 3) {
175 b2 = 0;
176 }
177 if (box_Nc_ < 3) {
178 c2 = 0;
179 }
180
181 if (box_Na_ < 2) {
182 a1 = 0;
183 }
184 if (box_Nb_ < 2) {
185 b1 = 0;
186 }
187 if (box_Nc_ < 2) {
188 c1 = 0;
189 }
190
191 // wow, setting up the neighbours is an ugly for construct!
192 // loop from N..2*N to avoid if and only use %
193 for (Index a = box_Na_; a < 2 * box_Na_; ++a) {
194 for (Index b = box_Nb_; b < 2 * box_Nb_; ++b) {
195 for (Index c = box_Nc_; c < 2 * box_Nc_; ++c) {
196 cell_t &cell = getCell(a % box_Na_, b % box_Nb_, c % box_Nc_);
197 for (Index aa = a + a1; aa <= a + a2; ++aa) {
198 for (Index bb = b + b1; bb <= b + b2; ++bb) {
199 for (Index cc = c + c1; cc <= c + c2; ++cc) {
200 // test: for 3body algorithm: each cell is a neighbor of its own
201 // !!!
202 cell.neighbours_.push_back(
203 &getCell(aa % box_Na_, bb % box_Nb_, cc % box_Nc_));
204 }
205 }
206 }
207 }
208 }
209 }
210}
211
213 Index a = (Index)floor(r.dot(norm_a_));
214 Index b = (Index)floor(r.dot(norm_b_));
215 Index c = (Index)floor(r.dot(norm_c_));
216
217 if (a < 0) {
218 a = box_Na_ + a % box_Na_;
219 }
220 a %= box_Na_;
221
222 if (b < 0) {
223 b = box_Nb_ + b % box_Nb_;
224 }
225 b %= box_Nb_;
226
227 if (c < 0) {
228 c = box_Nc_ + c % box_Nc_;
229 }
230 c %= box_Nc_;
231
232 return getCell(a, b, c);
233}
234
236 NBListGrid_3Body::cell_t &cell, Bead *bead) {
237 BeadList::iterator iter2;
238 BeadList::iterator iter3;
239 Eigen::Vector3d u = bead->getPos();
240
241 // loop over all neighbors (this now includes the cell itself!) to iterate
242 // over all beads of type2 of the cell and its neighbors
243 for (vector<cell_t *>::iterator iterc2 = cell.neighbours_.begin();
244 iterc2 != cell.neighbours_.end(); ++iterc2) {
245 for (iter2 = (*(*iterc2)).beads2_.begin();
246 iter2 != (*(*iterc2)).beads2_.end(); ++iter2) {
247
248 if (bead == *iter2) {
249 continue;
250 }
251
252 // loop again over all neighbors (this now includes the cell itself!)
253 // to iterate over all beads of type3 of the cell and its neighbors
254 for (auto &neighbour_ : cell.neighbours_) {
255 for (iter3 = (*neighbour_).beads3_.begin();
256 iter3 != (*neighbour_).beads3_.end(); ++iter3) {
257
258 // do not include the same beads twice in one triple!
259 if (bead == *iter3) {
260 continue;
261 }
262 if (*iter2 == *iter3) {
263 continue;
264 }
265
266 Eigen::Vector3d v = (*iter2)->getPos();
267 Eigen::Vector3d z = (*iter3)->getPos();
268
269 Eigen::Vector3d r12 = top.BCShortestConnection(u, v);
270 Eigen::Vector3d r13 = top.BCShortestConnection(u, z);
271 Eigen::Vector3d r23 = top.BCShortestConnection(v, z);
272 double d12 = r12.norm();
273 double d13 = r13.norm();
274 double d23 = r23.norm();
275
276 // to do: at the moment use only one cutoff value
277 // to do: so far only check the distance between bead 1 (central
278 // bead) and bead2 and bead 3
279 if ((d12 < cutoff_) && (d13 < cutoff_)) {
282 if (do_exclusions_) {
283 if ((top.getExclusions().IsExcluded(bead, *iter2)) ||
284 (top.getExclusions().IsExcluded(bead, *iter3)) ||
285 (top.getExclusions().IsExcluded(*iter2, *iter3))) {
286 continue;
287 }
288 }
289 if ((*match_function_)(bead, *iter2, *iter3, r12, r13, r23, d12,
290 d13, d23)) {
291 if (!FindTriple(bead, *iter2, *iter3)) {
292 AddTriple(triple_creator_(bead, *iter2, *iter3, r12, r13, r23));
293 }
294 }
295 }
296 }
297 }
298 }
299 }
300}
301
302} // namespace csg
303} // namespace votca
virtual const Eigen::Vector3d & getPos() const
Definition basebead.h:166
const Topology & getTopology() const
Definition beadlist.h:63
typename std::vector< Bead * >::iterator iterator
Definition beadlist.h:58
void push_back(Bead *bead)
Definition beadlist.h:56
bool empty() const
Definition beadlist.h:54
information about a bead
Definition bead.h:50
bool IsExcluded(Bead *bead1, Bead *bead2) const
std::vector< cell_t > grid_
cell_t & getCell(const Eigen::Vector3d &r)
void InitializeGrid(const Eigen::Matrix3d &box)
void TestBead(const Topology &top, cell_t &cell, Bead *bead)
void Generate(BeadList &list1, BeadList &list2, BeadList &list3, bool do_exclusions=true) override
bool do_exclusions_
take into account exclusions from topolgoy
triple_creator_t triple_creator_
the current bead pair creator function
std::unique_ptr< Functor > match_function_
double cutoff_
cutoff (at the moment use only one cutoff value)
topology of the whole system
Definition topology.h:81
const Eigen::Matrix3d & getBox() const
Definition topology.h:298
ExclusionList & getExclusions()
Definition topology.h:391
Eigen::Vector3d BCShortestConnection(const Eigen::Vector3d &r_i, const Eigen::Vector3d &r_j) const
calculate shortest vector connecting two points
Definition topology.cc:238
BeadTriple * FindTriple(Bead *e1, Bead *e2, Bead *e3)
Definition triplelist.h:83
STL namespace.
base class for all analysis tools
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26