OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
LocalIndexManager.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the appropriate papers when you publish your
33 * work. Good starting points are:
34 *
35 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
38 * [4] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
39 * [5] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
40 * [6] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
41 * [7] Lamichhane, Newman & Gezelter, J. Chem. Phys. 141, 134110 (2014).
42 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
43 */
44
45/**
46 * @file LocalIndexManager.hpp
47 * @author tlin
48 * @date 11/02/2004
49 * @version 1.0
50 */
51
52#ifndef UTILS_LOCALINDEXMANAGER_HPP
53#define UTILS_LOCALINDEXMANAGER_HPP
54
55#include <algorithm>
56#include <cassert>
57#include <iostream>
58#include <list>
59#include <utility>
60
61namespace OpenMD {
62
63 /**
64 * @class IndexListContainer
65 * @brief
66 * @todo documentation
67 */
69 public:
70 static const int MAX_INTEGER = 2147483647;
71
72 using IndexListContainerIterator = std::list<std::pair<int, int>>::iterator;
73
74 IndexListContainer(int minIndex = 0, int maxIndex = MAX_INTEGER) :
75 maxIndex_(maxIndex) {
76 indexContainer_.push_back(std::make_pair(minIndex, maxIndex));
77 }
78
79 int pop() {
80 if (indexContainer_.empty()) { std::cerr << "" << std::endl; }
81
82 int result;
83
84 result = indexContainer_.front().first;
85
86 if (indexContainer_.front().first == indexContainer_.front().second) {
87 indexContainer_.pop_front();
88 } else if (indexContainer_.front().first <
89 indexContainer_.front().second) {
90 ++indexContainer_.front().first;
91 } else {
92 std::cerr << "" << std::endl;
93 }
94
95 return result;
96 }
97
98 /**
99 *
100 */
101 void insert(int index) {
102 IndexListContainerIterator insertPos = internalInsert(index, index);
103 merge(insertPos);
104 }
105
106 /**
107 * Reclaims an index range
108 * @param beginIndex
109 * @param endIndex
110 */
111 void insert(int beginIndex, int endIndex) {
112 IndexListContainerIterator insertPos =
113 internalInsert(beginIndex, endIndex);
114 merge(insertPos);
115 }
116
117 /**
118 * Reclaims an index array.
119 * @param indices
120 */
121 void insert(std::vector<int>& indices) {
122 if (indices.empty()) { return; }
123
124 std::sort(indices.begin(), indices.end());
125 auto last = std::unique(indices.begin(), indices.end());
126 indices.erase(last, indices.end());
127
128 std::vector<int>::iterator i;
129 int beginIndex;
130
131 beginIndex = indices[0];
132
133 for (i = indices.begin() + 1; i != indices.end(); ++i) {
134 if (*i != *(i - 1) + 1) {
135 insert(beginIndex, *(i - 1));
136 beginIndex = *i;
137 }
138 }
139 }
140
141 std::vector<int> getIndicesBefore(int index) {
142 std::vector<int> result;
143 IndexListContainerIterator i;
144
145 for (i = indexContainer_.begin(); i != indexContainer_.end(); ++i) {
146 if ((*i).first > index) {
147 // we locate the node whose minimum index is greater that index
148 indexContainer_.erase(indexContainer_.begin(), i);
149 break;
150 } else if ((*i).second < index) {
151 // The biggest index current node hold is less than the index we want
152 for (int j = (*i).first; j <= (*i).second; ++j) {
153 result.push_back(j);
154 }
155 continue;
156 } else if ((*i).first == (*i).second) {
157 // the index happen to equal to a node which only contains one index
158 result.push_back((*i).first);
159 indexContainer_.erase(indexContainer_.begin(), i);
160 break;
161 } else {
162 for (int j = (*i).first; j < index; ++j) {
163 result.push_back(j);
164 }
165 (*i).first = index;
166 indexContainer_.erase(indexContainer_.begin(), i);
167 break;
168 }
169 }
170 return result;
171 }
172
173 int getMaxIndex() { return maxIndex_; }
174
175 private:
176 IndexListContainerIterator internalInsert(int beginIndex, int endIndex) {
177 if (beginIndex > endIndex) {
178 std::swap(beginIndex, endIndex);
179 std::cerr << "" << std::endl;
180 }
181
182 if (endIndex > maxIndex_) { std::cerr << "" << std::endl; }
183
184 IndexListContainerIterator i = indexContainer_.begin();
185 for (; i != indexContainer_.end(); ++i) {
186 if ((*i).first > endIndex) {
187 indexContainer_.insert(i, std::make_pair(beginIndex, endIndex));
188 return --i;
189 } else if ((*i).second < beginIndex) {
190 continue;
191 } else {
192 std::cerr << "" << std::endl;
193 }
194 }
195
196 indexContainer_.push_back(std::make_pair(beginIndex, endIndex));
197 return --indexContainer_.end();
198 }
199
200 void merge(IndexListContainerIterator i) {
201 IndexListContainerIterator j;
202
203 // check whether current node can be merged with its previous node
204 if (i != indexContainer_.begin()) {
205 j = i;
206 --j;
207 if (j != indexContainer_.begin() && (*j).second + 1 == (*i).first) {
208 (*i).first = (*j).first;
209 indexContainer_.erase(j);
210 }
211 }
212
213 // check whether current node can be merged with its next node
214 if (i != indexContainer_.end()) {
215 j = i;
216 ++j;
217
218 if (j != indexContainer_.end() && (*i).second + 1 == (*j).first) {
219 (*i).second = (*j).second;
220 indexContainer_.erase(j);
221 }
222 }
223 }
224
225 int maxIndex_;
226 std::list<std::pair<int, int>> indexContainer_;
227 };
228
229 /**
230 * @class LocalIndexManager LocalIndexManager.hpp
231 * "utils/LocalIndexManager.hpp"
232 * @brief
233 */
235 public:
236 int getNextAtomIndex() { return atomIndexContainer_.pop(); }
237
238 std::vector<int> getAtomIndicesBefore(int index) {
239 return atomIndexContainer_.getIndicesBefore(index);
240 }
241
242 void releaseAtomIndex(int index) { atomIndexContainer_.insert(index); }
243
244 void releaseAtomIndex(int beginIndex, int endIndex) {
245 atomIndexContainer_.insert(beginIndex, endIndex);
246 }
247
248 void releaseAtomIndex(std::vector<int> indices) {
249 atomIndexContainer_.insert(indices);
250 }
251
252 int getNextRigidBodyIndex() { return rigidBodyIndexContainer_.pop(); }
253
254 std::vector<int> getRigidBodyIndicesBefore(int index) {
255 return rigidBodyIndexContainer_.getIndicesBefore(index);
256 }
257
258 void releaseRigidBodyIndex(int index) {
259 rigidBodyIndexContainer_.insert(index);
260 }
261
262 void releaseRigidBodyIndex(int beginIndex, int endIndex) {
263 rigidBodyIndexContainer_.insert(beginIndex, endIndex);
264 }
265
266 void releaseRigidBodyIndex(std::vector<int> indices) {
267 rigidBodyIndexContainer_.insert(indices);
268 }
269
270 int getNextCutoffGroupIndex() { return cutoffGroupIndexContainer_.pop(); }
271
272 std::vector<int> getCutoffGroupIndicesBefore(int index) {
273 return cutoffGroupIndexContainer_.getIndicesBefore(index);
274 }
275
276 void releaseCutoffGroupIndex(int index) {
277 cutoffGroupIndexContainer_.insert(index);
278 }
279
280 void releaseCutoffGroupIndex(int beginIndex, int endIndex) {
281 cutoffGroupIndexContainer_.insert(beginIndex, endIndex);
282 }
283
284 void releaseCutoffGroupIndex(std::vector<int> indices) {
285 cutoffGroupIndexContainer_.insert(indices);
286 }
287
288 int getNextBondIndex() { return bondIndexContainer_.pop(); }
289
290 std::vector<int> getBondIndicesBefore(int index) {
291 return bondIndexContainer_.getIndicesBefore(index);
292 }
293
294 void releaseBondIndex(int index) { bondIndexContainer_.insert(index); }
295
296 void releaseBondIndex(int beginIndex, int endIndex) {
297 bondIndexContainer_.insert(beginIndex, endIndex);
298 }
299
300 void releaseBondIndex(std::vector<int> indices) {
301 bondIndexContainer_.insert(indices);
302 }
303
304 int getNextBendIndex() { return bendIndexContainer_.pop(); }
305
306 std::vector<int> getBendIndicesBefore(int index) {
307 return bendIndexContainer_.getIndicesBefore(index);
308 }
309
310 void releaseBendIndex(int index) { bendIndexContainer_.insert(index); }
311
312 void releaseBendIndex(int beginIndex, int endIndex) {
313 bendIndexContainer_.insert(beginIndex, endIndex);
314 }
315
316 void releaseBendIndex(std::vector<int> indices) {
317 bendIndexContainer_.insert(indices);
318 }
319
320 int getNextTorsionIndex() { return torsionIndexContainer_.pop(); }
321
322 std::vector<int> getTorsionIndicesBefore(int index) {
323 return torsionIndexContainer_.getIndicesBefore(index);
324 }
325
326 void releaseTorsionIndex(int index) {
327 torsionIndexContainer_.insert(index);
328 }
329
330 void releaseTorsionIndex(int beginIndex, int endIndex) {
331 torsionIndexContainer_.insert(beginIndex, endIndex);
332 }
333
334 void releaseTorsionIndex(std::vector<int> indices) {
335 torsionIndexContainer_.insert(indices);
336 }
337
338 int getNextInversionIndex() { return inversionIndexContainer_.pop(); }
339
340 std::vector<int> getInversionIndicesBefore(int index) {
341 return inversionIndexContainer_.getIndicesBefore(index);
342 }
343
344 void releaseInversionIndex(int index) {
345 inversionIndexContainer_.insert(index);
346 }
347
348 void releaseInversionIndex(int beginIndex, int endIndex) {
349 inversionIndexContainer_.insert(beginIndex, endIndex);
350 }
351
352 void releaseInversionIndex(std::vector<int> indices) {
353 inversionIndexContainer_.insert(indices);
354 }
355
356 private:
357 IndexListContainer atomIndexContainer_;
358 IndexListContainer rigidBodyIndexContainer_;
359 IndexListContainer cutoffGroupIndexContainer_;
360 IndexListContainer bondIndexContainer_;
361 IndexListContainer bendIndexContainer_;
362 IndexListContainer torsionIndexContainer_;
363 IndexListContainer inversionIndexContainer_;
364 };
365} // namespace OpenMD
366
367#endif // UTILS_LOCALINDEXMANAGER_HPP
void insert(std::vector< int > &indices)
Reclaims an index array.
void insert(int beginIndex, int endIndex)
Reclaims an index range.
"utils/LocalIndexManager.hpp"
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.