GCC Code Coverage Report


Directory: src/fortran/lib/
File: mod_dist_calcs.f90
Date: 2025-06-15 07:27:34
Exec Total Coverage
Lines: 47 52 90.4%
Functions: 0 0 -%
Branches: 76 96 79.2%

Line Branch Exec Source
1 module raffle__dist_calcs
2 !! Module containing distance calculators
3 !!
4 !! This module contains procedures to calculate the distance between atoms
5 !! and other points in the system.
6 use raffle__constants, only: pi,real32
7 use raffle__geom_rw, only: basis_type
8 use raffle__misc_linalg, only: get_angle
9 implicit none
10
11
12 private
13
14 public :: get_min_dist
15 public :: get_min_dist_between_point_and_atom
16 public :: get_min_dist_between_point_and_species
17 public :: get_dist_between_point_and_atom
18
19
20 contains
21
22 !###############################################################################
23 379777 pure function get_min_dist( &
24 basis, loc, lignore_close, axis, labove, lreal, tol &
25
1/2
✓ Branch 0 taken 379777 times.
✗ Branch 1 not taken.
379777 ) result(output)
26 !! Return the minimum distance between a point and the nearest atom
27 !! in a cell.
28 !!
29 !! This function returns the minimum distance between a point and the
30 !! nearest atom in a periodic cell.
31 implicit none
32
33 ! Arguments
34 logical, intent(in) :: lignore_close
35 !! If true, ignore atoms that are really close to the point.
36 class(basis_type), intent(in) :: basis
37 !! The basis of the cell.
38 real(real32), dimension(3), intent(in) :: loc
39 !! The location of the point (in crystal coordinates).
40
41 integer, intent(in), optional :: axis
42 !! The axis along which to calculate the distance (if undefined, the
43 !! distance is calculated in all directions).
44 real(real32), intent(in), optional :: tol
45 !! The tolerance for the distance.
46 logical, intent(in), optional :: labove, lreal
47 !! If true, return the real distance, otherwise return the vector.
48 real(real32), dimension(3) :: output
49 !! The minimum distance between the point and the nearest atom.
50
51
52 ! Local variables
53 integer :: js, ja, i
54 !! Loop counters.
55 integer :: axis_
56 !! Axis along which to calculate the distance.
57 real(real32) :: dtmp1
58 !! Temporary variables.
59 real(real32) :: min_bond
60 !! Minimum bond length.
61 real(real32) :: tol_
62 !! Tolerance for the distance.
63 logical :: labove_, lreal_
64 !! Booleans for above and real distance arguments
65 real(real32), dimension(3) :: vdtmp1, vdtmp2
66 !! Vectors for distance calculations.
67
68
69 ! CORRECT tol TO ACCOUNT FOR LATTICE SIZE
70 379777 tol_ = 1.E-5_real32
71 379777 labove_ = .false.
72 379777 lreal_ = .true.
73 379777 axis_ = 0
74
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 379777 times.
379777 if(present(tol)) tol_ = tol
75
76
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 379777 times.
379777 if(present(labove)) labove_ = labove
77
78
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 379777 times.
379777 if(present(lreal)) lreal_ = lreal
79
80
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 379777 times.
379777 if(present(axis)) axis_=axis
81
82 379777 min_bond=huge(0._real32)
83
2/2
✓ Branch 0 taken 1139331 times.
✓ Branch 1 taken 379777 times.
1519108 output = 0._real32
84
2/2
✓ Branch 0 taken 1029007 times.
✓ Branch 1 taken 379777 times.
1408784 do js = 1, basis%nspec
85
2/2
✓ Branch 0 taken 4212402 times.
✓ Branch 1 taken 1029007 times.
5621186 atmloop: do ja = 1, basis%spec(js)%num
86
2/2
✓ Branch 0 taken 2167336 times.
✓ Branch 1 taken 2045066 times.
4212402 if(.not.basis%spec(js)%atom_mask(ja)) cycle atmloop
87
2/2
✓ Branch 0 taken 6135198 times.
✓ Branch 1 taken 2045066 times.
8180264 vdtmp1 = basis%spec(js)%atom(ja,:3) - loc
88
6/8
✓ Branch 0 taken 6135198 times.
✓ Branch 1 taken 2045066 times.
✓ Branch 2 taken 6015716 times.
✓ Branch 3 taken 119482 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6015716 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2045066 times.
8180264 if(lignore_close.and.norm2(vdtmp1).lt.tol_) cycle atmloop
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2045066 times.
2045066 if(axis_.gt.0)then
90 if(abs(vdtmp1(axis_)).lt.tol_) cycle atmloop
91 if(labove_)then
92 vdtmp1(axis_) = 1._real32 + vdtmp1(axis_)
93 else
94 vdtmp1(axis_) = vdtmp1(axis_) - 1._real32
95 end if
96 else
97
4/4
✓ Branch 0 taken 6135198 times.
✓ Branch 1 taken 2045066 times.
✓ Branch 2 taken 6082066 times.
✓ Branch 3 taken 53132 times.
8180264 vdtmp1 = vdtmp1 - ceiling(vdtmp1 - 0.5_real32)
98 end if
99 2045066 vdtmp2 = matmul(vdtmp1,basis%lat)
100
6/6
✓ Branch 0 taken 6135198 times.
✓ Branch 1 taken 2045066 times.
✓ Branch 2 taken 6015716 times.
✓ Branch 3 taken 119482 times.
✓ Branch 4 taken 3261533 times.
✓ Branch 5 taken 2754183 times.
8180264 dtmp1 = norm2(vdtmp2)
101
2/2
✓ Branch 0 taken 829681 times.
✓ Branch 1 taken 1215385 times.
3074073 if(dtmp1.lt.min_bond)then
102 829681 min_bond = dtmp1
103
1/2
✓ Branch 0 taken 829681 times.
✗ Branch 1 not taken.
829681 if(lreal_)then
104
2/2
✓ Branch 0 taken 2489043 times.
✓ Branch 1 taken 829681 times.
3318724 output = vdtmp2
105 else
106 output = vdtmp1
107 end if
108 end if
109 end do atmloop
110 end do
111
112 379777 end function get_min_dist
113 !###############################################################################
114
115
116 !###############################################################################
117 1 pure function get_min_dist_between_point_and_atom(basis,loc,atom) result(dist)
118 !! Return the minimum distance between a point and an atom in a cell.
119 !!
120 !! This function returns the minimum distance between a point and an atom
121 !! in a periodic cell.
122 implicit none
123
124 ! Arguments
125 class(basis_type), intent(in) :: basis
126 !! The basis of the cell.
127 integer, dimension(2), intent(in) :: atom
128 !! The index of the atom in the cell (species, atom).
129 real(real32), dimension(3), intent(in) :: loc
130 !! The location of the point (in crystal coordinates).
131 real(real32) :: dist
132 !! The minimum distance between the point and the atom.
133
134 ! Local variables
135 real(real32), dimension(3) :: vec
136 !! Vector between the point and the atom.
137
138
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 vec = loc - basis%spec(atom(1))%atom(atom(2),:3)
139
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
4 vec = vec - ceiling(vec - 0.5_real32)
140
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
4 vec = matmul(vec,basis%lat)
141
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
4 dist = norm2(vec)
142
143 1 end function get_min_dist_between_point_and_atom
144 !###############################################################################
145
146
147 !###############################################################################
148 3 pure function get_min_dist_between_point_and_species( &
149 basis, loc, species) result(dist)
150 !! Return the minimum distance between a point and a species in a cell.
151 !!
152 !! This function returns the minimum distance between a point and any
153 !! instance of the specified species in a periodic cell.
154 implicit none
155
156 ! Arguments
157 class(basis_type), intent(in) :: basis
158 !! The basis of the cell.
159 integer, intent(in) :: species
160 !! The index of the species in the cell.
161 real(real32), dimension(3), intent(in) :: loc
162 !! The location of the point (in crystal coordinates).
163 real(real32) :: dist
164 !! The minimum distance between the point and the species.
165
166 ! Local variables
167 integer :: ia, i
168 !! Loop indices.
169 real(real32) :: rtmp1
170 !! Temporary variable.
171 real(real32), dimension(3) :: vec
172 !! Vector between the point and the atom.
173
174
175 3 dist = huge(0._real32)
176
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
7 atom_loop: do ia = 1,basis%spec(species)%num
177
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if(.not.basis%spec(species)%atom_mask(ia)) cycle atom_loop
178
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 vec = loc - basis%spec(species)%atom(ia,:3)
179
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 7 times.
12 vec = vec - ceiling(vec - 0.5_real32)
180
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 3 times.
12 vec = matmul(vec, basis%lat)
181
6/6
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
12 rtmp1 = norm2(vec)
182
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 if( rtmp1 .lt. dist ) dist = rtmp1
183 end do atom_loop
184
185 3 end function get_min_dist_between_point_and_species
186 !###############################################################################
187
188
189 !###############################################################################
190 2 pure function get_dist_between_point_and_atom(basis,loc,atom) result(dist)
191 !! Return the distance between a point and an atom in a cell.
192 !!
193 !! This function returns the distance between a point and an atom in a cell.
194 implicit none
195
196 ! Arguments
197 class(basis_type), intent(in) :: basis
198 !! The basis of the cell.
199 integer, dimension(2), intent(in) :: atom
200 !! The index of the atom in the cell (species, atom).
201 real(real32), dimension(3), intent(in) :: loc
202 !! The location of the point (in crystal coordinates).
203 real(real32) :: dist
204 !! The minimum distance between the point and the atom.
205
206 ! Local variables
207 real(real32), dimension(3) :: vec
208 !! Vector between the point and the atom.
209
210
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 vec = loc - basis%spec(atom(1))%atom(atom(2),:3)
211
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
8 vec = matmul(vec,basis%lat)
212
5/6
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 4 times.
8 dist = norm2(vec)
213
214 2 end function get_dist_between_point_and_atom
215 !###############################################################################
216
217 end module raffle__dist_calcs
218