Add replacements for pbc enumerations
[gromacs.git] / src / gromacs / math / tests / vectypes.cpp
blob4f208be6b357792950159577a8360407fc875dcf
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2014,2015,2016,2018,2019, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \internal \file
36 * \brief
37 * Tests various corners of gmx::RVec implementation.
39 * The main point of these tests is to check that all different constructs
40 * using gmx::RVec compile, and that some of the non-trivial conversions
41 * to/from rvec work as intended.
43 * \author Teemu Murtola <teemu.murtola@gmail.com>
44 * \ingroup module_math
46 #include "gmxpre.h"
48 #include "gromacs/math/vectypes.h"
50 #include <vector>
52 #include <gtest/gtest.h>
54 #include "gromacs/math/vec.h"
56 #include "testutils/testasserts.h"
58 namespace
61 using gmx::RVec;
62 using gmx::DVec;
63 using gmx::IVec;
65 TEST(RVecTest, CanBeStoredInVector)
67 std::vector<RVec> v;
68 v.emplace_back(1, 2, 3);
69 v.resize(2);
70 EXPECT_EQ(1, v[0][XX]);
71 EXPECT_EQ(2, v[0][YY]);
72 EXPECT_EQ(3, v[0][ZZ]);
75 TEST(RVecTest, ConvertsImplicitlyFrom_rvec)
77 std::vector<RVec> v;
78 rvec x = { 1, 2, 3 };
79 v.emplace_back(x);
80 EXPECT_EQ(1, v[0][XX]);
81 EXPECT_EQ(2, v[0][YY]);
82 EXPECT_EQ(3, v[0][ZZ]);
85 TEST(RVecTest, ConvertsImplicitlyTo_rvec)
87 std::vector<RVec> v;
88 v.emplace_back(1, 2, 3);
89 rvec x;
90 copy_rvec(v[0], x);
91 EXPECT_EQ(1, x[XX]);
92 EXPECT_EQ(2, x[YY]);
93 EXPECT_EQ(3, x[ZZ]);
96 TEST(RVecTest, WorksAsMutable_rvec)
98 std::vector<RVec> v;
99 v.emplace_back(1, 2, 3);
100 rvec x = {2, 3, 4};
101 copy_rvec(x, v[0]);
102 EXPECT_EQ(2, v[0][XX]);
103 EXPECT_EQ(3, v[0][YY]);
104 EXPECT_EQ(4, v[0][ZZ]);
107 TEST(RVecTest, WorksAs_rvec_Array)
109 std::vector<RVec> v;
110 v.emplace_back(1, 2, 3);
111 v.emplace_back(2, 3, 4);
112 const rvec *r = as_rvec_array(v.data());
113 EXPECT_EQ(1, r[0][XX]);
114 EXPECT_EQ(2, r[0][YY]);
115 EXPECT_EQ(3, r[0][ZZ]);
116 EXPECT_EQ(2, r[1][XX]);
117 EXPECT_EQ(3, r[1][YY]);
118 EXPECT_EQ(4, r[1][ZZ]);
121 /*! \brief
122 * Test overloaded math operations
125 TEST(RVecTest, CanAddRVecToRvec)
127 RVec a(1, 2, 3);
128 RVec b(3, 2, 1);
129 RVec c;
130 c = a + b;
131 EXPECT_EQ(4, c[XX]);
132 EXPECT_EQ(4, c[YY]);
133 EXPECT_EQ(4, c[ZZ]);
136 TEST(RVecTest, CanAddAssignRVecToRvec)
138 RVec a(1, 2, 3);
139 RVec b(3, 2, 1);
140 a += b;
141 EXPECT_EQ(4, a[XX]);
142 EXPECT_EQ(4, a[YY]);
143 EXPECT_EQ(4, a[ZZ]);
147 TEST(RVecTest, CanSubtractRVecFromRvec)
149 RVec a(1, 2, 3);
150 RVec b(3, 2, 1);
151 RVec c;
152 c = b - a;
153 EXPECT_EQ(2, c[XX]);
154 EXPECT_EQ(0, c[YY]);
155 EXPECT_EQ(-2, c[ZZ]);
158 TEST(RVecTest, CanSubtractAssignRVecFromRvec)
160 RVec a(1, 2, 3);
161 RVec b(3, 2, 1);
162 RVec c;
163 b -= a;
164 EXPECT_EQ(2, b[XX]);
165 EXPECT_EQ(0, b[YY]);
166 EXPECT_EQ(-2, b[ZZ]);
169 TEST(RVecTest, CanDotProductRVecByRvec)
171 RVec a(1, 2, 3);
172 RVec b(3, 2, 1);
173 float c;
174 c = a.dot(b);
175 EXPECT_EQ(10, c);
178 TEST(RVecTest, CanCrossProductRVecByRvec)
180 RVec a(1, 2, 3);
181 RVec b(3, 2, 1);
182 RVec c;
183 c = a.cross(b);
184 EXPECT_EQ(-4, c[XX]);
185 EXPECT_EQ(8, c[YY]);
186 EXPECT_EQ(-4, c[ZZ]);
189 /*! \brief
190 * Test for inplace operations imported from vec.h
193 TEST(RVecTest, CanDivideRVecInplace)
195 RVec a(1, 2, 3);
196 real b = 0.5;
197 RVec c;
198 c = a/b;
199 EXPECT_EQ(2, c[XX]);
200 EXPECT_EQ(4, c[YY]);
201 EXPECT_EQ(6, c[ZZ]);
204 TEST(RVecTest, CanScaleRVec)
206 RVec a(1, 2, 3);
207 real b = 2.0;
208 a *= b;
209 EXPECT_EQ(2, a[XX]);
210 EXPECT_EQ(4, a[YY]);
211 EXPECT_EQ(6, a[ZZ]);
214 TEST(RVecTest, CanDivideRVec)
216 RVec a(1, 2, 3);
217 real b = 0.5;
218 a /= b;
219 EXPECT_EQ(2, a[XX]);
220 EXPECT_EQ(4, a[YY]);
221 EXPECT_EQ(6, a[ZZ]);
224 TEST(RVecTest, CanDoUnitvFromRVec)
226 RVec a(3, 0, 0);
227 RVec b;
228 b = a.unitVector();
229 EXPECT_REAL_EQ(1, b[XX]);
230 EXPECT_REAL_EQ(0, b[YY]);
231 EXPECT_REAL_EQ(0, b[ZZ]);
234 TEST(RVecTest, CanSqLengthOfRVec)
236 RVec a(1, 2, 2);
237 real b;
238 b = a.norm2();
239 EXPECT_REAL_EQ(9, b);
242 TEST(RVecTest, CanLengthOfRVec)
244 RVec a(1, 2, 2);
245 real b;
246 b = a.norm();
247 EXPECT_REAL_EQ(3, b);
250 TEST(RVecTest, CanCastToRVec)
252 DVec a(1, 2, 2);
253 RVec b;
254 b = a.toRVec();
255 EXPECT_EQ(1, b[XX]);
256 EXPECT_EQ(2, b[YY]);
257 EXPECT_EQ(2, b[ZZ]);
260 TEST(RVecTest, CanCastToDVec)
262 RVec a(1, 2, 2);
263 DVec b;
264 b = a.toDVec();
265 EXPECT_EQ(1, b[XX]);
266 EXPECT_EQ(2, b[YY]);
267 EXPECT_EQ(2, b[ZZ]);
271 /*! \brief
272 * Tests for out of class functions
274 TEST(RVecTest, CanLeftScalarMultiply)
276 RVec a(1, 2, 3);
277 real b = 2.0;
278 RVec c;
279 c = b*a;
280 EXPECT_EQ(2, c[XX]);
281 EXPECT_EQ(4, c[YY]);
282 EXPECT_EQ(6, c[ZZ]);
285 TEST(RVecTest, CanRightScalarMultiply)
287 RVec a(1, 2, 3);
288 real b = 2.0;
289 RVec c;
290 c = a*b;
291 EXPECT_EQ(2, c[XX]);
292 EXPECT_EQ(4, c[YY]);
293 EXPECT_EQ(6, c[ZZ]);
296 TEST(RVecTest, CanGetUnitvFromRVec)
298 RVec a(3, 0, 0);
299 RVec b;
300 b = gmx::unitVector(a);
301 EXPECT_REAL_EQ(1, b[XX]);
302 EXPECT_REAL_EQ(0, b[YY]);
303 EXPECT_REAL_EQ(0, b[ZZ]);
306 TEST(RVecTest, CanGetSqLengthOfRVec)
308 RVec a(1, 2, 2);
309 real b;
310 b = gmx::norm2(a);
311 EXPECT_REAL_EQ(9, b);
314 TEST(RVecTest, CanGetLengthOfRVec)
316 RVec a(1, 2, 2);
317 real b;
318 b = gmx::norm(a);
319 EXPECT_REAL_EQ(3, b);
322 TEST(RVecTest, CanDoCrossProductOfRVec)
324 RVec a(1, 2, 3);
325 RVec b(3, 2, 1);
326 RVec c;
327 c = gmx::cross(a, b);
328 EXPECT_EQ(-4, c[XX]);
329 EXPECT_EQ(8, c[YY]);
330 EXPECT_EQ(-4, c[ZZ]);
333 TEST(RVecTest, CanDoDotProductOfRVec)
335 RVec a(1, 2, 3);
336 RVec b(3, 2, 1);
337 float c;
338 c = gmx::dot(a, b);
339 EXPECT_EQ(10, c);
342 TEST(RVecTest, CanScaleByVector)
344 RVec a(1, 2, 3);
345 RVec b(3, 2, 1);
346 RVec scaled = scaleByVector(a, b);
347 EXPECT_REAL_EQ(3, scaled[XX]);
348 EXPECT_REAL_EQ(4, scaled[YY]);
349 EXPECT_REAL_EQ(3, scaled[ZZ]);
352 TEST(RVecTest, asIVec)
354 RVec a(1.2, 2.7, -3e3);
355 auto asIvec = a.toIVec();
357 EXPECT_REAL_EQ(1, asIvec[XX]);
358 EXPECT_REAL_EQ(2, asIvec[YY]);
359 EXPECT_REAL_EQ(-3000, asIvec[ZZ]);
362 TEST(RVecTest, elementWiseMin)
364 RVec a(1, 2, 3);
365 RVec b(3, 2, 1);
366 auto minAB = elementWiseMin(a, b);
368 EXPECT_REAL_EQ(1, minAB[XX]);
369 EXPECT_REAL_EQ(2, minAB[YY]);
370 EXPECT_REAL_EQ(1, minAB[ZZ]);
373 TEST(RVecTest, elementWiseMax)
375 RVec a(1, 2, 3);
376 RVec b(3, 2, 1);
377 auto maxAB = elementWiseMax(a, b);
379 EXPECT_REAL_EQ(3, maxAB[XX]);
380 EXPECT_REAL_EQ(2, maxAB[YY]);
381 EXPECT_REAL_EQ(3, maxAB[ZZ]);
384 /*! \brief
385 * Helper function for testing DVec to dvec conversions.
387 const dvec *testFunction(const dvec &x)
389 return &x;
392 TEST(RVecTest, WorksAs_dvec_Reference)
394 DVec v(1, 2, 3);
395 const dvec *r = testFunction(v.as_vec());
396 EXPECT_EQ(1, r[0][XX]);
397 EXPECT_EQ(2, r[0][YY]);
398 EXPECT_EQ(3, r[0][ZZ]);
401 /*! \brief
402 * Helper function for testing IVec to ivec conversions.
404 const ivec *testFunction(const ivec &x)
406 return &x;
409 TEST(RVecTest, WorksAs_ivec_Reference)
411 IVec v(1, 2, 3);
412 const ivec *r = testFunction(v.as_vec());
413 EXPECT_EQ(1, r[0][XX]);
414 EXPECT_EQ(2, r[0][YY]);
415 EXPECT_EQ(3, r[0][ZZ]);
418 /*! \brief
419 * Helper function for testing RVec to rvec conversions.
421 #if !GMX_DOUBLE //otherwise rvec==dvec
422 const rvec *testFunction(const rvec &x)
424 return &x;
426 #endif
428 TEST(RVecTest, WorksAs_rvec_Reference)
430 RVec v(1, 2, 3);
431 const rvec *r = testFunction(v);
432 EXPECT_EQ(1, r[0][XX]);
433 EXPECT_EQ(2, r[0][YY]);
434 EXPECT_EQ(3, r[0][ZZ]);
437 TEST(RVecTest, CopyConstructorWorks)
439 RVec v(1, 2, 3);
440 RVec copy(v);
441 EXPECT_EQ(1, copy[XX]);
442 EXPECT_EQ(2, copy[YY]);
443 EXPECT_EQ(3, copy[ZZ]);
446 TEST(RVecTest, CopyAssignmentWorks)
448 RVec v(1, 2, 3);
449 RVec copy;
450 copy = v;
451 EXPECT_EQ(1, copy[XX]);
452 EXPECT_EQ(2, copy[YY]);
453 EXPECT_EQ(3, copy[ZZ]);
456 TEST(RVecTest, MoveConstructorWorks)
458 RVec v(1, 2, 3);
459 RVec copy(v);
460 EXPECT_EQ(1, copy[XX]);
461 EXPECT_EQ(2, copy[YY]);
462 EXPECT_EQ(3, copy[ZZ]);
465 TEST(RVecTest, MoveAssignmentWorks)
467 RVec v(1, 2, 3);
468 RVec copy;
469 copy = v;
470 EXPECT_EQ(1, copy[XX]);
471 EXPECT_EQ(2, copy[YY]);
472 EXPECT_EQ(3, copy[ZZ]);
475 } // namespace