OpenMPCD
MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles.hpp
Go to the documentation of this file.
1 /**
2  * @file
3  * Defines the
4  * `OpenMPCD::PairPotentials::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles`
5  * class.
6  */
7 
8 #ifndef OPENMPCD_PAIRPOTENTIALS_MAGNETICDIPOLEDIPOLEINTERACTION_CONSTANTIDENTICALDIPOLES_HPP
9 #define OPENMPCD_PAIRPOTENTIALS_MAGNETICDIPOLEDIPOLEINTERACTION_CONSTANTIDENTICALDIPOLES_HPP
10 
11 #include <OpenMPCD/PairPotentials/Base.hpp>
12 
14 
15 #include <boost/core/is_same.hpp>
16 #include <boost/static_assert.hpp>
17 #include <boost/type_traits/remove_cv.hpp>
18 
19 namespace OpenMPCD
20 {
21 namespace PairPotentials
22 {
23 
24 /**
25  * Interactions between two constant and identical magnetic dipoles.
26  *
27  * The general magnetic dipole-dipole interaction potential is given by
28  * \f[
29  * - \frac{ \mu_0 }{ 4 \pi r^3 }
30  * \left(
31  * 3
32  * \left(\vec{m_1} \cdot \hat{r} \right)
33  * \left(\vec{m_2} \cdot \hat{r} \right)
34  * -
35  * \vec{m_1} \cdot \vec{m_2}
36  * \right)
37  * \f]
38  * where \f$ \mu_0 \f$ is the vacuum permeability, \f$ \hat{r} \f$ and \f$ r \f$
39  * are, respectively, the unit vector and length of the vector \f$ \vec{r} \f$
40  * that points from one dipole's position to the other's, \f$ \vec{m_1} \f$ and
41  * \f$ \vec{m_2} \f$ are the magnetic dipole moments, and \f$ \cdot \f$ denotes
42  * the inner product.
43  *
44  * In the special case treated in this class, the magnetic dipole moments are
45  * assumed to be constant throughout time in size and orientation. Therefore,
46  * with \f$ m \f$ being the magnitude of the individual dipole moments and with
47  * \f$ \hat{m} \f$ being the unit vector of the individual dipole moments, the
48  * interaction potential is given by
49  * \f[
50  * - \frac{ \mu_0 m^2 }{ 4 \pi r^3 }
51  * \left( 3 \left(\hat{m} \cdot \hat{r} \right)^2 - 1 \right)
52  * \f]
53  *
54  * @tparam T The numeric data type.
55  */
56 template<typename T = FP>
58  : public Base<T>
59 {
60 public:
61  /**
62  * The constructor.
63  *
64  * @param[in] prefactor_
65  * The term \f$ \frac{\mu_0 m^2}{4 \pi} \f$.
66  * @param[in] orientation_
67  * The orientation unit vector \f$ \hat{m} \f$ of the dipole
68  * moments.
69  */
72  const T prefactor_, const Vector3D<T>& orientation_)
73  : prefactor(prefactor_), orientation(orientation_)
74  {
75  //Type `float` is not currently tested in the unit tests, since it
76  //seems to result in considerable inaccuracies.
77  BOOST_STATIC_ASSERT(
78  !boost::is_same<
79  typename boost::remove_cv<T>::type,
80  float>
81  ::value);
82  }
83 
84  /**
85  * Returns the force vector of the interaction for a given position vector.
86  *
87  * This function returns the directional derivative
88  * \f[ - \nabla_R V \left( \vec{R} \right) \f]
89  * where \f$ \vec{R} \f$ is the `R` parameter, \f$ V \f$ is the potential
90  * as given by the `potential` function, and \f$ \nabla_R V \f$ is the
91  * gradient of \f$ V \f$ with respect to \f$ \vec{R} \f$.
92  *
93  * @throw OpenMPCD::AssertionException
94  * If `OPENMPCD_DEBUG` is defined, throws if
95  * `OpenMPCD::Scalar::isZero(R.getMagnitudeSquared())`.
96  *
97  * @param[in] R The relative position vector.
98  */
100  Vector3D<T> force(const Vector3D<T>& R) const
101  {
102  const T r2 = R.getMagnitudeSquared();
103 
105 
106  const T r_m2 = 1 / r2;
107  const T r_m3 = r_m2 / sqrt(r2);
108  const T r_m5 = r_m2 * r_m3;
109 
110  const T dot = orientation.dot(R);
111 
112  Vector3D<T> F(2 * dot * orientation);
113 
114  F -= (5 * r_m2 * dot * dot - 1) * R;
115 
116  return (3 * prefactor * r_m5) * F;
117  }
118 
119  /**
120  * Returns the potential of the interaction for a given position vector.
121  *
122  * @throw OpenMPCD::AssertionException
123  * If `OPENMPCD_DEBUG` is defined, throws if
124  * `OpenMPCD::Scalar::isZero(R.getMagnitudeSquared())`.
125  *
126  * @param[in] R The relative position vector.
127  */
129  T potential(const Vector3D<T>& R) const
130  {
131  const T r2 = R.getMagnitudeSquared();
132 
134 
135  const T r_m2 = 1 / r2;
136  const T r_m3 = r_m2 / sqrt(r2);
137  const T dot = R.dot(orientation);
138 
139  return - prefactor * r_m3 * (3 * dot * dot * r_m2 - 1);
140  }
141 
142  /**
143  * Returns the term \f$ \frac{\mu_0 m^2}{4 \pi} \f$.
144  */
146  T getPrefactor() const
147  {
148  return prefactor;
149  }
150 
151  /**
152  * Returns the dipole orientation \f$ \hat{m} \f$.
153  */
156  {
157  return orientation;
158  }
159 
160 private:
161  const T prefactor; ///< The term \f$ \frac{\mu_0 m^2}{4 \pi} \f$.
162  const Vector3D<T> orientation;
163  ///< The orientation unit vector \f$ \hat{m} \f$ of the dipole moments.
164 }; //class MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles
165 
166 } //namespace PairPotentials
167 } //namespace OpenMPCD
168 #endif //OPENMPCD_PAIRPOTENTIALS_MAGNETICDIPOLEDIPOLEINTERACTION_CONSTANTIDENTICALDIPOLES_HPP
OpenMPCD::Scalar::isZero
OPENMPCD_CUDA_HOST_AND_DEVICE boost::enable_if< boost::is_floating_point< T >, bool >::type isZero(const T &val)
Returns whether the given value is zero.
Definition: Scalar.hpp:66
OpenMPCD::PairPotentials::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles::getDipoleOrientation
const OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< T > & getDipoleOrientation() const
Returns the dipole orientation .
Definition: MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles.hpp:155
OpenMPCD::Vector3D
3-dimensional vector.
Definition: Vector3D.hpp:38
OpenMPCD::Vector3D::dot
const OPENMPCD_CUDA_HOST_AND_DEVICE T dot(const Vector3D &rhs) const
Returns the scalar product of this vector with the given vector.
Definition: Vector3D.hpp:181
OpenMPCD::PairPotentials::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles
Interactions between two constant and identical magnetic dipoles.
Definition: MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles.hpp:57
OPENMPCD_DEBUG_ASSERT
#define OPENMPCD_DEBUG_ASSERT(assertion)
Asserts that the given expression evaluates to true, but only if OPENMPCD_DEBUG is defined.
Definition: OPENMPCD_DEBUG_ASSERT.hpp:88
OPENMPCD_CUDA_HOST_AND_DEVICE
#define OPENMPCD_CUDA_HOST_AND_DEVICE
Denotes a function to be callable both from the Host and from a CUDA Device.
Definition: Macros.hpp:15
OpenMPCD::PairPotentials::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles
OPENMPCD_CUDA_HOST_AND_DEVICE MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles(const T prefactor_, const Vector3D< T > &orientation_)
The constructor.
Definition: MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles.hpp:71
OpenMPCD::PairPotentials::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles::getPrefactor
OPENMPCD_CUDA_HOST_AND_DEVICE T getPrefactor() const
Returns the term .
Definition: MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles.hpp:146
OPENMPCD_DEBUG_ASSERT.hpp
OpenMPCD::PairPotentials::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles::potential
OPENMPCD_CUDA_HOST_AND_DEVICE T potential(const Vector3D< T > &R) const
Returns the potential of the interaction for a given position vector.
Definition: MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles.hpp:129
OpenMPCD::Utility::MathematicalFunctions::sqrt
OPENMPCD_CUDA_HOST_AND_DEVICE T sqrt(const T x)
Returns the sqaure root of the argument.
OpenMPCD::PairPotentials::Base
Abstract base class for pair potentials.
Definition: PairPotentials/Base.hpp:24
OpenMPCD::PairPotentials::MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles::force
OPENMPCD_CUDA_HOST_AND_DEVICE Vector3D< T > force(const Vector3D< T > &R) const
Returns the force vector of the interaction for a given position vector.
Definition: MagneticDipoleDipoleInteraction_ConstantIdenticalDipoles.hpp:100
OpenMPCD::Vector3D::getMagnitudeSquared
OPENMPCD_CUDA_HOST_AND_DEVICE RealType getMagnitudeSquared() const
Returns the square of the magnitude of this vector.
Definition: Vector3D.hpp:209