Merge branch 'maint'
[hoomd-blue.git] / test / unit / test_pdata.cc
blob51de20134f5654f5e956379dad0e2d73d9499647
1 /*
2 Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
3 (HOOMD-blue) Open Source Software License Copyright 2009-2014 The Regents of
4 the University of Michigan All rights reserved.
6 HOOMD-blue may contain modifications ("Contributions") provided, and to which
7 copyright is held, by various Contributors who have granted The Regents of the
8 University of Michigan the right to modify and/or distribute such Contributions.
10 You may redistribute, use, and create derivate works of HOOMD-blue, in source
11 and binary forms, provided you abide by the following conditions:
13 * Redistributions of source code must retain the above copyright notice, this
14 list of conditions, and the following disclaimer both in the code and
15 prominently in any materials provided with the distribution.
17 * Redistributions in binary form must reproduce the above copyright notice, this
18 list of conditions, and the following disclaimer in the documentation and/or
19 other materials provided with the distribution.
21 * All publications and presentations based on HOOMD-blue, including any reports
22 or published results obtained, in whole or in part, with HOOMD-blue, will
23 acknowledge its use according to the terms posted at the time of submission on:
24 http://codeblue.umich.edu/hoomd-blue/citations.html
26 * Any electronic documents citing HOOMD-Blue will link to the HOOMD-Blue website:
27 http://codeblue.umich.edu/hoomd-blue/
29 * Apart from the above required attributions, neither the name of the copyright
30 holder nor the names of HOOMD-blue's contributors may be used to endorse or
31 promote products derived from this software without specific prior written
32 permission.
34 Disclaimer
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND
37 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR ANY
39 WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.
41 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
42 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
43 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
45 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
46 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
47 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 /*! \file pdata_test.cc
52 \brief Unit tests for BoxDim, ParticleData, SimpleCubicInitializer, and RandomInitializer classes.
53 \ingroup unit_tests
56 #ifdef WIN32
57 #pragma warning( push )
58 #pragma warning( disable : 4103 4244 )
59 #endif
61 #include <iostream>
63 #include <boost/bind.hpp>
65 #include "ParticleData.h"
66 #include "Initializers.h"
67 #include "SnapshotSystemData.h"
69 using namespace std;
70 using namespace boost;
72 //! Name the boost unit test module
73 #define BOOST_TEST_MODULE ParticleDataTests
74 #include "boost_utf_configure.h"
76 //! Perform some basic tests on the boxdim structure
77 BOOST_AUTO_TEST_CASE( BoxDim_basic_test )
79 Scalar tol = Scalar(1e-6);
81 // test default constructor
82 BoxDim a;
83 MY_BOOST_CHECK_CLOSE(a.getLo().x,0.0, tol);
84 MY_BOOST_CHECK_CLOSE(a.getLo().y,0.0, tol);
85 MY_BOOST_CHECK_CLOSE(a.getLo().z,0.0, tol);
86 MY_BOOST_CHECK_CLOSE(a.getHi().x,0.0, tol);
87 MY_BOOST_CHECK_CLOSE(a.getHi().y,0.0, tol);
88 MY_BOOST_CHECK_CLOSE(a.getHi().z,0.0, tol);
90 BoxDim b(10.0);
91 MY_BOOST_CHECK_CLOSE(b.getLo().x,-5.0, tol);
92 MY_BOOST_CHECK_CLOSE(b.getLo().y,-5.0, tol);
93 MY_BOOST_CHECK_CLOSE(b.getLo().z,-5.0, tol);
94 MY_BOOST_CHECK_CLOSE(b.getHi().x,5.0, tol);
95 MY_BOOST_CHECK_CLOSE(b.getHi().y,5.0, tol);
96 MY_BOOST_CHECK_CLOSE(b.getHi().z,5.0, tol);
97 MY_BOOST_CHECK_CLOSE(b.getL().x,10.0, tol);
98 MY_BOOST_CHECK_CLOSE(b.getL().y,10.0, tol);
99 MY_BOOST_CHECK_CLOSE(b.getL().z,10.0, tol);
100 BOOST_CHECK_EQUAL(b.getPeriodic().x, 1);
101 BOOST_CHECK_EQUAL(b.getPeriodic().y, 1);
102 BOOST_CHECK_EQUAL(b.getPeriodic().z, 1);
104 BoxDim c(10.0, 30.0, 50.0);
105 MY_BOOST_CHECK_CLOSE(c.getLo().x,-5.0, tol);
106 MY_BOOST_CHECK_CLOSE(c.getLo().y,-15.0, tol);
107 MY_BOOST_CHECK_CLOSE(c.getLo().z,-25.0, tol);
108 MY_BOOST_CHECK_CLOSE(c.getHi().x,5.0, tol);
109 MY_BOOST_CHECK_CLOSE(c.getHi().y,15.0, tol);
110 MY_BOOST_CHECK_CLOSE(c.getHi().z,25.0, tol);
111 MY_BOOST_CHECK_CLOSE(c.getL().x,10.0, tol);
112 MY_BOOST_CHECK_CLOSE(c.getL().y,30.0, tol);
113 MY_BOOST_CHECK_CLOSE(c.getL().z,50.0, tol);
114 BOOST_CHECK_EQUAL(c.getPeriodic().x, 1);
115 BOOST_CHECK_EQUAL(c.getPeriodic().y, 1);
116 BOOST_CHECK_EQUAL(c.getPeriodic().z, 1);
118 // test for assignment and copy constructor
119 c.setPeriodic(make_uchar3(1,0,1));
120 BoxDim d(c);
121 MY_BOOST_CHECK_CLOSE(d.getLo().x,-5.0, tol);
122 MY_BOOST_CHECK_CLOSE(d.getLo().y,-15.0, tol);
123 MY_BOOST_CHECK_CLOSE(d.getLo().z,-25.0, tol);
124 MY_BOOST_CHECK_CLOSE(d.getHi().x,5.0, tol);
125 MY_BOOST_CHECK_CLOSE(d.getHi().y,15.0, tol);
126 MY_BOOST_CHECK_CLOSE(d.getHi().z,25.0, tol);
127 MY_BOOST_CHECK_CLOSE(d.getL().x,10.0, tol);
128 MY_BOOST_CHECK_CLOSE(d.getL().y,30.0, tol);
129 MY_BOOST_CHECK_CLOSE(d.getL().z,50.0, tol);
130 BOOST_CHECK_EQUAL(d.getPeriodic().x, 1);
131 BOOST_CHECK_EQUAL(d.getPeriodic().y, 0);
132 BOOST_CHECK_EQUAL(d.getPeriodic().z, 1);
134 BoxDim e;
135 e = c;
136 MY_BOOST_CHECK_CLOSE(e.getLo().x,-5.0, tol);
137 MY_BOOST_CHECK_CLOSE(e.getLo().y,-15.0, tol);
138 MY_BOOST_CHECK_CLOSE(e.getLo().z,-25.0, tol);
139 MY_BOOST_CHECK_CLOSE(e.getHi().x,5.0, tol);
140 MY_BOOST_CHECK_CLOSE(e.getHi().y,15.0, tol);
141 MY_BOOST_CHECK_CLOSE(e.getHi().z,25.0, tol);
142 MY_BOOST_CHECK_CLOSE(e.getL().x,10.0, tol);
143 MY_BOOST_CHECK_CLOSE(e.getL().y,30.0, tol);
144 MY_BOOST_CHECK_CLOSE(e.getL().z,50.0, tol);
145 BOOST_CHECK_EQUAL(d.getPeriodic().x, 1);
146 BOOST_CHECK_EQUAL(d.getPeriodic().y, 0);
147 BOOST_CHECK_EQUAL(d.getPeriodic().z, 1);
149 b = b;
150 MY_BOOST_CHECK_CLOSE(b.getLo().x,-5.0, tol);
151 MY_BOOST_CHECK_CLOSE(b.getLo().y,-5.0, tol);
152 MY_BOOST_CHECK_CLOSE(b.getLo().z,-5.0, tol);
153 MY_BOOST_CHECK_CLOSE(b.getHi().x,5.0, tol);
154 MY_BOOST_CHECK_CLOSE(b.getHi().y,5.0, tol);
155 MY_BOOST_CHECK_CLOSE(b.getHi().z,5.0, tol);
156 MY_BOOST_CHECK_CLOSE(b.getL().x,10.0, tol);
157 MY_BOOST_CHECK_CLOSE(b.getL().y,10.0, tol);
158 MY_BOOST_CHECK_CLOSE(b.getL().z,10.0, tol);
159 BOOST_CHECK_EQUAL(b.getPeriodic().x, 1);
160 BOOST_CHECK_EQUAL(b.getPeriodic().y, 1);
161 BOOST_CHECK_EQUAL(b.getPeriodic().z, 1);
164 BOOST_AUTO_TEST_CASE( BoxDim_functionality_test1 )
166 BoxDim b(5.0);
167 MY_BOOST_CHECK_CLOSE(b.getL().x,5.0, tol);
168 MY_BOOST_CHECK_CLOSE(b.getL().y,5.0, tol);
169 MY_BOOST_CHECK_CLOSE(b.getL().z,5.0, tol);
171 b.setL(make_scalar3(10.0, 10.0, 10.0));
172 MY_BOOST_CHECK_CLOSE(b.getL().x,10.0, tol);
173 MY_BOOST_CHECK_CLOSE(b.getL().y,10.0, tol);
174 MY_BOOST_CHECK_CLOSE(b.getL().z,10.0, tol);
176 Scalar3 v = b.makeFraction(make_scalar3(5.0, 5.0, 5.0));
177 MY_BOOST_CHECK_CLOSE(v.x,1.0, tol);
178 MY_BOOST_CHECK_CLOSE(v.y,1.0, tol);
179 MY_BOOST_CHECK_CLOSE(v.z,1.0, tol);
181 v = b.makeFraction(make_scalar3(1.0, -2.0, 3.0));
182 MY_BOOST_CHECK_CLOSE(v.x,0.6, tol);
183 MY_BOOST_CHECK_CLOSE(v.y,0.3, tol);
184 MY_BOOST_CHECK_CLOSE(v.z,0.8, tol);
186 v = b.minImage(make_scalar3(1.0, -2.0, 3.0));
187 MY_BOOST_CHECK_CLOSE(v.x,1.0, tol);
188 MY_BOOST_CHECK_CLOSE(v.y,-2.0, tol);
189 MY_BOOST_CHECK_CLOSE(v.z,3.0, tol);
191 // test minimum image
192 v = b.minImage(make_scalar3(6.0, -7.0, 8.0));
193 MY_BOOST_CHECK_CLOSE(v.x,-4.0, tol);
194 MY_BOOST_CHECK_CLOSE(v.y,3.0, tol);
195 MY_BOOST_CHECK_CLOSE(v.z,-2.0, tol);
197 b.setPeriodic(make_uchar3(0,0,0));
198 v = b.minImage(make_scalar3(6.0, -7.0, 8.0));
199 MY_BOOST_CHECK_CLOSE(v.x,6.0, tol);
200 MY_BOOST_CHECK_CLOSE(v.y,-7.0, tol);
201 MY_BOOST_CHECK_CLOSE(v.z,8.0, tol);
203 b.setPeriodic(make_uchar3(1,0,0));
204 v = b.minImage(make_scalar3(6.0, -7.0, 8.0));
205 MY_BOOST_CHECK_CLOSE(v.x,-4.0, tol);
206 MY_BOOST_CHECK_CLOSE(v.y,-7.0, tol);
207 MY_BOOST_CHECK_CLOSE(v.z,8.0, tol);
209 b.setPeriodic(make_uchar3(0,1,0));
210 v = b.minImage(make_scalar3(6.0, -7.0, 8.0));
211 MY_BOOST_CHECK_CLOSE(v.x,6.0, tol);
212 MY_BOOST_CHECK_CLOSE(v.y,3.0, tol);
213 MY_BOOST_CHECK_CLOSE(v.z,8.0, tol);
215 b.setPeriodic(make_uchar3(0,0,1));
216 v = b.minImage(make_scalar3(6.0, -7.0, 8.0));
217 MY_BOOST_CHECK_CLOSE(v.x,6.0, tol);
218 MY_BOOST_CHECK_CLOSE(v.y,-7.0, tol);
219 MY_BOOST_CHECK_CLOSE(v.z,-2.0, tol);
221 // test wrap
222 b.setPeriodic(make_uchar3(1,1,1));
223 int3 image = make_int3(10,20,30);
224 v = make_scalar3(1.0, -2.0, 3.0);
225 b.wrap(v, image);
226 MY_BOOST_CHECK_CLOSE(v.x,1.0, tol);
227 MY_BOOST_CHECK_CLOSE(v.y,-2.0, tol);
228 MY_BOOST_CHECK_CLOSE(v.z,3.0, tol);
229 BOOST_CHECK_EQUAL(image.x, 10);
230 BOOST_CHECK_EQUAL(image.y, 20);
231 BOOST_CHECK_EQUAL(image.z, 30);
233 image = make_int3(10,20,30);
234 v = make_scalar3(6.0, -7.0, 8.0);
235 b.wrap(v, image);
236 MY_BOOST_CHECK_CLOSE(v.x,-4.0, tol);
237 MY_BOOST_CHECK_CLOSE(v.y,3.0, tol);
238 MY_BOOST_CHECK_CLOSE(v.z,-2.0, tol);
239 BOOST_CHECK_EQUAL(image.x, 11);
240 BOOST_CHECK_EQUAL(image.y, 19);
241 BOOST_CHECK_EQUAL(image.z, 31);
243 b.setPeriodic(make_uchar3(1,0,0));
244 image = make_int3(10,20,30);
245 v = make_scalar3(6.0, -7.0, 8.0);
246 b.wrap(v, image);
247 MY_BOOST_CHECK_CLOSE(v.x,-4.0, tol);
248 MY_BOOST_CHECK_CLOSE(v.y,-7.0, tol);
249 MY_BOOST_CHECK_CLOSE(v.z,8.0, tol);
250 BOOST_CHECK_EQUAL(image.x, 11);
251 BOOST_CHECK_EQUAL(image.y, 20);
252 BOOST_CHECK_EQUAL(image.z, 30);
254 b.setPeriodic(make_uchar3(0,1,0));
255 image = make_int3(10,20,30);
256 v = make_scalar3(6.0, -7.0, 8.0);
257 b.wrap(v, image);
258 MY_BOOST_CHECK_CLOSE(v.x,6.0, tol);
259 MY_BOOST_CHECK_CLOSE(v.y,3.0, tol);
260 MY_BOOST_CHECK_CLOSE(v.z,8.0, tol);
261 BOOST_CHECK_EQUAL(image.x, 10);
262 BOOST_CHECK_EQUAL(image.y, 19);
263 BOOST_CHECK_EQUAL(image.z, 30);
265 b.setPeriodic(make_uchar3(0,0,1));
266 image = make_int3(10,20,30);
267 v = make_scalar3(6.0, -7.0, 8.0);
268 b.wrap(v, image);
269 MY_BOOST_CHECK_CLOSE(v.x,6.0, tol);
270 MY_BOOST_CHECK_CLOSE(v.y,-7.0, tol);
271 MY_BOOST_CHECK_CLOSE(v.z,-2.0, tol);
272 BOOST_CHECK_EQUAL(image.x, 10);
273 BOOST_CHECK_EQUAL(image.y, 20);
274 BOOST_CHECK_EQUAL(image.z, 31);
277 BOOST_AUTO_TEST_CASE( BoxDim_triclinic_test )
279 BoxDim b(5.0);
281 Scalar tol = Scalar(1e-4);
283 Scalar xy = 1.0;
284 Scalar xz = .4;
285 Scalar yz = .9;
287 b.setTiltFactors(xy,xz,yz);
288 MY_BOOST_CHECK_CLOSE(b.getTiltFactorXY(), xy,tol);
289 MY_BOOST_CHECK_CLOSE(b.getTiltFactorXZ(), xz,tol);
290 MY_BOOST_CHECK_CLOSE(b.getTiltFactorYZ(), yz,tol);
292 Scalar3 f = make_scalar3(.5,.6,.7);
293 Scalar3 L = b.getL();
295 Scalar3 pos;
296 pos.x = b.getLo().x + f.x * L.x + xy * L.y * (f.y-Scalar(0.5)) + xz * L.z * (f.z-Scalar(0.5));
297 pos.y = b.getLo().y + f.y * L.y + yz * L.z * (f.z-Scalar(0.5));
298 pos.z = b.getLo().z + f.z * L.z;
300 // convert pos to fraction
301 Scalar3 f2 = b.makeFraction(pos);
303 MY_BOOST_CHECK_CLOSE(f2.x,f.x,tol);
304 MY_BOOST_CHECK_CLOSE(f2.y,f.y,tol);
305 MY_BOOST_CHECK_CLOSE(f2.z,f.z,tol);
307 // convert fraction to pos
308 Scalar3 pos2 = b.makeCoordinates(f);
310 MY_BOOST_CHECK_CLOSE(pos2.x, pos.x,tol);
311 MY_BOOST_CHECK_CLOSE(pos2.y, pos.y,tol);
312 MY_BOOST_CHECK_CLOSE(pos2.z, pos.z,tol);
315 * test ghost layer padding
317 // fractional ghost layer
318 Scalar3 npd = b.getNearestPlaneDistance();
319 Scalar3 ghost_frac = make_scalar3(0.5,0.3,0.0);
320 Scalar3 ghost_width = ghost_frac*npd;
322 // make fraction with a ghost layer
323 Scalar3 f3 = b.makeFraction(pos, ghost_width);
325 // compare to new fraction, calculated from old fraction accounting for ghost layer
326 Scalar3 f3_cmp = (f2+ghost_frac)/(make_scalar3(1.0,1.0,1.0)+2.0*ghost_frac);
327 MY_BOOST_CHECK_CLOSE(f3.x, f3_cmp.x, tol);
328 MY_BOOST_CHECK_CLOSE(f3.y, f3_cmp.y, tol);
329 MY_BOOST_CHECK_CLOSE(f3.z, f3_cmp.z, tol);
331 // test minimum image
333 // along x coordinate
334 Scalar3 dx = make_scalar3(3.0,1.0,2.0);
335 Scalar3 dx2 = b.minImage(dx);
337 MY_BOOST_CHECK_CLOSE(dx2.x, -2.0, tol);
338 MY_BOOST_CHECK_CLOSE(dx2.y, 1.0, tol);
339 MY_BOOST_CHECK_CLOSE(dx2.z, 2.0, tol);
341 dx = make_scalar3(-3.0,1.0,2.0);
342 dx2 = b.minImage(dx);
344 MY_BOOST_CHECK_CLOSE(dx2.x, 2.0, tol);
345 MY_BOOST_CHECK_CLOSE(dx2.y, 1.0, tol);
346 MY_BOOST_CHECK_CLOSE(dx2.z, 2.0, tol);
348 // along y coordinate
349 dx = make_scalar3(2.0,2.6,1.5);
350 dx2 = b.minImage(dx);
352 MY_BOOST_CHECK_CLOSE(dx2.x, 2.0, tol);
353 MY_BOOST_CHECK_CLOSE(dx2.y, -2.4, tol);
354 MY_BOOST_CHECK_CLOSE(dx2.z, 1.5, tol);
356 dx = make_scalar3(2.0,-2.6,1.5);
357 dx2 = b.minImage(dx);
359 MY_BOOST_CHECK_CLOSE(dx2.x, 2.0, tol);
360 MY_BOOST_CHECK_CLOSE(dx2.y, 2.4, tol);
361 MY_BOOST_CHECK_CLOSE(dx2.z, 1.5, tol);
363 dx = make_scalar3(3.0,2.6,1.5);
364 dx2 = b.minImage(dx);
366 MY_BOOST_CHECK_CLOSE(dx2.x, -2.0, tol);
367 MY_BOOST_CHECK_CLOSE(dx2.y, -2.4, tol);
368 MY_BOOST_CHECK_CLOSE(dx2.z, 1.5, tol);
370 dx = make_scalar3(3.0,-2.6,1.5);
371 dx2 = b.minImage(dx);
373 MY_BOOST_CHECK_CLOSE(dx2.x,-2.0,tol);
374 MY_BOOST_CHECK_CLOSE(dx2.y,2.4,tol);
375 MY_BOOST_CHECK_CLOSE(dx.z, 1.5,tol);
377 // along z coordinate
378 dx = make_scalar3(2.1,1.5,3.0);
379 dx2 = b.minImage(dx);
381 MY_BOOST_CHECK_CLOSE(dx2.x, 0.1, tol);
382 MY_BOOST_CHECK_CLOSE(dx2.y, 2.0 ,tol);
383 MY_BOOST_CHECK_CLOSE(dx2.z, -2.0,tol);
385 dx = make_scalar3(2.1,1.5,-3.0);
386 dx2 = b.minImage(dx);
388 MY_BOOST_CHECK_CLOSE(dx2.x, -0.9, tol);
389 MY_BOOST_CHECK_CLOSE(dx2.y, 1.0, tol);
390 MY_BOOST_CHECK_CLOSE(dx2.z, 2.0, tol);
392 // test particle wrap
394 // along z direction
395 pos = make_scalar3(1.0,2.0,2.6);
396 int3 img = make_int3(0,0,0);
398 b.wrap(pos, img);
399 MY_BOOST_CHECK_CLOSE(pos.x, -1.0 ,tol);
400 MY_BOOST_CHECK_CLOSE(pos.y, -2.5,tol);
401 MY_BOOST_CHECK_CLOSE(pos.z, -2.4,tol);
402 BOOST_CHECK_EQUAL(img.x, 0);
403 BOOST_CHECK_EQUAL(img.y, 0);
404 BOOST_CHECK_EQUAL(img.z, 1);
406 pos = make_scalar3(-1.0,-2.0,-2.6);
407 img = make_int3(0,0,0);
408 b.wrap(pos,img);
410 MY_BOOST_CHECK_CLOSE(pos.x, 1.0 ,tol);
411 MY_BOOST_CHECK_CLOSE(pos.y, 2.5,tol);
412 MY_BOOST_CHECK_CLOSE(pos.z, 2.4,tol);
413 BOOST_CHECK_EQUAL(img.x, 0);
414 BOOST_CHECK_EQUAL(img.y, 0);
415 BOOST_CHECK_EQUAL(img.z, -1);
417 // along y direction
418 pos = make_scalar3(1.0,4.0,1.5);
419 img = make_int3(0,0,0);
421 b.wrap(pos, img);
422 MY_BOOST_CHECK_CLOSE(pos.x, -4.0,tol);
423 MY_BOOST_CHECK_CLOSE(pos.y, -1.0,tol);
424 MY_BOOST_CHECK_CLOSE(pos.z, 1.5,tol);
426 BOOST_CHECK_EQUAL(img.x, 0);
427 BOOST_CHECK_EQUAL(img.y, 1);
428 BOOST_CHECK_EQUAL(img.z, 0);
430 pos = make_scalar3(-1.0,-4.0,-1.5);
431 img = make_int3(0,0,0);
433 b.wrap(pos, img);
434 MY_BOOST_CHECK_CLOSE(pos.x, 4.0, tol);
435 MY_BOOST_CHECK_CLOSE(pos.y, 1.0, tol);
436 MY_BOOST_CHECK_CLOSE(pos.z, -1.5, tol);
438 BOOST_CHECK_EQUAL(img.x, 0);
439 BOOST_CHECK_EQUAL(img.y, -1);
440 BOOST_CHECK_EQUAL(img.z, 0);
442 // along x direction
443 pos = make_scalar3(4.2,1.5, 1.0);
444 img = make_int3(0,0,0);
446 b.wrap(pos, img);
447 MY_BOOST_CHECK_CLOSE(pos.x, -0.8, tol);
448 MY_BOOST_CHECK_CLOSE(pos.y, 1.5, tol);
449 MY_BOOST_CHECK_CLOSE(pos.z, 1.0, tol);
451 BOOST_CHECK_EQUAL(img.x, 1);
452 BOOST_CHECK_EQUAL(img.y, 0);
453 BOOST_CHECK_EQUAL(img.z, 0);
455 pos = make_scalar3(-5.0,-1.5, 1.0);
456 img = make_int3(0,0,0);
458 b.wrap(pos,img);
459 MY_BOOST_CHECK_CLOSE(pos.x, 0.0, tol);
460 MY_BOOST_CHECK_CLOSE(pos.y, -1.5, tol);
461 MY_BOOST_CHECK_CLOSE(pos.z, 1.0, tol);
463 BOOST_CHECK_EQUAL(img.x, -1);
464 BOOST_CHECK_EQUAL(img.y, 0);
465 BOOST_CHECK_EQUAL(img.z, 0);
468 //! Test operation of the particle data class
469 BOOST_AUTO_TEST_CASE( ParticleData_test )
471 BoxDim box(10.0, 30.0, 50.0);
472 boost::shared_ptr<ExecutionConfiguration> exec_conf(new ExecutionConfiguration(ExecutionConfiguration::CPU));
473 ParticleData a(1, box, 1, exec_conf);
475 Scalar tol = Scalar(1e-6);
477 // make sure the box is working
478 const BoxDim& c = a.getBox();
479 MY_BOOST_CHECK_CLOSE(c.getLo().x,-5.0, tol);
480 MY_BOOST_CHECK_CLOSE(c.getLo().y,-15.0, tol);
481 MY_BOOST_CHECK_CLOSE(c.getLo().z,-25.0, tol);
482 MY_BOOST_CHECK_CLOSE(c.getHi().x,5.0, tol);
483 MY_BOOST_CHECK_CLOSE(c.getHi().y,15.0, tol);
484 MY_BOOST_CHECK_CLOSE(c.getHi().z,25.0, tol);
486 a.setGlobalBoxL(make_scalar3(5.0, 5.0, 5.0));
487 const BoxDim& d = a.getBox();
488 MY_BOOST_CHECK_CLOSE(d.getLo().x,-2.5, tol);
489 MY_BOOST_CHECK_CLOSE(d.getLo().y,-2.5, tol);
490 MY_BOOST_CHECK_CLOSE(d.getLo().z,-2.5, tol);
491 MY_BOOST_CHECK_CLOSE(d.getHi().x,2.5, tol);
492 MY_BOOST_CHECK_CLOSE(d.getHi().y,2.5, tol);
493 MY_BOOST_CHECK_CLOSE(d.getHi().z,2.5, tol);
495 // make sure that getN is working
496 BOOST_CHECK(a.getN() == 1);
498 // Test the ability to acquire data
500 ArrayHandle<Scalar4> h_pos(a.getPositions(), access_location::host, access_mode::readwrite);
501 ArrayHandle<Scalar4> h_vel(a.getVelocities(), access_location::host, access_mode::readwrite);
502 ArrayHandle<Scalar3> h_accel(a.getAccelerations(), access_location::host, access_mode::readwrite);
503 ArrayHandle<int3> h_image(a.getImages(), access_location::host, access_mode::readwrite);
504 ArrayHandle<Scalar> h_charge(a.getCharges(), access_location::host, access_mode::readwrite);
505 ArrayHandle<Scalar> h_diameter(a.getDiameters(), access_location::host, access_mode::readwrite);
506 ArrayHandle<unsigned int> h_tag(a.getTags(), access_location::host, access_mode::readwrite);
507 ArrayHandle<unsigned int> h_rtag(a.getRTags(), access_location::host, access_mode::readwrite);
508 ArrayHandle<unsigned int> h_body(a.getBodies(), access_location::host, access_mode::readwrite);
510 // begin by verifying that the defaults the class adversizes are set
511 BOOST_CHECK(a.getPositions().getNumElements() == 1);
512 BOOST_CHECK(a.getVelocities().getNumElements() == 1);
513 BOOST_CHECK(a.getAccelerations().getNumElements() == 1);
514 BOOST_CHECK(a.getImages().getNumElements() == 1);
515 BOOST_CHECK(a.getCharges().getNumElements() == 1);
516 BOOST_CHECK(a.getDiameters().getNumElements() == 1);
517 BOOST_CHECK(a.getTags().getNumElements() == 1);
518 BOOST_CHECK(a.getRTags().getNumElements() == 1);
519 BOOST_CHECK(a.getBodies().getNumElements() == 1);
522 MY_BOOST_CHECK_CLOSE(h_pos.data[0].x, 0.0, tol);
523 MY_BOOST_CHECK_CLOSE(h_pos.data[0].y, 0.0, tol);
524 MY_BOOST_CHECK_CLOSE(h_pos.data[0].z, 0.0, tol);
525 MY_BOOST_CHECK_CLOSE(h_vel.data[0].x, 0.0, tol);
526 MY_BOOST_CHECK_CLOSE(h_vel.data[0].y, 0.0, tol);
527 MY_BOOST_CHECK_CLOSE(h_vel.data[0].z, 0.0, tol);
528 MY_BOOST_CHECK_CLOSE(h_accel.data[0].x, 0.0, tol);
529 MY_BOOST_CHECK_CLOSE(h_accel.data[0].y, 0.0, tol);
530 MY_BOOST_CHECK_CLOSE(h_accel.data[0].z, 0.0, tol);
531 MY_BOOST_CHECK_CLOSE(h_charge.data[0], 0.0, tol);
532 MY_BOOST_CHECK_CLOSE(h_vel.data[0].w, 1.0, tol); // mass
533 MY_BOOST_CHECK_CLOSE(h_diameter.data[0], 1.0, tol);
534 BOOST_CHECK_EQUAL(h_image.data[0].x, 0);
535 BOOST_CHECK_EQUAL(h_image.data[0].y, 0);
536 BOOST_CHECK_EQUAL(h_image.data[0].z, 0);
537 BOOST_CHECK(__scalar_as_int(h_pos.data[0].w) == 0); //type
538 BOOST_CHECK(h_rtag.data[0] == 0);
539 BOOST_CHECK(h_tag.data[0] == 0);
540 BOOST_CHECK(h_body.data[0] == NO_BODY);
542 // set some new values for testing
543 h_pos.data[0].x = 1.0;
544 h_pos.data[0].y = 2.0;
545 h_pos.data[0].z = -2.0;
546 h_vel.data[0].x = 11.0;
547 h_vel.data[0].y = 12.0;
548 h_vel.data[0].z = 13.0;
549 h_accel.data[0].x = 21.0;
550 h_accel.data[0].y = 22.0;
551 h_accel.data[0].z = 23.0;
552 h_charge.data[0] = 24.0;
553 h_vel.data[0].w = 25.0; // mass
554 h_diameter.data[0] = 26.0;
555 h_image.data[0].x = 27;
556 h_image.data[0].y = 28;
557 h_image.data[0].z = 29;
558 h_pos.data[0].w = __int_as_scalar(1); //type
559 h_body.data[0] = 0;
563 // make sure when the data is re-acquired, the values read properly
565 ArrayHandle<Scalar4> h_pos(a.getPositions(), access_location::host, access_mode::read);
566 ArrayHandle<Scalar4> h_vel(a.getVelocities(), access_location::host, access_mode::read);
567 ArrayHandle<Scalar3> h_accel(a.getAccelerations(), access_location::host, access_mode::read);
568 ArrayHandle<int3> h_image(a.getImages(), access_location::host, access_mode::read);
569 ArrayHandle<Scalar> h_charge(a.getCharges(), access_location::host, access_mode::read);
570 ArrayHandle<Scalar> h_diameter(a.getDiameters(), access_location::host, access_mode::read);
571 ArrayHandle<unsigned int> h_tag(a.getTags(), access_location::host, access_mode::read);
572 ArrayHandle<unsigned int> h_rtag(a.getRTags(), access_location::host, access_mode::read);
573 ArrayHandle<unsigned int> h_body(a.getBodies(), access_location::host, access_mode::read);
575 BOOST_CHECK(a.getPositions().getNumElements() == 1);
576 BOOST_CHECK(a.getVelocities().getNumElements() == 1);
577 BOOST_CHECK(a.getAccelerations().getNumElements() == 1);
578 BOOST_CHECK(a.getImages().getNumElements() == 1);
579 BOOST_CHECK(a.getCharges().getNumElements() == 1);
580 BOOST_CHECK(a.getDiameters().getNumElements() == 1);
581 BOOST_CHECK(a.getTags().getNumElements() == 1);
582 BOOST_CHECK(a.getRTags().getNumElements() == 1);
583 BOOST_CHECK(a.getBodies().getNumElements() == 1);
585 MY_BOOST_CHECK_CLOSE(h_pos.data[0].x, 1.0, tol);
586 MY_BOOST_CHECK_CLOSE(h_pos.data[0].y, 2.0, tol);
587 MY_BOOST_CHECK_CLOSE(h_pos.data[0].z,-2.0, tol);
588 MY_BOOST_CHECK_CLOSE(h_vel.data[0].x,11.0, tol);
589 MY_BOOST_CHECK_CLOSE(h_vel.data[0].y,12.0, tol);
590 MY_BOOST_CHECK_CLOSE(h_vel.data[0].z,13.0, tol);
591 MY_BOOST_CHECK_CLOSE(h_accel.data[0].x,21.0, tol);
592 MY_BOOST_CHECK_CLOSE(h_accel.data[0].y,22.0, tol);
593 MY_BOOST_CHECK_CLOSE(h_accel.data[0].z,23.0, tol);
594 MY_BOOST_CHECK_CLOSE(h_charge.data[0],24.0, tol);
595 MY_BOOST_CHECK_CLOSE(h_vel.data[0].w,25.0, tol); // mass
596 MY_BOOST_CHECK_CLOSE(h_diameter.data[0],26.0, tol);
597 BOOST_CHECK_EQUAL(h_image.data[0].x,27);
598 BOOST_CHECK_EQUAL(h_image.data[0].y,28);
599 BOOST_CHECK_EQUAL(h_image.data[0].z,29);
600 BOOST_CHECK(__scalar_as_int(h_pos.data[0].w) == 1); //type
601 BOOST_CHECK(h_rtag.data[0] == 0);
602 BOOST_CHECK(h_tag.data[0] == 0);
603 BOOST_CHECK(h_body.data[0] == 0);
606 // finally, lets check a larger ParticleData for correctness of the initialization
607 const unsigned int N = 1000;
608 ParticleData b(N, box, 1, exec_conf);
610 ArrayHandle<Scalar4> h_pos(b.getPositions(), access_location::host, access_mode::read);
611 ArrayHandle<Scalar4> h_vel(b.getVelocities(), access_location::host, access_mode::read);
612 ArrayHandle<Scalar3> h_accel(b.getAccelerations(), access_location::host, access_mode::read);
613 ArrayHandle<int3> h_image(b.getImages(), access_location::host, access_mode::read);
614 ArrayHandle<Scalar> h_charge(b.getCharges(), access_location::host, access_mode::read);
615 ArrayHandle<Scalar> h_diameter(b.getDiameters(), access_location::host, access_mode::read);
616 ArrayHandle<unsigned int> h_tag(b.getTags(), access_location::host, access_mode::read);
617 ArrayHandle<unsigned int> h_rtag(b.getRTags(), access_location::host, access_mode::read);
618 ArrayHandle<unsigned int> h_body(b.getBodies(), access_location::host, access_mode::read);
620 // begin by verifying that the defaults the class adversizes are set
621 BOOST_CHECK(b.getPositions().getNumElements() == N);
622 BOOST_CHECK(b.getVelocities().getNumElements() == N);
623 BOOST_CHECK(b.getAccelerations().getNumElements() == N);
624 BOOST_CHECK(b.getImages().getNumElements() == N);
625 BOOST_CHECK(b.getCharges().getNumElements() == N);
626 BOOST_CHECK(b.getDiameters().getNumElements() == N);
627 BOOST_CHECK(b.getTags().getNumElements() == N);
628 BOOST_CHECK(b.getRTags().getNumElements() == N);
629 BOOST_CHECK(b.getBodies().getNumElements() == N);
632 for (unsigned int i = 0; i < N; i++)
634 MY_BOOST_CHECK_CLOSE(h_pos.data[i].x, 0.0, tol);
635 MY_BOOST_CHECK_CLOSE(h_pos.data[i].y, 0.0, tol);
636 MY_BOOST_CHECK_CLOSE(h_pos.data[i].z, 0.0, tol);
637 MY_BOOST_CHECK_CLOSE(h_vel.data[i].x, 0.0, tol);
638 MY_BOOST_CHECK_CLOSE(h_vel.data[i].y, 0.0, tol);
639 MY_BOOST_CHECK_CLOSE(h_vel.data[i].z, 0.0, tol);
640 MY_BOOST_CHECK_CLOSE(h_accel.data[i].x, 0.0, tol);
641 MY_BOOST_CHECK_CLOSE(h_accel.data[i].y, 0.0, tol);
642 MY_BOOST_CHECK_CLOSE(h_accel.data[i].z, 0.0, tol);
643 MY_BOOST_CHECK_CLOSE(h_charge.data[i], 0.0, tol);
644 MY_BOOST_CHECK_CLOSE(h_vel.data[i].w, 1.0, tol); // mass
645 MY_BOOST_CHECK_CLOSE(h_diameter.data[i], 1.0, tol);
646 BOOST_CHECK_EQUAL(h_image.data[i].x, 0);
647 BOOST_CHECK_EQUAL(h_image.data[i].y, 0);
648 BOOST_CHECK_EQUAL(h_image.data[i].z, 0);
649 BOOST_CHECK(__scalar_as_int(h_pos.data[i].w) == 0); //type
650 BOOST_CHECK(h_rtag.data[i] == i);
651 BOOST_CHECK(h_tag.data[i] == i);
652 BOOST_CHECK(h_body.data[i] == NO_BODY);
658 //! Test operation of the simple cubic initializer class
659 BOOST_AUTO_TEST_CASE( SimpleCubic_test )
661 Scalar tol = Scalar(1e-6);
663 // make a simple one-particle box
664 boost::shared_ptr<ExecutionConfiguration> exec_conf(new ExecutionConfiguration(ExecutionConfiguration::CPU));
665 SimpleCubicInitializer one(1, 2.0, "ABC");
666 boost::shared_ptr<SnapshotSystemData> snapshot = one.getSnapshot();
667 ParticleData one_data(snapshot->particle_data, snapshot->global_box, exec_conf);
669 BOOST_CHECK(one_data.getN() == 1);
671 ArrayHandle<Scalar4> h_pos(one_data.getPositions(), access_location::host, access_mode::read);
673 MY_BOOST_CHECK_CLOSE(h_pos.data[0].x, -1.0, tol);
674 MY_BOOST_CHECK_CLOSE(h_pos.data[0].y, -1.0, tol);
675 MY_BOOST_CHECK_CLOSE(h_pos.data[0].z, -1.0, tol);
678 BOOST_CHECK_EQUAL(one_data.getNameByType(0), "ABC");
679 BOOST_CHECK_EQUAL(one_data.getTypeByName("ABC"), (unsigned int)0);
681 // now try an 8-particle one
682 SimpleCubicInitializer eight(2, 2.0, "A");
683 boost::shared_ptr<SnapshotSystemData> snapshot_eight = eight.getSnapshot();
684 ParticleData eight_data(snapshot_eight->particle_data, snapshot_eight->global_box, exec_conf);
686 BOOST_CHECK(eight_data.getN() == 8);
688 ArrayHandle<Scalar4> h_pos(eight_data.getPositions(), access_location::host, access_mode::read);
689 MY_BOOST_CHECK_CLOSE(h_pos.data[0].x, -2.0, tol);
690 MY_BOOST_CHECK_CLOSE(h_pos.data[0].y, -2.0, tol);
691 MY_BOOST_CHECK_CLOSE(h_pos.data[0].z, -2.0, tol);
692 MY_BOOST_CHECK_CLOSE(h_pos.data[1].x, 0.0, tol);
693 MY_BOOST_CHECK_CLOSE(h_pos.data[1].y, -2.0, tol);
694 MY_BOOST_CHECK_CLOSE(h_pos.data[1].z, -2.0, tol);
695 MY_BOOST_CHECK_CLOSE(h_pos.data[2].x, -2.0, tol);
696 MY_BOOST_CHECK_CLOSE(h_pos.data[2].y, 0.0, tol);
697 MY_BOOST_CHECK_CLOSE(h_pos.data[2].z, -2.0, tol);
698 MY_BOOST_CHECK_CLOSE(h_pos.data[3].x, 0.0, tol);
699 MY_BOOST_CHECK_CLOSE(h_pos.data[3].y, 0.0, tol);
700 MY_BOOST_CHECK_CLOSE(h_pos.data[3].z, -2.0, tol);
702 MY_BOOST_CHECK_CLOSE(h_pos.data[4].x, -2.0, tol);
703 MY_BOOST_CHECK_CLOSE(h_pos.data[4].y, -2.0, tol);
704 MY_BOOST_CHECK_CLOSE(h_pos.data[4].z, 0.0, tol);
705 MY_BOOST_CHECK_CLOSE(h_pos.data[5].x, 0.0, tol);
706 MY_BOOST_CHECK_CLOSE(h_pos.data[5].y, -2.0, tol);
707 MY_BOOST_CHECK_CLOSE(h_pos.data[5].z, 0.0, tol);
708 MY_BOOST_CHECK_CLOSE(h_pos.data[6].x, -2.0, tol);
709 MY_BOOST_CHECK_CLOSE(h_pos.data[6].y, 0.0, tol);
710 MY_BOOST_CHECK_CLOSE(h_pos.data[6].z, 0.0, tol);
711 MY_BOOST_CHECK_CLOSE(h_pos.data[7].x, 0.0, tol);
712 MY_BOOST_CHECK_CLOSE(h_pos.data[7].y, 0.0, tol);
713 MY_BOOST_CHECK_CLOSE(h_pos.data[7].z, 0.0, tol);
717 //! Tests the RandomParticleInitializer class
718 BOOST_AUTO_TEST_CASE( Random_test )
720 // create a fairly dense system with a minimum distance of 0.8
721 boost::shared_ptr<ExecutionConfiguration> exec_conf(new ExecutionConfiguration(ExecutionConfiguration::CPU));
722 Scalar min_dist = Scalar(0.8);
723 RandomInitializer rand_init(500, Scalar(0.4), min_dist, "ABC");
724 boost::shared_ptr<SnapshotSystemData> snap = rand_init.getSnapshot();
725 ParticleData pdata(snap->particle_data, snap->global_box, exec_conf);
727 BOOST_CHECK_EQUAL(pdata.getNameByType(0), "ABC");
728 BOOST_CHECK_EQUAL(pdata.getTypeByName("ABC"), (unsigned int)0);
731 ArrayHandle<Scalar4> h_pos(pdata.getPositions(), access_location::host, access_mode::read);
733 // check that the distances between particles are OK
734 BoxDim box = pdata.getBox();
735 Scalar L = box.getL().x;
736 for (unsigned int i = 0; i < pdata.getN(); i++)
738 BOOST_CHECK(h_pos.data[i].x <= box.getHi().x && h_pos.data[i].x >= box.getLo().x);
739 BOOST_CHECK(h_pos.data[i].y <= box.getHi().y && h_pos.data[i].y >= box.getLo().y);
740 BOOST_CHECK(h_pos.data[i].z <= box.getHi().z && h_pos.data[i].z >= box.getLo().z);
742 for (unsigned int j = 0; j < pdata.getN(); j++)
744 if (i == j)
745 continue;
747 Scalar dx = h_pos.data[j].x - h_pos.data[i].x;
748 Scalar dy = h_pos.data[j].y - h_pos.data[i].y;
749 Scalar dz = h_pos.data[j].z - h_pos.data[i].z;
751 if (dx < -L/Scalar(2.0))
752 dx += L;
753 if (dx > L/Scalar(2.0))
754 dx -= L;
756 if (dy < -L/Scalar(2.0))
757 dy += L;
758 if (dy > L/Scalar(2.0))
759 dy -= L;
761 if (dz < -L/Scalar(2.0))
762 dz += L;
763 if (dz > L/Scalar(2.0))
764 dz -= L;
766 Scalar dr2 = dx*dx + dy*dy + dz*dz;
767 BOOST_CHECK(dr2 >= min_dist*min_dist);
774 /*#include "RandomGenerator.h"
775 #include "MOL2DumpWriter.h"
776 BOOST_AUTO_TEST_CASE( Generator_test )
778 vector<string> types;
779 for (int i = 0; i < 6; i++)
780 types.push_back("A");
781 for (int i = 0; i < 7; i++)
782 types.push_back("B");
783 for (int i = 0; i < 6; i++)
784 types.push_back("A");
786 vector<string> types2;
787 for (int i = 0; i < 7; i++)
788 types2.push_back("B");
790 boost::shared_ptr<PolymerParticleGenerator> poly(new PolymerParticleGenerator(1.2, types, 100));
791 boost::shared_ptr<PolymerParticleGenerator> poly2(new PolymerParticleGenerator(1.2, types2, 100));
792 BoxDim box(40);
793 RandomGenerator generator(box, 1);
794 generator.setSeparationRadius("A", 0.5);
795 generator.setSeparationRadius("B", 0.5);
796 generator.addGenerator(20, poly);
797 generator.addGenerator(20, poly2);
799 generator.generate();
801 boost::shared_ptr<ParticleData> pdata(new ParticleData(generator));
802 MOL2DumpWriter dump(pdata, string("test.mol2"));
803 dump.analyze(0);
806 #ifdef WIN32
807 #pragma warning( pop )
808 #endif