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 "MANYBODY/pair_comb.h"
15 #include "MANYBODY/pair_comb3.h"
16 #include "MANYBODY/pair_gw.h"
17 #include "MANYBODY/pair_gw_zbl.h"
18 #include "MANYBODY/pair_nb3b_harmonic.h"
19 #include "MANYBODY/pair_sw.h"
20 #include "MANYBODY/pair_tersoff.h"
21 #include "MANYBODY/pair_tersoff_mod.h"
22 #include "MANYBODY/pair_tersoff_mod_c.h"
23 #include "MANYBODY/pair_tersoff_table.h"
24 #include "MANYBODY/pair_tersoff_zbl.h"
25 #include "MANYBODY/pair_vashishta.h"
26 #include "info.h"
27 #include "input.h"
28 #include "potential_file_reader.h"
29 #include "gmock/gmock.h"
30 #include "gtest/gtest.h"
31
32 #include "../testing/core.h"
33
34 #include <cstring>
35 #include <iostream>
36 #include <mpi.h>
37 #include <vector>
38
39 using namespace LAMMPS_NS;
40 using ::testing::MatchesRegex;
41 using utils::split_words;
42
43 // whether to print verbose output (i.e. not capturing LAMMPS screen output).
44 bool verbose = false;
45
46 #if __cplusplus < 201703L
47 constexpr int LAMMPS_NS::PairSW::NPARAMS_PER_LINE;
48 constexpr int LAMMPS_NS::PairComb::NPARAMS_PER_LINE;
49 constexpr int LAMMPS_NS::PairComb3::NPARAMS_PER_LINE;
50 constexpr int LAMMPS_NS::PairTersoff::NPARAMS_PER_LINE;
51 constexpr int LAMMPS_NS::PairTersoffMOD::NPARAMS_PER_LINE;
52 constexpr int LAMMPS_NS::PairTersoffMODC::NPARAMS_PER_LINE;
53 constexpr int LAMMPS_NS::PairTersoffZBL::NPARAMS_PER_LINE;
54 constexpr int LAMMPS_NS::PairGW::NPARAMS_PER_LINE;
55 constexpr int LAMMPS_NS::PairGWZBL::NPARAMS_PER_LINE;
56 constexpr int LAMMPS_NS::PairNb3bHarmonic::NPARAMS_PER_LINE;
57 constexpr int LAMMPS_NS::PairVashishta::NPARAMS_PER_LINE;
58 constexpr int LAMMPS_NS::PairTersoffTable::NPARAMS_PER_LINE;
59 #endif
60
61 class PotentialFileReaderTest : public LAMMPSTest {
62 };
63
64 // open for native units
TEST_F(PotentialFileReaderTest,Sw_native)65 TEST_F(PotentialFileReaderTest, Sw_native)
66 {
67 BEGIN_HIDE_OUTPUT();
68 command("units metal");
69 PotentialFileReader reader(lmp, "Si.sw", "Stillinger-Weber");
70 END_HIDE_OUTPUT();
71
72 auto line = reader.next_line(PairSW::NPARAMS_PER_LINE);
73 ASSERT_EQ(utils::count_words(line), PairSW::NPARAMS_PER_LINE);
74 }
75
76 // open with supported conversion enabled
TEST_F(PotentialFileReaderTest,Sw_conv)77 TEST_F(PotentialFileReaderTest, Sw_conv)
78 {
79 BEGIN_HIDE_OUTPUT();
80 command("units real");
81 PotentialFileReader reader(lmp, "Si.sw", "Stillinger-Weber", utils::METAL2REAL);
82 END_HIDE_OUTPUT();
83
84 auto line = reader.next_line(PairSW::NPARAMS_PER_LINE);
85 ASSERT_EQ(utils::count_words(line), PairSW::NPARAMS_PER_LINE);
86 }
87
88 // open without conversion enabled
TEST_F(PotentialFileReaderTest,Sw_noconv)89 TEST_F(PotentialFileReaderTest, Sw_noconv)
90 {
91 BEGIN_HIDE_OUTPUT();
92 command("units real");
93 END_HIDE_OUTPUT();
94
95 TEST_FAILURE(".*ERROR on proc.*potential.*requires metal units but real.*",
96 PotentialFileReader reader(lmp, "Si.sw", "Stillinger-Weber", utils::REAL2METAL););
97 }
98
TEST_F(PotentialFileReaderTest,Comb)99 TEST_F(PotentialFileReaderTest, Comb)
100 {
101 BEGIN_HIDE_OUTPUT();
102 command("units metal");
103 PotentialFileReader reader(lmp, "ffield.comb", "COMB");
104 END_HIDE_OUTPUT();
105
106 auto line = reader.next_line(PairComb::NPARAMS_PER_LINE);
107 ASSERT_EQ(utils::count_words(line), PairComb::NPARAMS_PER_LINE);
108 }
109
TEST_F(PotentialFileReaderTest,Comb3)110 TEST_F(PotentialFileReaderTest, Comb3)
111 {
112 BEGIN_HIDE_OUTPUT();
113 command("units metal");
114 PotentialFileReader reader(lmp, "ffield.comb3", "COMB3");
115 END_HIDE_OUTPUT();
116
117 auto line = reader.next_line(PairComb3::NPARAMS_PER_LINE);
118 ASSERT_EQ(utils::count_words(line), PairComb3::NPARAMS_PER_LINE);
119 }
120
TEST_F(PotentialFileReaderTest,Tersoff)121 TEST_F(PotentialFileReaderTest, Tersoff)
122 {
123 BEGIN_HIDE_OUTPUT();
124 command("units metal");
125 PotentialFileReader reader(lmp, "Si.tersoff", "Tersoff");
126 END_HIDE_OUTPUT();
127
128 auto line = reader.next_line(PairTersoff::NPARAMS_PER_LINE);
129 ASSERT_EQ(utils::count_words(line), PairTersoff::NPARAMS_PER_LINE);
130 }
131
TEST_F(PotentialFileReaderTest,TersoffMod)132 TEST_F(PotentialFileReaderTest, TersoffMod)
133 {
134 BEGIN_HIDE_OUTPUT();
135 command("units metal");
136 PotentialFileReader reader(lmp, "Si.tersoff.mod", "Tersoff/Mod");
137 END_HIDE_OUTPUT();
138
139 auto line = reader.next_line(PairTersoffMOD::NPARAMS_PER_LINE);
140 ASSERT_EQ(utils::count_words(line), PairTersoffMOD::NPARAMS_PER_LINE);
141 }
142
TEST_F(PotentialFileReaderTest,TersoffModC)143 TEST_F(PotentialFileReaderTest, TersoffModC)
144 {
145 BEGIN_HIDE_OUTPUT();
146 command("units metal");
147 PotentialFileReader reader(lmp, "Si.tersoff.modc", "Tersoff/ModC");
148 END_HIDE_OUTPUT();
149
150 auto line = reader.next_line(PairTersoffMODC::NPARAMS_PER_LINE);
151 ASSERT_EQ(utils::count_words(line), PairTersoffMODC::NPARAMS_PER_LINE);
152 }
153
TEST_F(PotentialFileReaderTest,TersoffTable)154 TEST_F(PotentialFileReaderTest, TersoffTable)
155 {
156 BEGIN_HIDE_OUTPUT();
157 command("units metal");
158 PotentialFileReader reader(lmp, "Si.tersoff", "TersoffTable");
159 END_HIDE_OUTPUT();
160
161 auto line = reader.next_line(PairTersoffTable::NPARAMS_PER_LINE);
162 ASSERT_EQ(utils::count_words(line), PairTersoffTable::NPARAMS_PER_LINE);
163 }
164
TEST_F(PotentialFileReaderTest,TersoffZBL)165 TEST_F(PotentialFileReaderTest, TersoffZBL)
166 {
167 BEGIN_HIDE_OUTPUT();
168 command("units metal");
169 PotentialFileReader reader(lmp, "SiC.tersoff.zbl", "Tersoff/ZBL");
170 END_HIDE_OUTPUT();
171
172 auto line = reader.next_line(PairTersoffZBL::NPARAMS_PER_LINE);
173 ASSERT_EQ(utils::count_words(line), PairTersoffZBL::NPARAMS_PER_LINE);
174 }
175
TEST_F(PotentialFileReaderTest,GW)176 TEST_F(PotentialFileReaderTest, GW)
177 {
178 BEGIN_HIDE_OUTPUT();
179 command("units metal");
180 PotentialFileReader reader(lmp, "SiC.gw", "GW");
181 END_HIDE_OUTPUT();
182
183 auto line = reader.next_line(PairGW::NPARAMS_PER_LINE);
184 ASSERT_EQ(utils::count_words(line), PairGW::NPARAMS_PER_LINE);
185 }
186
TEST_F(PotentialFileReaderTest,GWZBL)187 TEST_F(PotentialFileReaderTest, GWZBL)
188 {
189 BEGIN_HIDE_OUTPUT();
190 command("units metal");
191 PotentialFileReader reader(lmp, "SiC.gw.zbl", "GW/ZBL");
192 END_HIDE_OUTPUT();
193
194 auto line = reader.next_line(PairGWZBL::NPARAMS_PER_LINE);
195 ASSERT_EQ(utils::count_words(line), PairGWZBL::NPARAMS_PER_LINE);
196 }
197
TEST_F(PotentialFileReaderTest,Nb3bHarmonic)198 TEST_F(PotentialFileReaderTest, Nb3bHarmonic)
199 {
200 BEGIN_HIDE_OUTPUT();
201 command("units real");
202 PotentialFileReader reader(lmp, "MOH.nb3b.harmonic", "NB3B Harmonic");
203 END_HIDE_OUTPUT();
204
205 auto line = reader.next_line(PairNb3bHarmonic::NPARAMS_PER_LINE);
206 ASSERT_EQ(utils::count_words(line), PairNb3bHarmonic::NPARAMS_PER_LINE);
207 }
208
TEST_F(PotentialFileReaderTest,Vashishta)209 TEST_F(PotentialFileReaderTest, Vashishta)
210 {
211 BEGIN_HIDE_OUTPUT();
212 command("units metal");
213 PotentialFileReader reader(lmp, "SiC.vashishta", "Vashishta");
214 END_HIDE_OUTPUT();
215
216 auto line = reader.next_line(PairVashishta::NPARAMS_PER_LINE);
217 ASSERT_EQ(utils::count_words(line), PairVashishta::NPARAMS_PER_LINE);
218 }
219
TEST_F(PotentialFileReaderTest,UnitConvert)220 TEST_F(PotentialFileReaderTest, UnitConvert)
221 {
222 PotentialFileReader *reader;
223 int unit_convert, flag;
224
225 BEGIN_HIDE_OUTPUT();
226 command("units metal");
227 reader = new PotentialFileReader(lmp, "Si.sw", "Stillinger-Weber");
228 END_HIDE_OUTPUT();
229
230 unit_convert = reader->get_unit_convert();
231 ASSERT_EQ(unit_convert, 0);
232 delete reader;
233
234 BEGIN_HIDE_OUTPUT();
235 flag = utils::get_supported_conversions(utils::UNKNOWN);
236 reader = new PotentialFileReader(lmp, "Si.sw", "Stillinger-Weber", flag);
237 END_HIDE_OUTPUT();
238
239 unit_convert = reader->get_unit_convert();
240 ASSERT_EQ(unit_convert, 0);
241 delete reader;
242
243 BEGIN_HIDE_OUTPUT();
244 flag = utils::get_supported_conversions(utils::ENERGY);
245 reader = new PotentialFileReader(lmp, "Si.sw", "Stillinger-Weber", flag);
246 END_HIDE_OUTPUT();
247
248 unit_convert = reader->get_unit_convert();
249 ASSERT_EQ(unit_convert, 0);
250 delete reader;
251
252 BEGIN_HIDE_OUTPUT();
253 flag = utils::get_supported_conversions(utils::ENERGY);
254 command("units real");
255 reader = new PotentialFileReader(lmp, "Si.sw", "Stillinger-Weber", flag);
256 END_HIDE_OUTPUT();
257
258 unit_convert = reader->get_unit_convert();
259 ASSERT_EQ(unit_convert, utils::METAL2REAL);
260 delete reader;
261 }
262
263 class OpenPotentialTest : public LAMMPSTest {
264 };
265
266 // open for native units
TEST_F(OpenPotentialTest,Sw_native)267 TEST_F(OpenPotentialTest, Sw_native)
268 {
269 int convert_flag = utils::get_supported_conversions(utils::ENERGY);
270 BEGIN_CAPTURE_OUTPUT();
271 command("units metal");
272 FILE *fp = utils::open_potential("Si.sw", lmp, &convert_flag);
273 auto text = END_CAPTURE_OUTPUT();
274 double conv = utils::get_conversion_factor(utils::ENERGY, convert_flag);
275
276 ASSERT_NE(fp, nullptr);
277 ASSERT_DOUBLE_EQ(conv, 1.0);
278 fclose(fp);
279 }
280
281 // open with supported conversion enabled
TEST_F(OpenPotentialTest,Sw_conv)282 TEST_F(OpenPotentialTest, Sw_conv)
283 {
284 int convert_flag = utils::get_supported_conversions(utils::ENERGY);
285 ASSERT_EQ(convert_flag, utils::METAL2REAL | utils::REAL2METAL);
286 BEGIN_HIDE_OUTPUT();
287 command("units real");
288 FILE *fp = utils::open_potential("Si.sw", lmp, &convert_flag);
289 auto text = END_CAPTURE_OUTPUT();
290 double conv = utils::get_conversion_factor(utils::ENERGY, convert_flag);
291
292 ASSERT_NE(fp, nullptr);
293 ASSERT_EQ(convert_flag, utils::METAL2REAL);
294 ASSERT_DOUBLE_EQ(conv, 23.060549);
295 fclose(fp);
296 }
297
298 // open with conversion disabled
TEST_F(OpenPotentialTest,Sw_noconv)299 TEST_F(OpenPotentialTest, Sw_noconv)
300 {
301 BEGIN_HIDE_OUTPUT();
302 command("units real");
303 END_HIDE_OUTPUT();
304 TEST_FAILURE(".*potential.*requires metal units but real.*",
305 utils::open_potential("Si.sw", lmp, nullptr););
306 BEGIN_HIDE_OUTPUT();
307 command("units lj");
308 END_HIDE_OUTPUT();
309 int convert_flag = utils::get_supported_conversions(utils::UNKNOWN);
310 ASSERT_EQ(convert_flag, utils::NOCONVERT);
311 }
312
313 // open non-existing potential
TEST_F(OpenPotentialTest,No_file)314 TEST_F(OpenPotentialTest, No_file)
315 {
316 int convert_flag = utils::get_supported_conversions(utils::ENERGY);
317 BEGIN_HIDE_OUTPUT();
318 command("units metal");
319 FILE *fp = utils::open_potential("Unknown.sw", lmp, &convert_flag);
320 END_HIDE_OUTPUT();
321 ASSERT_EQ(fp, nullptr);
322 }
323
main(int argc,char ** argv)324 int main(int argc, char **argv)
325 {
326 MPI_Init(&argc, &argv);
327 ::testing::InitGoogleMock(&argc, argv);
328
329 if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
330 std::cout << "Warning: using OpenMPI without exceptions. "
331 "Death tests will be skipped\n";
332
333 // handle arguments passed via environment variable
334 if (const char *var = getenv("TEST_ARGS")) {
335 std::vector<std::string> env = split_words(var);
336 for (auto arg : env) {
337 if (arg == "-v") {
338 verbose = true;
339 }
340 }
341 }
342 if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
343
344 int rv = RUN_ALL_TESTS();
345 MPI_Finalize();
346 return rv;
347 }
348