Merge branch 'maint'
[hoomd-blue.git] / test / unit / test_const_external_field_dipole.cc
blob8b6de8ef3673322c282caad46df9b2eea193b5f9
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.
49 // Maintainer: baschult
51 #ifdef WIN32
52 #pragma warning( push )
53 #pragma warning( disable : 4103 4244 )
54 #endif
56 #include <iostream>
58 #include <boost/bind.hpp>
59 #include <boost/function.hpp>
60 #include <boost/shared_ptr.hpp>
62 #include "ConstExternalFieldDipoleForceCompute.h"
64 #include <math.h>
65 #include "QuaternionMath.h"
67 #ifndef PI
68 #define PI 3.141592653589793
69 #endif
71 using namespace std;
72 using namespace boost;
74 /*! \file lj_wall_compute_test.cc
75 \brief Implements unit tests for LJWallForceCompute and descendants
76 \ingroup unit_tests
79 //! Name the unit test module
80 #define BOOST_TEST_MODULE ConstExternalFieldDipoleForceTest
81 #include "boost_utf_configure.h"
83 //! Typedef'd ConstExternalFieldDipoleForceCompute factory
84 typedef boost::function<boost::shared_ptr<ConstExternalFieldDipoleForceCompute> (boost::shared_ptr<SystemDefinition> sysdef,
85 Scalar fx,Scalar fy, Scalar fz, Scalar p)> cefd_force_creator;
87 //! Test the ability of the lj wall force compute to actually calculate forces
88 void cefd_force_particle_test(cefd_force_creator cefd_creator, boost::shared_ptr<ExecutionConfiguration> exec_conf)
90 // this 3 particle test will check proper wall force computation among all 3 axes
91 boost::shared_ptr<SystemDefinition> sysdef_3(new SystemDefinition(3, BoxDim(1000.0), 1, 0, 0, 0, 0, exec_conf));
92 boost::shared_ptr<ParticleData> pdata_3 = sysdef_3->getParticleData();
94 pdata_3->setPosition(0,make_scalar3(0.0,1.2,0.0));
95 pdata_3->setPosition(1,make_scalar3(12.2,-10.0,0.0));
96 pdata_3->setPosition(2,make_scalar3(0.0,10.0,-12.9));
99 ArrayHandle<Scalar4> h_orientation(pdata_3->getOrientationArray());
100 eulerToQuat(0.0,0.5*PI, 0.0, h_orientation.data[0]); //dipole along x
101 eulerToQuat(0.5*PI,0, 0.0, h_orientation.data[1]); //dipole along y
102 eulerToQuat(2*PI, 2*PI, 2*PI, h_orientation.data[2]); //dipole along z
104 // create the wall force compute with a default cutoff of 1.0 => all forces should be 0 for the first round
105 boost::shared_ptr<ConstExternalFieldDipoleForceCompute> fc_3 = cefd_creator(sysdef_3, Scalar(0.0),Scalar(0.0),Scalar(0.0),Scalar(0.0));
107 // pick some parameters
108 Scalar field_x = 0.0;
109 Scalar field_y = 0.0;
110 Scalar field_z = 0.0;
111 Scalar p = 1.0;
112 fc_3->setParams(field_x,field_y,field_z,p);
114 // compute the forces
115 fc_3->compute(0);
118 // there are no walls, so all forces should be zero
119 GPUArray<Scalar4>& force_array_1 = fc_3->getForceArray();
120 GPUArray<Scalar>& virial_array_1 = fc_3->getVirialArray();
121 GPUArray<Scalar4>& torque_array_1 = fc_3->getTorqueArray();
122 ArrayHandle<Scalar4> h_force_1(force_array_1,access_location::host,access_mode::read);
123 ArrayHandle<Scalar> h_virial_1(virial_array_1,access_location::host,access_mode::read);
124 ArrayHandle<Scalar4> h_torque_1(torque_array_1,access_location::host,access_mode::read);
126 MY_BOOST_CHECK_SMALL(h_force_1.data[0].x, tol_small);
127 MY_BOOST_CHECK_SMALL(h_force_1.data[0].y, tol_small);
128 MY_BOOST_CHECK_SMALL(h_force_1.data[0].z, tol_small);
129 MY_BOOST_CHECK_SMALL(h_force_1.data[0].w, tol_small);
131 MY_BOOST_CHECK_SMALL(h_force_1.data[1].x, tol_small);
132 MY_BOOST_CHECK_SMALL(h_force_1.data[1].y, tol_small);
133 MY_BOOST_CHECK_SMALL(h_force_1.data[1].z, tol_small);
134 MY_BOOST_CHECK_SMALL(h_force_1.data[1].w, tol_small);
136 MY_BOOST_CHECK_SMALL(h_force_1.data[2].x, tol_small);
137 MY_BOOST_CHECK_SMALL(h_force_1.data[2].y, tol_small);
138 MY_BOOST_CHECK_SMALL(h_force_1.data[2].z, tol_small);
139 MY_BOOST_CHECK_SMALL(h_force_1.data[2].w, tol_small);
141 MY_BOOST_CHECK_SMALL(h_torque_1.data[0].x, tol_small);
142 MY_BOOST_CHECK_SMALL(h_torque_1.data[0].y, tol_small);
143 MY_BOOST_CHECK_SMALL(h_torque_1.data[0].z, tol_small);
144 MY_BOOST_CHECK_SMALL(h_torque_1.data[0].w, tol_small);
146 MY_BOOST_CHECK_SMALL(h_torque_1.data[1].x, tol_small);
147 MY_BOOST_CHECK_SMALL(h_torque_1.data[1].y, tol_small);
148 MY_BOOST_CHECK_SMALL(h_torque_1.data[1].z, tol_small);
149 MY_BOOST_CHECK_SMALL(h_torque_1.data[1].w, tol_small);
151 MY_BOOST_CHECK_SMALL(h_torque_1.data[2].x, tol_small);
152 MY_BOOST_CHECK_SMALL(h_torque_1.data[2].y, tol_small);
153 MY_BOOST_CHECK_SMALL(h_torque_1.data[2].z, tol_small);
154 MY_BOOST_CHECK_SMALL(h_torque_1.data[2].w, tol_small);
157 //turn on the field
158 field_x = 0.1;
159 field_y = 1.0;
160 field_z = 10.0;
161 p = 1.0;
162 fc_3->setParams(field_x,field_y,field_z,p);
164 // compute the forces again
165 fc_3->compute(1);
168 // they should still be zero
169 GPUArray<Scalar4>& force_array_2 = fc_3->getForceArray();
170 GPUArray<Scalar>& virial_array_2 = fc_3->getVirialArray();
171 GPUArray<Scalar4>& torque_array_2 = fc_3->getTorqueArray();
172 ArrayHandle<Scalar4> h_force_2(force_array_2,access_location::host,access_mode::read);
173 ArrayHandle<Scalar> h_virial_2(virial_array_2,access_location::host,access_mode::read);
174 ArrayHandle<Scalar4> h_torque_2(torque_array_2,access_location::host,access_mode::read);
176 MY_BOOST_CHECK_SMALL(h_force_2.data[0].x, tol_small);
177 MY_BOOST_CHECK_SMALL(h_force_2.data[0].y, tol_small);
178 MY_BOOST_CHECK_SMALL(h_force_2.data[0].z, tol_small);
179 MY_BOOST_CHECK_SMALL(h_force_2.data[0].w, tol_small);
181 MY_BOOST_CHECK_SMALL(h_force_2.data[1].x, tol_small);
182 MY_BOOST_CHECK_SMALL(h_force_2.data[1].y, tol_small);
183 MY_BOOST_CHECK_SMALL(h_force_2.data[1].z, tol_small);
184 MY_BOOST_CHECK_SMALL(h_force_2.data[1].w, tol_small);
186 MY_BOOST_CHECK_SMALL(h_force_2.data[2].x, tol_small);
187 MY_BOOST_CHECK_SMALL(h_force_2.data[2].y, tol_small);
188 MY_BOOST_CHECK_SMALL(h_force_2.data[2].z, tol_small);
189 MY_BOOST_CHECK_SMALL(h_force_2.data[2].w, tol_small);
191 MY_BOOST_CHECK_SMALL(h_torque_2.data[0].x, tol_small);
192 MY_BOOST_CHECK_CLOSE(h_torque_2.data[0].y, -field_z, tol);
193 MY_BOOST_CHECK_CLOSE(h_torque_2.data[0].z, field_y,tol);
194 MY_BOOST_CHECK_SMALL(h_torque_2.data[0].w, tol_small);
196 MY_BOOST_CHECK_CLOSE(h_torque_2.data[1].x, -field_z, tol);
197 MY_BOOST_CHECK_SMALL(h_torque_2.data[1].y, tol_small);
198 MY_BOOST_CHECK_CLOSE(h_torque_2.data[1].z, field_x,tol);
199 MY_BOOST_CHECK_SMALL(h_torque_2.data[1].w, tol_small);
201 MY_BOOST_CHECK_CLOSE(h_torque_2.data[2].x, -field_y, tol);
202 MY_BOOST_CHECK_CLOSE(h_torque_2.data[2].y, field_x, tol);
203 MY_BOOST_CHECK_SMALL(h_torque_2.data[2].z, tol_small);
204 MY_BOOST_CHECK_SMALL(h_torque_2.data[2].w, tol_small);
210 //! ConstExternalFieldDipoleForceCompute creator for unit tests
211 boost::shared_ptr<ConstExternalFieldDipoleForceCompute> base_class_cefd_creator(boost::shared_ptr<SystemDefinition> sysdef,Scalar fx, Scalar fy, Scalar fz, Scalar p)
213 return boost::shared_ptr<ConstExternalFieldDipoleForceCompute>(new ConstExternalFieldDipoleForceCompute(sysdef, fx, fy, fz, p));
216 //! boost test case for particle test on CPU
217 BOOST_AUTO_TEST_CASE( cefd_particle )
219 cefd_force_creator cefd_creator_base = bind(base_class_cefd_creator, _1, _2,_3,_4,_5);
220 cefd_force_particle_test(cefd_creator_base, boost::shared_ptr<ExecutionConfiguration>(new ExecutionConfiguration(ExecutionConfiguration::CPU)));
223 #ifdef WIN32
224 #pragma warning( pop )
225 #endif