1 /* ----------------------------------------------------------------------
2    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
3    https://www.lammps.org/, Sandia National Laboratories
4    Steve Plimpton, sjplimp@sandia.gov
5 
6    Copyright (2003) Sandia Corporation.  Under the terms of Contract
7    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
8    certain rights in this software.  This software is distributed under
9    the GNU General Public License.
10 
11    See the README file in the top-level LAMMPS directory.
12 ------------------------------------------------------------------------- */
13 
14 #include "../testing/core.h"
15 #include "atom.h"
16 #include "domain.h"
17 #include "fmt/format.h"
18 #include "info.h"
19 #include "input.h"
20 #include "lammps.h"
21 #include "lattice.h"
22 #include "region.h"
23 #include "utils.h"
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 
27 #include <cstdio>
28 #include <cstring>
29 #include <fstream>
30 #include <iostream>
31 #include <mpi.h>
32 
33 // whether to print verbose output (i.e. not capturing LAMMPS screen output).
34 bool verbose = false;
35 
36 using LAMMPS_NS::utils::split_words;
37 
38 namespace LAMMPS_NS {
39 using ::testing::ExitedWithCode;
40 using ::testing::MatchesRegex;
41 using ::testing::StrEq;
42 
43 class LatticeRegionTest : public LAMMPSTest {
44 protected:
SetUp()45     void SetUp() override
46     {
47         testbinary = "LatticeRegionTest";
48         LAMMPSTest::SetUp();
49         command("units metal");
50     }
51 };
52 
TEST_F(LatticeRegionTest,lattice_none)53 TEST_F(LatticeRegionTest, lattice_none)
54 {
55     BEGIN_HIDE_OUTPUT();
56     command("lattice none 2.0");
57     END_HIDE_OUTPUT();
58     auto lattice = lmp->domain->lattice;
59     ASSERT_EQ(lattice->style, Lattice::NONE);
60     ASSERT_EQ(lattice->xlattice, 2.0);
61     ASSERT_EQ(lattice->ylattice, 2.0);
62     ASSERT_EQ(lattice->zlattice, 2.0);
63     ASSERT_EQ(lattice->nbasis, 0);
64     ASSERT_EQ(lattice->basis, nullptr);
65 
66     TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice"););
67     TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice xxx"););
68     TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice none 1.0 origin"););
69     TEST_FAILURE(".*ERROR: Expected floating point.*", command("lattice none xxx"););
70 
71     BEGIN_HIDE_OUTPUT();
72     command("units lj");
73     command("lattice none 1.0");
74     END_HIDE_OUTPUT();
75     lattice = lmp->domain->lattice;
76     ASSERT_EQ(lattice->xlattice, 1.0);
77     ASSERT_EQ(lattice->ylattice, 1.0);
78     ASSERT_EQ(lattice->zlattice, 1.0);
79 }
80 
TEST_F(LatticeRegionTest,lattice_sc)81 TEST_F(LatticeRegionTest, lattice_sc)
82 {
83     BEGIN_CAPTURE_OUTPUT();
84     command("lattice sc 1.0 spacing 1.5 2.0 3.0");
85     auto output = END_CAPTURE_OUTPUT();
86     ASSERT_THAT(output, MatchesRegex(".*Lattice spacing in x,y,z = 1.50* 2.0* 3.0*.*"));
87 
88     auto lattice = lmp->domain->lattice;
89     ASSERT_EQ(lattice->xlattice, 1.5);
90     ASSERT_EQ(lattice->ylattice, 2.0);
91     ASSERT_EQ(lattice->zlattice, 3.0);
92 
93     BEGIN_CAPTURE_OUTPUT();
94     command("lattice sc 2.0");
95     output = END_CAPTURE_OUTPUT();
96     ASSERT_THAT(output, MatchesRegex(".*Lattice spacing in x,y,z = 2.0* 2.0* 2.0*.*"));
97 
98     lattice = lmp->domain->lattice;
99     ASSERT_EQ(lattice->style, Lattice::SC);
100     ASSERT_EQ(lattice->xlattice, 2.0);
101     ASSERT_EQ(lattice->ylattice, 2.0);
102     ASSERT_EQ(lattice->zlattice, 2.0);
103     ASSERT_EQ(lattice->nbasis, 1);
104     ASSERT_NE(lattice->basis, nullptr);
105     ASSERT_EQ(lattice->a1[0], 1.0);
106     ASSERT_EQ(lattice->a1[1], 0.0);
107     ASSERT_EQ(lattice->a1[2], 0.0);
108     ASSERT_EQ(lattice->a2[0], 0.0);
109     ASSERT_EQ(lattice->a2[1], 1.0);
110     ASSERT_EQ(lattice->a2[2], 0.0);
111     ASSERT_EQ(lattice->a3[0], 0.0);
112     ASSERT_EQ(lattice->a3[1], 0.0);
113     ASSERT_EQ(lattice->a3[2], 1.0);
114     ASSERT_EQ(lattice->basis[0][0], 0.0);
115     ASSERT_EQ(lattice->basis[0][1], 0.0);
116     ASSERT_EQ(lattice->basis[0][2], 0.0);
117 
118     TEST_FAILURE(".*ERROR: Illegal lattice command.*",
119                  command("lattice sc 1.0 origin 1.0 1.0 1.0"););
120     TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice sc 1.0 origin 1.0"););
121     TEST_FAILURE(".*ERROR: Illegal lattice command.*",
122                  command("lattice sc 1.0 origin 0.0 0.0 0.0 xxx"););
123     TEST_FAILURE(".*ERROR: Expected floating point.*",
124                  command("lattice sc 1.0 origin xxx 1.0 1.0"););
125     TEST_FAILURE(".*ERROR: Lattice orient vectors are not orthogonal.*",
126                  command("lattice sc 1.0 orient x 2 2 0"););
127     TEST_FAILURE(".*ERROR: Lattice orient vectors are not right-handed.*",
128                  command("lattice sc 1.0 orient y 0 -1 0"););
129     TEST_FAILURE(".*ERROR: Lattice spacings are invalid.*",
130                  command("lattice sc 1.0 spacing 0.0 1.0 1.0"););
131     TEST_FAILURE(".*ERROR: Lattice spacings are invalid.*",
132                  command("lattice sc 1.0 spacing 1.0 -0.1 1.0"););
133 
134     BEGIN_HIDE_OUTPUT();
135     command("units lj");
136     command("lattice sc 2.0");
137     END_HIDE_OUTPUT();
138     lattice = lmp->domain->lattice;
139     ASSERT_DOUBLE_EQ(lattice->xlattice, pow(0.5, 1.0 / 3.0));
140     ASSERT_DOUBLE_EQ(lattice->ylattice, pow(0.5, 1.0 / 3.0));
141     ASSERT_DOUBLE_EQ(lattice->zlattice, pow(0.5, 1.0 / 3.0));
142 
143     BEGIN_HIDE_OUTPUT();
144     command("dimension 2");
145     END_HIDE_OUTPUT();
146     TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
147                  command("lattice sc 1.0"););
148 }
149 
TEST_F(LatticeRegionTest,lattice_bcc)150 TEST_F(LatticeRegionTest, lattice_bcc)
151 {
152     BEGIN_HIDE_OUTPUT();
153     command("lattice bcc 4.2 orient x 1 1 0 orient y -1 1 0");
154     END_HIDE_OUTPUT();
155     auto lattice = lmp->domain->lattice;
156     ASSERT_EQ(lattice->style, Lattice::BCC);
157     ASSERT_DOUBLE_EQ(lattice->xlattice, sqrt(2.0) * 4.2);
158     ASSERT_DOUBLE_EQ(lattice->ylattice, sqrt(2.0) * 4.2);
159     ASSERT_DOUBLE_EQ(lattice->zlattice, 4.2);
160     ASSERT_EQ(lattice->nbasis, 2);
161     ASSERT_EQ(lattice->basis[0][0], 0.0);
162     ASSERT_EQ(lattice->basis[0][1], 0.0);
163     ASSERT_EQ(lattice->basis[0][2], 0.0);
164     ASSERT_EQ(lattice->basis[1][0], 0.5);
165     ASSERT_EQ(lattice->basis[1][1], 0.5);
166     ASSERT_EQ(lattice->basis[1][2], 0.5);
167 
168     BEGIN_HIDE_OUTPUT();
169     command("dimension 2");
170     END_HIDE_OUTPUT();
171     TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
172                  command("lattice bcc 1.0"););
173 }
174 
TEST_F(LatticeRegionTest,lattice_fcc)175 TEST_F(LatticeRegionTest, lattice_fcc)
176 {
177     BEGIN_HIDE_OUTPUT();
178     command("lattice fcc 3.5 origin 0.5 0.5 0.5");
179     END_HIDE_OUTPUT();
180     auto lattice = lmp->domain->lattice;
181     ASSERT_EQ(lattice->style, Lattice::FCC);
182     ASSERT_DOUBLE_EQ(lattice->xlattice, 3.5);
183     ASSERT_DOUBLE_EQ(lattice->ylattice, 3.5);
184     ASSERT_DOUBLE_EQ(lattice->zlattice, 3.5);
185     ASSERT_EQ(lattice->nbasis, 4);
186     ASSERT_EQ(lattice->basis[0][0], 0.0);
187     ASSERT_EQ(lattice->basis[0][1], 0.0);
188     ASSERT_EQ(lattice->basis[0][2], 0.0);
189     ASSERT_EQ(lattice->basis[1][0], 0.5);
190     ASSERT_EQ(lattice->basis[1][1], 0.5);
191     ASSERT_EQ(lattice->basis[1][2], 0.0);
192     ASSERT_EQ(lattice->basis[2][0], 0.5);
193     ASSERT_EQ(lattice->basis[2][1], 0.0);
194     ASSERT_EQ(lattice->basis[2][2], 0.5);
195     ASSERT_EQ(lattice->basis[3][0], 0.0);
196     ASSERT_EQ(lattice->basis[3][1], 0.5);
197     ASSERT_EQ(lattice->basis[3][2], 0.5);
198 
199     TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
200                  command("lattice fcc 1.0 basis 0.0 0.0 0.0"););
201     TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
202                  command("lattice fcc 1.0 a1 0.0 1.0 0.0"););
203     TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice fcc 1.0 orient w 1 0 0"););
204 
205     BEGIN_HIDE_OUTPUT();
206     command("dimension 2");
207     END_HIDE_OUTPUT();
208     TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
209                  command("lattice fcc 1.0"););
210 }
211 
TEST_F(LatticeRegionTest,lattice_hcp)212 TEST_F(LatticeRegionTest, lattice_hcp)
213 {
214     BEGIN_HIDE_OUTPUT();
215     command("lattice hcp 3.0 orient z 0 0 1");
216     END_HIDE_OUTPUT();
217     auto lattice = lmp->domain->lattice;
218     ASSERT_EQ(lattice->style, Lattice::HCP);
219     ASSERT_DOUBLE_EQ(lattice->xlattice, 3.0);
220     ASSERT_DOUBLE_EQ(lattice->ylattice, 3.0 * sqrt(3.0));
221     ASSERT_DOUBLE_EQ(lattice->zlattice, 2.0 * sqrt(6.0));
222     ASSERT_EQ(lattice->nbasis, 4);
223     ASSERT_EQ(lattice->basis[0][0], 0.0);
224     ASSERT_EQ(lattice->basis[0][1], 0.0);
225     ASSERT_EQ(lattice->basis[0][2], 0.0);
226     ASSERT_EQ(lattice->basis[1][0], 0.5);
227     ASSERT_EQ(lattice->basis[1][1], 0.5);
228     ASSERT_EQ(lattice->basis[1][2], 0.0);
229     ASSERT_EQ(lattice->basis[2][0], 0.5);
230     ASSERT_DOUBLE_EQ(lattice->basis[2][1], 5.0 / 6.0);
231     ASSERT_EQ(lattice->basis[2][2], 0.5);
232     ASSERT_EQ(lattice->basis[3][0], 0.0);
233     ASSERT_DOUBLE_EQ(lattice->basis[3][1], 1.0 / 3.0);
234     ASSERT_EQ(lattice->basis[3][2], 0.5);
235     ASSERT_EQ(lattice->a1[0], 1.0);
236     ASSERT_EQ(lattice->a1[1], 0.0);
237     ASSERT_EQ(lattice->a1[2], 0.0);
238     ASSERT_EQ(lattice->a2[0], 0.0);
239     ASSERT_DOUBLE_EQ(lattice->a2[1], sqrt(3.0));
240     ASSERT_EQ(lattice->a2[2], 0.0);
241     ASSERT_EQ(lattice->a3[0], 0.0);
242     ASSERT_EQ(lattice->a3[1], 0.0);
243     ASSERT_DOUBLE_EQ(lattice->a3[2], sqrt(8.0 / 3.0));
244 
245     TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
246                  command("lattice hcp 1.0 a2 0.0 1.0 0.0"););
247     TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
248                  command("lattice hcp 1.0 a3 0.0 1.0 0.0"););
249     BEGIN_HIDE_OUTPUT();
250     command("dimension 2");
251     END_HIDE_OUTPUT();
252     TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
253                  command("lattice hcp 1.0"););
254 }
255 
TEST_F(LatticeRegionTest,lattice_diamond)256 TEST_F(LatticeRegionTest, lattice_diamond)
257 {
258     BEGIN_HIDE_OUTPUT();
259     command("lattice diamond 4.1 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1");
260     END_HIDE_OUTPUT();
261     auto lattice = lmp->domain->lattice;
262     ASSERT_EQ(lattice->style, Lattice::DIAMOND);
263     ASSERT_DOUBLE_EQ(lattice->xlattice, 6.6952719636073539);
264     ASSERT_DOUBLE_EQ(lattice->ylattice, 5.7982756057296889);
265     ASSERT_DOUBLE_EQ(lattice->zlattice, 7.1014083110323973);
266     ASSERT_EQ(lattice->nbasis, 8);
267     ASSERT_EQ(lattice->basis[0][0], 0.0);
268     ASSERT_EQ(lattice->basis[0][1], 0.0);
269     ASSERT_EQ(lattice->basis[0][2], 0.0);
270     ASSERT_EQ(lattice->basis[1][0], 0.0);
271     ASSERT_EQ(lattice->basis[1][1], 0.5);
272     ASSERT_EQ(lattice->basis[1][2], 0.5);
273     ASSERT_EQ(lattice->basis[2][0], 0.5);
274     ASSERT_EQ(lattice->basis[2][1], 0.0);
275     ASSERT_EQ(lattice->basis[2][2], 0.5);
276     ASSERT_EQ(lattice->basis[3][0], 0.5);
277     ASSERT_EQ(lattice->basis[3][1], 0.5);
278     ASSERT_EQ(lattice->basis[3][2], 0.0);
279     ASSERT_EQ(lattice->basis[4][0], 0.25);
280     ASSERT_EQ(lattice->basis[4][1], 0.25);
281     ASSERT_EQ(lattice->basis[4][2], 0.25);
282     ASSERT_EQ(lattice->basis[5][0], 0.25);
283     ASSERT_EQ(lattice->basis[5][1], 0.75);
284     ASSERT_EQ(lattice->basis[5][2], 0.75);
285     ASSERT_EQ(lattice->basis[6][0], 0.75);
286     ASSERT_EQ(lattice->basis[6][1], 0.25);
287     ASSERT_EQ(lattice->basis[6][2], 0.75);
288     ASSERT_EQ(lattice->basis[7][0], 0.75);
289     ASSERT_EQ(lattice->basis[7][1], 0.75);
290     ASSERT_EQ(lattice->basis[7][2], 0.25);
291     ASSERT_EQ(lattice->a1[0], 1.0);
292     ASSERT_EQ(lattice->a1[1], 0.0);
293     ASSERT_EQ(lattice->a1[2], 0.0);
294     ASSERT_EQ(lattice->a2[0], 0.0);
295     ASSERT_EQ(lattice->a2[1], 1.0);
296     ASSERT_EQ(lattice->a2[2], 0.0);
297     ASSERT_EQ(lattice->a3[0], 0.0);
298     ASSERT_EQ(lattice->a3[1], 0.0);
299     ASSERT_EQ(lattice->a3[2], 1.0);
300 
301     BEGIN_HIDE_OUTPUT();
302     command("dimension 2");
303     END_HIDE_OUTPUT();
304     TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
305                  command("lattice diamond 1.0"););
306 }
307 
TEST_F(LatticeRegionTest,lattice_sq)308 TEST_F(LatticeRegionTest, lattice_sq)
309 {
310     BEGIN_HIDE_OUTPUT();
311     command("dimension 2");
312     command("lattice sq 3.0");
313     END_HIDE_OUTPUT();
314     auto lattice = lmp->domain->lattice;
315     ASSERT_EQ(lattice->style, Lattice::SQ);
316     ASSERT_DOUBLE_EQ(lattice->xlattice, 3.0);
317     ASSERT_DOUBLE_EQ(lattice->ylattice, 3.0);
318     ASSERT_DOUBLE_EQ(lattice->zlattice, 3.0);
319     ASSERT_EQ(lattice->nbasis, 1);
320     ASSERT_EQ(lattice->basis[0][0], 0.0);
321     ASSERT_EQ(lattice->basis[0][1], 0.0);
322     ASSERT_EQ(lattice->basis[0][2], 0.0);
323 
324     TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
325                  command("lattice sq 1.0 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1"););
326 
327     BEGIN_HIDE_OUTPUT();
328     command("dimension 3");
329     END_HIDE_OUTPUT();
330     TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
331                  command("lattice sq 1.0"););
332 }
333 
TEST_F(LatticeRegionTest,lattice_sq2)334 TEST_F(LatticeRegionTest, lattice_sq2)
335 {
336     BEGIN_HIDE_OUTPUT();
337     command("dimension 2");
338     command("lattice sq2 2.0");
339     END_HIDE_OUTPUT();
340     auto lattice = lmp->domain->lattice;
341     ASSERT_EQ(lattice->style, Lattice::SQ2);
342     ASSERT_DOUBLE_EQ(lattice->xlattice, 2.0);
343     ASSERT_DOUBLE_EQ(lattice->ylattice, 2.0);
344     ASSERT_DOUBLE_EQ(lattice->zlattice, 2.0);
345     ASSERT_EQ(lattice->nbasis, 2);
346     ASSERT_EQ(lattice->basis[0][0], 0.0);
347     ASSERT_EQ(lattice->basis[0][1], 0.0);
348     ASSERT_EQ(lattice->basis[0][2], 0.0);
349     ASSERT_EQ(lattice->basis[1][0], 0.5);
350     ASSERT_EQ(lattice->basis[1][1], 0.5);
351     ASSERT_EQ(lattice->basis[1][2], 0.0);
352 
353     BEGIN_HIDE_OUTPUT();
354     command("dimension 3");
355     END_HIDE_OUTPUT();
356     TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
357                  command("lattice sq2 1.0"););
358 }
359 
TEST_F(LatticeRegionTest,lattice_hex)360 TEST_F(LatticeRegionTest, lattice_hex)
361 {
362     BEGIN_HIDE_OUTPUT();
363     command("dimension 2");
364     command("lattice hex 2.0");
365     END_HIDE_OUTPUT();
366     auto lattice = lmp->domain->lattice;
367     ASSERT_EQ(lattice->style, Lattice::HEX);
368     ASSERT_DOUBLE_EQ(lattice->xlattice, 2.0);
369     ASSERT_DOUBLE_EQ(lattice->ylattice, 3.4641016151377544);
370     ASSERT_DOUBLE_EQ(lattice->zlattice, 2.0);
371     ASSERT_EQ(lattice->nbasis, 2);
372     ASSERT_EQ(lattice->basis[0][0], 0.0);
373     ASSERT_EQ(lattice->basis[0][1], 0.0);
374     ASSERT_EQ(lattice->basis[0][2], 0.0);
375     ASSERT_EQ(lattice->basis[1][0], 0.5);
376     ASSERT_EQ(lattice->basis[1][1], 0.5);
377     ASSERT_EQ(lattice->basis[1][2], 0.0);
378     ASSERT_EQ(lattice->a1[0], 1.0);
379     ASSERT_EQ(lattice->a1[1], 0.0);
380     ASSERT_EQ(lattice->a1[2], 0.0);
381     ASSERT_EQ(lattice->a2[0], 0.0);
382     ASSERT_DOUBLE_EQ(lattice->a2[1], sqrt(3.0));
383     ASSERT_EQ(lattice->a2[2], 0.0);
384     ASSERT_EQ(lattice->a3[0], 0.0);
385     ASSERT_EQ(lattice->a3[1], 0.0);
386     ASSERT_EQ(lattice->a3[2], 1.0);
387 
388     BEGIN_HIDE_OUTPUT();
389     command("dimension 3");
390     END_HIDE_OUTPUT();
391     TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
392                  command("lattice hex 1.0"););
393 }
394 
TEST_F(LatticeRegionTest,lattice_custom)395 TEST_F(LatticeRegionTest, lattice_custom)
396 {
397     BEGIN_HIDE_OUTPUT();
398     command("variable a equal 4.34");
399     command("variable b equal $a*sqrt(3.0)");
400     command("variable c equal $a*sqrt(8.0/3.0)");
401     command("variable t equal 1.0/3.0");
402     command("variable f equal 5.0/6.0");
403     command("lattice custom  1.0     "
404             "a1      $a   0.0  0.0   "
405             "a2      0.0  $b   0.0   "
406             "a3      0.0  0.0  $c    "
407             "basis   0.0  0.0  0.0   "
408             "basis   0.5  0.5  0.0   "
409             "basis   $t   0.0  0.5   "
410             "basis   $f   0.5  0.5   "
411             "basis   0.0  0.0  0.625 "
412             "basis   0.5  0.5  0.625 "
413             "basis   $t   0.0  0.125 "
414             "basis   $f   0.5  0.125 ");
415     END_HIDE_OUTPUT();
416     auto lattice = lmp->domain->lattice;
417     ASSERT_EQ(lattice->style, Lattice::CUSTOM);
418     ASSERT_DOUBLE_EQ(lattice->xlattice, 4.34);
419     ASSERT_DOUBLE_EQ(lattice->ylattice, 4.34 * sqrt(3.0));
420     ASSERT_DOUBLE_EQ(lattice->zlattice, 4.34 * sqrt(8.0 / 3.0));
421     ASSERT_EQ(lattice->nbasis, 8);
422     ASSERT_DOUBLE_EQ(lattice->basis[0][0], 0.0);
423     ASSERT_DOUBLE_EQ(lattice->basis[0][1], 0.0);
424     ASSERT_DOUBLE_EQ(lattice->basis[0][2], 0.0);
425     ASSERT_DOUBLE_EQ(lattice->basis[1][0], 0.5);
426     ASSERT_DOUBLE_EQ(lattice->basis[1][1], 0.5);
427     ASSERT_DOUBLE_EQ(lattice->basis[1][2], 0.0);
428     ASSERT_NEAR(lattice->basis[2][0], 1.0 / 3.0, 1.0e-14);
429     ASSERT_DOUBLE_EQ(lattice->basis[2][1], 0.0);
430     ASSERT_DOUBLE_EQ(lattice->basis[2][2], 0.5);
431     ASSERT_DOUBLE_EQ(lattice->basis[3][0], 5.0 / 6.0);
432     ASSERT_DOUBLE_EQ(lattice->basis[3][1], 0.5);
433     ASSERT_DOUBLE_EQ(lattice->basis[3][2], 0.5);
434     ASSERT_DOUBLE_EQ(lattice->basis[4][0], 0.0);
435     ASSERT_DOUBLE_EQ(lattice->basis[4][1], 0.0);
436     ASSERT_DOUBLE_EQ(lattice->basis[4][2], 0.625);
437     ASSERT_DOUBLE_EQ(lattice->basis[5][0], 0.5);
438     ASSERT_DOUBLE_EQ(lattice->basis[5][1], 0.5);
439     ASSERT_DOUBLE_EQ(lattice->basis[5][2], 0.625);
440     ASSERT_NEAR(lattice->basis[6][0], 1.0 / 3.0, 1.0e-14);
441     ASSERT_DOUBLE_EQ(lattice->basis[6][1], 0.0);
442     ASSERT_DOUBLE_EQ(lattice->basis[6][2], 0.125);
443     ASSERT_DOUBLE_EQ(lattice->basis[7][0], 5.0 / 6.0);
444     ASSERT_DOUBLE_EQ(lattice->basis[7][1], 0.5);
445     ASSERT_DOUBLE_EQ(lattice->basis[7][2], 0.125);
446     ASSERT_DOUBLE_EQ(lattice->a1[0], 4.34);
447     ASSERT_DOUBLE_EQ(lattice->a1[1], 0.0);
448     ASSERT_DOUBLE_EQ(lattice->a1[2], 0.0);
449     ASSERT_DOUBLE_EQ(lattice->a2[0], 0.0);
450     ASSERT_DOUBLE_EQ(lattice->a2[1], 4.34 * sqrt(3.0));
451     ASSERT_DOUBLE_EQ(lattice->a2[2], 0.0);
452     ASSERT_DOUBLE_EQ(lattice->a3[0], 0.0);
453     ASSERT_DOUBLE_EQ(lattice->a3[1], 0.0);
454     ASSERT_DOUBLE_EQ(lattice->a3[2], 4.34 * sqrt(8.0 / 3.0));
455 
456     TEST_FAILURE(".*ERROR: Illegal lattice command.*",
457                  command("lattice custom 1.0 basis -0.1 0 0"););
458     TEST_FAILURE(".*ERROR: Illegal lattice command.*",
459                  command("lattice custom 1.0 basis 0.0 1.0 0"););
460 
461     BEGIN_HIDE_OUTPUT();
462     command("dimension 2");
463     END_HIDE_OUTPUT();
464     TEST_FAILURE(".*ERROR: No basis atoms in lattice.*", command("lattice custom 1.0"););
465     TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
466                  command("lattice custom 1.0 origin 0.5 0.5 0.5 basis 0.0 0.0 0.0"););
467     TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
468                  command("lattice custom 1.0 a1 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
469     TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
470                  command("lattice custom 1.0 a2 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
471     TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
472                  command("lattice custom 1.0 a3 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
473 }
474 
TEST_F(LatticeRegionTest,region_fail)475 TEST_F(LatticeRegionTest, region_fail)
476 {
477     BEGIN_HIDE_OUTPUT();
478     command("lattice none 2.0");
479     command("region box block 0 1 0 1 0 1");
480     END_HIDE_OUTPUT();
481 
482     TEST_FAILURE(".*ERROR: Create_atoms command before simulation box is defined.*",
483                  command("create_atoms 1 box"););
484     BEGIN_HIDE_OUTPUT();
485     command("create_box 1 box");
486     END_HIDE_OUTPUT();
487     TEST_FAILURE(".*ERROR: Cannot create atoms with undefined lattice.*",
488                  command("create_atoms 1 box"););
489 }
490 
TEST_F(LatticeRegionTest,region_block_lattice)491 TEST_F(LatticeRegionTest, region_block_lattice)
492 {
493     BEGIN_HIDE_OUTPUT();
494     command("lattice sc 1.5");
495     command("region box block 0 2 0 2 0 2 units lattice");
496     command("create_box 1 box");
497     command("create_atoms 1 box");
498     END_HIDE_OUTPUT();
499 
500     ASSERT_EQ(lmp->domain->triclinic, 0);
501     auto x = lmp->atom->x;
502     ASSERT_EQ(lmp->atom->natoms, 8);
503     ASSERT_DOUBLE_EQ(x[0][0], 0.0);
504     ASSERT_DOUBLE_EQ(x[0][1], 0.0);
505     ASSERT_DOUBLE_EQ(x[0][2], 0.0);
506     ASSERT_DOUBLE_EQ(x[1][0], 1.5);
507     ASSERT_DOUBLE_EQ(x[1][1], 0.0);
508     ASSERT_DOUBLE_EQ(x[1][2], 0.0);
509     ASSERT_DOUBLE_EQ(x[2][0], 0.0);
510     ASSERT_DOUBLE_EQ(x[2][1], 1.5);
511     ASSERT_DOUBLE_EQ(x[2][2], 0.0);
512     ASSERT_DOUBLE_EQ(x[3][0], 1.5);
513     ASSERT_DOUBLE_EQ(x[3][1], 1.5);
514     ASSERT_DOUBLE_EQ(x[3][2], 0.0);
515 }
516 
TEST_F(LatticeRegionTest,region_block_box)517 TEST_F(LatticeRegionTest, region_block_box)
518 {
519     BEGIN_HIDE_OUTPUT();
520     command("lattice sc 1.5 origin 0.75 0.75 0.75");
521     command("region box block 0 2 0 2 0 2 units box");
522     command("create_box 1 box");
523     command("create_atoms 1 box");
524     END_HIDE_OUTPUT();
525     ASSERT_EQ(lmp->domain->triclinic, 0);
526 
527     auto x = lmp->atom->x;
528     ASSERT_EQ(lmp->atom->natoms, 1);
529     ASSERT_DOUBLE_EQ(x[0][0], 1.125);
530     ASSERT_DOUBLE_EQ(x[0][1], 1.125);
531     ASSERT_DOUBLE_EQ(x[0][2], 1.125);
532 }
533 
TEST_F(LatticeRegionTest,region_cone)534 TEST_F(LatticeRegionTest, region_cone)
535 {
536     BEGIN_HIDE_OUTPUT();
537     command("lattice fcc 2.5 origin 0.5 0.5 0.5");
538     command("region box cone x 1.0 1.0 0.5 2.1 0.0 2.0");
539     command("create_box 1 box");
540     command("create_atoms 1 region box");
541     command("write_dump all atom init.lammpstrj");
542     END_HIDE_OUTPUT();
543     ASSERT_EQ(lmp->domain->triclinic, 0);
544     ASSERT_EQ(lmp->atom->natoms, 42);
545 }
546 
TEST_F(LatticeRegionTest,region_cylinder)547 TEST_F(LatticeRegionTest, region_cylinder)
548 {
549     BEGIN_HIDE_OUTPUT();
550     command("lattice fcc 2.5 origin 0.5 0.5 0.5");
551     command("region box cylinder z 1.0 1.0 2.1 0.0 2.0 ");
552     command("create_box 1 box");
553     command("create_atoms 1 region box");
554     END_HIDE_OUTPUT();
555     ASSERT_EQ(lmp->domain->triclinic, 0);
556     ASSERT_EQ(lmp->atom->natoms, 114);
557 }
558 
TEST_F(LatticeRegionTest,region_prism)559 TEST_F(LatticeRegionTest, region_prism)
560 {
561     BEGIN_HIDE_OUTPUT();
562     command("lattice bcc 2.5 origin 0.75 0.75 0.75");
563     command("region box prism 0 2 0 2 0 2 0.5 0.0 0.0");
564     command("create_box 1 box");
565     command("create_atoms 1 box");
566     END_HIDE_OUTPUT();
567     ASSERT_EQ(lmp->domain->triclinic, 1);
568     ASSERT_EQ(lmp->atom->natoms, 16);
569 }
570 
TEST_F(LatticeRegionTest,region_sphere)571 TEST_F(LatticeRegionTest, region_sphere)
572 {
573     BEGIN_HIDE_OUTPUT();
574     command("lattice fcc 2.5 origin 0.5 0.5 0.5");
575     command("region box sphere 1.0 1.0 1.0 1.1");
576     command("create_box 1 box");
577     command("create_atoms 1 region box");
578     END_HIDE_OUTPUT();
579     ASSERT_EQ(lmp->domain->triclinic, 0);
580     ASSERT_EQ(lmp->atom->natoms, 14);
581 }
582 
TEST_F(LatticeRegionTest,region_union)583 TEST_F(LatticeRegionTest, region_union)
584 {
585     BEGIN_HIDE_OUTPUT();
586     command("lattice fcc 2.5 origin 0.5 0.5 0.5");
587     command("region part1 sphere 2.0 1.0 1.0 1.1");
588     command("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
589     command("region box union 2 part1 part2");
590     command("create_box 1 box");
591     command("create_atoms 1 region box");
592     END_HIDE_OUTPUT();
593     ASSERT_EQ(lmp->domain->triclinic, 0);
594     ASSERT_EQ(lmp->atom->natoms, 67);
595 }
596 
TEST_F(LatticeRegionTest,region_intersect)597 TEST_F(LatticeRegionTest, region_intersect)
598 {
599     BEGIN_HIDE_OUTPUT();
600     command("lattice fcc 2.5 origin 0.5 0.5 0.5");
601     command("region part1 sphere 2.0 1.0 1.0 1.8");
602     command("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
603     command("region box intersect 2 part1 part2");
604     command("create_box 1 box");
605     command("create_atoms 1 region box");
606     END_HIDE_OUTPUT();
607     ASSERT_EQ(lmp->domain->triclinic, 0);
608     ASSERT_EQ(lmp->atom->natoms, 21);
609 }
610 
TEST_F(LatticeRegionTest,region_plane)611 TEST_F(LatticeRegionTest, region_plane)
612 {
613     BEGIN_HIDE_OUTPUT();
614     command("lattice fcc 2.5 origin 0.5 0.5 0.5");
615     command("region box block 0.0 2.0 0.0 2.0 0.0 2.0");
616     command("region part1 plane 0.5 1.0 0.0  0.75 0.0 0.0");
617     command("region part2 plane 1.5 1.0 0.0  0.75 0.0 0.0 side out");
618     command("region atoms intersect 2 part1 part2");
619     command("create_box 1 box");
620     command("create_atoms 1 region atoms");
621     command("write_dump all atom init.lammpstrj");
622     END_HIDE_OUTPUT();
623     ASSERT_EQ(lmp->domain->triclinic, 0);
624     ASSERT_EQ(lmp->atom->natoms, 16);
625 }
626 
627 } // namespace LAMMPS_NS
628 
main(int argc,char ** argv)629 int main(int argc, char **argv)
630 {
631     MPI_Init(&argc, &argv);
632     ::testing::InitGoogleMock(&argc, argv);
633 
634     if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
635         std::cout << "Warning: using OpenMPI without exceptions. "
636                      "Death tests will be skipped\n";
637 
638     // handle arguments passed via environment variable
639     if (const char *var = getenv("TEST_ARGS")) {
640         std::vector<std::string> env = split_words(var);
641         for (auto arg : env) {
642             if (arg == "-v") {
643                 verbose = true;
644             }
645         }
646     }
647 
648     if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
649 
650     int rv = RUN_ALL_TESTS();
651     MPI_Finalize();
652     return rv;
653 }
654