OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
TypeContainer.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 TypeContainer.hpp
50 * @author tlin
51 * @date 11/04/2004
52 * @version 1.0
53 */
54
55#ifndef UTILS_TYPECONTAINER_HPP
56#define UTILS_TYPECONTAINER_HPP
57
58#include <algorithm>
59#include <map>
60#include <vector>
61
62#include "utils/MemoryUtils.hpp"
63#include "utils/Utility.hpp"
65
66namespace OpenMD {
67
68 /**
69 * @class TypeContainer TypeContainer.hpp "utils/TypeContainer.hpp"
70 */
71 template<class ElemType, int SIZE>
72 class TypeContainer {
73 public:
74 using ElemPtr = ElemType*;
75 using KeyType = std::vector<std::string>;
76 using KeyTypeIterator = typename KeyType::iterator;
77 using ValueType = std::pair<int, ElemPtr>;
78 using MapType = typename std::map<KeyType, ValueType>;
79 using MapTypeIterator = typename std::map<KeyType, ValueType>::iterator;
80 using value_type = typename MapType::value_type;
81 using MutableValues = typename std::vector<int>;
82
83 TypeContainer() : index_(0) {}
84
85 ~TypeContainer() { Utils::deletePointers(data_); }
86
87 bool add(KeyType& keys, ElemPtr elem) {
88 assert(keys.size() == SIZE);
89 assert(elem);
90 return data_.insert(value_type(keys, std::make_pair(index_++, elem)))
91 .second;
92 }
93
94 bool replace(KeyType& keys, ElemPtr elem) {
95 assert(keys.size() == SIZE);
96 assert(elem);
97
98 MapTypeIterator i;
99 i = data_.find(keys);
100 if (i != data_.end()) {
101 data_[keys] = std::make_pair((i->second).first, elem);
102 return true;
103 } else {
104 return data_.insert(value_type(keys, std::make_pair(index_++, elem)))
105 .second;
106 }
107 }
108
109 /** Exact Match */
110 ElemPtr find(KeyType& keys) {
111 assert(keys.size() == SIZE);
112 MapTypeIterator i;
113
114 i = data_.find(keys);
115 if (i != data_.end()) { return (i->second).second; }
116
117 KeyType reversedKeys = keys;
118 std::reverse(reversedKeys.begin(), reversedKeys.end());
119
120 i = data_.find(reversedKeys);
121 if (i != data_.end()) {
122 return (i->second).second;
123 } else {
124 return NULL;
125 }
126 }
127
128 ElemPtr permutedFindSkippingFirstElement(KeyType& keys) {
129 assert(keys.size() == SIZE);
130 MapTypeIterator i;
131
132 KeyType permutedKeys = keys;
133
134 // skip the first element:
135 KeyTypeIterator start;
136 start = permutedKeys.begin();
137 ++start;
138
139 std::sort(start, permutedKeys.end());
140
141 do {
142 i = data_.find(permutedKeys);
143 if (i != data_.end()) { return (i->second).second; }
144 } while (std::next_permutation(start, permutedKeys.end()));
145
146 return NULL;
147 }
148
149 /**
150 * @todo
151 */
152 ElemPtr find(KeyType& keys, const std::string& wildCard) {
153 assert(keys.size() == SIZE);
154
155 std::vector<KeyTypeIterator> iterCont;
156 KeyType replacedKey;
157 MapTypeIterator i;
158 std::vector<ValueType> foundTypes;
159
160 while (replaceWithWildCard(iterCont, keys, replacedKey, wildCard)) {
161 i = data_.find(replacedKey);
162 if (i != data_.end()) { foundTypes.push_back(i->second); }
163 }
164
165 // reverse the order of keys
166 KeyType reversedKeys = keys;
167 std::reverse(reversedKeys.begin(), reversedKeys.end());
168
169 // if the reversedKeys is the same as keys, just skip it
170 if (reversedKeys != keys) {
171 // empty the iterator container
172 iterCont.clear();
173
174 while (replaceWithWildCard(iterCont, reversedKeys, replacedKey,
175 wildCard)) {
176 i = data_.find(replacedKey);
177 if (i != data_.end()) { foundTypes.push_back(i->second); }
178 }
179
180 // replaceWithWildCard can not generate this particular sequence, we
181 // have to do it manually
182 KeyType allWildCards(SIZE, wildCard);
183 i = data_.find(allWildCards);
184 if (i != data_.end()) { foundTypes.push_back(i->second); }
185 }
186
187 typename std::vector<ValueType>::iterator j;
188 j = std::min_element(foundTypes.begin(), foundTypes.end());
189 return j == foundTypes.end() ? NULL : j->second;
190 }
191
192 ElemPtr permutedFindSkippingFirstElement(KeyType& keys,
193 const std::string& wildCard) {
194 assert(keys.size() == SIZE);
195 MapTypeIterator i;
196 MapTypeIterator i2;
197 std::vector<KeyTypeIterator> iterCont;
198 std::vector<std::string> replacedKeys;
199 std::vector<ValueType> foundTypes;
200
201 while (replaceWithWildCardSkippingFirstElement(iterCont, keys,
202 replacedKeys, wildCard)) {
203 KeyType permutedKeys = replacedKeys;
204 // skip the first element:
205 KeyTypeIterator start;
206 start = permutedKeys.begin();
207 ++start;
208 std::sort(start, permutedKeys.end());
209 do {
210 i2 = data_.find(permutedKeys);
211 if (i2 != data_.end()) { foundTypes.push_back(i2->second); }
212 } while (std::next_permutation(start, permutedKeys.end()));
213 }
214
215 // replaceWithWildCard can not generate this particular sequence, we
216 // have to do it manually
217
218 KeyType allWildCards(SIZE, wildCard);
219 // but retain first element:
220 allWildCards[0] = keys[0];
221 KeyTypeIterator start;
222 start = allWildCards.begin();
223 ++start;
224 std::sort(start, allWildCards.end());
225 do {
226 i2 = data_.find(allWildCards);
227 if (i2 != data_.end()) { foundTypes.push_back(i2->second); }
228 } while (std::next_permutation(start, allWildCards.end()));
229
230 typename std::vector<ValueType>::iterator j;
231 j = std::min_element(foundTypes.begin(), foundTypes.end());
232 return j == foundTypes.end() ? NULL : j->second;
233 }
234
235 size_t size() { return data_.size(); }
236
237 ElemPtr beginType(MapTypeIterator& i) {
238 i = data_.begin();
239 return i != data_.end() ? (i->second).second : NULL;
240 }
241
242 ElemPtr nextType(MapTypeIterator& i) {
243 ++i;
244 return i != data_.end() ? (i->second).second : NULL;
245 }
246
247 KeyType getKeys(MapTypeIterator& i) { return i->first; }
248
249 private:
250 int index_;
251 MapType data_;
252 };
253} // namespace OpenMD
254
255#endif // UTILS_TYPECONTAINER_HPP
ElemPtr find(KeyType &keys)
Exact Match.
ElemPtr find(KeyType &keys, const std::string &wildCard)
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
bool replaceWithWildCard(std::vector< std::vector< std::string >::iterator > &cont, std::vector< std::string > &sequence, std::vector< std::string > &result, const std::string &wildCard)
iteratively replace the sequence with wild cards
Definition Utility.cpp:58