Statistiques
| Révision :

root / src / ReadInput_siesta.f90 @ 12

Historique | Voir | Annoter | Télécharger (17,97 ko)

1 5 pfleura2
 SUBROUTINE ReadInput_siesta
2 5 pfleura2
3 5 pfleura2
! This routine reads an input template for Siesta
4 5 pfleura2
5 12 pfleura2
!----------------------------------------------------------------------
6 12 pfleura2
!  Copyright 2003-2014 Ecole Normale Supérieure de Lyon,
7 12 pfleura2
!  Centre National de la Recherche Scientifique,
8 12 pfleura2
!  Université Claude Bernard Lyon 1. All rights reserved.
9 12 pfleura2
!
10 12 pfleura2
!  This work is registered with the Agency for the Protection of Programs
11 12 pfleura2
!  as IDDN.FR.001.100009.000.S.P.2014.000.30625
12 12 pfleura2
!
13 12 pfleura2
!  Authors: P. Fleurat-Lessard, P. Dayal
14 12 pfleura2
!  Contact: optnpath@gmail.com
15 12 pfleura2
!
16 12 pfleura2
! This file is part of "Opt'n Path".
17 12 pfleura2
!
18 12 pfleura2
!  "Opt'n Path" is free software: you can redistribute it and/or modify
19 12 pfleura2
!  it under the terms of the GNU Affero General Public License as
20 12 pfleura2
!  published by the Free Software Foundation, either version 3 of the License,
21 12 pfleura2
!  or (at your option) any later version.
22 12 pfleura2
!
23 12 pfleura2
!  "Opt'n Path" is distributed in the hope that it will be useful,
24 12 pfleura2
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
25 12 pfleura2
!
26 12 pfleura2
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27 12 pfleura2
!  GNU Affero General Public License for more details.
28 12 pfleura2
!
29 12 pfleura2
!  You should have received a copy of the GNU Affero General Public License
30 12 pfleura2
!  along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>.
31 12 pfleura2
!
32 12 pfleura2
! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr,
33 12 pfleura2
! for commercial licensing opportunities.
34 12 pfleura2
!----------------------------------------------------------------------
35 12 pfleura2
36 5 pfleura2
  use VarTypes
37 5 pfleura2
  use Path_module
38 5 pfleura2
  use Io_module
39 5 pfleura2
40 5 pfleura2
  IMPLICIT NONE
41 5 pfleura2
42 6 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
43 6 pfleura2
!
44 5 pfleura2
  INTERFACE
45 6 pfleura2
!
46 6 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
47 6 pfleura2
48 5 pfleura2
     function valid(string) result (isValid)
49 5 pfleura2
       CHARACTER(*), intent(in) :: string
50 5 pfleura2
       logical                  :: isValid
51 5 pfleura2
     END function VALID
52 5 pfleura2
53 5 pfleura2
    FUNCTION SearchInput(Input,String,Line,Clean)  Result (Found)
54 5 pfleura2
55 5 pfleura2
      Use Vartypes
56 5 pfleura2
      use io_module
57 5 pfleura2
! Input
58 5 pfleura2
      TYPE (Input_line), POINTER, INTENT(IN) :: Input
59 5 pfleura2
      CHARACTER(*), INTENT(IN) :: String
60 5 pfleura2
      CHARACTER(*), OPTIONAL, INTENT(IN) :: Clean
61 5 pfleura2
62 5 pfleura2
! Output
63 5 pfleura2
      TYPE (Input_line), POINTER, INTENT(OUT) :: Line
64 5 pfleura2
65 5 pfleura2
      LOGICAL :: Found
66 5 pfleura2
67 5 pfleura2
    END FUNCTION SearchInput
68 5 pfleura2
69 5 pfleura2
    FUNCTION InString(Line,String,Case,Clean,Back)  Result(Pos)
70 5 pfleura2
71 5 pfleura2
      Use VarTypes
72 5 pfleura2
73 5 pfleura2
      implicit none
74 5 pfleura2
! Input
75 5 pfleura2
      CHARACTER(*), INTENT(IN) :: Line
76 5 pfleura2
      CHARACTER(*), INTENT(IN) :: String
77 5 pfleura2
      LOGICAL, OPTIONAL, INTENT(IN) :: Case
78 5 pfleura2
      LOGICAL, OPTIONAL, INTENT(IN) :: Back
79 5 pfleura2
      CHARACTER(*), OPTIONAL, INTENT(IN) :: Clean
80 5 pfleura2
81 5 pfleura2
! Output
82 5 pfleura2
! the position of String in Line (the first one) unless Back is present
83 5 pfleura2
      INTEGER(KINT) :: Pos
84 5 pfleura2
    END FUNCTION InString
85 5 pfleura2
86 5 pfleura2
    SUBROUTINE die(routine, msg, file, line, unit)
87 5 pfleura2
88 5 pfleura2
      Use VarTypes
89 5 pfleura2
      Use io_module
90 5 pfleura2
91 5 pfleura2
      implicit none
92 5 pfleura2
!--------------------------------------------------------------- Input Variables
93 5 pfleura2
      character(len=*), intent(in)           :: routine, msg
94 5 pfleura2
      character(len=*), intent(in), optional :: file
95 5 pfleura2
      integer(KINT), intent(in), optional      :: line, unit
96 5 pfleura2
97 5 pfleura2
    END SUBROUTINE die
98 5 pfleura2
99 5 pfleura2
    SUBROUTINE Warning(routine, msg, file, line, unit)
100 5 pfleura2
101 5 pfleura2
      Use VarTypes
102 5 pfleura2
      Use io_module
103 5 pfleura2
104 5 pfleura2
      implicit none
105 6 pfleura2
106 5 pfleura2
      character(len=*), intent(in)           :: routine, msg
107 5 pfleura2
      character(len=*), intent(in), optional :: file
108 5 pfleura2
      integer(KINT), intent(in), optional      :: line, unit
109 5 pfleura2
110 5 pfleura2
    END SUBROUTINE Warning
111 5 pfleura2
112 5 pfleura2
113 5 pfleura2
 SUBROUTINE WriteList(Input,Unit)
114 5 pfleura2
115 5 pfleura2
! This routine reads an input template for Siesta
116 5 pfleura2
117 5 pfleura2
  use VarTypes
118 5 pfleura2
  use Io_module
119 5 pfleura2
120 5 pfleura2
  IMPLICIT NONE
121 5 pfleura2
122 5 pfleura2
! Input
123 5 pfleura2
      TYPE (Input_line), POINTER, INTENT(IN) :: Input
124 5 pfleura2
      INTEGER(KINT), OPTIONAL, INTENT(IN) :: Unit
125 5 pfleura2
126 5 pfleura2
    END SUBROUTINE WriteList
127 5 pfleura2
128 6 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
129 6 pfleura2
!
130 6 pfleura2
 END  INTERFACE
131 6 pfleura2
!
132 6 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
133 5 pfleura2
134 6 pfleura2
135 5 pfleura2
  CHARACTER(132) ::  Line,Line2
136 10 pfleura2
  INTEGER(KINT) ::  Idx,LineL
137 5 pfleura2
  INTEGER(KINT) ::  IAt,I
138 5 pfleura2
  INTEGER(KINT) :: IoRead, ITmp
139 10 pfleura2
  REAL(KREAL) :: B(3),Xtmp, Ytmp, Ztmp
140 10 pfleura2
  REAL(KREAL) :: Lata,Latb,Latc,Alpha,Beta,Gamma
141 10 pfleura2
  REAL(KREAL), ALLOCATABLE :: GeomCartTmp(:,:) ! (Nat,3)
142 10 pfleura2
  REAL(KREAL) :: LatLoc(3,3)
143 5 pfleura2
144 5 pfleura2
  LOGICAL :: Debug
145 5 pfleura2
  LOGICAL :: FSpecies, FCoord
146 5 pfleura2
147 5 pfleura2
  TYPE(Input_Line), POINTER :: Search,Bla
148 5 pfleura2
149 5 pfleura2
  Debug=Valid("readinput").OR.Valid("readinput_siesta")
150 5 pfleura2
151 5 pfleura2
 if (debug) Call Header("Entering ReadInput_Siesta")
152 5 pfleura2
153 5 pfleura2
  ! We read the Siesta input file
154 5 pfleura2
155 5 pfleura2
     ALLOCATE(Siesta_Input)
156 5 pfleura2
     NULLIFY(Siesta_Input%next)
157 5 pfleura2
     NULLIFY(Siesta_Input%prev)
158 5 pfleura2
     Current => Siesta_Input
159 5 pfleura2
160 5 pfleura2
     FSpecies=.FALSE.
161 5 pfleura2
     FCoord=.FALSE.
162 5 pfleura2
163 5 pfleura2
     READ(IOIN,'(A)',iostat=IoRead) Line
164 5 pfleura2
165 5 pfleura2
     DO WHILE (IoRead==0)
166 5 pfleura2
        Line=AdjustL(Line)
167 5 pfleura2
        if (debug) WRITE(*,*) 'Line:', Line
168 5 pfleura2
        current%Line=TRIM(Line)
169 5 pfleura2
        ALLOCATE(current%next)
170 5 pfleura2
        Current%next%prev => Current
171 5 pfleura2
        Current => Current%next
172 5 pfleura2
        current%line="toto"
173 5 pfleura2
        Nullify(Current%next)
174 5 pfleura2
175 5 pfleura2
        READ(IOIN,'(A)',iostat=IoRead) Line
176 5 pfleura2
     END DO
177 5 pfleura2
! With this procedure, the last current is not valid and should be deleted.
178 5 pfleura2
       Bla => Current%prev
179 5 pfleura2
       nullify(Bla%next)
180 5 pfleura2
       deallocate(Current)
181 5 pfleura2
       current => Bla
182 5 pfleura2
183 5 pfleura2
     if (debug) THEN
184 5 pfleura2
        WRITE(*,*) 'Input just read'
185 5 pfleura2
        Call WriteList(Siesta_input,Unit=IOOUT)
186 5 pfleura2
     END IF
187 5 pfleura2
188 5 pfleura2
! We analyse the input
189 5 pfleura2
190 5 pfleura2
! We look for the NumberofAtoms
191 5 pfleura2
     If (SearchInput(Siesta_Input,"NUMBEROFATOMS",Search,Clean=".-_")) THEN
192 5 pfleura2
        Line=AdjustL(Search%line)
193 5 pfleura2
        Idx=Index(Line," ")
194 5 pfleura2
        Line2=Trim(AdjustL(Line(Idx+1:)))
195 5 pfleura2
        Read(Line2,*) IAt
196 5 pfleura2
        if (Iat/=Nat) THEN
197 5 pfleura2
           Call Die('ReadInput_siesta','Nat in FDF sample different from  Nat Path input', Unit=IOOUT)
198 5 pfleura2
        END IF
199 5 pfleura2
     ELSE
200 5 pfleura2
! There is no atom number defined !!!
201 5 pfleura2
           Call Warning('ReadInput_siesta','No NumberOfAtoms in FDF sample', Unit=IOOUT)
202 5 pfleura2
           WRITE(current%Line,'(1X,"NumberOfAtoms ",I5)') Nat
203 5 pfleura2
           ALLOCATE(current%next)
204 5 pfleura2
           Current%next%prev => Current
205 5 pfleura2
           Current => Current%next
206 5 pfleura2
           Nullify(Current%next)
207 5 pfleura2
208 5 pfleura2
        END IF
209 5 pfleura2
210 5 pfleura2
! We look for the NumberofSpecies
211 5 pfleura2
        IF (SearchInput(Siesta_Input,"NUMBEROFSPECIES",Search,Clean=".-_")) THEN
212 5 pfleura2
           Line=AdjustL(Search%line)
213 5 pfleura2
           Idx=Index(Line," ")
214 5 pfleura2
           Line2=Trim(AdjustL(Line(Idx+1:)))
215 5 pfleura2
           Read(Line2,*) Siesta_NbSpecies
216 9 pfleura2
           ALLOCATE(Siesta_SpeciesMass(Siesta_NbSpecies))
217 5 pfleura2
           ALLOCATE(Siesta_SpeciesName(Siesta_NbSpecies))
218 5 pfleura2
        END IF
219 5 pfleura2
220 5 pfleura2
! We look for SystemLabel
221 5 pfleura2
        If (SearchInput(Siesta_Input,"SYSTEMLABEL",Search,Clean=".-_")) THEN
222 5 pfleura2
           Line=AdjustL(Search%line)
223 5 pfleura2
           Idx=Index(Line," ")
224 5 pfleura2
           Siesta_Label=Trim(adjustl(Line(Idx+1:)))
225 5 pfleura2
        ELSE
226 5 pfleura2
           Siesta_label='siesta'
227 5 pfleura2
        END IF
228 5 pfleura2
229 5 pfleura2
! We look for the ChemicalSpeciesLabel block
230 5 pfleura2
        IF (SearchInput(Siesta_Input,"CHEMICALSPECIESLABEL",Search,Clean=".-_")) THEN
231 5 pfleura2
           if (.NOT.ALLOCATED(IdxSpecies)) ALLOCATE(IdxSpecies(NAt))
232 5 pfleura2
           I=0
233 5 pfleura2
           Search => Search%next
234 5 pfleura2
           DO WHILE (InString(Search%line,'ENDBLOCK',Case=.FALSE.,Clean=".-_")==0)
235 5 pfleura2
              I=I+1
236 5 pfleura2
              if (I>Siesta_NbSpecies) THEN
237 5 pfleura2
                 Call Die('ReadInput_siesta:Reading ChemicalSpeciesLabel','Found more line in this block than NbSpecies !')
238 5 pfleura2
              END IF
239 5 pfleura2
              Line=AdjustL(Search%Line)
240 5 pfleura2
              Read(Line,*) ITmp
241 5 pfleura2
              Idx=Index(Line,' ')
242 5 pfleura2
              Line=AdjustL(Line(Idx+1:))
243 9 pfleura2
              Read(Line,*) Idx
244 9 pfleura2
              Siesta_SpeciesMass(ITmp)=Idx
245 5 pfleura2
              Idx=Index(Line,' ')
246 5 pfleura2
              Line=AdjustL(Line(Idx+1:))
247 5 pfleura2
              Idx=Index(Line,' ')
248 5 pfleura2
              Siesta_SpeciesName(ITmp)=Line(1:Idx-1)
249 5 pfleura2
              Search => Search%next
250 5 pfleura2
           END DO
251 5 pfleura2
           IF (I/=Siesta_NbSpecies) Call Die('ReadInput_siesta:Reading ChemicalSpeciesLabel', &
252 5 pfleura2
                'Number of lines in this block different from NbSpecies')
253 5 pfleura2
        ELSE
254 5 pfleura2
           Call Die('ReadInput_siesta:Reading ChemicalSpeciesLabel', &
255 5 pfleura2
                'Block ChemicalSpeciesLabel is mandatory !')
256 5 pfleura2
        END IF
257 5 pfleura2
258 5 pfleura2
259 5 pfleura2
! We look for the AtomicCoordinatesAndAtomicSpecies  block
260 5 pfleura2
        IF (SearchInput(Siesta_Input,"ATOMICCOORDINATESANDATOMICSPECIES",Search,Clean=".-_")) THEN
261 5 pfleura2
           ALLOCATE(Siesta_Paste(Nat))
262 5 pfleura2
           Current=>Search
263 5 pfleura2
           DO I=1,NAt
264 5 pfleura2
              Search => Search%next
265 5 pfleura2
              Read(Search%line,*) XTmp,YTmp,ZTmp,IdxSpecies(I)
266 6 pfleura2
! We give a name to this atom
267 6 pfleura2
              IF (AtName(I)/="") THEN
268 6 pfleura2
!                    Write(Line,'(A,I5,1X,A2,1X,A32)') 'AtName & SpeciesName for atom ',I,AtName(I), &
269 6 pfleura2
!                         TRIM(Siesta_SpeciesName(IdxSpecies(I)))
270 6 pfleura2
!                    WRITE(*,'(1X,A)') Line
271 6 pfleura2
                 If (InString(Atname(I),TRIM(Siesta_SpeciesName(IdxSpecies(I))))==0) THEN
272 6 pfleura2
                    Write(Line,'(A,I5,1X,A2,1X,A32)') 'AtName /= SpeciesName for atom ',I,AtName(I), &
273 6 pfleura2
                         TRIM(Siesta_SpeciesName(IdxSpecies(I)))
274 6 pfleura2
                    Call Die('Readinput_siesta:Reading AtomicCoordinatesAndAtomicSpecies',Line,Unit=IOOUT)
275 6 pfleura2
                 END IF
276 9 pfleura2
! We look for the Mass number also
277 9 pfleura2
                 IF (Atome(I)/=Siesta_SpeciesMass(IdxSpecies(I))) THEN
278 9 pfleura2
                    Write(Line,'(A,I5,1X,I5,1X,I5)') 'AtMass /= SpeciesMass for atom ',I,Atome(I), &
279 9 pfleura2
                         Siesta_SpeciesMass(IdxSpecies(I))
280 9 pfleura2
                    Call Die('ReadInput_siesta:Reading AtomicCoordinatesAndAtomicSpecies',Line,Unit=IOOUT)
281 9 pfleura2
                 END IF
282 6 pfleura2
              ELSE
283 6 pfleura2
                 AtName(I)=AdjustL(Trim(Siesta_SpeciesName(IdxSpecies(I))))
284 9 pfleura2
                 Atome(I)=Siesta_SpeciesMass(IdxSpecies(I))
285 6 pfleura2
              END IF
286 6 pfleura2
! we look for something else at the end of the line
287 5 pfleura2
! We save everything but the x,y,z, and species description
288 5 pfleura2
              Line=AdjustL(search%line)
289 5 pfleura2
! We skip x
290 5 pfleura2
              Idx=Index(Line,' ')
291 5 pfleura2
              Line=AdjustL(Line(Idx+1:))
292 5 pfleura2
! we skip y
293 5 pfleura2
              Idx=Index(Line,' ')
294 5 pfleura2
              Line=AdjustL(Line(Idx+1:))
295 5 pfleura2
! we skip z
296 5 pfleura2
              Idx=Index(Line,' ')
297 5 pfleura2
              Line=AdjustL(Line(Idx+1:))
298 5 pfleura2
! we skip species
299 5 pfleura2
              Idx=Index(Line,' ')
300 5 pfleura2
              Line=AdjustL(Line(Idx+1:))
301 5 pfleura2
              Siesta_Paste(I)=TRIM(Line)
302 5 pfleura2
           END DO
303 5 pfleura2
           if (debug) THEN
304 5 pfleura2
              WRITE(*,*) 'Input before deletion of coord block'
305 5 pfleura2
              Call WriteList(Siesta_input)
306 5 pfleura2
           END IF
307 5 pfleura2
! We will now delete this block from our input sample as it will then be
308 5 pfleura2
! written directly by Opt'n Path
309 5 pfleura2
! Search%next point on %endblock
310 5 pfleura2
           search => search%next
311 5 pfleura2
           IF (ASSOCIATED(Search%next)) THEN
312 5 pfleura2
! we are not at the end of the input file
313 5 pfleura2
              if (ASSOCIATED(Current%Prev)) THEN
314 5 pfleura2
                 Search%next%prev => current%prev
315 5 pfleura2
                 current%prev%next => search%next
316 5 pfleura2
              ELSE
317 5 pfleura2
! the coordinate block is at the begining of the input
318 5 pfleura2
                 siesta_input => Search%next
319 5 pfleura2
                 Nullify(Siesta_Input%Prev)
320 5 pfleura2
              END IF
321 5 pfleura2
           ELSE
322 5 pfleura2
! the coordinate block is the last part of the input
323 5 pfleura2
              nullify(current%prev%next)
324 5 pfleura2
           END IF
325 5 pfleura2
           if (debug) THEN
326 5 pfleura2
              WRITE(*,*) 'Input after deletion of coord block 1'
327 5 pfleura2
              Call WriteList(Siesta_input)
328 5 pfleura2
           END IF
329 5 pfleura2
330 5 pfleura2
           DO I=1,Nat+2
331 5 pfleura2
              bla=>current
332 5 pfleura2
              current=> current%next
333 5 pfleura2
              deallocate(bla)
334 5 pfleura2
           END DO
335 5 pfleura2
           if (debug) THEN
336 5 pfleura2
              WRITE(*,*) 'Input after deletion of coord block 2'
337 5 pfleura2
              Call WriteList(Siesta_input)
338 5 pfleura2
           END IF
339 5 pfleura2
        ELSE
340 5 pfleura2
           IF (SearchInput(Siesta_Input,"ZMATRIX",Search,Clean=".-_")) THEN
341 5 pfleura2
              call Die('ReadInput_Siesta','For now, I need the full block'//&
342 5 pfleura2
                   'AtomicCoordinatesAndAtomicSpecies, ZMatrix not yet handled.')
343 5 pfleura2
           ELSE
344 5 pfleura2
              call Die('ReadInput_Siesta','For now, I need the full block' //&
345 5 pfleura2
              'AtomicCoordinatesAndAtomicSpecies.')
346 5 pfleura2
           END IF
347 5 pfleura2
        END IF
348 5 pfleura2
349 10 pfleura2
        IF (SearchInput(Siesta_Input,"LATTICE",Search,Clean=".-_")) THEN
350 10 pfleura2
! This is a pbc calculation
351 10 pfleura2
           FPBC=.TRUE.
352 10 pfleura2
           IPer=3
353 10 pfleura2
           Kabeg=-1
354 10 pfleura2
           kaEnd=1
355 10 pfleura2
           kbBeg=-1
356 10 pfleura2
           kbEnd=1
357 10 pfleura2
           kcBeg=-1
358 10 pfleura2
           kcEnd=1
359 10 pfleura2
360 10 pfleura2
361 10 pfleura2
         IF (SearchInput(Siesta_Input,"LATTICECONSTANT",Search,Clean=".-_")) THEN
362 5 pfleura2
           Line=Adjustl(Search%Line)
363 10 pfleura2
! We discar the label
364 5 pfleura2
           Idx=Index(Line,' ')
365 5 pfleura2
           Line=AdjustL(Line(Idx+1:))
366 10 pfleura2
! we read the value
367 10 pfleura2
           Read(Line,*) Siesta_LatticeConstant
368 10 pfleura2
! We discard the value
369 10 pfleura2
           Idx=Index(Line,' ')
370 10 pfleura2
           Line=AdjustL(Line(Idx+1:))
371 10 pfleura2
           LineL=Len_Trim(Line)
372 10 pfleura2
! We read the unit
373 10 pfleura2
           If (LineL>0) THEN
374 10 pfleura2
              Call UpCase(Line)
375 10 pfleura2
              SELECT CASE (Line)
376 10 pfleura2
                CASE ('ANG')
377 10 pfleura2
                   Siesta_Lat_Unit=1.d0
378 10 pfleura2
                CASE ('BOHR')
379 10 pfleura2
                   Siesta_Lat_Unit=a0
380 10 pfleura2
              END SELECT
381 10 pfleura2
           ELSE
382 10 pfleura2
              Siesta_Lat_Unit=1.d0
383 10 pfleura2
           END IF
384 10 pfleura2
         ELSE
385 10 pfleura2
! We have no LatticeConstant but we need one for our calculation
386 10 pfleura2
            Siesta_LatticeConstant=1.
387 10 pfleura2
            Siesta_Lat_Unit=1.d0
388 10 pfleura2
         END IF
389 10 pfleura2
390 10 pfleura2
         IF (SearchInput(Siesta_Input,"LATTICEVECTORS",Search,Clean=".-_")) THEN
391 10 pfleura2
           search => search%next
392 10 pfleura2
           Line=Adjustl(Search%Line)
393 10 pfleura2
           Read(Line,*) Lat_a(1:3)
394 10 pfleura2
           search => search%next
395 10 pfleura2
           Line=Adjustl(Search%Line)
396 10 pfleura2
           Read(Line,*) Lat_b(1:3)
397 10 pfleura2
           search => search%next
398 10 pfleura2
           Line=Adjustl(Search%Line)
399 10 pfleura2
           Read(Line,*) Lat_c(1:3)
400 10 pfleura2
401 10 pfleura2
         ELSEIF (SearchInput(Siesta_Input,"LATTICEPARAMETERS",Search,Clean=".-_")) THEN
402 10 pfleura2
           search => search%next
403 10 pfleura2
           Line=Adjustl(Search%Line)
404 10 pfleura2
           Read(Line,*) Lata,Latb,Latc,Alpha,Beta,Gamma
405 10 pfleura2
406 10 pfleura2
            Lat_a=0.
407 10 pfleura2
            Lat_b=0.
408 10 pfleura2
            Lat_c=0.
409 10 pfleura2
            Lat_a(1)=Lata
410 10 pfleura2
            Lat_b(1)=LatB*cos(Gamma*Pi/180d0)
411 10 pfleura2
            Lat_b(2)=LatB*sin(Gamma*Pi/180d0)
412 10 pfleura2
            Lat_c(1)=Latc*cos(Beta*Pi/180.)
413 10 pfleura2
            Lat_c(2)=(Latb*Latc*cos(Alpha*Pi/180.)-Lat_b(1)*Lat_c(1))/Lat_b(2)
414 10 pfleura2
            Lat_c(3)=sqrt(Latc*Latc-Lat_c(1)**2-Lat_c(2)**2)
415 10 pfleura2
         ELSE
416 10 pfleura2
! We have a lattice constant but nothing else. We issue a warning just in case,
417 10 pfleura2
! and we take the defaut values 1. 1. 1. 90. 90. 90.
418 10 pfleura2
            Line="LatticeConstant found, but not LatticeVectors nor LatticeParameters. Taking 1. 1. 1. 90. 90. 90."
419 10 pfleura2
            Call Warning("ReadInput_siesta",Line)
420 10 pfleura2
            Lat_a=(/1.,0.,0./)
421 10 pfleura2
            Lat_b=(/0.,1.,0./)
422 10 pfleura2
            Lat_c=(/0.,0.,1./)
423 10 pfleura2
         END IF
424 10 pfleura2
425 10 pfleura2
         IF (debug) THEN
426 10 pfleura2
            WRITE(*,*) "Lattice vectors before scaling with LatticeConstant"
427 10 pfleura2
            WRITE(*,'(1X,A,3(1X,F10.6))')   "Lat_a",Lat_a
428 10 pfleura2
            WRITE(*,'(1X,A,3(1X,F10.6))')   "Lat_b",Lat_b
429 10 pfleura2
            WRITE(*,'(1X,A,3(1X,F10.6))')   "Lat_c",Lat_c
430 10 pfleura2
         END IF
431 10 pfleura2
           Lat_a=Lat_a*Siesta_LatticeConstant*Siesta_Lat_Unit
432 10 pfleura2
           Lat_b=Lat_b*Siesta_LatticeConstant*Siesta_Lat_Unit
433 10 pfleura2
           Lat_c=Lat_c*Siesta_LatticeConstant*Siesta_Lat_Unit
434 10 pfleura2
435 10 pfleura2
         IF (debug) THEN
436 10 pfleura2
            WRITE(*,*) "Lattice vectors After scaling with LatticeConstant"
437 10 pfleura2
            WRITE(*,'(1X,A,3(1X,F10.6))')   "Lat_a",Lat_a
438 10 pfleura2
            WRITE(*,'(1X,A,3(1X,F10.6))')   "Lat_b",Lat_b
439 10 pfleura2
            WRITE(*,'(1X,A,3(1X,F10.6))')   "Lat_c",Lat_c
440 10 pfleura2
         END IF
441 10 pfleura2
442 10 pfleura2
      END IF
443 10 pfleura2
444 10 pfleura2
         IF (SearchInput(Siesta_Input,"ATOMICCOORDINATESFORMAT",Search,Clean=".-_")) THEN
445 10 pfleura2
           Line=Adjustl(Search%Line)
446 10 pfleura2
           Idx=Index(Line,' ')
447 10 pfleura2
           Line=AdjustL(Line(Idx+1:))
448 5 pfleura2
           Call UpCase(Line)
449 5 pfleura2
           SELECT CASE (Line)
450 5 pfleura2
              CASE ('ANG','NOTSCALEDCARTESIANANG')
451 5 pfleura2
                 Siesta_Unit_Read=1.d0
452 5 pfleura2
              CASE ('FRACTIONAL','SCALEDBYLATTICEVECTORS')
453 10 pfleura2
                 IF (FPBC) THEN
454 10 pfleura2
                    Siesta_Unit_Read=1.d0
455 10 pfleura2
                    V_DIRECT="DIRECT"
456 10 pfleura2
                    Latr(1:3,1)=Lat_a
457 10 pfleura2
                    Latr(1:3,2)=Lat_b
458 10 pfleura2
                    Latr(1:3,3)=Lat_c
459 10 pfleura2
                    B=1.
460 10 pfleura2
! TO DO: replace by LAPACK
461 10 pfleura2
                    CALL Gaussj(Latr,3,3,B,1,1)
462 10 pfleura2
                    LatLoc(1:3,1)=Lat_a
463 10 pfleura2
                    LatLoc(1:3,2)=Lat_b
464 10 pfleura2
                    LatLoc(1:3,3)=Lat_c
465 10 pfleura2
                    Allocate(GeomCartTmp(Nat,3))
466 10 pfleura2
                    Do I=1,NGeomI
467 10 pfleura2
                       GeomCartTmp=Reshape(XyzGeomI(I,1:3,1:Nat),(/Nat,3/),ORDER=(/2,1/))
468 10 pfleura2
! TO DO: shall we replace MatMull by DGEMM ?
469 10 pfleura2
                       XyzGeomI(I,1:3,1:Nat)=Reshape(MatMul(GeomCartTmp,Latloc),(/3,Nat/),ORDER=(/2,1/))
470 10 pfleura2
                   END DO
471 10 pfleura2
                 ELSE
472 10 pfleura2
                    WRITE(Line2,*) "AtomicCoordinatesFormat=" // Trim(Line) &
473 10 pfleura2
               //", but there is no information about Lattice parameters"
474 10 pfleura2
                    Call Die("ReadInput_siesta",Line2)
475 10 pfleura2
                 END IF
476 5 pfleura2
              CASE ('BOHR','NOTSCALEDCARTESIANBOHR')
477 5 pfleura2
                 Siesta_Unit_Read=a0
478 5 pfleura2
                 IF (INPUT=='SIESTA') THEN
479 5 pfleura2
! We have read the coordinates, but not the unit. This is corrected here
480 5 pfleura2
                    XyZGeomI=XyzGeomI*a0
481 5 pfleura2
                 END IF
482 10 pfleura2
              CASE ('SCALEDCARTESIAN')
483 10 pfleura2
                 Siesta_Unit_Read=Siesta_LatticeConstant
484 10 pfleura2
                 If (INPUT=='SIESTA') THEN
485 10 pfleura2
                    XyzGeomI=XyzGeomI*Siesta_Unit_Read
486 10 pfleura2
                 END IF
487 5 pfleura2
            END SELECT
488 10 pfleura2
         ELSE
489 10 pfleura2
            Siesta_Unit_Read=1.d0
490 5 pfleura2
         END IF
491 5 pfleura2
492 5 pfleura2
        IF (SearchInput(Siesta_Input,"ATOMICCOORFORMATOUT",Search,Clean=".-_")) THEN
493 5 pfleura2
           Line=Adjustl(Search%Line)
494 5 pfleura2
           Idx=Index(Line,' ')
495 5 pfleura2
           Line=AdjustL(Line(Idx+1:))
496 5 pfleura2
           Call UpCase(Line)
497 5 pfleura2
           SELECT CASE (Line)
498 5 pfleura2
              CASE ('ANG','NOTSCALEDCARTESIANANG')
499 5 pfleura2
                 Siesta_Unit_Write=1.d0
500 5 pfleura2
              CASE ('FRACTIONAL','SCALEDBYLATTICEVECTORS')
501 10 pfleura2
                 Siesta_Unit_Write=1.d0
502 10 pfleura2
                 V_DIRECT_Write='DIRECT'
503 5 pfleura2
              CASE ('BOHR','NOTSCALEDCARTESIANBOHR')
504 10 pfleura2
                 Siesta_Unit_Write=Unit ! 1/a0
505 5 pfleura2
            END SELECT
506 5 pfleura2
         END IF
507 5 pfleura2
         IF (SearchInput(Siesta_Input,"SUPERCELL",Search,Clean=".-_")) THEN
508 10 pfleura2
            Line=Adjustl(search%line)
509 10 pfleura2
            Call Upcase(Line)
510 10 pfleura2
            Call CleanString(Line,".-_")
511 10 pfleura2
            If (Index(Line,"%BLOCK")/=0) THEN
512 10 pfleura2
               Call Die('ReadInput_siesta:SuperCell',"SuperCell  NOT possible in Opt'n Path")
513 10 pfleura2
            END IF
514 5 pfleura2
         END IF
515 5 pfleura2
516 5 pfleura2
!         Call Die('Readinput_siesta:fin',' Lecture finie')
517 5 pfleura2
518 5 pfleura2
     if (debug) Call Header("Exiting ReadInput_Siesta")
519 5 pfleura2
520 5 pfleura2
   END SUBROUTINE READINPUT_SIESTA