Enable -march=native in OS X clang builds
[hoomd-blue.git] / libhoomd / potentials / EvaluatorPairDPDThermo.h
blob15d2b37d820ea94667fa506ad40f8e8824e3b527
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.
50 // Maintainer: phillicl
52 #ifndef __PAIR_EVALUATOR_DPD_H__
53 #define __PAIR_EVALUATOR_DPD_H__
55 #ifndef NVCC
56 #include <string>
57 #endif
59 #include "HOOMDMath.h"
61 #ifdef NVCC
62 #include "saruprngCUDA.h"
63 #else
64 #include "saruprng.h"
65 #endif
68 /*! \file EvaluatorPairDPDThermo.h
69 \brief Defines the pair evaluator class for the DPD conservative potential
72 // need to declare these class methods with __device__ qualifiers when building in nvcc
73 // DEVICE is __host__ __device__ when included in nvcc and blank when included into the host compiler
74 #ifdef NVCC
75 #define DEVICE __device__
76 #else
77 #define DEVICE
78 #endif
80 // call different Saru PRNG initializers on the host / device
81 // SARU is SaruGPU Class when included in nvcc and Saru Class when included into the host compiler
82 #ifdef NVCC
83 #define SARU(ix,iy,iz) SaruGPU saru( (ix) , (iy) , (iz) )
84 #else
85 #define SARU(ix, iy, iz) Saru saru( (ix) , (iy) , (iz) )
86 #endif
88 // use different Saru PRNG returns on the host / device
89 // CALL_SARU is currently define to return a random Scalar for both the GPU and Host. By changing saru.f to saru.d, a double could be returned instead.
90 #ifdef NVCC
91 #define CALL_SARU(x,y) saru.f( (x), (y))
92 #else
93 #define CALL_SARU(x,y) saru.f( (x), (y))
94 #endif
98 //! Class for evaluating the DPD Thermostat pair potential
99 /*! <b>General Overview</b>
101 See EvaluatorPairLJ
103 <b>DPD Thermostat and Conservative specifics</b>
105 EvaluatorPairDPDThermo::evalForceAndEnergy evaluates the function:
106 \f[ V_{\mathrm{DPD-C}}(r) = A \cdot \left( r_{\mathrm{cut}} - r \right)
107 - \frac{1}{2} \cdot \frac{A}{r_{\mathrm{cut}}} \cdot \left(r_{\mathrm{cut}}^2 - r^2 \right)\f]
109 The DPD Conservative potential does not need charge or diameter. One parameter is specified and stored in a Scalar.
110 \a A is placed in \a param.
112 EvaluatorPairDPDThermo::evalForceEnergyThermo evaluates the function:
113 \f{eqnarray*}
114 F = F_{\mathrm{C}}(r) + F_{\mathrm{R,ij}}(r_{ij}) + F_{\mathrm{D,ij}}(v_{ij}) \\
117 \f{eqnarray*}
118 F_{\mathrm{C}}(r) = & A \cdot w(r_{ij}) \\
119 F_{\mathrm{R, ij}}(r_{ij}) = & - \theta_{ij}\sqrt{3} \sqrt{\frac{2k_b\gamma T}{\Delta t}}\cdot w(r_{ij}) \\
120 F_{\mathrm{D, ij}}(r_{ij}) = & - \gamma w^2(r_{ij})\left( \hat r_{ij} \circ v_{ij} \right) \\
123 \f{eqnarray*}
124 w(r_{ij}) = &\left( 1 - r/r_{\mathrm{cut}} \right) & r < r_{\mathrm{cut}} \\
125 = & 0 & r \ge r_{\mathrm{cut}} \\
127 where \f$\hat r_{ij} \f$ is a normalized vector from particle i to particle j, \f$ v_{ij} = v_i - v_j \f$, and \f$ \theta_{ij} \f$ is a uniformly distributed
128 random number in the range [-1, 1].
130 The DPD Thermostat potential does not need charge or diameter. Two parameters are specified and stored in a Scalar.
131 \a A and \a gamma are placed in \a param.
133 These are related to the standard lj parameters sigma and epsilon by:
134 - \a A = \f$ A \f$
135 - \a gamma = \f$ \gamma \f$
138 class EvaluatorPairDPDThermo
140 public:
141 //! Define the parameter type used by this pair potential evaluator
142 typedef Scalar2 param_type;
144 //! Constructs the pair potential evaluator
145 /*! \param _rsq Squared distance beteen the particles
146 \param _rcutsq Sqauared distance at which the potential goes to 0
147 \param _params Per type pair parameters of this potential
149 DEVICE EvaluatorPairDPDThermo(Scalar _rsq, Scalar _rcutsq, const param_type& _params)
150 : rsq(_rsq), rcutsq(_rcutsq), a(_params.x), gamma(_params.y)
154 //! Set i and j, (particle tags), and the timestep
155 DEVICE void set_seed_ij_timestep(unsigned int seed, unsigned int i, unsigned int j, unsigned int timestep)
157 m_seed = seed;
158 m_i = i;
159 m_j = j;
160 m_timestep = timestep;
163 //! Set the timestep size
164 DEVICE void setDeltaT(Scalar dt)
166 m_deltaT = dt;
169 //! Set the velocity term
170 DEVICE void setRDotV(Scalar dot)
172 m_dot = dot;
175 //! Set the temperature
176 DEVICE void setT(Scalar Temp)
178 m_T = Temp;
181 //! Does not use diameter
182 DEVICE static bool needsDiameter() { return false; }
183 //! Accept the optional diameter values
184 /*! \param di Diameter of particle i
185 \param dj Diameter of particle j
187 DEVICE void setDiameter(Scalar di, Scalar dj) { }
189 //! Yukawa doesn't use charge
190 DEVICE static bool needsCharge() { return false; }
191 //! Accept the optional diameter values
192 /*! \param qi Charge of particle i
193 \param qj Charge of particle j
195 DEVICE void setCharge(Scalar qi, Scalar qj) { }
197 //! Evaluate the force and energy using the conservative force only
198 /*! \param force_divr Output parameter to write the computed force divided by r.
199 \param pair_eng Output parameter to write the computed pair energy
200 \param energy_shift If true, the potential must be shifted so that V(r) is continuous at the cutoff
201 \note There is no need to check if rsq < rcutsq in this method. Cutoff tests are performed
202 in PotentialPair.
204 \return True if they are evaluated or false if they are not because we are beyond the cuttoff
206 DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& pair_eng, bool energy_shift)
208 // compute the force divided by r in force_divr
209 if (rsq < rcutsq)
212 Scalar rinv = fast::rsqrt(rsq);
213 Scalar r = Scalar(1.0) / rinv;
214 Scalar rcutinv = fast::rsqrt(rcutsq);
215 Scalar rcut = Scalar(1.0) / rcutinv;
217 // force is easy to calculate
218 force_divr = a*(rinv - rcutinv);
219 pair_eng = a * (rcut - r) - Scalar(1.0/2.0) * a * rcutinv * (rcutsq - rsq);
221 return true;
223 else
224 return false;
227 //! Evaluate the force and energy using the thermostat
228 /*! \param force_divr Output parameter to write the computed force divided by r.
229 \param force_divr_cons Output parameter to write the computed conservative force divided by r.
230 \param pair_eng Output parameter to write the computed pair energy
231 \param energy_shift Ignored. DPD always goes to 0 at the cutoff.
232 \note There is no need to check if rsq < rcutsq in this method. Cutoff tests are performed
233 in PotentialPair.
235 \note The conservative part \b only must be output to \a force_divr_cons so that the virial may be
236 computed correctly.
238 \return True if they are evaluated or false if they are not because we are beyond the cuttoff
240 DEVICE bool evalForceEnergyThermo(Scalar& force_divr, Scalar& force_divr_cons, Scalar& pair_eng, bool energy_shift)
242 // compute the force divided by r in force_divr
243 if (rsq < rcutsq)
245 Scalar rinv = fast::rsqrt(rsq);
246 Scalar r = Scalar(1.0) / rinv;
247 Scalar rcutinv = fast::rsqrt(rcutsq);
248 Scalar rcut = Scalar(1.0) / rcutinv;
250 // force calculation
252 unsigned int m_oi, m_oj;
253 // initialize the RNG
254 if (m_i > m_j)
256 m_oi = m_j;
257 m_oj = m_i;
259 else
261 m_oi = m_i;
262 m_oj = m_j;
265 SARU(m_oi, m_oj, m_seed + m_timestep);
268 // Generate a single random number
269 Scalar alpha = CALL_SARU(-1,1) ;
271 // conservative dpd
272 //force_divr = FDIV(a,r)*(Scalar(1.0) - r*rcutinv);
273 force_divr = a*(rinv - rcutinv);
275 // conservative force only
276 force_divr_cons = force_divr;
278 // Drag Term
279 force_divr -= gamma*m_dot*(rinv - rcutinv)*(rinv - rcutinv);
281 // Random Force
282 force_divr += fast::rsqrt(m_deltaT/(m_T*gamma*Scalar(6.0)))*(rinv - rcutinv)*alpha;
284 //conservative energy only
285 pair_eng = a * (rcut - r) - Scalar(1.0/2.0) * a * rcutinv * (rcutsq - rsq);
288 return true;
290 else
291 return false;
294 #ifndef NVCC
295 //! Get the name of this potential
296 /*! \returns The potential name. Must be short and all lowercase, as this is the name energies will be logged as
297 via analyze.log.
299 static std::string getName()
301 return std::string("dpd");
303 #endif
305 protected:
306 Scalar rsq; //!< Stored rsq from the constructor
307 Scalar rcutsq; //!< Stored rcutsq from the constructor
308 Scalar a; //!< a parameter for potential extracted from params by constructor
309 Scalar gamma; //!< gamma parameter for potential extracted from params by constructor
310 unsigned int m_seed; //!< User set seed for thermostat PRNG
311 unsigned int m_i; //!< index of first particle (should it be tag?). For use in PRNG
312 unsigned int m_j; //!< index of second particle (should it be tag?). For use in PRNG
313 unsigned int m_timestep; //!< timestep for use in PRNG
314 Scalar m_T; //!< Temperature for Themostat
315 Scalar m_dot; //!< Velocity difference dotted with displacement vector
316 Scalar m_deltaT; //!< timestep size stored from constructor
319 #undef SARU
321 #endif // __PAIR_EVALUATOR_DPD_H__