dcdfort
Modern Fortran library for analyzing DCD trajectories
Functions/Subroutines
dcdfort_utils Module Reference

Module that contains some useful utilities. More...

Functions/Subroutines

real(8) function, dimension(3) pbc (a, box)
 Corrects for the periodic boundary condition. More...
 
real(8) function, dimension(3) cross (a, b)
 Performs cross product between two vectors. More...
 
real(8) function distance2 (a, b, box)
 Calculates the distance squared between two points. More...
 
real(8) function distance (a, b, box)
 Calculates the distance between two points. More...
 
real(8) function, dimension(3) bond_vector (a, b, box)
 Calculates the bond vector between two points. More...
 
real(8) function magnitude (a)
 Calculates the magnitude of a vector. More...
 
real(8) function bond_angle (a, b, c, box)
 Calculates the bond angle between two vectors. More...
 
real(8) function dihedral_angle (i, j, k, l, box)
 Calculates the dihedral angle between two planes formed by four atoms. More...
 

Detailed Description

Module that contains some useful utilities.

Function/Subroutine Documentation

◆ bond_angle()

real(8) function dcdfort_utils::bond_angle ( real(8), dimension(3), intent(in)  a,
real(8), dimension(3), intent(in)  b,
real(8), dimension(3), intent(in)  c,
real(8), dimension(6), intent(in)  box 
)

Calculates the bond angle between two vectors.

Calculates the angle between the vector formed by a-b and b-c.

Parameters
[in]afirst point
[in]bmiddle point
[in]cthird point
[in]boxbox, if pbc to be accounted for
Returns
bond angle between a-b-c
209 
210  implicit none
211  real(8) :: bond_angle
212  real(8), intent(in), dimension(3) :: a, b, c
213  real(8), intent(in) :: box(6)
214  real(8), dimension(3) :: bond1, bond2
215 
216  bond1 = bond_vector(b, a, box)
217  bond2 = bond_vector(b, c, box)
218 
219  bond_angle = dacos(dot_product(bond1, bond2)/(magnitude(bond1)*magnitude(bond2)))
220 

◆ bond_vector()

real(8) function, dimension(3) dcdfort_utils::bond_vector ( real(8), dimension(3), intent(in)  a,
real(8), dimension(3), intent(in)  b,
real(8), dimension(6), intent(in)  box 
)

Calculates the bond vector between two points.

Parameters
[in]afirst point
[in]bsecond point
[in]boxbox, if pbc to be accounted for
Returns
bond vector pointing from a to b
178 
179  implicit none
180  real(8) :: bond_vector(3)
181  real(8), intent(in), dimension(3) :: a, b
182  real(8), intent(in) :: box(6)
183 
184  bond_vector = pbc(a-b, box)
185 

◆ cross()

real(8) function, dimension(3) dcdfort_utils::cross ( real(8), dimension(3), intent(in)  a,
real(8), dimension(3), intent(in)  b 
)

Performs cross product between two vectors.

Parameters
[in]afirst vector
[in]bsecond vector
Returns
resulting cross product
119 
120  implicit none
121  real(8) :: cross(3)
122  real(8), intent(in), dimension(3) :: a, b
123 
124  cross(1) = a(2) * b(3) - a(3) * b(2)
125  cross(2) = a(3) * b(1) - a(1) * b(3)
126  cross(3) = a(1) * b(2) - a(2) * b(1)
127 

◆ dihedral_angle()

real(8) function dcdfort_utils::dihedral_angle ( real(8), dimension(3), intent(in)  i,
real(8), dimension(3), intent(in)  j,
real(8), dimension(3), intent(in)  k,
real(8), dimension(3), intent(in)  l,
real(8), dimension(6), intent(in)  box 
)

Calculates the dihedral angle between two planes formed by four atoms.

Calculates the dihedral angle between the vectors formed by i-j, j-k, k-l

Parameters
[in]ifirst point
[in]jmiddle point
[in]kthird point
[in]lfourth point
[in]boxbox, if pbc to be accounted for
Returns
dihedral angle forms by i-j-k-l
232 
233  implicit none
234  real(8) :: dihedral_angle
235  real(8), intent(in), dimension(3) :: i, j, k, l
236  real(8), intent(in), dimension(6) :: box
237  real(8) :: a_mag, b_mag, g_mag
238  real(8), dimension(3) :: h, g, f, a, b, cross_ba
239 
240  h = bond_vector(k, l, box)
241  g = bond_vector(k, j, box)
242  f = bond_vector(j, i, box)
243  a = cross(f, g)
244  b = cross(h, g)
245  cross_ba = cross(b, a)
246  a_mag = magnitude(a)
247  b_mag = magnitude(b)
248  g_mag = magnitude(g)
249 
250  dihedral_angle = atan2(dot_product(cross_ba, g) / (a_mag*b_mag*g_mag), dot_product(a, b) / (a_mag*b_mag))
251 

◆ distance()

real(8) function dcdfort_utils::distance ( real(8), dimension(3), intent(in)  a,
real(8), dimension(3), intent(in)  b,
real(8), dimension(6), intent(in), optional  box 
)

Calculates the distance between two points.

Parameters
[in]afirst point
[in]bsecond point
[in]boxbox, if pbc to be accounted for
Returns
distance
158 
159  implicit none
160  real(8) :: distance
161  real(8), intent(in), dimension(3) :: a, b
162  real(8), intent(in), optional :: box(6)
163 
164  if (present(box)) then
165  distance = dsqrt(distance2(a, b, box))
166  else
167  distance = dsqrt(distance2(a, b))
168  end if
169 

◆ distance2()

real(8) function dcdfort_utils::distance2 ( real(8), dimension(3), intent(in)  a,
real(8), dimension(3), intent(in)  b,
real(8), dimension(6), intent(in), optional  box 
)

Calculates the distance squared between two points.

Parameters
[in]afirst point
[in]bsecond point
[in]boxbox, if pbc to be accounted for
Returns
distance squared
136 
137  implicit none
138  real(8) :: distance2
139  real(8), intent(in), dimension(3) :: a, b
140  real(8) :: c(3)
141  real(8), intent(in), optional :: box(6)
142 
143  if (present(box)) then
144  c = pbc(a - b, box)
145  else
146  c = a - b
147  end if
148  distance2 = dot_product(c, c)
149 

◆ magnitude()

real(8) function dcdfort_utils::magnitude ( real(8), dimension(3), intent(in)  a)

Calculates the magnitude of a vector.

Parameters
[in]avector
Returns
magnitude of a
192 
193  implicit none
194  real(8) :: magnitude
195  real(8), intent(in) :: a(3)
196 
197  magnitude = dsqrt(dot_product(a, a))
198 

◆ pbc()

real(8) function, dimension(3) dcdfort_utils::pbc ( real(8), dimension(3), intent(in)  a,
real(8), dimension(6), intent(in)  box 
)

Corrects for the periodic boundary condition.

Moves particle (or vector) the distance of half the box if it is more than half the distance of the box

Parameters
[in]aoriginal coordinates
[in]boxsimulation box
Returns
the shifted coordinates
39 
40  implicit none
41  real(8), intent(in) :: a(3), box(6)
42  real(8) :: pbc(3), tbox(3,3) = 0.0d0
43  integer :: i, shift
44 
45  ! A = box(1), length of unit cell vector along x-axis;
46  ! B = box(2), length of unit cell vector in xy-plane;
47  ! C = box(3), length of unit cell vector in yz-plane;
48  ! alpha = box(4), cosine of angle between B and C
49  ! beta = box(5), cosine of angle between A and C
50  ! gamma = box(6), cosine of angle between A and B
51 
52  ! New matrix made up of box vectors:
53 
54  ! ax bx cx
55  ! 0 by cy
56  ! 0 0 cz
57 
58  ! convert angles to box vectors
59 
60  ! A**2 = ax**2 + ay**2 + az**2
61  ! A**2 = ax**2 + (0)**2 + (0)**2
62  ! ax = A
63  tbox(1,1) = box(1)
64 
65  ! dot(A_vec,B_vec) = ax*bx + ay*by + az*bz
66  ! dot(A_vec,B_vec) = ax*bx + (0)*by + (0)*bz
67  ! A*B*gamma = ax*bx
68  ! bx = B*gamma
69  tbox(1,2) = box(2)*box(6)
70 
71  ! dot(A_vec,C_vec) = ax*cx + ay*cy + az*cz
72  ! dot(A_vec,C_vec) = ax*cx + (0)*cy + (0)*cz
73  ! A*C*beta = ax*cx
74  ! cx = C*beta
75  tbox(1,3) = box(3)*box(5)
76 
77  ! B**2 = bx**2 + by**2 + bz**2
78  ! B**2 = bx**2 + by**2 + (0)**2
79  ! by = sqrt(B**2 - bx**2)
80  tbox(2,2) = dsqrt(box(2)**2-tbox(1,2)**2)
81 
82  ! dot(B_vec,C_vec) = bx*cx + by*cy + (0)*cz
83  ! B*C*alpha = bx*cx + by*cy
84  ! cy = (B*C*alpha - bx*cx) / by
85  tbox(2,3) = (box(2)*box(3)*box(4) - tbox(1,2)*tbox(1,3))/tbox(2,2)
86 
87  ! C = cx**2 + cy**2 + cz**2
88  ! cz = sqrt(C**2 - cx**2 - cy**2)
89  tbox(3,3) = dsqrt(box(3)**2-tbox(1,3)**2-tbox(2,3)**2)
90 
91  pbc = a
92 
93  ! Now perform PBC calculation
94  shift = nint(pbc(3) / tbox(3,3))
95  if (shift .ne. 0) then
96  pbc(3) = pbc(3) - tbox(3,3) * shift
97  pbc(2) = pbc(2) - tbox(2,3) * shift
98  pbc(1) = pbc(1) - tbox(1,3) * shift
99  end if
100 
101  shift = nint(pbc(2) / tbox(2,2))
102  if (shift .ne. 0) then
103  pbc(2) = pbc(2) - tbox(2,2) * shift
104  pbc(1) = pbc(1) - tbox(1,2) * shift
105  end if
106 
107  shift = nint(pbc(1) / tbox(1,1))
108  if (shift .ne. 0) then
109  pbc(1) = pbc(1) - tbox(1,1) * shift
110  end if
111