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 "force.h"
17 #include "info.h"
18 #include "input.h"
19 #include "output.h"
20 #include "pair.h"
21 #include "thermo.h"
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 
25 #include <cmath>
26 #include <cstring>
27 #include <vector>
28 
29 // whether to print verbose output (i.e. not capturing LAMMPS screen output).
30 bool verbose = false;
31 
32 using LAMMPS_NS::utils::split_words;
33 
34 namespace LAMMPS_NS {
35 using ::testing::Eq;
36 
37 // eV to kcal/mol conversion constant (CODATA 2018)
38 const double ev_convert = utils::get_conversion_factor(utils::ENERGY, utils::METAL2REAL);
39 // 1atm in bar
40 const double p_convert = 1.01325;
41 // relative error for comparing numbers
42 // cannot use smaller value due to lack of consistency
43 // of data in update.cpp. could be 1.0e-12
44 const double rel_error = 5.0e-7;
45 
46 class PairUnitConvertTest : public LAMMPSTest {
47 protected:
48     double fold[4][3];
49 
SetUp()50     void SetUp() override
51     {
52         testbinary = "PairUnitConvertTest";
53         LAMMPSTest::SetUp();
54         ASSERT_NE(lmp, nullptr);
55 
56         BEGIN_HIDE_OUTPUT();
57         command("units metal");
58         command("dimension 3");
59         command("region box block -4 4 -4 4 -4 4");
60         command("create_box 2 box");
61         command("create_atoms 1 single -1.1  1.2  0.0 units box");
62         command("create_atoms 1 single -1.2 -1.1  0.0 units box");
63         command("create_atoms 2 single  0.9  1.0  0.0 units box");
64         command("create_atoms 2 single  1.0 -0.9  0.0 units box");
65         command("pair_style zero 4.0");
66         command("pair_coeff * *");
67         command("mass * 1.0");
68         command("write_data test_pair_unit_convert.data nocoeff");
69         command("clear");
70         END_HIDE_OUTPUT();
71     }
72 
TearDown()73     void TearDown() override
74     {
75         LAMMPSTest::TearDown();
76         remove("test_pair_unit_convert.data");
77     }
78 };
79 
TEST_F(PairUnitConvertTest,zero)80 TEST_F(PairUnitConvertTest, zero)
81 {
82     // check if the prerequisite pair style is available
83     if (!info->has_style("pair", "zero")) GTEST_SKIP();
84 
85     BEGIN_HIDE_OUTPUT();
86     command("units metal");
87     command("read_data test_pair_unit_convert.data");
88     command("pair_style zero 6.0");
89     command("pair_coeff * *");
90     command("run 0 post no");
91     END_HIDE_OUTPUT();
92 
93     // copy pressure, energy, and force from first step
94     double pold;
95     lmp->output->thermo->evaluate_keyword("press", &pold);
96     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
97     double **f  = lmp->atom->f;
98     for (int i = 0; i < 4; ++i)
99         for (int j = 0; j < 3; ++j)
100             fold[i][j] = f[i][j];
101 
102     BEGIN_HIDE_OUTPUT();
103     command("clear");
104     command("units real");
105     command("read_data test_pair_unit_convert.data");
106     command("pair_style zero 6.0");
107     command("pair_coeff * *");
108     command("run 0 post no");
109     END_HIDE_OUTPUT();
110 
111     double pnew;
112     lmp->output->thermo->evaluate_keyword("press", &pnew);
113     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
114     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
115     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
116 
117     f = lmp->atom->f;
118     for (int i = 0; i < 4; ++i)
119         for (int j = 0; j < 3; ++j)
120             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
121 }
122 
TEST_F(PairUnitConvertTest,lj_cut)123 TEST_F(PairUnitConvertTest, lj_cut)
124 {
125     // check if the prerequisite pair style is available
126     if (!info->has_style("pair", "lj/cut")) GTEST_SKIP();
127 
128     BEGIN_HIDE_OUTPUT();
129     command("units metal");
130     command("read_data test_pair_unit_convert.data");
131     command("pair_style lj/cut 6.0");
132     command("pair_coeff * * 0.01014286346782117 2.0");
133     remove("test.table.metal");
134     command("pair_write 1 1 1000 r 0.1 6.0 test.table.metal lj_1_1");
135     command("pair_write 1 2 1000 r 0.1 6.0 test.table.metal lj_1_2");
136     command("pair_write 2 2 1000 r 0.1 6.0 test.table.metal lj_2_2");
137     command("run 0 post no");
138     END_HIDE_OUTPUT();
139 
140     // copy pressure, energy, and force from first step
141     double pold;
142     lmp->output->thermo->evaluate_keyword("press", &pold);
143     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
144     double **f  = lmp->atom->f;
145     for (int i = 0; i < 4; ++i)
146         for (int j = 0; j < 3; ++j)
147             fold[i][j] = f[i][j];
148 
149     BEGIN_HIDE_OUTPUT();
150     command("clear");
151     command("units real");
152     command("read_data test_pair_unit_convert.data");
153     command("pair_style lj/cut 6.0");
154     command("pair_coeff * * 0.2339 2.0");
155     remove("test.table.real");
156     command("pair_write 1 1 1000 r 0.1 6.0 test.table.real lj_1_1");
157     command("pair_write 1 2 1000 r 0.1 6.0 test.table.real lj_1_2");
158     command("pair_write 2 2 1000 r 0.1 6.0 test.table.real lj_2_2");
159     command("run 0 post no");
160     END_HIDE_OUTPUT();
161 
162     double pnew;
163     lmp->output->thermo->evaluate_keyword("press", &pnew);
164     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
165     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
166     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
167 
168     f = lmp->atom->f;
169     for (int i = 0; i < 4; ++i)
170         for (int j = 0; j < 3; ++j)
171             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
172 }
173 
TEST_F(PairUnitConvertTest,eam)174 TEST_F(PairUnitConvertTest, eam)
175 {
176     // check if the prerequisite pair style is available
177     if (!info->has_style("pair", "eam")) GTEST_SKIP();
178 
179     BEGIN_HIDE_OUTPUT();
180     command("units metal");
181     command("read_data test_pair_unit_convert.data");
182     command("pair_style eam");
183     command("pair_coeff * * Cu_u3.eam");
184     command("run 0 post no");
185     END_HIDE_OUTPUT();
186 
187     // copy pressure, energy, and force from first step
188     double pold;
189     lmp->output->thermo->evaluate_keyword("press", &pold);
190     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
191     double **f  = lmp->atom->f;
192     for (int i = 0; i < 4; ++i)
193         for (int j = 0; j < 3; ++j)
194             fold[i][j] = f[i][j];
195 
196     BEGIN_HIDE_OUTPUT();
197     command("clear");
198     command("units real");
199     command("read_data test_pair_unit_convert.data");
200     command("pair_style eam");
201     command("pair_coeff * * Cu_u3.eam");
202     command("run 0 post no");
203     END_HIDE_OUTPUT();
204 
205     double pnew;
206     lmp->output->thermo->evaluate_keyword("press", &pnew);
207     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
208     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
209     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
210 
211     f = lmp->atom->f;
212     for (int i = 0; i < 4; ++i)
213         for (int j = 0; j < 3; ++j)
214             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
215 }
216 
TEST_F(PairUnitConvertTest,eam_alloy)217 TEST_F(PairUnitConvertTest, eam_alloy)
218 {
219     // check if the prerequisite pair style is available
220     if (!info->has_style("pair", "eam/alloy")) GTEST_SKIP();
221 
222     BEGIN_HIDE_OUTPUT();
223     command("units metal");
224     command("read_data test_pair_unit_convert.data");
225     command("pair_style eam/alloy");
226     command("pair_coeff * * AlCu.eam.alloy Al Cu");
227     command("run 0 post no");
228     END_HIDE_OUTPUT();
229 
230     // copy pressure, energy, and force from first step
231     double pold;
232     lmp->output->thermo->evaluate_keyword("press", &pold);
233     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
234     double **f  = lmp->atom->f;
235     for (int i = 0; i < 4; ++i)
236         for (int j = 0; j < 3; ++j)
237             fold[i][j] = f[i][j];
238 
239     BEGIN_HIDE_OUTPUT();
240     command("clear");
241     command("units real");
242     command("read_data test_pair_unit_convert.data");
243     command("pair_style eam/alloy");
244     command("pair_coeff * * AlCu.eam.alloy Al Cu");
245     command("run 0 post no");
246     END_HIDE_OUTPUT();
247 
248     double pnew;
249     lmp->output->thermo->evaluate_keyword("press", &pnew);
250     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
251     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
252     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
253 
254     f = lmp->atom->f;
255     for (int i = 0; i < 4; ++i)
256         for (int j = 0; j < 3; ++j)
257             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
258 }
259 
TEST_F(PairUnitConvertTest,eam_fs)260 TEST_F(PairUnitConvertTest, eam_fs)
261 {
262     // check if the prerequisite pair style is available
263     if (!info->has_style("pair", "eam/fs")) GTEST_SKIP();
264 
265     BEGIN_HIDE_OUTPUT();
266     command("units metal");
267     command("read_data test_pair_unit_convert.data");
268     command("pair_style eam/fs");
269     command("pair_coeff * * FeP_mm.eam.fs Fe P");
270     command("run 0 post no");
271     END_HIDE_OUTPUT();
272 
273     // copy pressure, energy, and force from first step
274     double pold;
275     lmp->output->thermo->evaluate_keyword("press", &pold);
276     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
277     double **f  = lmp->atom->f;
278     for (int i = 0; i < 4; ++i)
279         for (int j = 0; j < 3; ++j)
280             fold[i][j] = f[i][j];
281 
282     BEGIN_HIDE_OUTPUT();
283     command("clear");
284     command("units real");
285     command("read_data test_pair_unit_convert.data");
286     command("pair_style eam/fs");
287     command("pair_coeff * * FeP_mm.eam.fs Fe P");
288     command("run 0 post no");
289     END_HIDE_OUTPUT();
290 
291     double pnew;
292     lmp->output->thermo->evaluate_keyword("press", &pnew);
293     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
294     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
295     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
296 
297     f = lmp->atom->f;
298     for (int i = 0; i < 4; ++i)
299         for (int j = 0; j < 3; ++j)
300             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
301 }
302 
TEST_F(PairUnitConvertTest,eam_cd)303 TEST_F(PairUnitConvertTest, eam_cd)
304 {
305     // check if the prerequisite pair style is available
306     if (!info->has_style("pair", "eam/cd")) GTEST_SKIP();
307 
308     BEGIN_HIDE_OUTPUT();
309     command("units metal");
310     command("read_data test_pair_unit_convert.data");
311     command("pair_style eam/cd");
312     command("pair_coeff * * FeCr.cdeam Cr Fe");
313     command("run 0 post no");
314     END_HIDE_OUTPUT();
315 
316     // copy pressure, energy, and force from first step
317     double pold;
318     lmp->output->thermo->evaluate_keyword("press", &pold);
319     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
320     double **f  = lmp->atom->f;
321     for (int i = 0; i < 4; ++i)
322         for (int j = 0; j < 3; ++j)
323             fold[i][j] = f[i][j];
324 
325     BEGIN_HIDE_OUTPUT();
326     command("clear");
327     command("units real");
328     command("read_data test_pair_unit_convert.data");
329     command("pair_style eam/cd");
330     command("pair_coeff * * FeCr.cdeam Cr Fe");
331     command("run 0 post no");
332     END_HIDE_OUTPUT();
333 
334     double pnew;
335     lmp->output->thermo->evaluate_keyword("press", &pnew);
336     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
337     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
338     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
339 
340     f = lmp->atom->f;
341     for (int i = 0; i < 4; ++i)
342         for (int j = 0; j < 3; ++j)
343             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
344 }
345 
TEST_F(PairUnitConvertTest,eim)346 TEST_F(PairUnitConvertTest, eim)
347 {
348     // check if the prerequisite pair style is available
349     if (!info->has_style("pair", "eim")) GTEST_SKIP();
350 
351     BEGIN_HIDE_OUTPUT();
352     command("units metal");
353     command("read_data test_pair_unit_convert.data");
354     command("pair_style eim");
355     command("pair_coeff * * Na Cl ffield.eim Na Cl");
356     command("run 0 post no");
357     END_HIDE_OUTPUT();
358 
359     // copy pressure, energy, and force from first step
360     double pold;
361     lmp->output->thermo->evaluate_keyword("press", &pold);
362     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
363     double **f  = lmp->atom->f;
364     for (int i = 0; i < 4; ++i)
365         for (int j = 0; j < 3; ++j)
366             fold[i][j] = f[i][j];
367 
368     BEGIN_HIDE_OUTPUT();
369     command("clear");
370     command("units real");
371     command("read_data test_pair_unit_convert.data");
372     command("pair_style eim");
373     command("pair_coeff * * Na Cl ffield.eim Na Cl");
374     command("run 0 post no");
375     END_HIDE_OUTPUT();
376 
377     double pnew;
378     lmp->output->thermo->evaluate_keyword("press", &pnew);
379     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
380     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
381     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
382 
383     f = lmp->atom->f;
384     for (int i = 0; i < 4; ++i)
385         for (int j = 0; j < 3; ++j)
386             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
387 }
388 
TEST_F(PairUnitConvertTest,gw)389 TEST_F(PairUnitConvertTest, gw)
390 {
391     // check if the prerequisite pair style is available
392     if (!info->has_style("pair", "gw")) GTEST_SKIP();
393 
394     BEGIN_HIDE_OUTPUT();
395     command("units metal");
396     command("read_data test_pair_unit_convert.data");
397     command("pair_style gw");
398     command("pair_coeff * * SiC.gw Si C");
399     command("run 0 post no");
400     END_HIDE_OUTPUT();
401 
402     // copy pressure, energy, and force from first step
403     double pold;
404     lmp->output->thermo->evaluate_keyword("press", &pold);
405     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
406     double **f  = lmp->atom->f;
407     for (int i = 0; i < 4; ++i)
408         for (int j = 0; j < 3; ++j)
409             fold[i][j] = f[i][j];
410 
411     BEGIN_HIDE_OUTPUT();
412     command("clear");
413     command("units real");
414     command("read_data test_pair_unit_convert.data");
415     command("pair_style gw");
416     command("pair_coeff * * SiC.gw Si C");
417     command("run 0 post no");
418     END_HIDE_OUTPUT();
419 
420     double pnew;
421     lmp->output->thermo->evaluate_keyword("press", &pnew);
422     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
423     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
424     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
425 
426     f = lmp->atom->f;
427     for (int i = 0; i < 4; ++i)
428         for (int j = 0; j < 3; ++j)
429             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
430 }
431 
TEST_F(PairUnitConvertTest,gw_zbl)432 TEST_F(PairUnitConvertTest, gw_zbl)
433 {
434     // check if the prerequisite pair style is available
435     if (!info->has_style("pair", "gw/zbl")) GTEST_SKIP();
436 
437     BEGIN_HIDE_OUTPUT();
438     command("units metal");
439     command("read_data test_pair_unit_convert.data");
440     command("pair_style gw/zbl");
441     command("pair_coeff * * SiC.gw.zbl Si C");
442     command("run 0 post no");
443     END_HIDE_OUTPUT();
444 
445     // copy pressure, energy, and force from first step
446     double pold;
447     lmp->output->thermo->evaluate_keyword("press", &pold);
448     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
449     double **f  = lmp->atom->f;
450     for (int i = 0; i < 4; ++i)
451         for (int j = 0; j < 3; ++j)
452             fold[i][j] = f[i][j];
453 
454     BEGIN_HIDE_OUTPUT();
455     command("clear");
456     command("units real");
457     command("read_data test_pair_unit_convert.data");
458     command("pair_style gw/zbl");
459     command("pair_coeff * * SiC.gw.zbl Si C");
460     command("run 0 post no");
461     END_HIDE_OUTPUT();
462 
463     double pnew;
464     lmp->output->thermo->evaluate_keyword("press", &pnew);
465     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
466     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
467     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
468 
469     f = lmp->atom->f;
470     for (int i = 0; i < 4; ++i)
471         for (int j = 0; j < 3; ++j)
472             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
473 }
474 
TEST_F(PairUnitConvertTest,nb3b_harmonic)475 TEST_F(PairUnitConvertTest, nb3b_harmonic)
476 {
477     // check if the prerequisite pair style is available
478     if (!info->has_style("pair", "nb3b/harmonic")) GTEST_SKIP();
479 
480     BEGIN_HIDE_OUTPUT();
481     command("units metal");
482     command("read_data test_pair_unit_convert.data");
483     command("pair_style nb3b/harmonic");
484     command("pair_coeff * * MOH.nb3b.harmonic M O");
485     command("run 0 post no");
486     END_HIDE_OUTPUT();
487 
488     // copy pressure, energy, and force from first step
489     double pold;
490     lmp->output->thermo->evaluate_keyword("press", &pold);
491     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
492     double **f  = lmp->atom->f;
493     for (int i = 0; i < 4; ++i)
494         for (int j = 0; j < 3; ++j)
495             fold[i][j] = f[i][j];
496 
497     BEGIN_HIDE_OUTPUT();
498     command("clear");
499     command("units real");
500     command("read_data test_pair_unit_convert.data");
501     command("pair_style nb3b/harmonic");
502     command("pair_coeff * * MOH.nb3b.harmonic M O");
503     command("run 0 post no");
504     END_HIDE_OUTPUT();
505 
506     double pnew;
507     lmp->output->thermo->evaluate_keyword("press", &pnew);
508     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
509     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
510     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
511 
512     f = lmp->atom->f;
513     for (int i = 0; i < 4; ++i)
514         for (int j = 0; j < 3; ++j)
515             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
516 }
517 
TEST_F(PairUnitConvertTest,sw)518 TEST_F(PairUnitConvertTest, sw)
519 {
520     // check if the prerequisite pair style is available
521     if (!info->has_style("pair", "sw")) GTEST_SKIP();
522 
523     BEGIN_HIDE_OUTPUT();
524     command("units metal");
525     command("read_data test_pair_unit_convert.data");
526     command("pair_style sw");
527     command("pair_coeff * * GaN.sw Ga N");
528     command("run 0 post no");
529     END_HIDE_OUTPUT();
530 
531     // copy pressure, energy, and force from first step
532     double pold;
533     lmp->output->thermo->evaluate_keyword("press", &pold);
534     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
535     double **f  = lmp->atom->f;
536     for (int i = 0; i < 4; ++i)
537         for (int j = 0; j < 3; ++j)
538             fold[i][j] = f[i][j];
539 
540     BEGIN_HIDE_OUTPUT();
541     command("clear");
542     command("units real");
543     command("read_data test_pair_unit_convert.data");
544     command("pair_style sw");
545     command("pair_coeff * * GaN.sw Ga N");
546     command("run 0 post no");
547     END_HIDE_OUTPUT();
548 
549     double pnew;
550     lmp->output->thermo->evaluate_keyword("press", &pnew);
551     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
552     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
553     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
554 
555     f = lmp->atom->f;
556     for (int i = 0; i < 4; ++i)
557         for (int j = 0; j < 3; ++j)
558             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
559 }
560 
TEST_F(PairUnitConvertTest,table_metal2real)561 TEST_F(PairUnitConvertTest, table_metal2real)
562 {
563     // check if the prerequisite pair style is available
564     if (!info->has_style("pair", "table")) GTEST_SKIP();
565 
566     BEGIN_HIDE_OUTPUT();
567     command("units metal");
568     command("read_data test_pair_unit_convert.data");
569     command("pair_style table linear 1000");
570     command("pair_coeff 1 1 test.table.metal lj_1_1");
571     command("pair_coeff 1 2 test.table.metal lj_1_2");
572     command("pair_coeff 2 2 test.table.metal lj_2_2");
573     command("run 0 post no");
574     END_HIDE_OUTPUT();
575 
576     // copy pressure, energy, and force from first step
577     double pold;
578     lmp->output->thermo->evaluate_keyword("press", &pold);
579     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
580     double **f  = lmp->atom->f;
581     for (int i = 0; i < 4; ++i)
582         for (int j = 0; j < 3; ++j)
583             fold[i][j] = f[i][j];
584 
585     BEGIN_HIDE_OUTPUT();
586     command("clear");
587     command("units real");
588     command("read_data test_pair_unit_convert.data");
589     command("pair_style table linear 1000");
590     command("pair_coeff 1 1 test.table.metal lj_1_1");
591     command("pair_coeff 1 2 test.table.metal lj_1_2");
592     command("pair_coeff 2 2 test.table.metal lj_2_2");
593     command("run 0 post no");
594     END_HIDE_OUTPUT();
595 
596     double pnew;
597     lmp->output->thermo->evaluate_keyword("press", &pnew);
598     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
599     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
600     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
601 
602     f = lmp->atom->f;
603     for (int i = 0; i < 4; ++i)
604         for (int j = 0; j < 3; ++j)
605             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
606 }
607 
TEST_F(PairUnitConvertTest,table_real2metal)608 TEST_F(PairUnitConvertTest, table_real2metal)
609 {
610     // check if the prerequisite pair style is available
611     if (!info->has_style("pair", "table")) GTEST_SKIP();
612 
613     BEGIN_HIDE_OUTPUT();
614     command("units real");
615     command("read_data test_pair_unit_convert.data");
616     command("pair_style table linear 1000");
617     command("pair_coeff 1 1 test.table.real lj_1_1");
618     command("pair_coeff 1 2 test.table.real lj_1_2");
619     command("pair_coeff 2 2 test.table.real lj_2_2");
620     command("run 0 post no");
621     END_HIDE_OUTPUT();
622 
623     // copy pressure, energy, and force from first step
624     double pold;
625     lmp->output->thermo->evaluate_keyword("press", &pold);
626     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
627     double **f  = lmp->atom->f;
628     for (int i = 0; i < 4; ++i)
629         for (int j = 0; j < 3; ++j)
630             fold[i][j] = f[i][j];
631 
632     BEGIN_HIDE_OUTPUT();
633     command("clear");
634     command("units metal");
635     command("read_data test_pair_unit_convert.data");
636     command("pair_style table linear 1000");
637     command("pair_coeff 1 1 test.table.real lj_1_1");
638     command("pair_coeff 1 2 test.table.real lj_1_2");
639     command("pair_coeff 2 2 test.table.real lj_2_2");
640     command("run 0 post no");
641     END_HIDE_OUTPUT();
642 
643     double pnew;
644     lmp->output->thermo->evaluate_keyword("press", &pnew);
645     EXPECT_NEAR(pold, 1.0 / p_convert * pnew, fabs(pnew * rel_error));
646     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
647     EXPECT_NEAR(1.0 / ev_convert * eold, enew, fabs(enew * rel_error));
648 
649     f = lmp->atom->f;
650     for (int i = 0; i < 4; ++i)
651         for (int j = 0; j < 3; ++j)
652             EXPECT_NEAR(1.0 / ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
653 }
654 
TEST_F(PairUnitConvertTest,tersoff)655 TEST_F(PairUnitConvertTest, tersoff)
656 {
657     // check if the prerequisite pair style is available
658     if (!info->has_style("pair", "tersoff")) GTEST_SKIP();
659 
660     BEGIN_HIDE_OUTPUT();
661     command("units metal");
662     command("read_data test_pair_unit_convert.data");
663     command("pair_style tersoff");
664     command("pair_coeff * * SiC.tersoff Si C");
665     command("run 0 post no");
666     END_HIDE_OUTPUT();
667 
668     // copy pressure, energy, and force from first step
669     double pold;
670     lmp->output->thermo->evaluate_keyword("press", &pold);
671     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
672     double **f  = lmp->atom->f;
673     for (int i = 0; i < 4; ++i)
674         for (int j = 0; j < 3; ++j)
675             fold[i][j] = f[i][j];
676 
677     BEGIN_HIDE_OUTPUT();
678     command("clear");
679     command("units real");
680     command("read_data test_pair_unit_convert.data");
681     command("pair_style tersoff");
682     command("pair_coeff * * SiC.tersoff Si C");
683     command("run 0 post no");
684     END_HIDE_OUTPUT();
685 
686     double pnew;
687     lmp->output->thermo->evaluate_keyword("press", &pnew);
688     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
689     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
690     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
691 
692     f = lmp->atom->f;
693     for (int i = 0; i < 4; ++i)
694         for (int j = 0; j < 3; ++j)
695             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
696 }
697 
TEST_F(PairUnitConvertTest,tersoff_mod)698 TEST_F(PairUnitConvertTest, tersoff_mod)
699 {
700     // check if the prerequisite pair style is available
701     if (!info->has_style("pair", "tersoff/mod")) GTEST_SKIP();
702 
703     BEGIN_HIDE_OUTPUT();
704     command("units metal");
705     command("read_data test_pair_unit_convert.data");
706     command("pair_style tersoff/mod");
707     command("pair_coeff * * Si.tersoff.mod Si Si");
708     command("run 0 post no");
709     END_HIDE_OUTPUT();
710 
711     // copy pressure, energy, and force from first step
712     double pold;
713     lmp->output->thermo->evaluate_keyword("press", &pold);
714     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
715     double **f  = lmp->atom->f;
716     for (int i = 0; i < 4; ++i)
717         for (int j = 0; j < 3; ++j)
718             fold[i][j] = f[i][j];
719 
720     BEGIN_HIDE_OUTPUT();
721     command("clear");
722     command("units real");
723     command("read_data test_pair_unit_convert.data");
724     command("pair_style tersoff/mod");
725     command("pair_coeff * * Si.tersoff.mod Si Si");
726     command("run 0 post no");
727     END_HIDE_OUTPUT();
728 
729     double pnew;
730     lmp->output->thermo->evaluate_keyword("press", &pnew);
731     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
732     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
733     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
734 
735     f = lmp->atom->f;
736     for (int i = 0; i < 4; ++i)
737         for (int j = 0; j < 3; ++j)
738             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
739 }
740 
TEST_F(PairUnitConvertTest,tersoff_mod_c)741 TEST_F(PairUnitConvertTest, tersoff_mod_c)
742 {
743     // check if the prerequisite pair style is available
744     if (!info->has_style("pair", "tersoff/mod/c")) GTEST_SKIP();
745 
746     BEGIN_HIDE_OUTPUT();
747     command("units metal");
748     command("read_data test_pair_unit_convert.data");
749     command("pair_style tersoff/mod/c");
750     command("pair_coeff * * Si.tersoff.modc Si Si");
751     command("run 0 post no");
752     END_HIDE_OUTPUT();
753 
754     // copy pressure, energy, and force from first step
755     double pold;
756     lmp->output->thermo->evaluate_keyword("press", &pold);
757     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
758     double **f  = lmp->atom->f;
759     for (int i = 0; i < 4; ++i)
760         for (int j = 0; j < 3; ++j)
761             fold[i][j] = f[i][j];
762 
763     BEGIN_HIDE_OUTPUT();
764     command("clear");
765     command("units real");
766     command("read_data test_pair_unit_convert.data");
767     command("pair_style tersoff/mod/c");
768     command("pair_coeff * * Si.tersoff.modc Si Si");
769     command("run 0 post no");
770     END_HIDE_OUTPUT();
771 
772     double pnew;
773     lmp->output->thermo->evaluate_keyword("press", &pnew);
774     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
775     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
776     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
777 
778     f = lmp->atom->f;
779     for (int i = 0; i < 4; ++i)
780         for (int j = 0; j < 3; ++j)
781             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
782 }
783 
TEST_F(PairUnitConvertTest,tersoff_table)784 TEST_F(PairUnitConvertTest, tersoff_table)
785 {
786     // check if the prerequisite pair style is available
787     if (!info->has_style("pair", "tersoff/table")) GTEST_SKIP();
788 
789     BEGIN_HIDE_OUTPUT();
790     command("units metal");
791     command("read_data test_pair_unit_convert.data");
792     command("pair_style tersoff/table");
793     command("pair_coeff * * SiC.tersoff Si C");
794     command("run 0 post no");
795     END_HIDE_OUTPUT();
796 
797     // copy pressure, energy, and force from first step
798     double pold;
799     lmp->output->thermo->evaluate_keyword("press", &pold);
800     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
801     double **f  = lmp->atom->f;
802     for (int i = 0; i < 4; ++i)
803         for (int j = 0; j < 3; ++j)
804             fold[i][j] = f[i][j];
805 
806     BEGIN_HIDE_OUTPUT();
807     command("clear");
808     command("units real");
809     command("read_data test_pair_unit_convert.data");
810     command("pair_style tersoff/table");
811     command("pair_coeff * * SiC.tersoff Si C");
812     command("run 0 post no");
813     END_HIDE_OUTPUT();
814 
815     double pnew;
816     lmp->output->thermo->evaluate_keyword("press", &pnew);
817     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
818     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
819     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
820 
821     f = lmp->atom->f;
822     for (int i = 0; i < 4; ++i)
823         for (int j = 0; j < 3; ++j)
824             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
825 }
826 
TEST_F(PairUnitConvertTest,tersoff_zbl)827 TEST_F(PairUnitConvertTest, tersoff_zbl)
828 {
829     // check if the prerequisite pair style is available
830     if (!info->has_style("pair", "tersoff/zbl")) GTEST_SKIP();
831 
832     BEGIN_HIDE_OUTPUT();
833     command("units metal");
834     command("read_data test_pair_unit_convert.data");
835     command("pair_style tersoff/zbl");
836     command("pair_coeff * * SiC.tersoff.zbl Si C");
837     command("run 0 post no");
838     END_HIDE_OUTPUT();
839 
840     // copy pressure, energy, and force from first step
841     double pold;
842     lmp->output->thermo->evaluate_keyword("press", &pold);
843     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
844     double **f  = lmp->atom->f;
845     for (int i = 0; i < 4; ++i)
846         for (int j = 0; j < 3; ++j)
847             fold[i][j] = f[i][j];
848 
849     BEGIN_HIDE_OUTPUT();
850     command("clear");
851     command("units real");
852     command("read_data test_pair_unit_convert.data");
853     command("pair_style tersoff/zbl");
854     command("pair_coeff * * SiC.tersoff.zbl Si C");
855     command("run 0 post no");
856     END_HIDE_OUTPUT();
857 
858     double pnew;
859     lmp->output->thermo->evaluate_keyword("press", &pnew);
860     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
861     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
862     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
863 
864     f = lmp->atom->f;
865     for (int i = 0; i < 4; ++i)
866         for (int j = 0; j < 3; ++j)
867             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
868 }
869 
TEST_F(PairUnitConvertTest,tersoff_zbl_omp)870 TEST_F(PairUnitConvertTest, tersoff_zbl_omp)
871 {
872     // check if the prerequisite pair style is available
873     if (!info->has_style("pair", "tersoff/zbl/omp")) GTEST_SKIP();
874 
875     BEGIN_HIDE_OUTPUT();
876     command("package omp 4");
877     command("units metal");
878     command("read_data test_pair_unit_convert.data");
879     command("pair_style tersoff/zbl/omp");
880     command("pair_coeff * * SiC.tersoff.zbl Si C");
881     command("run 0 post no");
882     END_HIDE_OUTPUT();
883 
884     // copy pressure, energy, and force from first step
885     double pold;
886     lmp->output->thermo->evaluate_keyword("press", &pold);
887     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
888     double **f  = lmp->atom->f;
889     for (int i = 0; i < 4; ++i)
890         for (int j = 0; j < 3; ++j)
891             fold[i][j] = f[i][j];
892 
893     BEGIN_HIDE_OUTPUT();
894     command("clear");
895     command("package omp 4");
896     command("units real");
897     command("read_data test_pair_unit_convert.data");
898     command("pair_style tersoff/zbl/omp");
899     command("pair_coeff * * SiC.tersoff.zbl Si C");
900     command("run 0 post no");
901     END_HIDE_OUTPUT();
902 
903     double pnew;
904     lmp->output->thermo->evaluate_keyword("press", &pnew);
905     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
906     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
907     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
908 
909     f = lmp->atom->f;
910     for (int i = 0; i < 4; ++i)
911         for (int j = 0; j < 3; ++j)
912             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
913 }
914 
TEST_F(PairUnitConvertTest,vashishta)915 TEST_F(PairUnitConvertTest, vashishta)
916 {
917     // check if the prerequisite pair style is available
918     if (!info->has_style("pair", "vashishta")) GTEST_SKIP();
919 
920     BEGIN_HIDE_OUTPUT();
921     command("units metal");
922     command("read_data test_pair_unit_convert.data");
923     command("pair_style vashishta");
924     command("pair_coeff * * SiC.vashishta Si C");
925     command("run 0 post no");
926     END_HIDE_OUTPUT();
927 
928     // copy pressure, energy, and force from first step
929     double pold;
930     lmp->output->thermo->evaluate_keyword("press", &pold);
931     double eold = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
932     double **f  = lmp->atom->f;
933     for (int i = 0; i < 4; ++i)
934         for (int j = 0; j < 3; ++j)
935             fold[i][j] = f[i][j];
936 
937     BEGIN_HIDE_OUTPUT();
938     command("clear");
939     command("units real");
940     command("read_data test_pair_unit_convert.data");
941     command("pair_style vashishta");
942     command("pair_coeff * * SiC.vashishta Si C");
943     command("run 0 post no");
944     END_HIDE_OUTPUT();
945 
946     double pnew;
947     lmp->output->thermo->evaluate_keyword("press", &pnew);
948     EXPECT_NEAR(pold, p_convert * pnew, fabs(pnew * rel_error));
949     double enew = lmp->force->pair->eng_vdwl + lmp->force->pair->eng_coul;
950     EXPECT_NEAR(ev_convert * eold, enew, fabs(enew * rel_error));
951 
952     f = lmp->atom->f;
953     for (int i = 0; i < 4; ++i)
954         for (int j = 0; j < 3; ++j)
955             EXPECT_NEAR(ev_convert * fold[i][j], f[i][j], fabs(f[i][j] * rel_error));
956 }
957 
958 } // namespace LAMMPS_NS
959 
main(int argc,char ** argv)960 int main(int argc, char **argv)
961 {
962     MPI_Init(&argc, &argv);
963     ::testing::InitGoogleMock(&argc, argv);
964 
965     // handle arguments passed via environment variable
966     if (const char *var = getenv("TEST_ARGS")) {
967         std::vector<std::string> env = split_words(var);
968         for (auto arg : env) {
969             if (arg == "-v") {
970                 verbose = true;
971             }
972         }
973     }
974     if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
975 
976     int rv = RUN_ALL_TESTS();
977     MPI_Finalize();
978     remove("test.table.metal");
979     remove("test.table.real");
980     return rv;
981 }
982