1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.crystal;
39
40 import static org.apache.commons.math3.util.FastMath.abs;
41 import static org.apache.commons.math3.util.FastMath.random;
42
43
44
45
46
47
48
49
50
51
52
53
54 public enum LatticeSystem {
55
56
57
58 TRICLINIC_LATTICE,
59
60
61
62 MONOCLINIC_LATTICE,
63
64
65
66 ORTHORHOMBIC_LATTICE,
67
68
69
70 TETRAGONAL_LATTICE,
71
72
73
74 RHOMBOHEDRAL_LATTICE,
75
76
77
78 HEXAGONAL_LATTICE,
79
80
81
82 CUBIC_LATTICE;
83
84
85
86
87
88
89
90
91
92 private static final double tolerance = 1.0e-15;
93
94
95
96
97
98
99
100
101 public static boolean check(double x1, double x2) {
102 return abs(x1 - x2) < tolerance;
103 }
104
105
106
107
108
109
110 public double[] resetUnitCellParams() {
111 double alpha = 60.0 + random() * 60.0;
112 double beta = 60.0 + random() * 60.0;
113 double gamma = 60.0 + random() * 60.0;
114 double[] params = {0.25 + random(), 0.25 + random(), 0.25 + random(), alpha, beta, gamma};
115 double ab = 0.5 * (params[0] + params[1]);
116 double abc = (params[0] + params[1] + params[2]) / 3.0;
117 switch (this) {
118 default -> {
119
120 }
121 case MONOCLINIC_LATTICE -> {
122
123 params[3] = 90.0;
124 params[5] = 90.0;
125 }
126 case ORTHORHOMBIC_LATTICE -> {
127
128 params[3] = 90.0;
129 params[4] = 90.0;
130 params[5] = 90.0;
131 }
132 case TETRAGONAL_LATTICE -> {
133
134 params[0] = ab;
135 params[1] = ab;
136 params[3] = 90.0;
137 params[4] = 90.0;
138 params[5] = 90.0;
139 }
140 case RHOMBOHEDRAL_LATTICE -> {
141
142 double angles = (params[3] + params[4] + params[5]) / 3.0;
143 params[0] = abc;
144 params[1] = abc;
145 params[2] = abc;
146 params[3] = angles;
147 params[4] = angles;
148 params[5] = angles;
149 }
150 case HEXAGONAL_LATTICE -> {
151
152 params[0] = ab;
153 params[1] = ab;
154 params[3] = 90.0;
155 params[4] = 90.0;
156 params[5] = 120.0;
157 }
158 case CUBIC_LATTICE -> {
159
160 params[0] = abc;
161 params[1] = abc;
162 params[2] = abc;
163 params[3] = 90.0;
164 params[4] = 90.0;
165 params[5] = 90.0;
166 }
167 }
168 return params;
169 }
170
171
172
173
174
175
176
177
178
179
180
181
182 public boolean validParameters(double a, double b, double c, double alpha, double beta,
183 double gamma) {
184 switch (this) {
185 default -> {
186
187 return true;
188 }
189 case MONOCLINIC_LATTICE -> {
190
191 return check(alpha, 90.0) && check(gamma, 90.0);
192 }
193 case ORTHORHOMBIC_LATTICE -> {
194
195 return check(alpha, 90.0) && check(beta, 90.0) && check(gamma, 90.0);
196 }
197 case TETRAGONAL_LATTICE -> {
198
199 return check(a, b) && check(alpha, 90.0) && check(beta, 90.0) && check(gamma, 90.0);
200 }
201 case RHOMBOHEDRAL_LATTICE -> {
202
203 return check(a, b) && check(b, c) && check(alpha, beta) && check(beta, gamma);
204 }
205 case HEXAGONAL_LATTICE -> {
206
207 return check(a, b) && check(alpha, 90.0) && check(beta, 90.0) && check(gamma, 120.0);
208 }
209 case CUBIC_LATTICE -> {
210
211 return check(a, b) && check(b, c) && check(alpha, 90.0) && check(beta, 90.0) && check(gamma,
212 90.0);
213 }
214 }
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228 public double[] fixParameters(double a, double b, double c, double alpha, double beta,
229 double gamma) {
230 double[] parameters = {a, b, c, alpha, beta, gamma};
231 double ab = (parameters[0] + parameters[1]) / 2;
232 double abc = (parameters[0] + parameters[1] + parameters[2]) / 3;
233 switch (this) {
234 default -> {
235
236 return parameters;
237 }
238 case MONOCLINIC_LATTICE -> {
239
240 parameters[3] = 90.0;
241 parameters[5] = 90.0;
242 return parameters;
243 }
244 case ORTHORHOMBIC_LATTICE -> {
245
246 parameters[3] = 90.0;
247 parameters[4] = 90.0;
248 parameters[5] = 90.0;
249 return parameters;
250 }
251 case TETRAGONAL_LATTICE -> {
252
253 parameters[0] = ab;
254 parameters[1] = ab;
255 parameters[3] = 90.0;
256 parameters[4] = 90.0;
257 parameters[5] = 90.0;
258 return parameters;
259 }
260 case RHOMBOHEDRAL_LATTICE -> {
261
262 double angles = (parameters[3] + parameters[4] + parameters[5]) / 3;
263 parameters[0] = abc;
264 parameters[1] = abc;
265 parameters[2] = abc;
266 parameters[3] = angles;
267 parameters[4] = angles;
268 parameters[5] = angles;
269 return parameters;
270 }
271 case HEXAGONAL_LATTICE -> {
272
273 parameters[0] = ab;
274 parameters[1] = ab;
275 parameters[3] = 90.0;
276 parameters[4] = 90.0;
277 parameters[5] = 120.0;
278 return parameters;
279 }
280 case CUBIC_LATTICE -> {
281
282 parameters[0] = abc;
283 parameters[1] = abc;
284 parameters[2] = abc;
285 parameters[3] = 90.0;
286 parameters[4] = 90.0;
287 parameters[5] = 90.0;
288 return parameters;
289 }
290 }
291 }
292
293
294
295
296
297
298
299 public double getDefaultBAxis(double aaxis) {
300 return aaxis;
301 }
302
303
304
305
306
307
308
309
310 public double getDefaultCAxis(double aaxis, double baxis) {
311 return (aaxis + baxis) / 2;
312 }
313
314
315
316
317
318
319 public double getDefaultAlpha() {
320 return 90.0;
321 }
322
323
324
325
326
327
328 public double getDefaultBeta() {
329 return 90.0;
330 }
331
332
333
334
335
336
337 public double getDefaultGamma() {
338 double gamma = 90.0;
339 if (this == HEXAGONAL_LATTICE) {
340 gamma = 120.0;
341 }
342 return gamma;
343 }
344 }