RMPCDMD
interaction.f90
Go to the documentation of this file.
1 ! This file is part of RMPCDMD
2 ! Copyright (c) 2015-2016 Pierre de Buyl and contributors
3 ! License: BSD 3-clause (see file LICENSE)
4 
9 
11  implicit none
12 
13  private
14 
15  public :: lj_params_t
16  public :: lj_force
17  public :: lj_energy
18  public :: lj_force_9_6
19  public :: lj_energy_9_6
20  public :: lj_force_9_3
21  public :: lj_energy_9_3
22 
24  integer :: n1, n2
25  double precision, allocatable :: epsilon(:,:)
26  double precision, allocatable :: sigma(:,:)
27  double precision, allocatable :: sigma_sq(:,:)
28  double precision, allocatable :: cut(:,:)
29  double precision, allocatable :: cut_sq(:,:)
30  double precision, allocatable :: cut_energy(:,:)
31  double precision, allocatable :: shift(:)
32  contains
33  procedure :: init => lj_params_init
34  end type lj_params_t
35 
36 contains
37 
38  subroutine lj_params_init(this, epsilon, sigma, cut, shift)
39  class(lj_params_t), intent(out) :: this
40  double precision, intent(in) :: epsilon(:,:)
41  double precision, intent(in) :: sigma(:,:)
42  double precision, intent(in) :: cut(:,:)
43  double precision, intent(in), optional :: shift(:)
44 
45  integer :: n1, n2
46 
47  if ( size(epsilon, 1) /= size(sigma, 1) .or. &
48  size(epsilon, 1) /= size(cut, 1) .or. &
49  size(epsilon, 2) /= size(sigma, 2) .or. &
50  size(epsilon, 2) /= size(cut, 2) ) then
51  error stop 'unequal sizes for arguments to lj_params_init'
52  end if
53 
54  n1 = size(epsilon, 1)
55  n2 = size(epsilon, 2)
56  this% n1 = n1
57  this% n2 = n2
58 
59  allocate(this% epsilon(n1, n2))
60  allocate(this% sigma(n1, n2))
61  allocate(this% sigma_sq(n1, n2))
62  allocate(this% cut(n1, n2))
63  allocate(this% cut_sq(n1, n2))
64  allocate(this% cut_energy(n1, n2))
65  allocate(this% shift(n1))
66 
67  this% epsilon = epsilon
68  this% sigma = sigma
69  this% sigma_sq = sigma**2
70  this% cut = cut
71  this% cut_sq = cut**2
72  if (present(shift)) then
73  this% shift = shift
74  else
75  this% shift = 0.d0
76  end if
77 
78  this% cut_energy = lj_energy(this%cut_sq, this%epsilon, this%sigma, this%sigma*0)
79 
80  end subroutine lj_params_init
81 
82 
83  pure function lj_force(d, r_sq, epsilon, sigma) result(f)
84  double precision, intent(in) :: d(3)
85  double precision, intent(in) :: r_sq, epsilon, sigma
86  double precision :: f(3)
87 
88  double precision :: sig6_o_r6, force_over_r
89 
90  sig6_o_r6 = sigma**6/r_sq**3
91 
92  force_over_r = 24.d0*epsilon* sig6_o_r6/r_sq * (2.d0*sig6_o_r6 - 1.d0)
93 
94  f = force_over_r*d
95 
96  end function lj_force
97 
98  !interaction of colloid with the wall (9-6 LJ from SklogWiki)
99  pure function lj_force_9_6(d, r_sq, epsilon, sigma) result(f)
100  double precision, intent(in) :: d(3)
101  double precision, intent(in) :: r_sq, epsilon, sigma
102  double precision :: f(3)
103 
104  double precision :: sig6_o_r6, sig3_o_r3, force_o_r
105  sig6_o_r6 = sigma**6/r_sq**3
106  sig3_o_r3 = sigma**3/r_sq**(3.d0/2.d0)
107 
108  force_o_r = 6.75d0*3.d0*epsilon*sig6_o_r6/r_sq*(3.d0*sig3_o_r3-2.d0)
109 
110  f = force_o_r*d
111 
112  end function lj_force_9_6
113 
114  pure function lj_force_9_3(z, z_sq, epsilon, sigma) result(e)
115  double precision, intent(in) ::z, z_sq, epsilon, sigma
116  double precision :: e
117 
118  double precision :: sig3_o_r3, force_o_z
119 
120  sig3_o_r3 = sigma**3/z_sq**(3.d0/2.d0)
121 
122  force_o_z = 9*sqrt(3.d0)/2*epsilon/z_sq* (3.d0*sig3_o_r3**3 - sig3_o_r3)
123  e = force_o_z*z
124  end function lj_force_9_3
125 
126  pure elemental function lj_energy(r_sq, epsilon, sigma, cut_energy) result(e)
127  double precision, intent(in) :: r_sq, epsilon, sigma, cut_energy
128  double precision :: e
129 
130  double precision :: sig6_o_r6
131 
132  sig6_o_r6 = sigma**6/r_sq**3
133 
134  e = 4.d0*epsilon * (sig6_o_r6**2 - sig6_o_r6) - cut_energy
135 
136  end function lj_energy
137 
138  pure function lj_energy_9_6(r_sq, epsilon, sigma) result(e)
139  double precision, intent(in) :: r_sq, epsilon, sigma
140  double precision :: e
141 
142  double precision :: sig6_o_r6, sig3_o_r3
143 
144  sig6_o_r6 = sigma**6/r_sq**3
145  sig3_o_r3 = sigma**3/r_sq**(3.d0/2.d0)
146 
147  e = 6.75d0*epsilon * (sig6_o_r6*(sig3_o_r3 - 1.d0) + 4.d0/27.d0)
148 
149  end function lj_energy_9_6
150 
151  pure function lj_energy_9_3(z_sq, epsilon, sigma) result(e)
152  double precision, intent(in) :: z_sq, epsilon, sigma
153  double precision :: e
154 
155  double precision :: sig3_o_r3
156 
157  sig3_o_r3 = sigma**3/z_sq**(3.d0/2.d0)
158 
159  e = 3*sqrt(3.d0)/2*epsilon*(sig3_o_r3**3 - sig3_o_r3) + epsilon
160  end function lj_energy_9_3
161 
162 end module interaction
pure elemental double precision function, public lj_energy(r_sq, epsilon, sigma, cut_energy)
subroutine lj_params_init(this, epsilon, sigma, cut, shift)
Definition: interaction.f90:39
pure double precision function, dimension(3), public lj_force_9_6(d, r_sq, epsilon, sigma)
pure double precision function, public lj_energy_9_3(z_sq, epsilon, sigma)
pure double precision function, public lj_energy_9_6(r_sq, epsilon, sigma)
pure double precision function, dimension(3), public lj_force(d, r_sq, epsilon, sigma)
Definition: interaction.f90:84
pure double precision function, public lj_force_9_3(z, z_sq, epsilon, sigma)
Lennard-Jones potential definition.
Definition: interaction.f90:10