forked from pierrehirel/atomsk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mode_interpolate.f90
285 lines (285 loc) · 9.6 KB
/
mode_interpolate.f90
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
MODULE mode_interpolate
!
!**********************************************************************************
!* MODE_INTERPOLATE *
!**********************************************************************************
!* This module reads two files containing atom positions of similar systems, *
!* and generates N new configurations by interpolating atom positions. *
!**********************************************************************************
!* (C) July 2013 - Pierre Hirel *
!* Université de Lille, Sciences et Technologies *
!* UMR CNRS 8207, UMET - C6, F-59655 Villeneuve D'Ascq, France *
!* [email protected] *
!* Last modification: P. Hirel - 18 March 2024 *
!**********************************************************************************
!* This program is free software: you can redistribute it and/or modify *
!* it under the terms of the GNU General Public License as published by *
!* the Free Software Foundation, either version 3 of the License, or *
!* (at your option) any later version. *
!* *
!* This program is distributed in the hope that it will be useful, *
!* but WITHOUT ANY WARRANTY; without even the implied warranty of *
!* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
!* GNU General Public License for more details. *
!* *
!* You should have received a copy of the GNU General Public License *
!* along with this program. If not, see <http://www.gnu.org/licenses/>. *
!**********************************************************************************
!
USE comv
USE constants
USE messages
USE files
USE subroutines
!Modules to read and write files
USE readin
USE writeout
!Module to apply options
USE options
!
!
CONTAINS
!
!
SUBROUTINE INTERPOLATE_XYZ(file1,file2,Nimages,prefix,outfileformats,options_array)
!
!
IMPLICIT NONE
CHARACTER(LEN=*),INTENT(IN):: file1, file2
CHARACTER(LEN=*),INTENT(IN):: prefix
CHARACTER(LEN=5),DIMENSION(:),ALLOCATABLE:: outfileformats
CHARACTER(LEN=4096):: msg, outputfile
CHARACTER(LEN=128),DIMENSION(:),ALLOCATABLE:: AUXNAMES1, AUXNAMES2 !names of auxiliary properties of ini.&final images
CHARACTER(LEN=128),DIMENSION(:),ALLOCATABLE:: AUXNAMESimg !names of auxiliary properties of an image
CHARACTER(LEN=128),DIMENSION(:),ALLOCATABLE:: comment, comment1, comment2
CHARACTER(LEN=128),DIMENSION(:),ALLOCATABLE:: options_array !options and their parameters
LOGICAL:: doaux !take auxiliary properties into account?
LOGICAL:: doshells !also take shells into account?
LOGICAL,DIMENSION(:),ALLOCATABLE:: SELECT !mask for atom list
INTEGER:: i, j, k
INTEGER,INTENT(IN):: Nimages !number of configurations to interpolate (that excludes initial & final images)
INTEGER,DIMENSION(:,:),ALLOCATABLE:: AUXid !index of matching aux.prop. in AUX1, AUX2
REAL(dp),DIMENSION(3,3):: Huc !Box vectors of unit cell (unknown, set to 0 here)
REAL(dp),DIMENSION(3,3):: H1, H2 !Base vectors of the supercells of initial, final images
REAL(dp),DIMENSION(3,3):: Himg !Base vectors of the supercell
REAL(dp),DIMENSION(3,3):: ORIENT !crystal orientation
REAL(dp),DIMENSION(9,9):: C_tensor !elastic tensor
REAL(dp),DIMENSION(:,:),ALLOCATABLE:: AUX1, AUX2 !auxiliary properties of initial, final images
REAL(dp),DIMENSION(:,:),ALLOCATABLE:: P1, P2 !positions of initial, final images
REAL(dp),DIMENSION(:,:),ALLOCATABLE:: S1, S2 !positions of initial, final shells
REAL(dp),DIMENSION(:,:),ALLOCATABLE:: Pimg, Simg !positions of atoms, shells in an image
REAL(dp),DIMENSION(:,:),ALLOCATABLE:: AUXimg !auxiliary properties of an image
!
!
!Initialize variables
doaux = .FALSE.
doshells = .FALSE.
IF(ALLOCATED(Pimg)) DEALLOCATE(Pimg)
IF(ALLOCATED(Simg)) DEALLOCATE(Simg)
IF(ALLOCATED(SELECT)) DEALLOCATE(SELECT)
IF(ALLOCATED(AUXid)) DEALLOCATE(AUXid)
C_tensor(:,:) = 0.d0
ORIENT(:,:) = 0.d0
!
!
CALL ATOMSK_MSG(4059,(/''/),(/0.d0/))
!
!
100 CONTINUE
!Read files
CALL READ_AFF(file1,H1,P1,S1,comment1,AUXNAMES1,AUX1)
CALL READ_AFF(file2,H2,P2,S2,comment2,AUXNAMES2,AUX2)
!
!Check if the number of atoms coincide
IF( SIZE(P1,1) .NE. SIZE(P2,1) ) THEN
RETURN
ENDIF
!
!If both configurations have shells, their positions will be interpolated
IF( ALLOCATED(S1) .AND. ALLOCATED(S2) ) THEN
IF( SIZE(S1,1) == SIZE(S2,1) ) THEN
doshells = .TRUE.
ENDIF
ENDIF
!
IF( .NOT. doshells ) THEN
IF(ALLOCATED(S1)) DEALLOCATE(S1)
IF(ALLOCATED(S2)) DEALLOCATE(S2)
ENDIF
!
!Deal with auxiliary properties
IF( ALLOCATED(AUXNAMES1) .AND. ALLOCATED(AUXNAMES2) ) THEN
!Auxiliary properties are defined in both systems
!Construct a table matching identical properties from both systems
ALLOCATE( AUXid( MIN(SIZE(AUXNAMES1),SIZE(AUXNAMES2)) , 2 ) )
AUXid(:,:) = 0
k=0
DO i=1,SIZE(AUXNAMES1)
DO j=1,SIZE(AUXNAMES2)
IF( AUXNAMES1(i) == AUXNAMES2(j) ) THEN
k = k+1
AUXid(k,1) = i
AUXid(k,2) = j
ENDIF
ENDDO
ENDDO
ALLOCATE( AUXNAMESimg(k) )
AUXNAMESimg(:) = ""
k=0
DO i=1,SIZE(AUXNAMES1)
DO j=1,SIZE(AUXNAMES2)
IF( AUXNAMES1(i) == AUXNAMES2(j) ) THEN
k = k+1
AUXNAMESimg(k) = TRIM(AUXNAMES1(i))
ENDIF
ENDDO
ENDDO
IF( k>0 ) THEN
!Matching aux.prop. were found, and their names are now in AUXNAMESimg(:)
doaux = .TRUE.
IF(verbosity>=4) THEN
WRITE(msg,*) "Found ", k, " matching properties:"
CALL ATOMSK_MSG(999,(/TRIM(msg)/),(/0.d0/))
DO j=1,SIZE(AUXNAMESimg)
WRITE(msg,*) j, " ", TRIM(AUXNAMESimg(j))
CALL ATOMSK_MSG(999,(/TRIM(msg)/),(/0.d0/))
ENDDO
ENDIF
ELSE
!Found zero matching aux.prop. between the two systems: ignore aux.prop.
doaux = .FALSE.
IF(ALLOCATED(AUXNAMESimg)) DEALLOCATE(AUXNAMESimg)
ENDIF
ENDIF
!
IF(.NOT.doaux) THEN
!Ignore auxiliary properties
IF(ALLOCATED(AUX1)) DEALLOCATE(AUX1)
IF(ALLOCATED(AUX2)) DEALLOCATE(AUX2)
IF(ALLOCATED(AUXimg)) DEALLOCATE(AUXimg)
IF(ALLOCATED(AUXNAMES1)) DEALLOCATE(AUXNAMES1)
IF(ALLOCATED(AUXNAMES2)) DEALLOCATE(AUXNAMES2)
IF(ALLOCATED(AUXNAMESimg)) DEALLOCATE(AUXNAMESimg)
ENDIF
!
!
!
200 CONTINUE
!Loop on all interpolated images
DO i=0,Nimages+1
CALL ATOMSK_MSG(4060,(/''/),(/DBLE(i)/))
!
IF( i==0 .OR. i==Nimages+1 ) THEN
!Initial or final configuration
ALLOCATE( Pimg( SIZE(P1,1) , 4) )
Pimg(:,:) = 0.d0
!Copy positions of relevant configuration
IF( i==0 ) THEN
Himg = H1
Pimg = P1
ELSE
Himg = H2
Pimg = P2
ENDIF
!Same with positions of shells, if any
IF( doshells ) THEN
ALLOCATE( Simg(SIZE(P1,1) , 4) )
IF( i==0 ) THEN
Simg = S1
ELSE
Simg = S2
ENDIF
ENDIF
!Same with aux.prop, if any
IF( doaux ) THEN
ALLOCATE( AUXimg(SIZE(P1,1) , SIZE(AUXNAMESimg) ) )
IF( i==0 ) THEN
DO j=1,SIZE(AUXNAMESimg)
DO k=1,SIZE(AUXNAMES1)
IF( AUXNAMESimg(j)==AUXNAMES1(k) ) THEN
AUXimg(:,j) = AUX1(:,k)
ENDIF
ENDDO
ENDDO
ELSE
DO j=1,SIZE(AUXNAMESimg)
DO k=1,SIZE(AUXNAMES2)
IF( AUXNAMESimg(j)==AUXNAMES2(k) ) THEN
AUXimg(:,j) = AUX2(:,k)
ENDIF
ENDDO
ENDDO
ENDIF
ENDIF
!
ELSE
!Compute interpolated box vectors
DO j=1,3
DO k=1,3
Himg(j,k) = H1(j,k) + (H2(j,k)-H1(j,k))*DBLE(i)/DBLE(Nimages)
ENDDO
ENDDO
!
!Compute interpolated positions, save them into Pimg
ALLOCATE( Pimg( SIZE(P1,1) , 4) )
Pimg(:,:) = 0.d0
DO j=1,SIZE(P1,1)
Pimg(j,1:3) = P1(j,1:3) + (P2(j,1:3)-P1(j,1:3))*DBLE(i)/DBLE(Nimages)
Pimg(j,4) = P1(j,4)
ENDDO
!
!Same with positions of shells, if any
IF( doshells ) THEN
ALLOCATE( Simg(SIZE(P1,1) , 4) )
Simg(:,:) = 0.d0
DO j=1,SIZE(S1,1)
Simg(j,1:3) = S1(j,1:3) + (S2(j,1:3)-S1(j,1:3))*DBLE(i)/DBLE(Nimages)
Simg(j,4) = S1(j,4)
ENDDO
ENDIF
!
!Interpolate matching aux.prop., save them into AUXimg
IF( doaux ) THEN
ALLOCATE( AUXimg(SIZE(P1,1),SIZE(AUXNAMESimg) ) )
AUXimg(:,:) = 0.d0
DO j=1,SIZE(AUXimg,2)
AUXimg(:,j) = AUX1(:,AUXid(j,1)) + (AUX2(:,AUXid(j,2))-AUX1(:,AUXid(j,1)))*DBLE(i)/DBLE(Nimages)
ENDDO
ENDIF
!
ENDIF
!
!Apply options to current image
CALL OPTIONS_AFF(options_array,Huc,Himg,Pimg,Simg,AUXNAMESimg,AUXimg,ORIENT,SELECT,C_tensor)
!
!Write current image to file(s)
ALLOCATE(comment(1))
WRITE(comment(1),*) i
outputfile = TRIM(ADJUSTL(prefix))//"_img"//TRIM(ADJUSTL(comment(1)))
comment(1) = "Image #"//TRIM(ADJUSTL(comment(1)))
CALL WRITE_AFF(outputfile,outfileformats,Himg,Pimg,Simg,comment,AUXNAMESimg,AUXimg)
!
!Free memory
IF(ALLOCATED(comment)) DEALLOCATE(comment)
IF(ALLOCATED(Pimg)) DEALLOCATE(Pimg)
IF(ALLOCATED(Simg)) DEALLOCATE(Simg)
IF(ALLOCATED(AUXimg)) DEALLOCATE(AUXimg)
ENDDO
!
!
!
1000 CONTINUE
IF(ALLOCATED(P1)) DEALLOCATE(P1)
IF(ALLOCATED(S1)) DEALLOCATE(S1)
IF(ALLOCATED(P2)) DEALLOCATE(P2)
IF(ALLOCATED(S2)) DEALLOCATE(S2)
IF(ALLOCATED(AUX1)) DEALLOCATE(AUX1)
IF(ALLOCATED(AUX2)) DEALLOCATE(AUX2)
IF(ALLOCATED(AUXid)) DEALLOCATE(AUXid)
IF(ALLOCATED(AUXNAMESimg)) DEALLOCATE(AUXNAMESimg)
!
!
END SUBROUTINE INTERPOLATE_XYZ
!
!
END MODULE mode_interpolate