2003-02-08 00:04:36 +08:00
|
|
|
!
|
2005-03-21 21:43:38 +08:00
|
|
|
! Copyright (C) 2003 Tone Kokalj
|
2003-01-29 02:47:19 +08:00
|
|
|
! This file is distributed under the terms of the
|
|
|
|
! GNU General Public License. See the file `License'
|
|
|
|
! in the root directory of the present distribution,
|
|
|
|
! or http://www.gnu.org/copyleft/gpl.txt .
|
2005-03-21 21:43:38 +08:00
|
|
|
!
|
|
|
|
! This file holds XSF (=Xcrysden Structure File) utilities.
|
|
|
|
! Routines written by Tone Kokalj on Mon Jan 27 18:51:17 CET 2003
|
|
|
|
!
|
2003-01-29 02:47:19 +08:00
|
|
|
! -------------------------------------------------------------------
|
|
|
|
! this routine writes the crystal structure in XSF format
|
|
|
|
! -------------------------------------------------------------------
|
|
|
|
subroutine xsf_struct (alat, at, nat, tau, atm, ityp, ounit)
|
2004-01-23 23:08:03 +08:00
|
|
|
USE kinds, only : DP
|
2006-12-14 16:53:47 +08:00
|
|
|
USE constants, only : BOHR_RADIUS_ANGS
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
|
|
|
integer :: nat, ityp (nat), ounit
|
2003-01-29 02:47:19 +08:00
|
|
|
character(len=3) :: atm(*)
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) :: alat, tau (3, nat), at (3, 3)
|
2003-01-29 02:47:19 +08:00
|
|
|
! --
|
|
|
|
integer :: i, j, n
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) :: at1 (3, 3)
|
2003-01-29 02:47:19 +08:00
|
|
|
! convert lattice vectors to ANGSTROM units ...
|
|
|
|
do i=1,3
|
|
|
|
do j=1,3
|
2006-12-14 16:53:47 +08:00
|
|
|
at1(j,i) = at(j,i)*alat*BOHR_RADIUS_ANGS
|
2003-01-29 02:47:19 +08:00
|
|
|
enddo
|
|
|
|
enddo
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
write(ounit,*) 'CRYSTAL'
|
|
|
|
write(ounit,*) 'PRIMVEC'
|
|
|
|
write(ounit,'(2(3F15.9/),3f15.9)') at1
|
|
|
|
write(ounit,*) 'PRIMCOORD'
|
|
|
|
write(ounit,*) nat, 1
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
do n=1,nat
|
|
|
|
! positions are in Angstroms
|
|
|
|
write(ounit,'(a3,3x,3f15.9)') atm(ityp(n)), &
|
2006-12-14 16:53:47 +08:00
|
|
|
tau(1,n)*alat*BOHR_RADIUS_ANGS, &
|
|
|
|
tau(2,n)*alat*BOHR_RADIUS_ANGS, &
|
|
|
|
tau(3,n)*alat*BOHR_RADIUS_ANGS
|
2003-01-29 02:47:19 +08:00
|
|
|
enddo
|
|
|
|
return
|
|
|
|
end subroutine xsf_struct
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
! -------------------------------------------------------------------
|
|
|
|
! this routine writes the 3D scalar field (i.e. uniform mesh of points)
|
|
|
|
! in XSF format using the FFT mesh (i.e. fast write)
|
|
|
|
! -------------------------------------------------------------------
|
|
|
|
subroutine xsf_fast_datagrid_3d &
|
|
|
|
(rho, nr1, nr2, nr3, nrx1, nrx2, nrx3, at, alat, ounit)
|
2004-01-23 23:08:03 +08:00
|
|
|
USE kinds, only : DP
|
2006-12-14 16:53:47 +08:00
|
|
|
USE constants, ONLY : BOHR_RADIUS_ANGS
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
|
|
|
integer :: nrx1, nrx2, nrx3, nr1, nr2, nr3, ounit
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) :: alat, at (3, 3), rho(nrx1,nrx2,nrx3)
|
2003-01-29 02:47:19 +08:00
|
|
|
! --
|
|
|
|
integer :: i1, i2, i3, ix, iy, iz, count, i, ii, &
|
|
|
|
ind_x(10), ind_y(10),ind_z(10)
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
! XSF scalar-field header
|
|
|
|
write(ounit,'(a)') 'BEGIN_BLOCK_DATAGRID_3D'
|
|
|
|
write(ounit,'(a)') '3D_PWSCF'
|
|
|
|
write(ounit,'(a)') 'DATAGRID_3D_UNKNOWN'
|
|
|
|
|
|
|
|
! number of points in each direction
|
|
|
|
write(ounit,*) nr1+1, nr2+1, nr3+1
|
|
|
|
! origin
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') 0.0d0, 0.0d0, 0.0d0
|
2003-01-29 02:47:19 +08:00
|
|
|
! 1st spanning (=lattice) vector
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*at(i,1),i=1,3) ! in ANSTROMS
|
2003-01-29 02:47:19 +08:00
|
|
|
! 2nd spanning (=lattice) vector
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*at(i,2),i=1,3)
|
2003-01-29 02:47:19 +08:00
|
|
|
! 3rd spanning (=lattice) vector
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*at(i,3),i=1,3)
|
2003-01-29 02:47:19 +08:00
|
|
|
|
|
|
|
count=0
|
|
|
|
do i3=0,nr3
|
|
|
|
!iz = mod(i3,nr3)
|
|
|
|
iz = mod(i3,nr3) + 1
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
do i2=0,nr2
|
|
|
|
!iy = mod(i2,nr2)
|
|
|
|
iy = mod(i2,nr2) + 1
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
do i1=0,nr1
|
|
|
|
!ix = mod(i1,nr1)
|
|
|
|
ix = mod(i1,nr1) + 1
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
!ii = (1+ix) + iy*nrx1 + iz*nrx1*nrx2
|
|
|
|
if (count.lt.6) then
|
|
|
|
count = count + 1
|
|
|
|
!ind(count) = ii
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
2003-01-29 02:47:19 +08:00
|
|
|
write(ounit,'(6e13.5)') &
|
2003-05-08 23:59:00 +08:00
|
|
|
(rho(ind_x(i),ind_y(i),ind_z(i)),i=1,6)
|
2003-01-29 02:47:19 +08:00
|
|
|
count=1
|
|
|
|
!ind(count) = ii
|
|
|
|
endif
|
|
|
|
ind_x(count) = ix
|
|
|
|
ind_y(count) = iy
|
|
|
|
ind_z(count) = iz
|
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
enddo
|
2003-05-08 23:59:00 +08:00
|
|
|
write(ounit,'(6e13.5:)') (rho(ind_x(i),ind_y(i),ind_z(i)),i=1,count)
|
2003-01-29 02:47:19 +08:00
|
|
|
write(ounit,'(a)') 'END_DATAGRID_3D'
|
|
|
|
write(ounit,'(a)') 'END_BLOCK_DATAGRID_3D'
|
|
|
|
return
|
|
|
|
end subroutine xsf_fast_datagrid_3d
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
|
|
|
|
|
2003-05-08 23:59:00 +08:00
|
|
|
subroutine xsf_datagrid_2d (rho, nx, ny, m1, m2, x0, e1, e2, alat, ounit)
|
2004-01-23 23:08:03 +08:00
|
|
|
USE kinds, only : DP
|
2006-12-14 16:53:47 +08:00
|
|
|
USE constants, ONLY : BOHR_RADIUS_ANGS
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
|
|
|
integer :: nx, ny, ounit
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) :: m1, m2, alat, x0(3), e1(3), e2(3), rho(2, nx, ny)
|
2003-01-29 02:47:19 +08:00
|
|
|
! --
|
|
|
|
integer :: ix, iy, count, i, ind_x(10), ind_y(10)
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
! XSF scalar-field header
|
|
|
|
write(ounit,'(a)') 'BEGIN_BLOCK_DATAGRID_2D'
|
|
|
|
write(ounit,'(a)') '2D_PWSCF'
|
|
|
|
write(ounit,'(a)') 'DATAGRID_2D_UNKNOWN'
|
|
|
|
|
|
|
|
! number of points in each direction
|
|
|
|
write(ounit,*) nx, ny
|
|
|
|
! origin
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*x0(i),i=1,3) ! in ANSTROMS
|
2003-01-29 02:47:19 +08:00
|
|
|
! 1st spanning (=lattice) vector
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*e1(i)*m1,i=1,3) ! in ANSTROMS
|
2003-01-29 02:47:19 +08:00
|
|
|
! 2nd spanning (=lattice) vector
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*e2(i)*m2,i=1,3) ! in ANSTROMS
|
2003-01-29 02:47:19 +08:00
|
|
|
|
|
|
|
count=0
|
|
|
|
do iy=1,ny
|
|
|
|
do ix=1,nx
|
2003-05-08 23:59:00 +08:00
|
|
|
if (count < 6) then
|
2003-01-29 02:47:19 +08:00
|
|
|
count = count + 1
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
2003-01-29 02:47:19 +08:00
|
|
|
write(ounit,'(6e13.5)') (rho(1,ind_x(i),ind_y(i)),i=1,6)
|
|
|
|
count=1
|
|
|
|
endif
|
|
|
|
ind_x(count) = ix
|
|
|
|
ind_y(count) = iy
|
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
write(ounit,'(6e13.5:)') (rho(1,ind_x(i),ind_y(i)),i=1,count)
|
2003-01-29 02:47:19 +08:00
|
|
|
write(ounit,'(a)') 'END_DATAGRID_2D'
|
|
|
|
write(ounit,'(a)') 'END_BLOCK_DATAGRID_2D'
|
|
|
|
return
|
|
|
|
end subroutine xsf_datagrid_2d
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-05-08 23:59:00 +08:00
|
|
|
subroutine xsf_datagrid_3d &
|
|
|
|
(rho, nx, ny, nz, m1, m2, m3, x0, e1, e2, e3, alat, ounit)
|
2004-01-23 23:08:03 +08:00
|
|
|
USE kinds, only : DP
|
2006-12-14 16:53:47 +08:00
|
|
|
USE constants, ONLY : BOHR_RADIUS_ANGS
|
2003-02-08 00:04:36 +08:00
|
|
|
implicit none
|
|
|
|
integer :: nx, ny, nz, ounit
|
2005-08-28 22:09:42 +08:00
|
|
|
real(DP) :: m1, m2, m3, alat, x0(3), e1(3),e2(3),e3(3), rho(nx, ny, nz)
|
2003-01-29 02:47:19 +08:00
|
|
|
! --
|
|
|
|
integer :: ix, iy, iz, count, i, ind_x(10), ind_y(10), ind_z(10)
|
2003-02-08 00:04:36 +08:00
|
|
|
|
2003-01-29 02:47:19 +08:00
|
|
|
! XSF scalar-field header
|
|
|
|
write(ounit,'(a)') 'BEGIN_BLOCK_DATAGRID_3D'
|
|
|
|
write(ounit,'(a)') '3D_PWSCF'
|
|
|
|
write(ounit,'(a)') 'DATAGRID_3D_UNKNOWN'
|
|
|
|
|
|
|
|
! number of points in each direction
|
|
|
|
write(ounit,*) nx, ny, nz
|
|
|
|
! origin
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*x0(i),i=1,3) ! in ANSTROMS
|
2003-01-29 02:47:19 +08:00
|
|
|
! 1st spanning (=lattice) vector
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*e1(i)*m1,i=1,3) ! in ANSTROMS
|
2003-01-29 02:47:19 +08:00
|
|
|
! 2nd spanning (=lattice) vector
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*e2(i)*m2,i=1,3) ! in ANSTROMS
|
2003-01-29 02:47:19 +08:00
|
|
|
! 3rd spanning (=lattice) vector
|
2006-12-14 16:53:47 +08:00
|
|
|
write(ounit,'(3f10.6)') (BOHR_RADIUS_ANGS*alat*e3(i)*m3,i=1,3)
|
2003-01-29 02:47:19 +08:00
|
|
|
|
|
|
|
count=0
|
|
|
|
do iz=1,nz
|
|
|
|
do iy=1,ny
|
|
|
|
do ix=1,nx
|
|
|
|
if (count.lt.6) then
|
|
|
|
count = count + 1
|
2003-02-08 00:04:36 +08:00
|
|
|
else
|
2003-01-29 02:47:19 +08:00
|
|
|
write(ounit,'(6e13.5)') (rho(ind_x(i),ind_y(i),ind_z(i)),i=1,6)
|
|
|
|
count=1
|
|
|
|
endif
|
|
|
|
ind_x(count) = ix
|
|
|
|
ind_y(count) = iy
|
|
|
|
ind_z(count) = iz
|
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
enddo
|
|
|
|
|
2003-02-08 00:04:36 +08:00
|
|
|
write(ounit,'(6e13.5:)') (rho(ind_x(i),ind_y(i),ind_z(i)),i=1,count)
|
2003-01-29 02:47:19 +08:00
|
|
|
write(ounit,'(a)') 'END_DATAGRID_3D'
|
|
|
|
write(ounit,'(a)') 'END_BLOCK_DATAGRID_3D'
|
|
|
|
return
|
|
|
|
end subroutine xsf_datagrid_3d
|