OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
Icosahedron.cpp
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
49
50#include <tuple>
51
52namespace OpenMD {
53
55 Basis.clear();
56 Edges.clear();
57 Facets.clear();
58 Points.clear();
59
60 //
61 // Initialize Basis vectors.
62 //
63 const RealType HGR = (sqrt(5.0) + 1.0) / 4.0; // half of the golden ratio
64
65 Basis.push_back(Vector3d(HGR, 0.0, 0.5));
66 Basis.push_back(Vector3d(HGR, 0.0, -0.5));
67 Basis.push_back(Vector3d(0.5, HGR, 0.0));
68 Basis.push_back(Vector3d(-0.5, HGR, 0.0));
69 Basis.push_back(Vector3d(0.0, 0.5, HGR));
70 Basis.push_back(Vector3d(0.0, -0.5, HGR));
71 Basis.push_back(Vector3d(0.5, -HGR, 0.0));
72 Basis.push_back(Vector3d(0.0, 0.5, -HGR));
73 Basis.push_back(Vector3d(-HGR, 0.0, 0.5));
74 Basis.push_back(Vector3d(0.0, -0.5, -HGR));
75 Basis.push_back(Vector3d(-HGR, 0.0, -0.5));
76 Basis.push_back(Vector3d(-0.5, -HGR, 0.0));
77
78 //
79 // Initialize 30 edges
80 //
81
82 Edges.push_back(std::make_pair(0, 1));
83 Edges.push_back(std::make_pair(0, 2));
84 Edges.push_back(std::make_pair(0, 4));
85 Edges.push_back(std::make_pair(0, 5));
86 Edges.push_back(std::make_pair(0, 6));
87
88 Edges.push_back(std::make_pair(10, 3));
89 Edges.push_back(std::make_pair(10, 7));
90 Edges.push_back(std::make_pair(10, 8));
91 Edges.push_back(std::make_pair(10, 9));
92 Edges.push_back(std::make_pair(10, 11));
93
94 Edges.push_back(std::make_pair(1, 2));
95 Edges.push_back(std::make_pair(1, 6));
96 Edges.push_back(std::make_pair(1, 7));
97 Edges.push_back(std::make_pair(1, 9));
98
99 Edges.push_back(std::make_pair(8, 3));
100 Edges.push_back(std::make_pair(8, 4));
101 Edges.push_back(std::make_pair(8, 5));
102 Edges.push_back(std::make_pair(8, 11));
103
104 Edges.push_back(std::make_pair(2, 3));
105 Edges.push_back(std::make_pair(2, 4));
106 Edges.push_back(std::make_pair(2, 7));
107
108 Edges.push_back(std::make_pair(11, 5));
109 Edges.push_back(std::make_pair(11, 6));
110 Edges.push_back(std::make_pair(11, 9));
111
112 Edges.push_back(std::make_pair(6, 5));
113 Edges.push_back(std::make_pair(6, 9));
114
115 Edges.push_back(std::make_pair(3, 4));
116 Edges.push_back(std::make_pair(3, 7));
117
118 Edges.push_back(std::make_pair(7, 9));
119
120 Edges.push_back(std::make_pair(5, 4));
121
122 //
123 // Initialize 20 facets
124 //
125 Facets.push_back(std::make_tuple(0, 1, 2));
126 Facets.push_back(std::make_tuple(0, 2, 4));
127 Facets.push_back(std::make_tuple(0, 4, 5));
128 Facets.push_back(std::make_tuple(0, 5, 6));
129 Facets.push_back(std::make_tuple(0, 1, 6));
130
131 Facets.push_back(std::make_tuple(10, 3, 7));
132 Facets.push_back(std::make_tuple(10, 3, 8));
133 Facets.push_back(std::make_tuple(10, 8, 11));
134 Facets.push_back(std::make_tuple(10, 9, 11));
135 Facets.push_back(std::make_tuple(10, 7, 9));
136
137 Facets.push_back(std::make_tuple(1, 2, 7));
138 Facets.push_back(std::make_tuple(1, 7, 9));
139 Facets.push_back(std::make_tuple(1, 6, 9));
140
141 Facets.push_back(std::make_tuple(8, 5, 11));
142 Facets.push_back(std::make_tuple(8, 4, 5));
143 Facets.push_back(std::make_tuple(8, 3, 4));
144
145 Facets.push_back(std::make_tuple(2, 3, 7));
146 Facets.push_back(std::make_tuple(2, 3, 4));
147
148 Facets.push_back(std::make_tuple(11, 5, 6));
149 Facets.push_back(std::make_tuple(11, 6, 9));
150 }
151
153 // OEIS A005902
154 if (n <= 0)
155 return 0;
156 else
157 return ((2 * n + 1) * (5 * n * n + 5 * n + 3)) / 3;
158 }
159
160 int Icosahedron::np(int n) {
161 // OEIS A005901
162 if (n < 0)
163 return -1;
164 else if (n == 0)
165 return 1;
166 else
167 return 10 * n * n + 2;
168 }
169
170 std::vector<Vector3d> Icosahedron::ih(int n) {
171 if (n < 0) return Points;
172
173 if (n == 0) {
174 // center particle only
175
176 Points.push_back(Vector3d(0.0, 0.0, 0.0));
177 return Points;
178 }
179
180 //
181 // Generate edge particles
182 //
183 for (std::vector<Vector3d>::iterator i = Basis.begin(); i != Basis.end();
184 ++i) {
185 Points.push_back((*i) * RealType(n));
186 }
187
188 //
189 // Generate side particles
190 //
191 if (n < 2) return Points;
192
193 for (std::vector<std::pair<int, int>>::iterator i = Edges.begin();
194 i != Edges.end(); ++i) {
195 Vector3d e1 = Basis[(*i).first] * RealType(n);
196 Vector3d e2 = Basis[(*i).second] * RealType(n);
197
198 for (int j = 1; j <= n - 1; j++) {
199 Points.push_back(e1 + (e2 - e1) * RealType(j) / RealType(n));
200 }
201 }
202
203 //
204 // Generate body particles
205 //
206 if (n < 3) return Points;
207
208 for (const auto& [first, second, third] : Facets) {
209 Vector3d e1 = Basis[first] * RealType(n);
210 Vector3d e2 = Basis[second] * RealType(n);
211 Vector3d e3 = Basis[third] * RealType(n);
212
213 for (int j = 1; j <= n - 2; j++) {
214 Vector3d v1 = e1 + (e2 - e1) * RealType(j + 1) / RealType(n);
215 Vector3d v2 = e1 + (e3 - e1) * RealType(j + 1) / RealType(n);
216
217 for (int k = 1; k <= j; k++) {
218 Points.push_back(v1 + (v2 - v1) * RealType(k) / RealType(j + 1));
219 }
220 }
221 }
222
223 return Points;
224 }
225
226 std::vector<Vector3d> Icosahedron::getPoints(int nshells) {
227 // generate the coordinates
228 for (int i = 0; i <= nshells; i++)
229 ih(i);
230 return Points;
231 }
232} // namespace OpenMD
Icosahedron cluster structure generator.
int np(int n)
Calculate number of particles on the nth layer.
Icosahedron()
Default constructor.
int getNpoints(int nShells)
Calculate number of particles in an icosahedron with nShells shells.
std::vector< Vector3d > getPoints(int nShells)
Get the generated points in an icosahedron with nShells shells.
std::vector< Vector3d > ih(int n)
Create nth layer particles.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.