17 #include "./base/base_uses.f90"
22 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'rmsd'
23 REAL(KIND=
dp),
PARAMETER,
PRIVATE :: epsi = epsilon(0.0_dp)*1.0e4_dp
51 SUBROUTINE rmsd3(particle_set, r, r0, output_unit, weights, my_val, &
52 rotate, transl, rot, drmsd3)
53 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
54 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: r, r0
55 INTEGER,
INTENT(IN) :: output_unit
56 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: weights
57 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: my_val
58 LOGICAL,
INTENT(IN),
OPTIONAL :: rotate
59 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT),
OPTIONAL :: transl
60 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT), &
61 OPTIONAL :: rot, drmsd3
63 INTEGER :: i, ix, j, k, natom
65 REAL(kind=
dp) :: dm_r(4, 4, 3), lambda(4), loc_tr(3), &
66 m(4, 4), mtot, my_rot(3, 3), q(0:3), &
67 rr(3), rr0(3), rrsq, s, xx, yy, &
69 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: w
70 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: r0p, rp
72 cpassert(
SIZE(r) ==
SIZE(r0))
73 natom =
SIZE(particle_set)
75 IF (
PRESENT(rotate)) my_rotate = rotate
77 IF (
PRESENT(weights))
THEN
83 w(i) = particle_set(i)%atomic_kind%mass
86 IF (mtot /= 0.0_dp) w(:) = w(:)/mtot
88 ALLOCATE (rp(3, natom))
89 ALLOCATE (r0p(3, natom))
97 mtot = mtot + particle_set(i)%atomic_kind%mass
98 xx = xx + r((i - 1)*3 + 1)*particle_set(i)%atomic_kind%mass
99 yy = yy + r((i - 1)*3 + 2)*particle_set(i)%atomic_kind%mass
100 zz = zz + r((i - 1)*3 + 3)*particle_set(i)%atomic_kind%mass
106 rp(1, i) = r((i - 1)*3 + 1) - xx
107 rp(2, i) = r((i - 1)*3 + 2) - yy
108 rp(3, i) = r((i - 1)*3 + 3) - zz
110 IF (
PRESENT(transl))
THEN
121 xx = xx + r0((i - 1)*3 + 1)*particle_set(i)%atomic_kind%mass
122 yy = yy + r0((i - 1)*3 + 2)*particle_set(i)%atomic_kind%mass
123 zz = zz + r0((i - 1)*3 + 3)*particle_set(i)%atomic_kind%mass
129 r0p(1, i) = r0((i - 1)*3 + 1) - xx
130 r0p(2, i) = r0((i - 1)*3 + 2) - yy
131 r0p(3, i) = r0((i - 1)*3 + 3) - zz
137 IF (
PRESENT(transl))
THEN
138 transl(1) = transl(1) - xx
139 transl(2) = transl(2) - yy
140 transl(3) = transl(3) - zz
145 IF (w(i) == 0.0_dp) cycle
152 rrsq = w(i)*(rr0(1)**2 + rr0(2)**2 + rr0(3)**2 + rr(1)**2 + rr(2)**2 + rr(3)**2)
156 m(1, 1) = m(1, 1) + rrsq + 2.0_dp*(-rr0(1)*rr(1) - rr0(2)*rr(2) - rr0(3)*rr(3))
157 m(2, 2) = m(2, 2) + rrsq + 2.0_dp*(-rr0(1)*rr(1) + rr0(2)*rr(2) + rr0(3)*rr(3))
158 m(3, 3) = m(3, 3) + rrsq + 2.0_dp*(rr0(1)*rr(1) - rr0(2)*rr(2) + rr0(3)*rr(3))
159 m(4, 4) = m(4, 4) + rrsq + 2.0_dp*(rr0(1)*rr(1) + rr0(2)*rr(2) - rr0(3)*rr(3))
160 m(1, 2) = m(1, 2) + 2.0_dp*(-rr0(2)*rr(3) + rr0(3)*rr(2))
161 m(1, 3) = m(1, 3) + 2.0_dp*(rr0(1)*rr(3) - rr0(3)*rr(1))
162 m(1, 4) = m(1, 4) + 2.0_dp*(-rr0(1)*rr(2) + rr0(2)*rr(1))
163 m(2, 3) = m(2, 3) - 2.0_dp*(rr0(1)*rr(2) + rr0(2)*rr(1))
164 m(2, 4) = m(2, 4) - 2.0_dp*(rr0(1)*rr(3) + rr0(3)*rr(1))
165 m(3, 4) = m(3, 4) - 2.0_dp*(rr0(2)*rr(3) + rr0(3)*rr(2))
179 IF (z(1, 1) .LT. 0.0_dp) s = -1.0_dp
184 IF (
PRESENT(my_val))
THEN
185 IF (abs(lambda(1)) < epsi)
THEN
188 my_val = lambda(1)/real(natom, kind=
dp)
191 IF (abs(lambda(1) - lambda(2)) < epsi)
THEN
192 IF (output_unit > 0)
WRITE (output_unit, fmt=
'(T2,"RMSD3|",A)') &
193 'NORMAL EXECUTION, NON-UNIQUE SOLUTION'
196 IF (
PRESENT(drmsd3))
THEN
198 IF (w(i) == 0.0_dp) cycle
199 rr(1) = w(i)*2.0_dp*rp(1, i)
200 rr(2) = w(i)*2.0_dp*rp(2, i)
201 rr(3) = w(i)*2.0_dp*rp(3, i)
202 rr0(1) = w(i)*2.0_dp*r0p(1, i)
203 rr0(2) = w(i)*2.0_dp*r0p(2, i)
204 rr0(3) = w(i)*2.0_dp*r0p(3, i)
206 dm_r(1, 1, 1) = (rr(1) - rr0(1))
207 dm_r(1, 1, 2) = (rr(2) - rr0(2))
208 dm_r(1, 1, 3) = (rr(3) - rr0(3))
210 dm_r(1, 2, 1) = 0.0_dp
211 dm_r(1, 2, 2) = rr0(3)
212 dm_r(1, 2, 3) = -rr0(2)
214 dm_r(1, 3, 1) = -rr0(3)
215 dm_r(1, 3, 2) = 0.0_dp
216 dm_r(1, 3, 3) = rr0(1)
218 dm_r(1, 4, 1) = rr0(2)
219 dm_r(1, 4, 2) = -rr0(1)
220 dm_r(1, 4, 3) = 0.0_dp
222 dm_r(2, 2, 1) = (rr(1) - rr0(1))
223 dm_r(2, 2, 2) = (rr(2) + rr0(2))
224 dm_r(2, 2, 3) = (rr(3) + rr0(3))
226 dm_r(2, 3, 1) = -rr0(2)
227 dm_r(2, 3, 2) = -rr0(1)
228 dm_r(2, 3, 3) = 0.0_dp
230 dm_r(2, 4, 1) = -rr0(3)
231 dm_r(2, 4, 2) = 0.0_dp
232 dm_r(2, 4, 3) = -rr0(1)
234 dm_r(3, 3, 1) = (rr(1) + rr0(1))
235 dm_r(3, 3, 2) = (rr(2) - rr0(2))
236 dm_r(3, 3, 3) = (rr(3) + rr0(3))
238 dm_r(3, 4, 1) = 0.0_dp
239 dm_r(3, 4, 2) = -rr0(3)
240 dm_r(3, 4, 3) = -rr0(2)
242 dm_r(4, 4, 1) = (rr(1) + rr0(1))
243 dm_r(4, 4, 2) = (rr(2) + rr0(2))
244 dm_r(4, 4, 3) = (rr(3) - rr0(3))
247 dm_r(2, 1, ix) = dm_r(1, 2, ix)
248 dm_r(3, 1, ix) = dm_r(1, 3, ix)
249 dm_r(4, 1, ix) = dm_r(1, 4, ix)
250 dm_r(3, 2, ix) = dm_r(2, 3, ix)
251 dm_r(4, 2, ix) = dm_r(2, 4, ix)
252 dm_r(4, 3, ix) = dm_r(3, 4, ix)
256 drmsd3(ix, i) = 0.0_dp
259 drmsd3(ix, i) = drmsd3(ix, i) + q(k - 1)*q(j - 1)*dm_r(j, k, ix)
262 drmsd3(ix, i) = drmsd3(ix, i)/real(natom, kind=
dp)
267 my_rot(1, 1) = -2.0_dp*q(2)**2 - 2.0_dp*q(3)**2 + 1.0_dp
268 my_rot(1, 2) = 2.0_dp*(-q(0)*q(3) + q(1)*q(2))
269 my_rot(1, 3) = 2.0_dp*(q(0)*q(2) + q(1)*q(3))
270 my_rot(2, 1) = 2.0_dp*(q(0)*q(3) + q(1)*q(2))
271 my_rot(2, 2) = -2.0_dp*q(1)**2 - 2.0_dp*q(3)**2 + 1.0_dp
272 my_rot(2, 3) = 2.0_dp*(-q(0)*q(1) + q(2)*q(3))
273 my_rot(3, 1) = 2.0_dp*(-q(0)*q(2) + q(1)*q(3))
274 my_rot(3, 2) = 2.0_dp*(q(0)*q(1) + q(2)*q(3))
275 my_rot(3, 3) = -2.0_dp*q(1)**2 - 2.0_dp*q(2)**2 + 1.0_dp
276 IF (
PRESENT(rot)) rot = my_rot
280 r((i - 1)*3 + 1:(i - 1)*3 + 3) = matmul(transpose(my_rot), rp(:, i)) + loc_tr
Defines the basic variable types.
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Define the data structure for the particle information.
Defines functions to perform rmsd in 3D.
subroutine, public rmsd3(particle_set, r, r0, output_unit, weights, my_val, rotate, transl, rot, drmsd3)
Computes the RMSD in 3D. Provides also derivatives.