root / src / Read_geom.f90 @ 2
Historique | Voir | Annoter | Télécharger (9,8 ko)
1 |
SUBROUTINE Read_Geom(input) |
---|---|
2 |
|
3 |
Use Path_module |
4 |
Use Io_module |
5 |
|
6 |
IMPLICIT NONE |
7 |
|
8 |
|
9 |
CHARACTER(32), INTENT(IN) :: input |
10 |
CHARACTER(132) :: LineTmp,Line |
11 |
|
12 |
INTEGER(KINT), ALLOCATABLE :: NbAtType(:) !na |
13 |
INTEGER(KINT) :: NbType, NbTypeUser |
14 |
INTEGER(KINT) :: I, J, Iat,NAtP,Idx,JStart |
15 |
INTEGER(KINT) :: IGeom |
16 |
REAL(KREAL) :: Xt,Yt,Zt |
17 |
LOGICAL :: Debug, TChk |
18 |
CHARACTER(4), ALLOCATABLE :: FFFt(:,:) ! 3,Na |
19 |
LOGICAL, ALLOCATABLE :: FFFl(:,:) ! 3,Na |
20 |
|
21 |
!!! for VASP inputs |
22 |
! latx_loc used to check that the lattice parameters are the same for all geometries |
23 |
REAL(KREAL) :: lata_loc(3), latb_loc(3), latc_loc(3) |
24 |
! VaspPar_loc is the local value of the vasp parametre |
25 |
REAL(KREAL) :: VaspPar_loc |
26 |
! Vdir_loc is used to convert the read geometry to Cartesian. |
27 |
! V_direct is set by the first geometry. |
28 |
CHARACTER(LCHARS) :: Vdir_loc |
29 |
|
30 |
|
31 |
INTERFACE |
32 |
function valid(string) result (isValid) |
33 |
CHARACTER(*), intent(in) :: string |
34 |
logical :: isValid |
35 |
END function VALID |
36 |
END INTERFACE |
37 |
|
38 |
debug=valid('Read_geom') |
39 |
if (debug) Call Header("Entering Read_Geom") |
40 |
if (debug) WRITE(*,*) "Input:",Trim(Input) |
41 |
|
42 |
SELECT CASE(Input) |
43 |
CASE ('XYZ','CART') |
44 |
DO I=1,NGeomI |
45 |
IF (DEBUG) WRITE(*,*) "Reading Geom :",I |
46 |
READ(IOIN,*) NAtp |
47 |
if (NAtp.NE.Nat) THEN |
48 |
IF (I==1) THEN |
49 |
WRITE(IOOUT,*) 'WARNING Number of atoms not consistent between NAMELIST &path and First geom' |
50 |
WRITE(IOOUT,*) "Using:",Natp |
51 |
DEALLOCATE(XyzGeomI, AtName) |
52 |
Nat=Natp |
53 |
ALLOCATE(XyzGeomI(NGeomI,3,Nat), AtName(NAt)) |
54 |
ELSE |
55 |
WRITE(IOOUT,*) 'Number of atoms not consistent between geometries. STOP' |
56 |
STOP |
57 |
END IF |
58 |
END IF |
59 |
READ(IOIN,'(A)') Line |
60 |
DO J=1,NAt |
61 |
READ(IOIN,*) AtName(J),XyzGeomI(I,1:3,J) |
62 |
END DO |
63 |
If (Debug) THEN |
64 |
WRITE(*,*) "Geom ",I |
65 |
DO J=1,NAt |
66 |
WRITE(*,'(1X,A2,3(1X,F15.6))') AtName(J),XyzGeomI(I,1:3,J) |
67 |
END DO |
68 |
END IF |
69 |
END DO |
70 |
CASE ('TURBOMOLE') |
71 |
DO I=1,NGeomI |
72 |
IF (DEBUG) WRITE(*,*) "Reading Geom :",I |
73 |
JStart=1 |
74 |
! read the $coord line, or $user-defined, or $end |
75 |
Line='$ok' |
76 |
DO WHILE (Line(1:1).EQ."$") |
77 |
READ(IOIN,'(A)') Line |
78 |
Line=AdjustL(Line) |
79 |
END DO |
80 |
J=1 |
81 |
READ(Line,*) XyzGeomI(I,1:3,J),AtName(J) |
82 |
DO J=2,NAt |
83 |
READ(IOIN,*) XyzGeomI(I,1:3,J),AtName(J) |
84 |
END DO |
85 |
XyzGeomI(I,:,:)= XyzGeomI(I,:,:)*a0 |
86 |
If (Debug) THEN |
87 |
WRITE(*,*) "Geom ",I |
88 |
DO J=1,NAt |
89 |
WRITE(*,'(1X,A2,3(1X,F15.6))') AtName(J),XyzGeomI(I,1:3,J) |
90 |
END DO |
91 |
END IF |
92 |
END DO |
93 |
CASE ('VASP') |
94 |
ALLOCATE(FFF(3,nat),FFFl(3,Nat),FFFt(3,Nat)) |
95 |
! First geometry is a bit special for VASP as we have to set |
96 |
! many things |
97 |
IGeom=1 |
98 |
IF (DEBUG) WRITE(*,*) "Reading Geom :",IGeom |
99 |
READ(IOIN,'(A)') Vasp_Title |
100 |
READ(IOIN,*) Vasp_param |
101 |
|
102 |
READ(IOIN,*) Lat_a |
103 |
READ(IOIN,*) Lat_b |
104 |
READ(IOIN,*) Lat_c |
105 |
|
106 |
Lat_a=Lat_a*Vasp_param |
107 |
Lat_b=Lat_b*Vasp_param |
108 |
Lat_c=Lat_c*Vasp_param |
109 |
|
110 |
ALLOCATE(NbAtType(nat)) |
111 |
READ(IOIN,'(A)') Vasp_types |
112 |
! First, how many different types ? |
113 |
NbAtType=0 |
114 |
READ(Vasp_types,*,END=999) NbAtType |
115 |
999 CONTINUE |
116 |
NbType=0 |
117 |
NatP=0 |
118 |
DO WHILE (NbAtType(NbType+1).NE.0) |
119 |
NbType=NbType+1 |
120 |
Natp=Natp+NbAtType(NbType) |
121 |
END DO |
122 |
|
123 |
|
124 |
if (NAtp.NE.Nat) THEN |
125 |
WRITE(IOOUT,*) 'WARNING Number of atoms not consistent between NAMELIST &path and First geom' |
126 |
WRITE(IOOUT,*) "Using:",Natp |
127 |
DEALLOCATE(XyzGeomI, AtName) |
128 |
Nat=Natp |
129 |
ALLOCATE(XyzGeomI(NGeomI,3,Nat), AtName(NAt)) |
130 |
END if |
131 |
|
132 |
! Do we know the atom types ? |
133 |
IF (AtTypes(1).EQ.' ') THEN |
134 |
! user has not provided atom types... we have to find them by ourselves |
135 |
! by looking into the POTCAR file... |
136 |
INQUIRE(File="POTCAR", EXIST=Tchk) |
137 |
IF (.NOT.Tchk) THEN |
138 |
WRITE(*,*) "ERROR! No AtTypes provided, and POTCAR file not found" |
139 |
STOP |
140 |
END IF |
141 |
OPEN(IOTMP,File="POTCAR") |
142 |
DO I=1,NbType |
143 |
Line='Empty' |
144 |
DO WHILE (Line(1:5).NE.'TITEL') |
145 |
READ(IOTMP,'(A)') Line |
146 |
Line=AdjustL(Line) |
147 |
END DO |
148 |
Line=adjustl(Line(9:)) |
149 |
Idx=index(Line," ") |
150 |
Line=adjustl(Line(Idx+1:)) |
151 |
AtTypes(I)=Line(1:2) |
152 |
END DO |
153 |
if (debug) WRITE(*,'(A,100(1X,A2))') "ReadG:VASP AtTypes",AtTypes(1:NbType) |
154 |
CLOSE(IOTMP) |
155 |
|
156 |
ELSE !AtTypes(1).EQ.' ' |
157 |
! user has provided atom types |
158 |
NbTypeUser=0 |
159 |
DO WHILE (AtTypes(NbTypeUser+1).NE.' ') |
160 |
NbTypeUser=NbTypeUser+1 |
161 |
END DO |
162 |
IF (NbType.NE.NbTypeUser) THEN |
163 |
WRITE(*,*) "ERROR Read_Geom : NbType in POSCAR do not match AtTypes" |
164 |
STOP |
165 |
END IF |
166 |
END IF |
167 |
|
168 |
IAt=1 |
169 |
DO I=1,NbType |
170 |
DO J=1,NbAtType(I) |
171 |
AtName(Iat)=AtTypes(I) |
172 |
Iat=Iat+1 |
173 |
END DO |
174 |
END DO |
175 |
DEALLOCATE(NbAtType) |
176 |
|
177 |
NbTypes=NbType |
178 |
|
179 |
READ(IOIN,'(A)') Vasp_comment |
180 |
READ(IOIN,'(A)') Vasp_direct |
181 |
|
182 |
V_direct=adjustl(Vasp_direct) |
183 |
Call upcase(V_direct) |
184 |
|
185 |
if (debug) WRITE(*,*) "V_direct=",Trim(V_Direct) |
186 |
|
187 |
DO I=1,Nat |
188 |
READ(IOIN,*) XyzGeomI(IGeom,1:3,I),FFF(1:3,I) |
189 |
DO J=1,3 |
190 |
FFF(J,I)=AdjustL(FFF(J,I)) |
191 |
FFFl(j,i)=(FFF(j,i)(1:1).EQ.'T') |
192 |
END DO |
193 |
|
194 |
END DO |
195 |
IF (V_direct(1:6).EQ.'DIRECT') THEN |
196 |
DO I=1,Nat |
197 |
Xt=XyzGeomI(IGeom,1,I) |
198 |
Yt=XyzGeomI(IGeom,2,I) |
199 |
Zt=XyzGeomI(IGeom,3,I) |
200 |
XyzGeomI(IGeom,1,I)=Xt*lat_a(1)+Yt*lat_b(1)+Zt*lat_c(1) |
201 |
XyzGeomI(IGeom,2,I)=Xt*lat_a(2)+Yt*lat_b(2)+Zt*lat_c(2) |
202 |
XyzGeomI(IGeom,3,I)=Xt*lat_a(3)+Yt*lat_b(3)+Zt*lat_c(3) |
203 |
END DO |
204 |
|
205 |
END IF |
206 |
|
207 |
ALLOCATE(X0_vasp(Nat),Y0_vasp(Nat),Z0_vasp(Nat)) |
208 |
X0_vasp=XyzGeomI(IGeom,1,:) |
209 |
Y0_vasp=XyzGeomI(IGeom,2,:) |
210 |
Z0_vasp=XyzGeomI(IGeom,3,:) |
211 |
|
212 |
if (debug) THEN |
213 |
WRITE(*,*) Nat |
214 |
WRITE(*,*) "Geom ",IGeom,"/",NGeomI |
215 |
DO I=1,Nat |
216 |
WRITE(*,'(1X,A2,3(1X,F15.6))') AtName(I),XyzGeomI(IGeom,1:3,I) |
217 |
END DO |
218 |
END IF |
219 |
|
220 |
|
221 |
DO IGeom=2,NGeomI |
222 |
!!! PFL 16th March 2008 -> |
223 |
! Users might want to use different conditions for different geometries |
224 |
! i.e. to mix Cartesian and Direct :-p |
225 |
! thus we check for each geom which condition is used. |
226 |
! |
227 |
|
228 |
! Title |
229 |
READ(IOIN,*) LineTmp |
230 |
! if (debug) WRITE(*,*) "1 LineTmp:",Trim(LineTmp) |
231 |
! Vasp_Param |
232 |
READ(IOIN,*) VaspPar_loc |
233 |
! if (debug) WRITE(*,*) "2 LineTmp:",Trim(LineTmp) |
234 |
! Lattice parameters |
235 |
READ(IOIN,*) Lata_loc |
236 |
! if (debug) WRITE(*,*) "3 LineTmp:",Trim(LineTmp) |
237 |
READ(IOIN,*) latb_loc |
238 |
! if (debug) WRITE(*,*) "4 LineTmp:",Trim(LineTmp) |
239 |
READ(IOIN,*) Latc_loc |
240 |
! if (debug) WRITE(*,*) "5 LineTmp:",Trim(LineTmp) |
241 |
! Attypes |
242 |
READ(IOIN,*) LineTmp |
243 |
! if (debug) WRITE(*,*) "6 LineTmp:",Trim(LineTmp) |
244 |
! Comment |
245 |
READ(IOIN,*) LineTmp,line |
246 |
! if (debug) WRITE(*,*) "7 LineTmp:",Trim(LineTmp),Trim(Line) |
247 |
! V_direct |
248 |
READ(IOIN,*) Vdir_loc |
249 |
Vdir_loc=adjustl(Vdir_loc) |
250 |
Call upcase(Vdir_loc) |
251 |
! if (debug) WRITE(*,*) "8 LineTmp:",Trim(LineTmp) |
252 |
|
253 |
Lata_loc=Lata_loc*VaspPar_loc-Lat_a |
254 |
if (dot_product(lata_loc,Lata_loc).GE.1e-6) THEN |
255 |
WRITE(*,*) "Lattice parameter a is different between geometries 1 and ",IGeom |
256 |
WRITE(IOOUT,*) "Lattice parameter a is different between geometries 1 and ",IGeom |
257 |
STOP |
258 |
END IF |
259 |
|
260 |
Latb_loc=Latb_loc*VaspPar_loc-Lat_b |
261 |
if (dot_product(latb_loc,Latb_loc).GE.1e-6) THEN |
262 |
WRITE(*,*) "Lattice parameter b is different between geometries 1 and ",IGeom |
263 |
WRITE(IOOUT,*) "Lattice parameter b is different between geometries 1 and ",IGeom |
264 |
STOP |
265 |
END IF |
266 |
|
267 |
Latc_loc=Latc_loc*VaspPar_loc-Lat_c |
268 |
if (dot_product(latc_loc,Latc_loc).GE.1e-6) THEN |
269 |
WRITE(*,*) "Lattice parameter c is different between geometries 1 and ",IGeom |
270 |
WRITE(IOOUT,*) "Lattice parameter c is different between geometries 1 and ",IGeom |
271 |
STOP |
272 |
END IF |
273 |
|
274 |
DO I=1,Nat |
275 |
READ(IOIN,*) XyzGeomI(IGeom,1:3,I),FFFt(1:3,I) |
276 |
DO J=1,3 |
277 |
! A frozen atom in any geom is considered frozen in all geom |
278 |
FFFt(j,I)=AdjustL(FFFt(j,i)) |
279 |
FFFl(j,i)=FFFl(j,i).AND.(FFFt(j,i).EQ.'T') |
280 |
END DO |
281 |
END DO |
282 |
|
283 |
IF (Vdir_loc(1:6).EQ.'DIRECT') THEN |
284 |
DO I=1,Nat |
285 |
Xt=XyzGeomI(IGeom,1,I) |
286 |
Yt=XyzGeomI(IGeom,2,I) |
287 |
Zt=XyzGeomI(IGeom,3,I) |
288 |
XyzGeomI(IGeom,1,I)=Xt*lat_a(1)+Yt*lat_b(1)+Zt*lat_c(1) |
289 |
XyzGeomI(IGeom,2,I)=Xt*lat_a(2)+Yt*lat_b(2)+Zt*lat_c(2) |
290 |
XyzGeomI(IGeom,3,I)=Xt*lat_a(3)+Yt*lat_b(3)+Zt*lat_c(3) |
291 |
END DO |
292 |
END IF |
293 |
|
294 |
if (debug) THEN |
295 |
WRITE(*,*) Nat |
296 |
WRITE(*,*) "Geom ",IGeom,"/",NGeomI |
297 |
DO I=1,Nat |
298 |
WRITE(*,'(1X,A2,3(1X,F15.6))') AtName(I),XyzGeomI(IGeom,1:3,I) |
299 |
END DO |
300 |
END IF |
301 |
|
302 |
END DO |
303 |
|
304 |
! PFL 23 Nov 2008 -> |
305 |
! This is done in Path.f90 |
306 |
! ! We put FFrozen in place |
307 |
! Idx=1 |
308 |
! DO I=1,Nat |
309 |
! TChk=.FALSE. |
310 |
! DO J=1,3 |
311 |
! TChk=Tchk.OR.(.NOT.FFFl(j,i)) |
312 |
! END DO |
313 |
! IF (TChk) THEN |
314 |
! Frozen(Idx)=I |
315 |
! Idx=Idx+1 |
316 |
! END IF |
317 |
! END DO |
318 |
! Frozen(Idx)=0 |
319 |
! We put FFF in place because FFFl is a logical flag |
320 |
DO I=1,Nat |
321 |
DO J=1,3 |
322 |
if (FFFl(j,i)) FFF(j,i)="T" |
323 |
END DO |
324 |
END DO |
325 |
|
326 |
!<- PFL 23 Nov 2008 |
327 |
|
328 |
Deallocate(FFFl,FFFt) |
329 |
|
330 |
CASE Default |
331 |
WRITe(*,*) 'Input=',trim(Input),' UNKNOWN. Stop' |
332 |
STOP |
333 |
|
334 |
END SELECT |
335 |
|
336 |
|
337 |
if (debug) Call Header("Exiting Read_Geom") |
338 |
|
339 |
END SUBROUTINE Read_Geom |