-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathexp.f90
More file actions
129 lines (104 loc) · 3.82 KB
/
Copy pathexp.f90
File metadata and controls
129 lines (104 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
! This file is part of mctc-lib.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!> Coordination number implementation using an exponential counting function as in dftd3.
module mctc_ncoord_exp
use mctc_data_covrad, only : get_covalent_rad
use mctc_env, only : wp
use mctc_io, only : structure_type
use mctc_ncoord_type, only : ncoord_type
implicit none
private
public :: new_exp_ncoord
!> Coordination number evaluator
type, public, extends(ncoord_type) :: exp_ncoord_type
!> Covalent radii
real(wp), allocatable :: rcov(:)
contains
!> Evaluates the exponential counting function
procedure :: ncoord_count
!> Evaluates the derivative of the exponential counting function
procedure :: ncoord_dcount
end type exp_ncoord_type
!> Steepness of counting function
real(wp), parameter :: default_kcn = 16.0_wp
!> Real-space cutoff for coordination number
real(wp), parameter :: default_cutoff = 25.0_wp
contains
subroutine new_exp_ncoord(self, mol, kcn, cutoff, rcov, cut)
!> Coordination number container
type(exp_ncoord_type), intent(out) :: self
!> Molecular structure data
type(structure_type), intent(in) :: mol
!> Steepness of counting function
real(wp), intent(in), optional :: kcn
!> Real space cutoff
real(wp), intent(in), optional :: cutoff
!> Covalent radii
real(wp), intent(in), optional :: rcov(:)
!> Cutoff for the maximum coordination number
real(wp), intent(in), optional :: cut
if(present(kcn)) then
self%kcn = kcn
else
self%kcn = default_kcn
end if
if (present(cutoff)) then
self%cutoff = cutoff
else
self%cutoff = default_cutoff
end if
allocate(self%rcov(mol%nid))
if (present(rcov)) then
self%rcov(:) = rcov
else
self%rcov(:) = get_covalent_rad(mol%num)
end if
self%directed_factor = 1.0_wp
if (present(cut)) then
self%cut = cut
else
! Negative value deactivates the cutoff
self%cut = -1.0_wp
end if
end subroutine new_exp_ncoord
!> Exponential counting function for coordination number contributions.
elemental function ncoord_count(self, izp, jzp, r) result(count)
!> Coordination number container
class(exp_ncoord_type), intent(in) :: self
!> Atom i index
integer, intent(in) :: izp
!> Atom j index
integer, intent(in) :: jzp
!> Current distance.
real(wp), intent(in) :: r
real(wp) :: rc, count
rc = self%rcov(izp) + self%rcov(jzp)
count =1.0_wp/(1.0_wp+exp(-self%kcn*(rc/r-1.0_wp)))
end function ncoord_count
!> Derivative of the exponential counting function w.r.t. the distance.
elemental function ncoord_dcount(self, izp, jzp, r) result(count)
!> Coordination number container
class(exp_ncoord_type), intent(in) :: self
!> Atom i index
integer, intent(in) :: izp
!> Atom j index
integer, intent(in) :: jzp
!> Current distance.
real(wp), intent(in) :: r
real(wp) :: rc, expterm, count
rc = self%rcov(izp) + self%rcov(jzp)
expterm = exp(-self%kcn*(rc/r-1.0_wp))
count = (-self%kcn*rc*expterm)/(r**2.0_wp*((expterm+1.0_wp)**2.0_wp))
end function ncoord_dcount
end module mctc_ncoord_exp