OpenMD 3.2
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 following paper when you publish your work:
33 *
34 * [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35 *
36 * Good starting points for code and simulation methodology are:
37 *
38 * [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39 * [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40 * [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43 * [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45 * [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46 */
47
48/**
49 * @file LocalIndexManager.hpp
50 * @author tlin
51 * @date 11/02/2004
52 * @version 1.0
53 */
54
55#ifndef UTILS_LOCALINDEXMANAGER_HPP
56#define UTILS_LOCALINDEXMANAGER_HPP
57
58#include <algorithm>
59#include <cassert>
60#include <iostream>
61#include <list>
62#include <utility>
63
64namespace OpenMD {
65
66 /**
67 * @class IndexListContainer
68 * @brief
69 * @todo documentation
70 */
71 class IndexListContainer {
72 public:
73 static const int MAX_INTEGER = 2147483647;
74
75 using IndexListContainerIterator = std::list<std::pair<int, int>>::iterator;
76
77 IndexListContainer(int minIndex = 0, int maxIndex = MAX_INTEGER) :
78 maxIndex_(maxIndex) {
79 indexContainer_.push_back(std::make_pair(minIndex, maxIndex));
80 }
81
82 int pop() {
83 if (indexContainer_.empty()) { std::cerr << "" << std::endl; }
84
85 int result;
86
87 result = indexContainer_.front().first;
88
89 if (indexContainer_.front().first == indexContainer_.front().second) {
90 indexContainer_.pop_front();
91 } else if (indexContainer_.front().first <
92 indexContainer_.front().second) {
93 ++indexContainer_.front().first;
94 } else {
95 std::cerr << "" << std::endl;
96 }
97
98 return result;
99 }
100
101 /**
102 *
103 */
104 void insert(int index) {
105 IndexListContainerIterator insertPos = internalInsert(index, index);
106 merge(insertPos);
107 }
108
109 /**
110 * Reclaims an index range
111 * @param beginIndex
112 * @param endIndex
113 */
114 void insert(int beginIndex, int endIndex) {
115 IndexListContainerIterator insertPos =
116 internalInsert(beginIndex, endIndex);
117 merge(insertPos);
118 }
119
120 /**
121 * Reclaims an index array.
122 * @param indices
123 */
124 void insert(std::vector<int>& indices) {
125 if (indices.empty()) { return; }
126
127 std::sort(indices.begin(), indices.end());
128 auto last = std::unique(indices.begin(), indices.end());
129 indices.erase(last, indices.end());
130
131 std::vector<int>::iterator i;
132 int beginIndex;
133
134 beginIndex = indices[0];
135
136 for (i = indices.begin() + 1; i != indices.end(); ++i) {
137 if (*i != *(i - 1) + 1) {
138 insert(beginIndex, *(i - 1));
139 beginIndex = *i;
140 }
141 }
142 }
143
144 std::vector<int> getIndicesBefore(int index) {
145 std::vector<int> result;
146 IndexListContainerIterator i;
147
148 for (i = indexContainer_.begin(); i != indexContainer_.end(); ++i) {
149 if ((*i).first > index) {
150 // we locate the node whose minimum index is greater that index
151 indexContainer_.erase(indexContainer_.begin(), i);
152 break;
153 } else if ((*i).second < index) {
154 // The biggest index current node hold is less than the index we want
155 for (int j = (*i).first; j <= (*i).second; ++j) {
156 result.push_back(j);
157 }
158 continue;
159 } else if ((*i).first == (*i).second) {
160 // the index happen to equal to a node which only contains one index
161 result.push_back((*i).first);
162 indexContainer_.erase(indexContainer_.begin(), i);
163 break;
164 } else {
165 for (int j = (*i).first; j < index; ++j) {
166 result.push_back(j);
167 }
168 (*i).first = index;
169 indexContainer_.erase(indexContainer_.begin(), i);
170 break;
171 }
172 }
173 return result;
174 }
175
176 int getMaxIndex() { return maxIndex_; }
177
178 private:
179 IndexListContainerIterator internalInsert(int beginIndex, int endIndex) {
180 if (beginIndex > endIndex) {
181 std::swap(beginIndex, endIndex);
182 std::cerr << "" << std::endl;
183 }
184
185 if (endIndex > maxIndex_) { std::cerr << "" << std::endl; }
186
187 IndexListContainerIterator i = indexContainer_.begin();
188 for (; i != indexContainer_.end(); ++i) {
189 if ((*i).first > endIndex) {
190 indexContainer_.insert(i, std::make_pair(beginIndex, endIndex));
191 return --i;
192 } else if ((*i).second < beginIndex) {
193 continue;
194 } else {
195 std::cerr << "" << std::endl;
196 }
197 }
198
199 indexContainer_.push_back(std::make_pair(beginIndex, endIndex));
200 return --indexContainer_.end();
201 }
202
203 void merge(IndexListContainerIterator i) {
204 IndexListContainerIterator j;
205
206 // check whether current node can be merged with its previous node
207 if (i != indexContainer_.begin()) {
208 j = i;
209 --j;
210 if (j != indexContainer_.begin() && (*j).second + 1 == (*i).first) {
211 (*i).first = (*j).first;
212 indexContainer_.erase(j);
213 }
214 }
215
216 // check whether current node can be merged with its next node
217 if (i != indexContainer_.end()) {
218 j = i;
219 ++j;
220
221 if (j != indexContainer_.end() && (*i).second + 1 == (*j).first) {
222 (*i).second = (*j).second;
223 indexContainer_.erase(j);
224 }
225 }
226 }
227
228 int maxIndex_;
229 std::list<std::pair<int, int>> indexContainer_;
230 };
231
232 /**
233 * @class LocalIndexManager LocalIndexManager.hpp
234 * "utils/LocalIndexManager.hpp"
235 * @brief
236 */
238 public:
239 int getNextAtomIndex() { return atomIndexContainer_.pop(); }
240
241 std::vector<int> getAtomIndicesBefore(int index) {
242 return atomIndexContainer_.getIndicesBefore(index);
243 }
244
245 void releaseAtomIndex(int index) { atomIndexContainer_.insert(index); }
246
247 void releaseAtomIndex(int beginIndex, int endIndex) {
248 atomIndexContainer_.insert(beginIndex, endIndex);
249 }
250
251 void releaseAtomIndex(std::vector<int> indices) {
252 atomIndexContainer_.insert(indices);
253 }
254
255 int getNextRigidBodyIndex() { return rigidBodyIndexContainer_.pop(); }
256
257 std::vector<int> getRigidBodyIndicesBefore(int index) {
258 return rigidBodyIndexContainer_.getIndicesBefore(index);
259 }
260
261 void releaseRigidBodyIndex(int index) {
262 rigidBodyIndexContainer_.insert(index);
263 }
264
265 void releaseRigidBodyIndex(int beginIndex, int endIndex) {
266 rigidBodyIndexContainer_.insert(beginIndex, endIndex);
267 }
268
269 void releaseRigidBodyIndex(std::vector<int> indices) {
270 rigidBodyIndexContainer_.insert(indices);
271 }
272
273 int getNextCutoffGroupIndex() { return cutoffGroupIndexContainer_.pop(); }
274
275 std::vector<int> getCutoffGroupIndicesBefore(int index) {
276 return cutoffGroupIndexContainer_.getIndicesBefore(index);
277 }
278
279 void releaseCutoffGroupIndex(int index) {
280 cutoffGroupIndexContainer_.insert(index);
281 }
282
283 void releaseCutoffGroupIndex(int beginIndex, int endIndex) {
284 cutoffGroupIndexContainer_.insert(beginIndex, endIndex);
285 }
286
287 void releaseCutoffGroupIndex(std::vector<int> indices) {
288 cutoffGroupIndexContainer_.insert(indices);
289 }
290
291 int getNextBondIndex() { return bondIndexContainer_.pop(); }
292
293 std::vector<int> getBondIndicesBefore(int index) {
294 return bondIndexContainer_.getIndicesBefore(index);
295 }
296
297 void releaseBondIndex(int index) { bondIndexContainer_.insert(index); }
298
299 void releaseBondIndex(int beginIndex, int endIndex) {
300 bondIndexContainer_.insert(beginIndex, endIndex);
301 }
302
303 void releaseBondIndex(std::vector<int> indices) {
304 bondIndexContainer_.insert(indices);
305 }
306
307 int getNextBendIndex() { return bendIndexContainer_.pop(); }
308
309 std::vector<int> getBendIndicesBefore(int index) {
310 return bendIndexContainer_.getIndicesBefore(index);
311 }
312
313 void releaseBendIndex(int index) { bendIndexContainer_.insert(index); }
314
315 void releaseBendIndex(int beginIndex, int endIndex) {
316 bendIndexContainer_.insert(beginIndex, endIndex);
317 }
318
319 void releaseBendIndex(std::vector<int> indices) {
320 bendIndexContainer_.insert(indices);
321 }
322
323 int getNextTorsionIndex() { return torsionIndexContainer_.pop(); }
324
325 std::vector<int> getTorsionIndicesBefore(int index) {
326 return torsionIndexContainer_.getIndicesBefore(index);
327 }
328
329 void releaseTorsionIndex(int index) {
330 torsionIndexContainer_.insert(index);
331 }
332
333 void releaseTorsionIndex(int beginIndex, int endIndex) {
334 torsionIndexContainer_.insert(beginIndex, endIndex);
335 }
336
337 void releaseTorsionIndex(std::vector<int> indices) {
338 torsionIndexContainer_.insert(indices);
339 }
340
341 int getNextInversionIndex() { return inversionIndexContainer_.pop(); }
342
343 std::vector<int> getInversionIndicesBefore(int index) {
344 return inversionIndexContainer_.getIndicesBefore(index);
345 }
346
347 void releaseInversionIndex(int index) {
348 inversionIndexContainer_.insert(index);
349 }
350
351 void releaseInversionIndex(int beginIndex, int endIndex) {
352 inversionIndexContainer_.insert(beginIndex, endIndex);
353 }
354
355 void releaseInversionIndex(std::vector<int> indices) {
356 inversionIndexContainer_.insert(indices);
357 }
358
359 private:
360 IndexListContainer atomIndexContainer_;
361 IndexListContainer rigidBodyIndexContainer_;
362 IndexListContainer cutoffGroupIndexContainer_;
363 IndexListContainer bondIndexContainer_;
364 IndexListContainer bendIndexContainer_;
365 IndexListContainer torsionIndexContainer_;
366 IndexListContainer inversionIndexContainer_;
367 };
368} // namespace OpenMD
369
370#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.